Dynamics AX 3.0 'da ODBC Insert-Update

Son olarak ODBC kullanarak Insert ve Update işlemlerine bakalım, Bu işlemin diğer yaptığımız işlemden çok bir farkı yok.


Static boolean ODBCInsertUpdate()

{
str strSQL;
ODBCConnector ODBCContent; // bir önceki makalede bulunan fonksiyon bulunduğu Class
Statement statementContent;

;
try {

strSQL=strfmt("INSERT INTO Table (fld1,fld2) VALUES ('%1','%2')",statement1,statement2);
statementContent=ODBCConnector::newODBCConnectionStatement();
statementContent.executeUpdate(strSQL);
statementContent.close();
return true;

}
catch (Exception::Error)
{
throw Exception::Error;
}
catch (Exception::Break)
{
throw Exception::Break;
}
catch (Exception::DDEerror)
{
throw Exception::DDEerror;
}
catch (Exception::Deadlock)
{
throw Exception::Error;
}
catch (Exception::Info)
{
throw Exception::Info;
}
catch (Exception::Internal)
{
throw Exception::Internal;
}
catch (Exception::Numeric)
{
throw Exception::Numeric;
}
catch (Exception::Sequence)
{
throw Exception::Sequence;
}
catch (Exception::Warning)
{
throw Exception::Warning;
}
}

Dynamics AX 3.0 'da ODBC Select

Bir önceki makalemizin devamı olarak değerlendirebilirsiniz. Şimdi bir Select ifadesini nasıl kullanacağımızı ve dönen değeri resultSet'e atarak nasıl kullancağımıza bakalım.

Static boolean ODBCSelect()
{
str strSQL;
ODBCConnector ODBCContent; // bir önceki makalede bulunan fonksiyon bulunduğu Class
ResultSet resultSetContent;
Statement statementContent;
int contentID ;
str contentStr;
;
try {

strSQL=strfmt("SELECT * FROM Table WHERE con ='%1' ",statement,);
statementContent=ODBCConnector::newODBCConnectionStatement();
resultSetContent=statementContent.executeQuery(strSQL);
while(resultSetContent.next())
{
contentID = resultSetContent.getInt(1);
contentStr=resultSetContent.getString(2); // Alanın dönen değerdeki yeri parametre olarak verilmeli

}
resultSetContent.close();
statementContent.close();
return true;

}
catch (Exception::Error)
{
throw Exception::Error;
}
catch (Exception::Break)
{
throw Exception::Break;
}
catch (Exception::DDEerror)
{
throw Exception::DDEerror;
}
catch (Exception::Deadlock)
{
throw Exception::Error;
}
catch (Exception::Info)
{
throw Exception::Info;
}
catch (Exception::Internal)
{
throw Exception::Internal;
}
catch (Exception::Numeric)
{
throw Exception::Numeric;
}
catch (Exception::Sequence)
{
throw Exception::Sequence;
}
catch (Exception::Warning)
{
throw Exception::Warning;
}
}

Dynamics AX 3.0 'da ODBC Connection

Bu makalemizde Axapta'da ODBC kullanarak SQL veritabanına nasıl erişeceğimize ait örnekleri görebilirsiniz.
Axaptada ODBC ayarlarını yapmak ve SQL üzerinde işlem yapmak son derece kolaydır.
İlk olarak bir ODBC kullanarak SQL'e nasıl login olacağımıza bakalım. Aşağadaki örnekte görebileceğiniz gibi ODBCConnection ve loginProperty isimli 2sınıf (Classes) kullanılmış. Login olunacak server bilgileri LoginProperty ile tanımlandıktan sonra. Yeni bir ODBCConnection statement 'ı oluştrulur.
diğer örneklerde kullanmak açısından, bu fonksyonun oluşturacağımız ODBCConnector isimli bir classes'da kullanabilirsiniz.

Static Statement newODBCConnectionStatement()
{
ODBCConnection oDBCConnection;
LoginProperty loginProperty;
Statement statement;
;
try
{
loginProperty = new LoginProperty();
loginProperty.setServer("SQLServer");
loginProperty.setDatabase("Database");
loginProperty.setUsername("UserName");
loginProperty.setPassword("UserPassword");

oDBCConnection = new ODBCConnection(loginProperty);
statement = oDBCConnection.createStatement();
Return statement;

}
catch (Exception::Error)
{
throw Exception::Error;
}
catch (Exception::Break)
{
throw Exception::Break;
}
catch (Exception::DDEerror)
{
throw Exception::DDEerror;
}
catch (Exception::Deadlock)
{
throw Exception::Error;
}
catch (Exception::Info)
{
throw Exception::Info;
}
catch (Exception::Internal)
{
throw Exception::Internal;
}
catch (Exception::Numeric)
{
throw Exception::Numeric;
}
catch (Exception::Sequence)
{
throw Exception::Sequence;
}
catch (Exception::Warning)
{
throw Exception::Warning;
}

Pack / UnPack Metodu

İçinde diaolg bulunan bir Clases değişik kullanıcılar tarafından farklı zamanlarda çalıştırıldığında, data ve değişken karışıklıklarını önlemek amacıyla classes dioloğundan girilmiş olan değişkenleri ve yapılmış olan ayıklama işlemlerini kullanıcı bazında tutmak isteyebiliriz. Axaptada bu isteğimize çözüm olarak Pack ve UnPack metodlarını kullanabiliriz.

Bir Classes'ın çalışmasını izlemeye aldığımızda göreceğimiz gibi Classes 'da gerekli değişkenleri girip OK/TAMAM tuşuna bastığımızda pack metodu da tetiklenmiş olur. Bu şu anlamada gelir, bizim dialog üzerinden girdiğimiz değişkenler Axapta tarafından saklanacaktır. Bu Classes'ı tekrardan çalıştırdığızda ise bu Classes daha önce çalıştırıldığı için UnPack metodu tetiklenmiş olur ve dialog'a bir önce girdiğimiz değişkenler görüntülenir. Peki bu işlemleri Axapta nasıl yapıyor. Pack ve UnPack metodlarını tanımaya çalışalım.

Pack metodunun son derece bazit bir içeriği vardır. Bu metod dialog'a girdiğimiz değerleri Axapta tarafından saklanmasını sağlar. Yalnız girilen değişkinlerden hangisinin saklanacağına ise Classes Declaration 'un da yerel olarak tanımladığımız macro ile belirleriz. Bu macronun oluşturulmuş olması gereklidir.

Pack metodu Container tipinde değişken döndürür ve dönen Container'ın elemanları bizim oluşturduğumuz macro elemanlarıdır.

Basit bir şekilde Pack metodu ;

public container pack()
{
return [#CurrentVersion,#CurrentList];
}

UnPack metodu ise Pack metodunun kardeşidir. UnPack metodu ise bu Classes daha önce çalıştırılmış mı çalıştırıldıysa hangi değerle çalıştırıldı onun bilgisini getir. Aslında birisi değerleri yazarken dieri değerleri okur.

UnPack metodu Container tipinde değişken alır ve boolean tipinde değişen döndürür. Eğer geri yüklenecek değer sistemde mevcutsa Unpack metodu bize true döndürecektir.

Basit bir şekilde Unpack metodu;

public boolean unpack(container packedClass)
{
Version version = runbase::getVersion(packedClass);
;
switch (version)
{
case #CurrentVersion:
[version,#CurrentList] = packedClass;
break;
default:
return false;
}
return true;
}

Classes'da lookup İşlemi

Bildiğiniz gibi Dynamics Ax'da kodlarımızı X++ dilinde yazmaktayız. X++ dilinin içeriği ve biçimi C#, Visual .Net ve java dillerine benzemekte. X++ dili bu dillerin referanslarına ve benzer içeriklerine sahiptir. Tabi Java biçimine daha çok benzediğini söylemeliyiz. X++ dilini daha iyi anlayabilmemiz ve farklılıkları daha iyi tespit edebilmemiz için object oriented programlama yöntemlerini iyi anlamamız gerekecektir.

Axapta içersinde object oriented programlama'ya ait en güçlü örnekleri Classes'larda görmekteyiz. Axapta 'da Classes yazmak ve yönetmek son derece kolaydır. Biz Classes'ları birçok uygulamamızda veya yaptığımız geliştirmelerde kullanmaktayız. Axapta'da Classes'ları bu kadar çok kullanmamızı sağlayan en güçlü özelliklerinden biri Dialog metodudur. Bu metod ile değişkenlerimizi ( parametre, girdi) tanımlamamızı sağlar.

Bu makalede de Classes'larda kullandığımız Dialog metodunda StringEdit tipinde bir değişkende(alanda) Lookup metodunu nasıl oluşturacağımızı bir örnekle anlamaya çalışacağız.

Örneğimizde Fiş Numarası ve Fiş tarihi bilgilerini alan, bu parametrelerle de muhasebe günlüğü işlemlerini bir StringEdit alanında görüntüleyeceğiz.

Bu örnek için LedgerJournalTrans tablosunu kullanacağız. Tabi olaya dialog metodumuzu yazarak başlayacağız yalnız Classes'la ilgili diğer metodların ve gerekli değişkenlerin tanımlandığını var saymaktayım.

Object dialog(DialogRunbase _dialog, boolean _forceOnClient )
{
DialogGroup dimensionGroup;
Dialog dialog = super(_dialog, _forceOnClient);
;

dialogVoucher = dialog.addFieldValue(typeid(voucher),voucher,"Fiş Numarası");
dialogTransDate = dialog.addFieldValue(typeid(TransDate),transDate,"İşlem Tarihi");
dialogJournalRecId = dialog.addFieldValue(typeid(RecId),journalRecId,"Fiş Satırı");
dialogJournalRecId.lookupButton(FormLookupButton::Always);


return dialog;
}

Classes'ımızı dialog'unda görüntülenmek üzere 3 adet dialog alanı oluşturuyoruz. Yukarıda belirtiğim gibi bu alanlardan dialogVoucher ve dialogTransDate alanları görüntüleyeceğimiz fiş ve fişin tarihi. Günlük işlemlerini ise dialogJournalRecId alanında lookup olarak görüntüleyeceğiz. Burada dikkat etmemiz geren nokta bu alanın LookUpButton özelliğini "herzaman" olarak atamak olmalıdır. Bu özellik bize StringEdit alanı için lookup işlemini açacaktır. Şimdi lookup metodumuzu yazalım.

Classes'ların dialog'larına alan eklediğimizde bunlar birer object olduğu için, Axapta bunlara birer isim atayacaktır. "Fld_1_1" gibi. Bizim eklediğimiz alanın ismini ise (info(dialogJournalRecId .name)) ile alabiliriz.

Aslında şimdi yapacağımız işlem .Net den alışık olduğumuz bir object'in metodunu OverWrite (Üzerine Yazmak) etmeden farklı değildir. Bizde Axapta tarafından ismi verilmiş olan dialogJournalRecId isimli alanımızın Lookup metodunu OverWrite edeceğiz.

Şimdi Axapta dialogJournalRecId alanına Fld3_1 ismini verecektir. Classes'ımızın içine aşağadaki metod'u yazarak işlemimizi tamamlayalım.

void Fld3_1_lookup()
{
FormRun fr=this.dialogModify().parmDialog().formRun();
object control = fr.controlCallingMethod();

SysTableLookupsysTableLookup=SysTableLookup::newParameters(tableNum(LedgerJournalTrans), control);
Query query = new Query();
QueryBuildDataSource qbds;
;

sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, RecId));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, JournalNum));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, AccountType));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, AccountNum));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, txt));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, AmountCurDebit));
sysTableLookup.addLookupfield(fieldNum(LedgerJournalTrans, AmountCurCredit));

qbds = query.addDataSource(tableNum(LedgerJournalTrans));
qbds.addRange(fieldNum(LedgerJournalTrans,Voucher)).value(queryValue(dialogVoucher.value()));
qbds.addRange(fieldNum(LedgerJournalTrans,TransDate)).value(queryValue(dialogTransDate.value()));
sysTableLookup.parmQuery(query);
sysTableLookup.performFormLookup();
}

Classes'ı çalıştırdığımıda fiş ve fiş tarihi girdiğimizde dialogJournalRecId alanında yukarıda belirttiğimiz alanları gösteren bir lookup açılacaktır. Benzer yöntemlerle lookup haricindeki diğer özellikleri de kullanabilirsiniz.

Yukarıda yazılan metodların içeriklerine ve detaylarına girmedim. Bunlarla ilgili açıklamaları birçok yerde bulabilirsiniz.

Volkan Acar

volkan.vacar@gmail.com

Kod içinden rapor dosyası oluşturma

Axapta içinden kod ile bir raporu (PDF formatında) nasıl oluşturacağımızı görelim.
Örnek olarakta bir satış şiparişine ait faturayı PDF formatında kaydedelim.
Arzu ederseniz raporu HTML formatına dönüştürüp e-mail olarakta gönderebiliriz.

CustInvoiceJour custInvoice;
SalesId salesId;
ReportRun report;
RecordSortedList List = new RecordSortedList(62);

SalesId='00001';

Select custInvoice Index hint SalesIdx Where custInvoice.SalesId == salesId;

List.ins(custInvoice);
report = new ReportRun(new Args(ReportStr(SalesInvoice)));
report.args().caller(null);
report.args().parmEnum(1);
report.args().parmEnumType(920);
report.args().object(List);
report.args().name("KeepSettings");
report.printJobSettings().setTarget(PrintMedium::File);
report.printJobSettings().format(PrintFormat::PDF);
report.printJobSettings().fileName("C:\\Invoice.pdf");
report.prompt();
report.run();

C# kullanarak Axapta işlemleri

VB.net kullanarak Axapta'ya nasıl bağlanacağımızı (Login) olacağımızı ve Axapta Class'larını nasıl kullanacağımızı bir önceki makelemizde görmüştük.

Şimdi ise VB.net ile yazdığımız kodların C# şeklide yazılmış şekillerini görelim.

private object Logon2(string defaultLogon, string configuration, string company, string Password)
{
const object FUNCTION_NAME = "GetNotificationHeader";
try {
axapta = new AxaptaCOMConnector.Axapta2();
axapta.Logon2(defaultLogon, Password, company, "", "", "", configuration, "false", "", "");
}
catch (Exception ex) {
string strErrorMessage;
strErrorMessage = " ERROR IN " + MODULE_NAME + "." + FUNCTION_NAME + " ERRSOURCE: " + Err.Source + " ERRCODE: " + Err.Number + " ERRDESC: " + Err.Description + " ERRLINE: " + Erl();
InformationManager.HandleError(MODULE_NAME, FUNCTION_NAME, strErrorMessage, InformationManager.LOG_TYPE_ERROR);
Err.Clear();
}
finally {
}

Axapta'ya bağlandıktan sonra aynı Axapta nesnesini kullanarak Axapta içinde bulunan Global Class ına ait operatingSystem metod'unu çağırmaya çalışalım.

private string getOSName()
{
object result;
try {
result = axapta.CallStaticClassMethod("Global", "operatingSystem", null, null, null, null, null, null);
if ((!(result == null))) {
return result.ToString();
} else {
return null;
}
}
catch (Exception ex) {
}
finally {
if (!(axapta == null)) {
try {
axapta.Logoff();
}
catch (Exception ex) {
}
}
}
}

Axapta Class'ını nasıl çağıracağımıza bakalım. Yukarıda yazdığımız fonksiyonu da kullanalım. Yazacağımız örnekte bir recordSet'i göndermeye çalışacağız.

private object CallAxaptaClassMethod(ADODB.Recordset axRecorset, string strAxMethodName)
{
const object FUNCTION_NAME = "CallAxaptaClassMethod";
string osName;
object returnd;
string ssss;
try {
osName = getOSName();
if (!(osName == null)) {
axapta.TTSBegin();
returnd = axapta.CallStaticClassMethod("dataInAxapta", strAxMethodName, axRecorset, null, null, null, null, null);
axapta.TTSCommit();
} else {
throw new Exception("Axapta Connection Not Setvvvv");
}
}
catch (Exception ex) {
string strErrorMessage;
axapta.TTSAbort();
if (!(axapta == null)) {
axapta.Logoff();
}
strErrorMessage = " ERROR IN " + MODULE_NAME + "." + FUNCTION_NAME + " ERRSOURCE: " + Err.Source + " ERRCODE: " + Err.Number + " ERRDESC: " + Err.Description + " ERRLINE: " + Erl();
InformationManager.HandleError(MODULE_NAME, FUNCTION_NAME, strErrorMessage, InformationManager.LOG_TYPE_ERROR);
Err.Clear();
}
finally {
}
}

VB.Net kullanarak Axapta işlemleri

Bir önceki makalemizde Axapta Business Connector arabirimini ve arabirimde bulunan fonksiyonları tanımıya çalışmıştık.

Şimdi VB.Net kullanarak Axapta'ya nasıl bağlanacağımızı (logon), bir Axapta Class'ını nasıl çağıracağımızı ve Axapta'dan bunu nasıl karşılayacağımıza bakalım.

İlk olarak açtığımız .net projemizde Axapta Business Connector 'ü projemizin referanslarına eklememiz gerekmektedir.

Bu yapabilmek için projemizin "references" kısmına gelerek yeni bir referans ekleyiniz, COM sekmesinde "Axapta COM Connector 1.2 Type Library " i bulunuz ve OK tuşuna basınız. Bu işlem proje referanslarına Axapta Business Connector 'ü ekleyecektir.

Projemizin referanslarına COM connector'ü eklediğimizi düşünelim. Dikkat edecek olursanız referanslara eklediğimiz dll aslında Axapta Configuration Utility kullanarak register (bilgi kütüğü) ettiğimiz "axcom.dll' lidir.

Projemizin Public Class'ında referans a eklediğimiz COM Connector'u tanımlamalıyız.

Private axapta As AxaptaCOMConnector.Axapta2

Şimdi Axapta'ya nasıl bağlanacağımız bakalım.

NOT : Örneklerini göreceğiniz foksiyonların hata ve sonlandırma kısımlarını ihtiyaca bağlı olarak değişeceğinden fazla detaylı yazmadım. Genel .Net kurallarına göre yazabilirsiniz.

Private Function Logon2(ByVal defaultLogon As String, ByVal configuration As String, ByVal company As String, ByVal Password As String)
Const FUNCTION_NAME = "GetNotificationHeader"
Try
axapta = New AxaptaCOMConnector.Axapta2
axapta.Logon2(defaultLogon, Password, company, "", "", "", configuration, "false", "", "")
Catch ex As Exception
Dim strErrorMessage As String
strErrorMessage = " ERROR IN " & MODULE_NAME & "." & FUNCTION_NAME & _
" ERRSOURCE: " & Err.Source & _
" ERRCODE: " & Err.Number & _
" ERRDESC: " & Err.Description & _
" ERRLINE: " & Erl()
InformationManager.HandleError(MODULE_NAME, FUNCTION_NAME, strErrorMessage, InformationManager.LOG_TYPE_ERROR)
Err.Clear()
Finally
End Try
End Function
  • defaultLogon: Axapta'ya bağlanacak kullanıcı. configuration: Axapta'ya bağlantı kuracağımız konfigürasyon'un ismi. company: Axapta da şirket ismi. Password: Axapta'ya bağlanacak kullanıcının parolası. Bu örnekte kullanıcımız Axapta'da tanımlı normal Axapta kullanıcısıdır.
  • axapta = New AxaptaCOMConnector.Axapta2 Axapta değişkenimizi new'leyerek yeni bir nesne olarak tanımlıyoruz.
  • axapta.Logon2(defaultLogon, Password, company, "", "", "", configuration, "false", "", "") Axapta2 arabirimini kullanarak IAxapta2::Logon2 fonksiyonu ile Axapta'ya bağlanıyoruz. Diğer parametrelerini görmek için bir önceki makalemizi inceleyebilirsiniz.
  • InformationManager.HandleError bir hata olması durumunda hatayı sistem event log 'una kayıt atar.
Axapta'ya bağlandıktan sonra aynı Axapta nesnesini kullanarak Axapta içinde bulunan Global Class ına ait operatingSystem metod'unu çağırmaya çalışalım.

Private Function getOSName() As String
Dim result As Object
Try
result = axapta.CallStaticClassMethod("Global", "operatingSystem",
Nothing, Nothing, Nothing, Nothing, Nothing, Nothing)
If (Not result Is Nothing) Then
Return result.ToString()
Else
Return Nothing
End If
Catch ex As Exception
Finally
If Not axapta Is Nothing Then
Try
axapta.Logoff()
Catch ex As Exception
End Try
End
If
End Try
End Function


  • Bu fonsiyon bize kullandığımız operasyon sistemimizi döndürecektir.
  • result = axapta.CallStaticClassMethod("Global", "operatingSystem", Nothing, Nothing, Nothing, Nothing, Nothing, Nothing) Axapta2 arabiriminin IAxapta::CallStaticClassMethod fonksiyonunu kullandık. Hatırlayacağınız gibi CallStaticClassMethod fonksiyonunun ilk parametresi Class ismi ikinci parametresi ise Class'a ait metod du.
  • result.ToString() operatingSystem metodu tarafından dönen değer.
  • axapta.Logoff() sistemle bağlantımızı keser.

Bir de bizim yazdığımız bir Axapta Class'ını nasıl çağıracağımıza bakalım. Yukarıda yazdığımız fonksiyonu da kullanalım. Yazacağımız örnekte bir recordSet'i göndermeye çalışacağız.

Private Function CallAxaptaClassMethod(ByVal axRecorset As ADODB.Recordset, ByVal strAxMethodName As String)
Const FUNCTION_NAME = "CallAxaptaClassMethod"
Dim osName As String
Dim returnd As Object
Dim ssss As String
Try
osName = getOSName()
If Not osName Is Nothing Then
axapta.TTSBegin()
returnd = axapta.CallStaticClassMethod("dataInAxapta", strAxMethodName, axRecorset, Nothing, Nothing, Nothing, Nothing, Nothing)
axapta.TTSCommit()
Else
Throw New Exception("Axapta Connection Not Setvvvv")
End If

Catch ex As Exception
Dim strErrorMessage As String
axapta.TTSAbort()
If Not axapta Is Nothing Then
axapta.Logoff()
End If
strErrorMessage = " ERROR IN " & MODULE_NAME & "." & FUNCTION_NAME & _
" ERRSOURCE: " & Err.Source & _
" ERRCODE: " & Err.Number & _
" ERRDESC: " & Err.Description & _
" ERRLINE: " & Erl()
InformationManager.HandleError(MODULE_NAME, FUNCTION_NAME, strErrorMessage, InformationManager.LOG_TYPE_ERROR)
Err.Clear()
Finally
End Try
End Function
  • Bu örnekte CallStaticClassMethod kullanarak bizim tanımladığımız dataInAxapta Class'ımızın strAxMethodName parametresi ile belirtiğimiz metod 'u çağırıyoruz. Gördüğünüz gibi bir recordset'i de parametre olarak göndere biliriz.

Şimdi son olarak Axapta da bu işlemi nasıl karşılayacağımızı görelim.

Static boolean axaptaCOM(COM _recordSet)
{
CCADORecordSet CCADORecordSet;
;
try
{
CCADORecordSet = new CCADORecordSet(_recordSet);

while (!CCADORecordSet.EOF())
{
Alan = CCADORecordSet.fields().itemName("Alanİsmi").value();
...................

CCADORecordSet.moveNext();
}
return true;
}

catch(Exception::Error)
{
.................
return False;
}
....................
}
}
  • Dikkate ederseniz VB.Net ile gönderdiğimiz recordset 'i bir COM nesnesi olarak içeri alıyoruz. Bunu bir recordset'e dönüştürmemiz için Axaptada tanımlanmış CCADORecordSet Class'ını kullanabiliriz. Axapta isimlendirmesi biraz garip olduğu için aramalarda bulamaya bilirsiniz ama CC ile başlayan Class'ların çoğu bu tür işlemler için hazırlanmış Class'lardır. İncelemenizde fayda olduğunu düşünüyorum.

Daya çok bilgi için http://msdn2.microsoft.com/en-us/library/default.aspx sayfasını ziyaret edebilirsiniz.

Volkan Acar

volkan.vacar@gmail.com

Dynamics AX 3.0 'da Axapta Business Connector (COM+ )-2

Axapta Business Connector (COM+ nesnesi) 'e ister Vb ister Vb.net istersek C# kullanarak erişiyor olalım, COM+ nesnesi üzerinden Axapta'ya erişimimizi sağlayacak Axapta Interface (arabirim)'ine ait fonksiyonlardan en çok kullanılanları tanımaya çalışacağız.

Axapta'ya erişmemizi sağlayan ve IAxapta a olarak bilinen arabirimler, IDisPatch arabiriminden türetilmiştir.

IAxapta arabirimini kullanarak yaratabileceğimiz nesneler(Object) Class Object, Record(Kayıt) Object, Container Object ve Buffer Object dir.

Axapta Business Connector'e baktığımızda üç tane IAxapta arabirimi göreceksiniz (AxaptaCOMConnector.Axapta.1, AxaptaCOMConnector.Axapta.2.1, AxaptaCOMConnector.AxaptaParameterList.1) AxaptaCOMConnector.Axapta.2.1 arabirimi AxaptaCOMConnector.Axapta.1 arabiriminin bir üst versiyonudur. Axapta 2.1 de sadece logon metod'unda değişiklik yapılmıştır. Tavsiyem sizin de 2. versiyonu kullanmanız yönündedir.

Şimdi fonksiyonları tanımaya çalışalım:

IAxapta::CreateObject :

Bu fonksiyon Axapta'da tanımlı bir Class'ımızı nesne(objects) olarak yaratmamızı sağlar. Nesne(Objects) olarak yarattığımız Class'ımıza ait metod'ları IAxaptaObject::Call ve IAxaptaObject::CallEx fonksiyonları ile çağırabiliriz.

CreateObject(
[in] BSTR bstrClass,
[in, optional] VARIANT v1,
[in, optional] VARIANT v2,
[in, optional] VARIANT v3,
[in, optional] VARIANT v4,
[in, optional] VARIANT v5,
[in, optional] VARIANT v6,
[out, retval] IAxaptaObject **ppObject
)

Paramerteler

bstrClass : Yaratacağımız nesnenin ismi. (Axaptada bulunan Class ismi)
v1-v6: Metod'a ailt parametrelere üyeleri. Bu parametre bilgisini göndermek isteğe bağlıdır.
ppObject: Fonksiyonun döndürdüğü değer, yaratılan COM nesnesine ait pointer.

MyObject = Axapta.CreateObject("MyClass", "new parameter1", 2)

IAxapta::CallStaticClassMethod

Bu fonksiyon Axapta içinde bulunan Class ve Class'a ait static metod'unu çağırmayı sağlar. En çok kullanılan fonksiyonlardan birisidir.

CallStaticClassMethod(
[in] BSTR bstrClass,
[in] BSTR bstrMethod,
[in, optional] VARIANT v1,
[in, optional] VARIANT v2,
[in, optional] VARIANT v3,
[in, optional] VARIANT v4,
[in, optional] VARIANT v5,
[in, optional] VARIANT v6,
[out, retval] VARIANT *pResult
)

Parametreler

bstrClass : Static metod'u olan Class ismi
btsMethot: bstrClass parametresinde kullandığımız Class'a ait Static Metod ismi. Metod mutlaka Static olaması gerekir.
v1-v6: Metod'a ailt parametrelere üyeleri. Bu parametre bilgisini göndermek isteğe bağlıdır. Dikkat edilirse parametre olarak Variant tipi değişkenler kullanıyoruz. Axapta'ya string, XML,Recordset vb. kullana biliriz. Bu değişkenleri Axapta tarafında COM değişkeni ile karşılayacağız makalemizin ilerleyen bölümlerinde bu konudaki örneklerimizi göreceksiniz.
ppObject: Fonksiyonun döndürdüğü değer, yaratılan COM nesnesine ait pointer.

IAxapta arabirimine ait fonksiyonlara baktığımızda fonsiyonlarının bazılarının sonunda Ex bulunan versiyonlarını göreceksiniz. Ex'li olan versiyonlar kullandığımız 6 parametrenin yerine yada 6 parametreden fazla parametre kullanmamız gerektiğinde bir parametre listesi kullanmamızı sağlayan fonsiyonlardır. (IAxaptaParameterList) Neden 6 parametre sorusu da aklınıza geliyor olabilir. Bunun cevabı ise bir fonksiyonun yada metod'un 6 dan fazla parametre kullanması o foksiyonun veya metod'un esnekliğini bozar. Bu konu hakkındaki daha geniş bilgiyi genel yazılım kuralları konusundaki makalelerde veya ilgili kitaplarda bulabilirsiniz.

txt = Axapta.CallStaticClassMethod("MyClass", "MyMethod", "parameter1", 2)

IAxapta2::Logon2

Axapta sistemine bağlanmamızı (Connect) olmamızı sağlar.

Logon2(
[in, optional] VARIANT user,
[in, optional] VARIANT userPassword,
[in, optional] VARIANT company,
[in, optional] VARIANT language,
[in, optional] VARIANT serverManager,
[in, optional] VARIANT objectServer,
[in, optional] VARIANT configuration,
[in, optional] VARIANT isWebUser,
[in, optional] VARIANT reserved2,
[in, optional] VARIANT reserved3
)

Parametreler

user: Sisteme bağlanacak kullanıcı. Bu parametre bilgisini göndermek isteğe bağlıdır.
userPassword:Sisteme bağlanacak kullanıcının parolası. Bu parametre bilgisini göndermek isteğe bağlıdır.
company:Bağlanılacak şirket bilgisi. Bu parametre bilgisini göndermek isteğe bağlıdır.
language:Dil bilgisi. Bu parametre bilgisini göndermek isteğe bağlıdır.
serverManager:Bağlanacak server manager bilgisi. Bu parametre bilgisini göndermek isteğe bağlıdır.
objectServer:Bağlanacak object server bilgisi. Bu parametre bilgisini göndermek isteğe bağlıdır.
configuration: Axaptaya bağlanacağımız konfigürasyonun ismi. Bu parametre bilgisini göndermek isteğe bağlıdır.
isWebUser: user olarak normal Axapta kullanıcısı mı ? Yoksa Web kullanıcısı mı ? bağlanacak. Bu parametre bilgisini göndermek isteğe bağlıdır.
reserved2-reserved2: ileride kullanılmak üzere ayrılmış parametreler. Bu parametre bilgisini göndermek isteğe bağlıdır.

Gördüğünüz gibi sisteme bağlanmamız sağlayan bir çok parametre bulunmaktadır. Bu parametrelerden user, userPassword, configuration en çok kullanılan parametrelerdir. Sağlıklı bir şekilde bağlanmamız için bu parametreler yeterlidir. "Axapta Configuration Utility" de belirtilen parametrelerin çoğunu tanımlamaktayız. Doğru ve istenilen şekilde çalışan bir "Axapta Configuration" 'u ve yetki tanımlaması yapılmış normal Axapta kullanıcı ile sorunsuz bir şekilde bağlantı kurabilirsiniz. Aslında dikkat edecek olursanız normal kullanıcılarımızda aynı yöntemle Axapta'ya bağlanmaktadırlar.

Bir kaç kritik noktayı belirmek gerekir. Eğer web kullanıcı ile bağlanacaksak isWebUser bilgisi sıfırdan farklı olmalı ve web kullanıcısının sistemde tanımlı olması gerekir. Unutmayalım ki web kullanıcısının şirket tanımı sabittir.

serverManager ve objectServer parametreleri three-tiered yapılarda kullanılır. two-tiered yapılarda kullanılmaz.

Axapta.Logon2 "MyUserName", "MyPassword", "", "", "", "", "MyConfiguration"

IAxapta::Logoff

Sistemle bağlantıyı keser. İşlemimiz bittiğinde bu fonksiyonu çalıştırmayı unutmamalıyız.

Axapta.Logoff

IAxapta::Stop

Eğer COM+ nesnesi çalışıyorsa nesneyi kapatır. Logon fonksiyonu ile axaptaya bağlandığımızda COM+ nesnesi çalışmaya başlayacaktır. Durumunu Component Services den kontrol edebilirsiniz.

IAxapta::TTSAbort , IAxapta::TTSBegin , IAxapta::TTSCommit

Axapta X++ kodunda kullandığımız TTSBegin,TTSCommit ve TTSAbort fonksiyonlarını çağırır . Axapta içinde kullandığımız şartların tamamı için burada da kullanmalıyız.

Axapta.TTSBegin, Axapta.TTSCommit, Axapta.TTSAbort

Sonraki makalelerimizde bu fonksiyonlardan bazılarının kullanım şekillerini göreceğiz.

Tüm foksiyonları görmek yada daha fazla bilgi edinmek için; benim de kaynak olarak kullandığım Axapta Client klasörü içinde bulunan bin klasöründeki ''AxDvgCOMUs.chm" isimli yardım dökümanını okuya bilirsiniz.

Eğer COM+ nesneleri hakkında daha fazla bilgi almak isterseniz http://msdn.microsoft.com/library/en-us/dnanchor/html/complus_anchor.asp sayfasında bulunan bilgilere göz atabilirsiniz.

Volkan Acar

volkan.vacar@gmail.com

COM + Nesneleri

Merhaba,
COM+ nesneleri ile ilgili yazılmış güzel bir makalenin bir kısmını sizinle paylaşmak istedim.
Makaleyi yazan Tamer Öz makalenin tamamına http://www.tameroz.com adresinden ulaşabilirsiniz.

"Nedir bu COM+

Geçtigimiz uzun yıllar boyunca programcılık tek parça uygulama gelistirmekten ibaretti.
Monolithic (tek parça) uygulamalarda bir veya birden fazla fonksiyonalite bir arada
bulunuyordu. Böyle bir ortamda ise uygulamaların çalısabilmesi için IBM tarafından
gelistirilmis server teknolojisi olan mainframe sunucular kullanılmaktaydı. Ancak genis
monolithic uygulamalarda tek sorun sunuculara yapılan yatırımlar degildi. Yazılım gelistirici
tarafındada bir çok problemle karsılasılıyordu. Bu problemlerin belli baslılarını arasında
monolithic uygulamaların gelistirilmesinin uzun bir süre alması, bakım ve uygulamada
yapılacak düzeltme, yeni özellik ekleme gibi islemlerinin zor olması ve çok efor gerektirmesi
ve günümüzde hakim olan yazılım gelistirme mimarisi ve mantıgına aykırı olarak monolithic
uygulamalarda yazılmıs olan bir islevsellik veya bir özellik tasıyan bilesen aynı programlama
dilinde yazılmıs olsa bile baska bir uygulamada kullanılamaması ve yazılım gelistiricilerin
yeni uygulama için aynı kodu tekrar yazmak zorunda kalması veya uygulamanın bir kısmını
degistirilmesinin,kaldırılmasının istenmesi durumunda bile tüm uygulamanın kodu üzerinde
degisiklik yapılması gerekmesi bulunmaktadır.
Zamanla yazılım dünyasındaki bu probleme karsı çözümler gelistirilmistir. Bu çözümlerden
ilki uygulamaları server (sunucu) ve client (istemci) tarafına bölmektir. Client/Server Model
adı verilen bu çözümde arayüzün ve bazı islemlerin clientta, data erisimi ve diger islemlerin
serverda bulunacak sekilde paylastırılması sonucu monolithic uygulamaların kompleksligine
kısmen çözüm bulunabilmesine karsın bilesenlerin tekrar kullanılamaması sorununa çözüm
gelistirememistir. Yani Visual Basic’te yazılmıs bir bileseni C temelli diller desteklemiyor,
kullanamıyordu yada C temelli bir dille yazılmıs bir bilesen Visual Basic de kullanılamıyordu.
Diger bir çözüm yöntemi olarak gelistirilen Component Model (Bilesen Modeli) hem
monolithic hemde Client/Server uygulamaların problemlerine çözüm bulmustur. Artık yazılım
gelistiriciler gelistirdikleri uygulamaları bilesenler ile yazarak bu bilesenleri ileride baska
projelerde tekrar kullanabiliyorlardı.
COM (Component Object Model) uzun zamandır yazılım dünyasının karsılastıgı birçok
probleme çözüm olan ve sürekli yenilenerek zamana ayak uyduran bir teknolojidir. Bu
teknolojinin yaratılmasının arkasında bulunan temel düsünce yazılım bilesenlerinin en az
isgücü ile en verimli biçimde yeniden kullanılabilmesidir. Bu tanım bir yazılım gelistirici için
daha önceden yazılmıs olan bir kodun tekrar yazılmaması, bir IT yöneticisi için ise bu kodun
tekrar yazılmasından kaynaklanan maliyet ve zamandan tasarruf demektir.
Nesne tabanlı bir programlama modeli olan COM uygulamaların birlikte kullanılabilirligini
saglamıstır. Yani iki veya daha fazla uygulama veya bu uygulamalara ait bilesenler
birbirleriyle iletisim saglayabilmektedirler. Burada esas can alıcı nokta bu uygulamaların
farklı dillerde yazılmıs olduklarında ve hatta farklı bilgisayarlar üzerinde bulunan farklı
isletim sistemleri üzerinde çalısıyor olmaları durumunda bile bu iletisimin basarıyla
saglanmasıdır.

COM ve .NET

COM ile server tabanlı uygulama gelistirmenin faydaları arasında yazılım gelistiricilerin
COM uygulamalarını farklı diller ile farklı platformlar (Unix vs.) için gelistirilmis olsalar bile
uygulamaların birbirleri ile çalısabilir bir yapıda olmaları, COM nesneleri baska makinelerde
olsalar bile client programın bir parçasıymıs gibi çalısabilmeleri,COM bileseni gelistirmek
için gerekli olan standartlar Interface ler ile saglandı, böylece bir programın COM nesnesini
kullanırken Interface leri kullanarak COM nesnesine erisebilmesi, Versiyon özelligi yani her
bir class a yeni interfaceler ekleyerek ek islevselliklerin katılması ve bu islevsellik katılırken
uygulamayı halihazırda kullanan kullanıcıların herhangi bir kesinti yasamaması,bir COM
nesnesinin, COM arayüzlerini olusturmayı destekleyen bir programlama dili ile çok hızlı bir
sekilde gerlistirilebilmesi, örnegin VB 6.0, C++ gibi diller varsayılan olarak COM
standartlarına uyum saglaması bulunur.
COM Server tabanlı program gelistirmede birçok soruna çözüm olmasına ragmen zamanla
ortaya bazı diger sorunlar çıkmıstır. Ortaya çıkan bu sorunlara COM’un çözüm
saglayamamasına karsın .NET Framework bu sorunla çözüm olmustur.
.NET Framework’un çözüm getirdigi konular;Bir COM uygulamasının belirli bir platform
için gelistirilmesi sonucu sadece o platformda çalısabilir olmasıdır. Ancak .NET
teknolojisinde gelistirilen çözüm .Net dillerinden herhangi biri kullanılarak yazılmıs
bilesenlerin MSIL (Microsot Intermediate Language) ‘e derlenmesi ve kullanılacak
platformda CLR(Common Language Runtime) yüklü olması sonucu her platformda çalısabilir
olmasısır. Bunun yanı sıra COM’un cevap veremedigi diger bir sorun ise .NET’te gelistirilmis
uygulamaların sadece kendi yetkileri olan memory alanlarına erisebilmesidir. Yani çalısan bir
uygulama diger bir uygulamaya özel degiskenlere erisemez ve diger uygulamanın
kilitlenmesine sebep olamaz. .NET’i ön plana çıkaran bir diger özellik ise daha gelismis bir
versiyon kontrol mekanizmasını barındırmasıdır. COM’da bulunan ve biraz önce
inceledigimiz versiyonlama özelligine ek olarak .NET’te uygulamanın eski sürümünün eski
istemcilere hizmet vermeye devam etmesinin garanti altına alınması vede yeni halinin ise yeni
istemcilerde kullanılabiliyor olması saglanmıstır.
Birçok kisi tarafından COM+ programcılıgının eskidigi düsünülse bile COM+ sundugu
enterprise-level (genis çaplı) uygulamalar halen gelistiriciler tarafından .NET e
uygulanmaktadır ve .NET su an COM+ servislerine tam erisim hakkı vermektedir. Bunun
yanı sıra bunu bildiginiz veya sevdiginiz programlama dilini kullanarak gelistirme sansı
sunmaktadır. Eger enterprise-level uygulamalar yazacaksanız COM+ servislerinin
avantajlarından yararlanmak bazı noktalarda kaçınılmaz olacaktır.

COM+ Uygulamaları

COM+ uygulamaları configured bilesenlerin bir araya gelmesinden olusmaktadır. COM+
uygulamaları aynı zamanda bir güvenlik sınırını yapısı olarak koyar. COM+ uygulamaları
Server Uygulaması ve Library uygulaması olmak üzere iki çesitte olabilir.
Surrogate çalıstırılabilir bir görevdir ve DLL olarak olusturulmus bir COM bilesenini
barındırabilir. Surrogate Exe uygulamasını çalıstırmak suretiyle uzaktaki bir bilgisayardaki
DLL sunucusunu çalıstırılabilir.
Bir server uygulaması kendisine özel tahsis edilmis islemde çalısır. COM+ server
uygulamalarını barındırmak için Dllhost.exe’yi kullanır. Her bir server uygulaması kendi
Dllhost.exe örneginde çalısmaktadır.
Dllhost.exe surrogate’i COM+ çalısma zamanının çekirdegini olusturur. Bilesenlere servisleri
kullanabilmek için gerekli olan thread yönetimi, es zamanlı baglantı yönetimi gibi hizmetlerin
altyapısını sunar. Server uygulaması COM+ servislerinin tamamını desteklemektedir.
Library uygulamaları client in isleminde aktive olurlar.Client islemi unmanaged bir islem
olabilir. Örnegin IIS üzerinde çalısan bir asp uygulamasının configured bileseni çagırabilir.
Çogu durumda bu islem DllHost.exe nin bir örnegi olmasına karsın üzerlerindeki
sınırlamalardan dolayı COM+ ‘ın bazı özelliklerini kullanamazlar.
Kitaplık uygulamalarının sunucu uygulamalarına göre daha iyi performans saglamalarının
sebebi kitaplık uygulamasında bulunan bir nesneye erisim süresinin islemler ve bilgisayarlar
arasında dolasarak erisebilecek bir nesneye erisme süresinden çok daha kısa olmasıdır. Ancak
kitaplık uygulamalarındada connection pooling, queued bilesen yüklenememe, bazı güvenlik
ayarlarının çagırıcıdan yani classımızdan türetilmesinden dolayı bir kısım güvenlik ayarlarını
kullanamama gibi bazı sınırlandırmaları vardır.Ayrıca bir islemde hata olusması durumunda
sunucu uygulama sadece dllhost.exe yi sonlandıracak ve diger çalısmakta olan islemlere bir
zarar gelmeyecektir. Ancak kitaplık uygulamasındaki hata istemci tarafındaki islemlerin
tamamen durmasına sebep olacaktır. Bu sebepten dolayı server uygualamaları çogunlukla
tercih edilmektedir.
Her iki tip uygualamanında birbirine üstünlüklerini inceleyecek olursak Sunucu uygulamalar,
hata olusturabilecek bir koda karsı izolasyon gelistirilmistir, queued bilesenleri ve object
poolingi destekler ancak islemler arası metod çagırmalar çok maliyetlidir. Kitaplık
uygulamalarında ise metod çagırımları daha hızlı olmasına ve istemciye özel bazı kaynaklara
erisilebilmesine ragmen, sunucu uygulamalarındaki avantajları saglamamaktadır.
COM+ ın yeni versiyonu olan 1.5 numaralı versiyonu gelistirilmis bir sunucu uygulamayı
windows servis olarak kullanabilme olanagı sunar. Bu ise bilgisayar yeniden basladıgında
belirtilen kullanıcı veya sistem hesabının o islemi yeniden baslatacagı böylece uygulamamızın
sürekli çalısır halde olacagı anlamına gelmektedir. Bilesenleri Windows Service olarak
çalıstırabilmek için My Application Properties penceresinden ve Activation tabından Server
Application’ a tıklandıktan sonra Run Application As NT Service isaretlenmelidir."...

Volkan Acar

volkan.vacar@gmail.com

Dynamics AX 3.0 'da Axapta Business Connector (COM+ )-1

COM+ nesnelerini kısaca tanıyacak olursak: COM (Component Object Model), Nesne tabanlı bir programlama modeli olarakta bilinen COM uygulamaları, iki yada daha fazla uygulama veya bu uygulamaların bileşenlerinin birbirleri ile iletişimini sağlamaya yarayan teknolojidir. Axapta açısından COM+ nesnesi Axapata ile dış uygulamaların iletişim sağlamasında kullanılır (.Net, Vb,Word,Excel vb....)

İlk olarak Axapta Business Connector'ü nasıl register (bilgi kütüğü) edeceğimize bakalım. Axapta Configuration Utility i çalıştırıp Business Connector segmesini seçtiğimizde Business Connector register (bilgi kütüğü) sayfası ile karşılaşırız


1. Business Connector üzerinden gelerek; Axata içinde bulunan kodumuzu debug (ayıklama) etmek istiyorsak işaretlenmelidir. Portal kullanıyorsak ve web sayfasından gönderilen post işlemini de takip etmek istiyorsak yine işaretlenmiş olması gereklidir.

2. Business Connector üzerinden gelerek; Axapta'ya login olmak istediğimizde varsılan kullanıcı parolasını veya bizim tarafımızdan atanan bir paraloyu kullanabiliriz. Yalnız dikkat etmemiz gereken bu parolanın Axaptaya login olma yetkisine sahip bir kullanıcıya ait olmasına dikkat edilmelidir.

3.Business Connector 'ü register(bilgi kütüğüne ) eder yada kapatır.


Bu formda üzerinde register tuşuna bastığımızda, COM+ nesnesi register etme seçenekleri karşınıza gelecektir.

Makalemizde sıkça kullanılan COM+ nesnesi şeklinde yapılan register (bilgi kütüğü) işlemi üzerinde duracağız. O sebepten dolayı Register COM+ seçeneğini seçerek register etmek isteğimiz bilgisayar bilgisi seçiyoruz. Axapta Business Connector library de register edeceğimiz DLL 'in yolunu göstermektedir. Aslında sistem tarafından register edilen DLL Axapta Client'ın bin alt dosyası içinde bulunan axcom.dll'i dir.

"OK" tuşuna bastığımızda Business Connector COM+ nesnesi belirtiğimiz bilgisayarda yaratılmış olacaktır.









Bilgisayardaki durumunu Component Services konsolundan görebilirsiniz. İlgili konsol'a Administrative Tools 'un altından erişe bilirsiniz. Component Services konsolu ile COM+ nesnesinin çalışıp çalışmadığını görebileceğimiz gibi nesneyi kapatıp tekrardan başlatabiliriz.

Yarattığınız Business Connector COM+ nesnesinin çalışıp çalışmadığını Axapta üzerinden de test etmek istiyorsak. Axapta içinden Yönetim > Kuruluş > Internet > Parametreler formununun COM statüsü segmesinden Test tuşuna basarak test edebiliriz.










Test işlemini Business Connector COM+ nesnesini kurduğunuz bilsayar üzerinden test etmelisiniz. Test sonucunuz başarı ile sonuçlanması durumunda yukarıda gördüğünüz ekrana benzer bir ekranın görüntülenmesi gerekir. Bağlantı raporunda sisteme hangi konfigürasyon,uygulama, veritabanı,sistem dizini ve AOS bilgileri raporlanacaktır.

En sık rastlanan hata olarak, yetki ile ilgili bir hata çıkması durumunda Component Services konsolundan Navision Axapta Business Connector üzerine gelip sağ tuşa basarak özellikleri seçiniz ve Identity segmesinden this user bölümüne kurulumu yaptığınız bilgisayarda yönetici (Administrator) yetkisine sahip kullanıcı tanımını yapınız. Yetki probleminizi bu şekilde aşabilirsiniz.

Volkan Acar

volkan.vacar@gmail.com

Dynamics AX 3.0 'da XML Dosya Okuma

“Dynamics AX ’da XML dosya oluşturma” makalemizin devamı yada ters işlemi niteliğinde olan bu yazımızda aşağadaki örnek XML belgesini okumaya çalışacağız.







Kullanacağımız nesneleri tekrar hatırlayacak olursak.

XmlDocument: Bir XML belgesinden veri okumak, değiştirmek, verilerin konumlarını bulmak için kullandığımız nesnedir.
XmlNode: XML belgesinde bulunan düğümleri temsil eder.
XmlAttribute :XML belgesinde bulunan bir düğüme ait nitelik bilgilerini temsil eder.
XMLNodeList :XML belgesinde bulunan element e ait değerlerin listesini verir.
XMLNamedNodeMap:XML belgesinde düğüme ait kesişim kümesini verir. Genel kullanımı Attribute tipi düğümlerde nitelik değerlerini verir.

static void Read_XMLExample (Args _args)

{

str filename, nodeName,txtFile,strTxtRow;
str AttName;
int i,j,k;
boolean Valid;

---> XML nesneleri tanımlanıyor.
XMLDocument XMLdoc;
XMLNode rootNode, bodyNode,bodyNode1;
XmlAttribute AttNode;
XMLNodeList bodyLines,childLine;
XMLNodeList _xmlNodelist;
XMLNamedNodeMap attrs;
//<---

;

//--->XML belgesi kullanıcı sistemine yükleniyor
XMLdoc=new XMLDocument();
XMLdoc.load("C:\\XMLExample.xml");
//<---

// 1. düğüm nesnesi.
rootNode = xmldoc.documentElement();
// 1.düğüm nesnesinin ismi.
nodeName = rootNode.baseName();


// 1. düğüm nesnesinin alt düğüm'leri var mı?
if(rootNode.hasChildNodes())
{
// eğer 1. düğüm nesnesinin alt düğümleri varsa
bodyLines = rootNode.childNodes();
// ---> 1.düğüm boyunca dönüyoruz - başlangıç
for(i = 0; i<>
{
// 2. düğüm nesnesi.
bodyNode = bodyLines.nextNode();
// 2.düğüm nesnesinin ismi.
strTxtRow = bodyNode.baseName();
// 2. düğüm nesnesinin alt düğüm'leri var mı ?

if(bodyNode.hasChildNodes())
{
childLine = bodyNode.childNodes();
// ---> 2.düğüm boyunca dönülür-başlangıç
for(j= 0; j
{
//2.düğüm nesnesinin alt düğümünü.
bodyNode1 = childLine.item(j);
//alt düğümün ismi
nodeName = bodyNode1.baseName();
strTxtRow += ': '+ nodeName;
// alt düğüm bir attribute nesnesi mi ?
// eğer bir attribute nesnesi ise değerler bir map içine alınır.
attrs=bodyNode1.attributes();
if (attrs.length()>0)
{
// attribute map'i üzerinde dönüyoruz.
for(k= 0;k<>

{
// alt düğüm ismi ve düğüm değeri.
strTxtRow +=': ' + attrs.item(k).baseName() +'-'+ attrs.item(k).text();

}
}
else
{
_xmlNodelist = bodyNode.selectNodes(nodeName);
// 2.düğüm listesi boyunca dönüyoruz.

for(k= 0;k<>

{

// alt düğüm ismi ve düğüm değeri alınıyor.
strTxtRow += ': ' + _xmlNodelist.item(k).text();
}

//bodyNode.selectSingleNode(nodeName).text();
}

}//<---2.düğüm boyunca dönüyoruz-bitiş
}

}//<--- 1.düğüm boyunca dönüyoruz-bitiş

// yazdır.
print (strTxtRow);
pause;

}

Dynamics AX 3.0’ da XML Dosya Oluşturma

eXtensible Markup Language(XML); Axapta kapsamında genellikle kurumlararası entegrasyon uygulamalarında metin bazlı veri transferi işlemleri için kullanılan belge tipleridir.

Kısaca XML' e ve yapısına bakacak olursak; Temelde XML dosyaları görsel olarak biçimlendirilmiş sıralı dosya formatında bulunan metin dosyalarıdır. Bir XML belgesi düğümler hiyerarşi'sinden oluşur ve HTML yapısına çok benzer bir yapısı vardır. Bir XML belgesini normal metin belgesinden ayıran belli kurallara sahip işaretler içermesinir.

Gerek .Net ortamında gerekse Axapta ortamında kod yazıyor olalım, bir XML belgesini okumak yada yazmak için ortak kullanılan bazı nesneleri tanıyacak olursak :

XmlDocument: Bir XML belgesinden veri okumak, değiştirmek, verilerin konumlarını bulmak için kullandığımız nesnedir. XML belgesinin kök nesnesidir.
XMLElement: XML belgesinde bulunan elementleri temsil eder.
XmlNode: Xml belgesinde bulunan düğümleri temsil eder.
XmlAttribute :Xml belgesinde bulunan bir düğüme ait nitelik bilgilerini temsil eder.

Dynamic Ax ortamında XML belgesi yaratma ve okuma işlemleri son derece kolaydır. Yalnız burada unutulmaması gereken konu case sensitive (büyük ve küçük harfe duyarlı) çalışılması gerektiğidir.

Axaptada XML ile ilgili yazılmış olan sınıfları Application Object Tree’de Classes grubunda bulabilirsiniz.

X++ ile XML dosyası nasıl oluşturacağımızı görelim.

static void Create_XMLExample(args a)
{
XMLDocument objDOM ;
XMLElement elNode ;
XMLText textNode;

XMLNode pNode;
XMLNode oNode;
XMLNode aNode;
XMLNode nNode;
XMLNode kNode;
XMLNode lNode;
XMLNode topNode;
XMLProcessingInstruction pi;
XmlAttribute idAttribute;
XmlAttribute descriptionAttribute;
InventTable artikelStamm;
;
try
{

// XML Document nesnesi oluşturuluyor.
objDOM = new XMLDocument();
// XML İşlem konumutu satırı oluşturuluyor.
pi = objDOM.createProcessingInstruction("xml", "version=\"1.0\" standalone=\"yes\" ");
// Üst ana düğüm.
// Kullanıcı sistemine XML dökümanı yüklenir.
objDOM.loadXML('');
topNode= objDOM.documentElement();
objDOM.insertBefore(pi,topNode.com() ) ;
// InventTable tablosundan belli kriterlere göre seçim işlemi yapılıyor.
while select * from artikelStamm Where artikelStamm.ItemId=='ProductId'
{
// XML alt düğümü (Child Node)
pNode = objDOM.documentElement();
elNode = objDOM.createElement('Aggregation');
oNode = pNode.appendChild(elNode);

// XML elemanı (Metin doyaları için örnek içerik)
nNode = objDOM.createElement('productId');
lNode = oNode.appendChild(nNode);
// InventTable.ItemId alanı
textNode = objDOM.createTextNode(ArtikelStamm.ItemId);
kNode = nNode.appendChild(textNode);

// XML elemanı (Sayısal doyaları için örnek içerik)
nNode = objDOM.createElement('startamount');
lNode = oNode.appendChild(nNode);
// InventTable.StartAmount alanı
textNode = objDOM.createTextNode(int2Str(ArtikelStamm.Height));
kNode = nNode.appendChild(textNode);

// XML elemenı (XML niteliği attribute örnek içerik)
nNode = objDOM.createElement('minduration');
idAttribute = objDOM.createAttribute('id');
idAttribute.value(strfmt('%1', int2Str(ArtikelStamm.Height)));
kNode = nNode.attributes().setNamedItem(idAttribute);
// InventTable.ItemId alanı
descriptionAttribute = objDOM.createAttribute('description');
descriptionAttribute.value(ArtikelStamm.ItemId);
kNode=nNode.attributes().setNamedItem(descriptionAttribute);
lNode = oNode.appendChild(nNode);

} // InventTable tablosu seçim işleminin sonu.

// Döküman kaydediliyor.
objDOM.save('C:/XMLExample.xml');
}
catch
{
error('Exception caught');
}