Questionnaires kullanımı ve çalıştırma hakkında bir çok sayfa var web'de. Bu yüzden Questionnaires nedir, nasıl kullanılır konusunda bir şey anlatmayacağım.
KMCollection - Questionnaire kayıtları tablosu. kmCollectionId anahtar alan.
KMVirtualNetworkAnswerTable - Cevaplar tablosu. kmVirtualNetworkAnswerTableId anahtar alan. evaluation alanında failed/passed veya boş olarak sonuç saklı.
KMVirtualNetworkAnswerLine - Cevap satırları tablosu.
Kod ile Questionnaire formu çalıştırma:
KMQuestionnaireRun o = new CrsKMQuestionnaireRun();
o.set(KMQuestionnaireRunMode::All,myKMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
Kod ile Answer formu çalıştırma:
KMVirtualNetworkAnswerTable answerTable;
Args args = new Args();
RecId recId = DirPersonUser::find(curUserId()).party();
select firstOnly answerTable
where answerTable.kmVirtualNetworkAnswerTableId == this.AnswerId;
args.record(answerTable);args.caller(o);
new MenuFunction(menuItemDisplayStr(KMKnowledgeCollectorUserResults), MenuItemType::Display).run(args);
Questionnaire Idlerini sakladığım kendi formumdan ve tablomdan kod ile Questionnaire formu çalıştırıp oluşan KMVirtualNetworkAnswerTable kaydının ID'sini almak için KMQuestionnaireRun_Win32 sınıfından yeni bir sınıf türettim:
class myKMQuestionnaireRun extends KMQuestionnaireRun_Win32
{
recId myRecId;
}
formu çağırdığım tablonun recId'sini saklamak için bir parm metodu ekledim:
RecId parmMyRecId(RecId _recId = myRecId)
{
myRecId =_recId;
return myRecId;
}
Daha sonra end metodunu türettim:
public void end(KMVirtualNetworkAnswerTableId _kmVirtualNetworkAnswerTableId)
{
myCallerTable tbl; //Questionnaries formunu çağıran tablo
super(_kmVirtualNetworkAnswerTableId);
if (_kmVirtualNetworkAnswerTableId == "")
return;
ttsBegin;
update_recordSet tbl setting AnswerId = _kmVirtualNetworkAnswerTableId
where tbl.RecId == myRecId;
ttsCommit;
}
Ve kendi tablomdan formu bu kodla çağırdım:
...
myKMQuestionnaireRun o = new myKMQuestionnaireRun();
myQTable c;
o.parmMyRecId(this.RecId);
o.set(KMQuestionnaireRunMode::All,this.KMCollectionId, DirPersonUser::find(curUserId()).party());
o.run();
...
Blog Listem
2012 etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
2012 etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
12 Aralık 2016 Pazartesi
23 Aralık 2015 Çarşamba
Axapta - XPO export dialog formunda dosya adının tarih - saat ile gelmesi
Bu sayede XPO'larımız versiyon kontrollü olmuş oluyor. Yedekleme açısından çok faydalı olan aşağıdaki kodu Eren Polat'dan aldım.
SysExportDialog formunun metodlarına aşağıdaki kodları ekleyin:
classDeclaration:
str sDate, sTime, sDateTime;
str sMilliSeconds;
init:
sMilliSeconds = int2str(winApi::getTickCount());
sDate = int2str(year(today())) + strReplace(num2str(mthofyr(today()),2,0,0,0), ' ', '0') + strReplace(num2str(dayofmth(today()),2,0,0,0), ' ', '0');
sTime = strfmt("%1:%2", time2str(timeNow(),1,1), substr(sMilliSeconds, strlen(sMilliSeconds)-2,2));
sTime = strReplace(sTime,":","");
sDateTime = strfmt("_%1%2",sDate,sTime);
run:
//element.updateBox(fileNameNext(strfmt('%1%2_%3%4', filePath, preFix, treeNode.treeNodeName(), #xpo)));
element.updateBox(fileNameNext(strfmt('%1%2_%3%4%5', filePath, preFix, treeNode.treeNodeName(), sDateTime, #xpo)));
SysExportDialog formunun metodlarına aşağıdaki kodları ekleyin:
classDeclaration:
str sDate, sTime, sDateTime;
str sMilliSeconds;
init:
sMilliSeconds = int2str(winApi::getTickCount());
sDate = int2str(year(today())) + strReplace(num2str(mthofyr(today()),2,0,0,0), ' ', '0') + strReplace(num2str(dayofmth(today()),2,0,0,0), ' ', '0');
sTime = strfmt("%1:%2", time2str(timeNow(),1,1), substr(sMilliSeconds, strlen(sMilliSeconds)-2,2));
sTime = strReplace(sTime,":","");
sDateTime = strfmt("_%1%2",sDate,sTime);
run:
//element.updateBox(fileNameNext(strfmt('%1%2_%3%4', filePath, preFix, treeNode.treeNodeName(), #xpo)));
element.updateBox(fileNameNext(strfmt('%1%2_%3%4%5', filePath, preFix, treeNode.treeNodeName(), sDateTime, #xpo)));
22 Aralık 2015 Salı
AX 2012 - Yeni WMS el terminali geliştirme
Microsoft kendi geliştirdiği WMS-II çözümünü bırakıp başka bir firmadan satın aldığı WMS çözümünü AX içine koydu. Bu yeni WMS çözümünün web ortamında çalışan kendine ait bir el terminali çözümü de var. El terminali çözümü tamamen web ortamında çalışırken geliştirme yaparken AX içinden çalıştırılması da sağlanmış. WHSWorkExecute isimli menu item ile AX tarafında bu çözümü çalıştırabiliriz. Microsoft WMS ve TM için ayrıntılı birer klavuz yayınlamış. WMS klavuzunda el terminali için kullanıcı tanımlama ve ayarlarını yapma anlatılmış. Ben bunları geçerek direk konuya giriyorum.
Klavuzda geliştirme hakkında bir bilgi yok. Ben bu konuda bulduğum bir blogdan faydalandım. Kendim uğraşsam bulamayacağımı sandığım püf noktalarını da hiçbir çaba sarfetmeden bu blogdan öğrenmiş oldum. :)
El terminali geliştirme yöntemini anlatırken WMS dökümanında anlatılan konuları bildiğinizi farzedeceğim.
El terminali geliştirmesi tamamen X++ classlar üzerinden çalışıyor. Yaptığınız her yeni menu item için bir class oluyor. Tüm menu item classları WMSWorkExecuteDisplay ile başlıyor.
Kendi menu itemimizi geliştirdiğimizi farzedelim. Eğer kendi menu itemimizi geliştirmeyeceksek bu adımı atlayabiliriz:
Yeni bir work ve/veya indirect menu item ekleyeceğiniz zaman WHSWorkCreationProcess enumuna bunu yeni bir eleman olarak eklemelisiniz. Eğer eklediğiniz menu item bir work ise ayrıca WHSWorkExecuteMode enum içine de eklemeniz gerekiyor. Okuduğum blogda yazdığına göre WHSWorkExecuteMode içine eklediğiniz elemanın adı ve label içeriği WHSWorkCreationProcess içine eklediğiniz ile birebir aynı olmalıymış, ben bunu hiç test etmedim, aynen söylenene uydum. Bizim elemanın adı Test olsun.
Bizim sınıfın adının WMSWorkExecuteDisplayTest olduğunu farzedelim. Sınıfımız WHSWorkExecuteDisplay sınıfından türeyecek.
Yukarıda anlattığımız enumlara eklenen eleman sayesinde kullanıcıya menu item tanımlama ekranında (Mobile device menu items ->Genel->Work creation process) yeni bir menu item daha görülebilecek. Ancak onun çağrılabilmesini sağlamak için yapılması gereken birşey daha var; WHSWorkExecuteDisplay sınıfının construct metodundaki switch/case bloğuna aşağıdaki kod parçasını eklemek:
case WHSWorkExecuteMode::MyTest : return WHSWorkExecuteDisplayTest::construct();
El terminali geliştirmesindeki tüm menu itemler kendi sınıfları içindeki displayForm metodu vasıtasıyla çalışıyor. Ben mevcut sınıflardan birini alıp kopyaladım ve onun üzerinde yaptığım değişikliklerle işimi gördüm. displayForm metodu aşamalar şeklinde çalışıyor. Bunu step isimli değişkenle takip ediyor. birinci aşama sıfır. Benim kopyaladığım sınıfta son aşama 2 olan kayıt aşamasıydı. Aşamaları orijinal sınıflarda da yapıldığı gibi displayForm metodunda bir switch/case ile takip edebilirsiniz.
Web formumuza yeni bir kontrol eklemek için buildControl metodunu kullanıyoruz:
ret += [this.buildControl(#RFText, #vendor, "@SYS14048", 1, pass.lookup(#vendor), extendedTypeNum(VendAccount), '', 0,false)];
Yukarıdaki kontroldeki #vendor makrosu WHSRF makrosunda yoksa bizim bunu ayrıca eklememiz gerekiyor. Yine blogdan öğrendiğim üzere bu metodun parametreleri şöyle (ordan copy/paste yapıp türkçeye çevirdim sadece):
Kontrolde kullandığımız datanın map edilip edilmediğini öğrenmek için exists, edilmişse de değerini öğrenmek için lookup metodlarını kullanıyoruz. Genelde aşağıdaki şekilde kullanılıyor:
if (pass.exists(#vendor) && pass.lookup(#vendor) != '")
Data değerini eklemek/değiştirmek için insert metodunu kullanıyoruz:
pass.insert(#vendor,purchTable.OrderAccount);
Bu arada Mobile device menu items formunda diğer menu itemlerinde gözüken ancak sizinkinde gözükmeyen seçenekleri görmek istiyorsanız bunun için (daire içinde işaretlediklerim)
WHSRFMenuItem formunun togglefields metodunda ufak bir değişiklik gerekiyor:
if (whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderItemReceiving ||
whsrfMenuItemTable.WorkCreationProcess ==
...
...
//memre 22.12.2015
whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderLineReceivingWithVendor)
//memre
...
...
Aynı zamanda WHSRFControlData sınıfının processControl metodunda ekstra güncellemeler yapmanız gerekebilir. Benim yaptığım bir geliştirmede orijinalinden kopyaladığım sınıfta orijinalinde LP (License Plate) oluşurken benimkinde oluşmuyordu. Sebebiyse enum ile yapılan LP kontrolüydü. Benim için aşağıdaki güncelleme iş gördü:
case #LicensePlateId:
...
...
else if (mode != WHSWorkExecuteMode::AdjustmentIn &&
mode != WHSWorkExecuteMode::ReportAsFinished &&
...
...
...
//memre 22.12.2015
mode != WHSWorkExecuteMode::PurchaseOrderLineReceivingWithVendor &&
//memre
mode != WHSWorkExecuteMode::PurchaseOrderItemReceivingAndLocate &&
...
...
Bildiğim kadarıyla tüm temel noktalar bunlar. Daha fazla ayrıntı için benim de faydalandığım blog ve WMS dökümanından faydalanabilirsiniz.
Klavuzda geliştirme hakkında bir bilgi yok. Ben bu konuda bulduğum bir blogdan faydalandım. Kendim uğraşsam bulamayacağımı sandığım püf noktalarını da hiçbir çaba sarfetmeden bu blogdan öğrenmiş oldum. :)
El terminali geliştirme yöntemini anlatırken WMS dökümanında anlatılan konuları bildiğinizi farzedeceğim.
El terminali geliştirmesi tamamen X++ classlar üzerinden çalışıyor. Yaptığınız her yeni menu item için bir class oluyor. Tüm menu item classları WMSWorkExecuteDisplay ile başlıyor.
Kendi menu itemimizi geliştirdiğimizi farzedelim. Eğer kendi menu itemimizi geliştirmeyeceksek bu adımı atlayabiliriz:
Yeni bir work ve/veya indirect menu item ekleyeceğiniz zaman WHSWorkCreationProcess enumuna bunu yeni bir eleman olarak eklemelisiniz. Eğer eklediğiniz menu item bir work ise ayrıca WHSWorkExecuteMode enum içine de eklemeniz gerekiyor. Okuduğum blogda yazdığına göre WHSWorkExecuteMode içine eklediğiniz elemanın adı ve label içeriği WHSWorkCreationProcess içine eklediğiniz ile birebir aynı olmalıymış, ben bunu hiç test etmedim, aynen söylenene uydum. Bizim elemanın adı Test olsun.
Bizim sınıfın adının WMSWorkExecuteDisplayTest olduğunu farzedelim. Sınıfımız WHSWorkExecuteDisplay sınıfından türeyecek.
Yukarıda anlattığımız enumlara eklenen eleman sayesinde kullanıcıya menu item tanımlama ekranında (Mobile device menu items ->Genel->Work creation process) yeni bir menu item daha görülebilecek. Ancak onun çağrılabilmesini sağlamak için yapılması gereken birşey daha var; WHSWorkExecuteDisplay sınıfının construct metodundaki switch/case bloğuna aşağıdaki kod parçasını eklemek:
case WHSWorkExecuteMode::MyTest : return WHSWorkExecuteDisplayTest::construct();
El terminali geliştirmesindeki tüm menu itemler kendi sınıfları içindeki displayForm metodu vasıtasıyla çalışıyor. Ben mevcut sınıflardan birini alıp kopyaladım ve onun üzerinde yaptığım değişikliklerle işimi gördüm. displayForm metodu aşamalar şeklinde çalışıyor. Bunu step isimli değişkenle takip ediyor. birinci aşama sıfır. Benim kopyaladığım sınıfta son aşama 2 olan kayıt aşamasıydı. Aşamaları orijinal sınıflarda da yapıldığı gibi displayForm metodunda bir switch/case ile takip edebilirsiniz.
Web formumuza yeni bir kontrol eklemek için buildControl metodunu kullanıyoruz:
ret += [this.buildControl(#RFText, #vendor, "@SYS14048", 1, pass.lookup(#vendor), extendedTypeNum(VendAccount), '', 0,false)];
Yukarıdaki kontroldeki #vendor makrosu WHSRF makrosunda yoksa bizim bunu ayrıca eklememiz gerekiyor. Yine blogdan öğrendiğim üzere bu metodun parametreleri şöyle (ordan copy/paste yapıp türkçeye çevirdim sadece):
| Paremetre | Data tipi | Açıklama |
| _controlType | str | Kontrolün türü. Bu türler WHSRF makrosunda eklenen türlerden biri olmak zorunda: #define.RFButton('button') #define.RFLabel('label') #define.RFText('text') #define.RFPassword('password') #define.RFListbox('listbox') #define.RFCombobox('combobox') #define.RFError('error') |
| _name | str | Kontrolün ismi. Kontrolde saklanan dataya ulaşmak için bu ismi kullanacağız. |
| _label | str | UI'de gözükecek text içeriği. |
| _newLine | int | 1 ise kontrol yeni bir satırda olacak, 0 ise aynı satırda. |
| _data | str | Kontrolde gösterilecek data. |
| _inputType | ExtendedTypeId | Kontrolün data türü. Doğrulama için bu önemli. Doğrulama gerekmiyorsa #WHSRFUndefinedDataType makrosu kullanılabilir. |
| _error | str | Doğrulama gerçekleşmediğinde çıkacak mesaj. |
| _defaultButton | int | 1 ise buton kontrolü varsayılan kontrol demektir, Genellikle "Tamam" butonu için kullanılır. |
| _enabled | boolean | true olduğunda kontrol enabled olur, false olduğunda disabled, default enabled. |
| _selected | int | 1 olduğunda aktif kontrol olur. |
| _color | WHSRFColorText | Kontrolün rengi. WHSRFColorText enumda tanımlı birkaç renk var. |
Kontrolde kullandığımız datanın map edilip edilmediğini öğrenmek için exists, edilmişse de değerini öğrenmek için lookup metodlarını kullanıyoruz. Genelde aşağıdaki şekilde kullanılıyor:
if (pass.exists(#vendor) && pass.lookup(#vendor) != '")
Data değerini eklemek/değiştirmek için insert metodunu kullanıyoruz:
pass.insert(#vendor,purchTable.OrderAccount);
Bu arada Mobile device menu items formunda diğer menu itemlerinde gözüken ancak sizinkinde gözükmeyen seçenekleri görmek istiyorsanız bunun için (daire içinde işaretlediklerim)
WHSRFMenuItem formunun togglefields metodunda ufak bir değişiklik gerekiyor:
if (whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderItemReceiving ||
whsrfMenuItemTable.WorkCreationProcess ==
...
...
//memre 22.12.2015
whsrfMenuItemTable.WorkCreationProcess == WHSWorkCreationProcess::PurchaseOrderLineReceivingWithVendor)
//memre
...
...
Aynı zamanda WHSRFControlData sınıfının processControl metodunda ekstra güncellemeler yapmanız gerekebilir. Benim yaptığım bir geliştirmede orijinalinden kopyaladığım sınıfta orijinalinde LP (License Plate) oluşurken benimkinde oluşmuyordu. Sebebiyse enum ile yapılan LP kontrolüydü. Benim için aşağıdaki güncelleme iş gördü:
case #LicensePlateId:
...
...
else if (mode != WHSWorkExecuteMode::AdjustmentIn &&
mode != WHSWorkExecuteMode::ReportAsFinished &&
...
...
...
//memre 22.12.2015
mode != WHSWorkExecuteMode::PurchaseOrderLineReceivingWithVendor &&
//memre
mode != WHSWorkExecuteMode::PurchaseOrderItemReceivingAndLocate &&
...
...
Bildiğim kadarıyla tüm temel noktalar bunlar. Daha fazla ayrıntı için benim de faydalandığım blog ve WMS dökümanından faydalanabilirsiniz.
Etiketler:
2012,
ax,
AXAPTA,
development,
el,
el terminali,
geliştirme,
new,
terminal,
wms,
yeni
1 Aralık 2015 Salı
AX 2012 - Müşteri ve satıcı hesabı ekleme/güncelleme
Müşteri hesabı:
CustTable custTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
CustGroup custGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
;
select firstOnly forUpdate custTable
where custTable.AccountNum == custAccount;
//-------------------- custtable --------------------------
if (custTable.RecId == 0)
{
custTable.initValue();
custTable.AccountNum = custAccount;
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.IdentificationNumber = identificationNumber;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.Blocked = custBlocked;
custTable.insert(DirPartyType::Organization, custName);
}
else
{
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.IdentificationNumber = identificationNumber;
custTable.Blocked = custBlocked;
custTable.update();
update_recordSet partyTable setting name = custName, NameAlias = nameAlias
where partyTable.RecId == custTable.Party;
}
//-------------------- adres -----------------------------
dirParty = DirParty::constructFromCommon(custTable);
select firstonly dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == custTable.Party &&
dirPartyPostalAddressView.LocationName == "Adres";
dirPartyPostalAddressView.LocationName = "Adres";
dirPartyPostalAddressView.City = city;
dirPartyPostalAddressView.State = state;
dirPartyPostalAddressView.Street = street;
dirPartyPostalAddressView.IsPrimary = NoYes::Yes;
dirPartyPostalAddressView.CountryRegionId = countryRegionId;
dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
if (phone)
{
dirParty = DirParty::constructFromCommon(custTable);
select dirPartyContactInfo
where firstonly dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "Telefon";
dirPartyContactInfo.LocationName ="Telefon";
dirPartyContactInfo.Locator = phone;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Phone;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
if (email)
{
select firstonly dirPartyContactInfo
where dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "E-mail";
dirPartyContactInfo.LocationName ="E-mail";
dirPartyContactInfo.Locator = email;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Email;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
Satıcı hesabı eklemenin müşteri hesabı eklemekten tek farkı dirParty kaydının ayrıca oluşturulması . Eğer hesap organizasyon yerine bir kişi ise DirOrganization tablosu yerine DirPersonName tablosu kullanılıyor:
VendTable vendTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
VendGroup vendGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
DirOrganization organization;
;
select firstOnly forUpdate vendTable
where vendTable.AccountNum == vendAccount;
//-------------------- vendTable --------------------------
if (vendTable.RecId == 0)
{
organization.Name = vendName;
organization.NameAlias = nameAlias;
organization.LanguageId = CompanyInfo::languageId();
organization.insert();
vendTable.initValue();
vendTable.party = organization.recid;
vendTable.AccountNum = vendAccount;
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.TaxOfficeName_TR = taxOfficeName_TR;
vendTable.insert();
}
else
{
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.update();
update_recordSet organization setting name = vendName, NameAlias = nameAlias
where organization.RecId == vendTable.Party;
}
CustTable custTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
CustGroup custGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
;
select firstOnly forUpdate custTable
where custTable.AccountNum == custAccount;
//-------------------- custtable --------------------------
if (custTable.RecId == 0)
{
custTable.initValue();
custTable.AccountNum = custAccount;
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.IdentificationNumber = identificationNumber;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.Blocked = custBlocked;
custTable.insert(DirPartyType::Organization, custName);
}
else
{
custTable.CustGroup = custGroupId;
custTable.VATNum = vatNum;
custTable.TaxOfficeName_TR = taxOfficeName_TR;
custTable.IdentificationNumber = identificationNumber;
custTable.Blocked = custBlocked;
custTable.update();
update_recordSet partyTable setting name = custName, NameAlias = nameAlias
where partyTable.RecId == custTable.Party;
}
//-------------------- adres -----------------------------
dirParty = DirParty::constructFromCommon(custTable);
select firstonly dirPartyPostalAddressView
where dirPartyPostalAddressView.Party == custTable.Party &&
dirPartyPostalAddressView.LocationName == "Adres";
dirPartyPostalAddressView.LocationName = "Adres";
dirPartyPostalAddressView.City = city;
dirPartyPostalAddressView.State = state;
dirPartyPostalAddressView.Street = street;
dirPartyPostalAddressView.IsPrimary = NoYes::Yes;
dirPartyPostalAddressView.CountryRegionId = countryRegionId;
dirParty.createOrUpdatePostalAddress(dirPartyPostalAddressView);
if (phone)
{
dirParty = DirParty::constructFromCommon(custTable);
select dirPartyContactInfo
where firstonly dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "Telefon";
dirPartyContactInfo.LocationName ="Telefon";
dirPartyContactInfo.Locator = phone;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Phone;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
if (email)
{
select firstonly dirPartyContactInfo
where dirPartyContactInfo.Party == custTable.Party &&
dirPartyContactInfo.LocationName == "E-mail";
dirPartyContactInfo.LocationName ="E-mail";
dirPartyContactInfo.Locator = email;
dirPartyContactInfo.IsPrimary = NoYes::Yes;
dirPartyContactInfo.Type = LogisticsElectronicAddressMethodType::Email;
dirParty.createOrUpdateContactInfo(dirPartyContactInfo);
}
Satıcı hesabı eklemenin müşteri hesabı eklemekten tek farkı dirParty kaydının ayrıca oluşturulması . Eğer hesap organizasyon yerine bir kişi ise DirOrganization tablosu yerine DirPersonName tablosu kullanılıyor:
VendTable vendTable;
DirParty dirParty;
DirPartyPostalAddressView dirPartyPostalAddressView;
DirPartyContactInfoView dirPartyContactInfo;
VendGroup vendGroup;
DirPartyTable partyTable;
DirPartyLocation dirLocation;
LogisticsPostalAddress address;
LogisticsLocation logisticsLocation;
DirOrganization organization;
;
select firstOnly forUpdate vendTable
where vendTable.AccountNum == vendAccount;
//-------------------- vendTable --------------------------
if (vendTable.RecId == 0)
{
organization.Name = vendName;
organization.NameAlias = nameAlias;
organization.LanguageId = CompanyInfo::languageId();
organization.insert();
vendTable.initValue();
vendTable.party = organization.recid;
vendTable.AccountNum = vendAccount;
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.TaxOfficeName_TR = taxOfficeName_TR;
vendTable.insert();
}
else
{
vendTable.vendGroup = vendGroupId;
vendTable.VATNum = vatNum;
vendTable.Blocked = VendBlocked;
vendTable.update();
update_recordSet organization setting name = vendName, NameAlias = nameAlias
where organization.RecId == vendTable.Party;
}
30 Kasım 2015 Pazartesi
AX 2012 - Ürün ekleme/güncelleme
//http://daxtechies.blogspot.com.tr/2013/12/ax2012-r2-creating-product-or-product.html
if ( InventTable::find(itemId).ItemId != "" )
this.updateProduct();
else
this.newProduct();
itemRecId = EcoResProduct::findByDisplayProductNumber(itemId).RecId;
this.updateInventTable();
private void newProduct(EcoResProductSubtype _subType = EcoResProductSubtype::Product)
{
EcoResProductService erProdSvc;
EcoResEcoResProduct ecoResProd;
EcoResEcoResProduct_Product_Master prodMaster;
EcoResEcoResProduct_Translation translation;
EcoResEcoResProduct_Identifier identifier;
EcoResEcoResProduct_ProductDimGroup prodDimGroup;
EcoResEcoResProduct_Product_Distinct distMaster;
EcoResEcoResProduct_StorageDimGroup storDimGroup;
EcoResEcoResProduct_TrackingDimGroup tracDimGroup;
InventTable inventTable;
erProdSvc = EcoResProductService::construct();
ecoResProd = new EcoResEcoResProduct();
if (_subType == EcoResProductSubtype::ProductMaster) //varyantlı ürün
{
prodMaster = new EcoResEcoResProduct_Product_Master();
prodMaster.parmDisplayProductNumber(itemId);
prodMaster.parmProductType(EcoResProductType::Item);
prodMaster.parmSearchName(nameAlias);
prodMaster.parmVariantConfigurationTechnology(EcoResVariantConfigurationTechnologyType::PredefinedVariants);
translation = prodMaster.createTranslation().addNew();
identifier = prodMaster.createIdentifier().addNew();
prodDimGroup = prodMaster.createProductDimGroup().addNew();
prodDimGroup.parmProduct(itemId);
prodDimGroup.parmProductDimensionGroup(dimGroup);
storDimGroup = prodMaster.createStorageDimGroup().addNew();
tracDimGroup = prodMaster.createTrackingDimGroup().addNew();
}
if (_subType == EcoResProductSubtype::Product) //varyantsız ürün
{
distMaster = new EcoResEcoResProduct_Product_Distinct();
distMaster.parmDisplayProductNumber(itemId);
distMaster.parmProductType(EcoResProductType::Item);
distMaster.parmSearchName(nameAlias);
translation = distMaster.createTranslation().addNew();
identifier = distMaster.createIdentifier().addNew();
storDimGroup = distMaster.createStorageDimGroup().addNew();
tracDimGroup = distMaster.createTrackingDimGroup().addNew();
}
translation.parmDescription(itemName);
translation.parmLanguageId(SystemParameters::getSystemLanguageId());
translation.parmName(itemName);
storDimGroup.parmProduct(itemId);
storDimGroup.parmStorageDimensionGroup(storeGroup);
tracDimGroup.parmProduct(itemId);
tracDimGroup.parmTrackingDimensionGroup(trackingGroup);
identifier.parmProductNumber(itemId);
if (_subType == EcoResProductSubtype::ProductMaster) //varyantlı ürün
ecoResProd.createProduct().add(prodMaster);
if (_subType == EcoResProductSubtype::Product) //varyantsız ürün
ecoResProd.createProduct().add(distMaster);
erProdSvc.create(ecoResProd);
EcoResProductReleaseManagerBase::releaseProduct(EcoResProduct::findByProductNumber(itemId).RecId,CompanyInfo::find().RecId);
}
private void updateProduct()
{
InventTableModule inventModule;
EcoResProductTranslation translation;
update_recordSet inventModule setting unitId = unitId
where inventModule.ItemId == itemId;
update_recordSet translation
setting Description = itemName,
Name = itemName
where translation.Product == itemRecId &&
translation.LanguageId == SystemParameters::getSystemLanguageId();
}
private void updateInventTable()
{
InventTable inventTable;
InventModelGroupItem modelGroup;
update_recordSet inventTable
setting NetWeight = netWeight,
TaraWeight = taraWeight,
GrossDepth = depth,
GrossWidth = width,
GrossHeight = height,
UnitVolume = volume
where
inventTable.Product == itemRecId;
if (inventModelGroupId == "")
delete_from modelGroup
where modelGroup.ItemId == itemId && modelGroup.ItemDataAreaId == curext() &&
modelGroup.ModelGroupDataAreaId == curext();
else
{
select firstOnly forUpdate modelGroup
where modelGroup.ItemId == itemId && modelGroup.ItemDataAreaId == curext() &&
modelGroup.ModelGroupDataAreaId == curext();
modelGroup.ItemId = itemId;
modelGroup.ItemDataAreaId = curext();
modelGroup.ModelGroupDataAreaId = curext();
modelGroup.ModelGroupId = inventModelGroupId;
if (modelGroup.RecId == 0)
modelGroup.insert();
else
modelGroup.update();
}
}
if ( InventTable::find(itemId).ItemId != "" )
this.updateProduct();
else
this.newProduct();
itemRecId = EcoResProduct::findByDisplayProductNumber(itemId).RecId;
this.updateInventTable();
private void newProduct(EcoResProductSubtype _subType = EcoResProductSubtype::Product)
{
EcoResProductService erProdSvc;
EcoResEcoResProduct ecoResProd;
EcoResEcoResProduct_Product_Master prodMaster;
EcoResEcoResProduct_Translation translation;
EcoResEcoResProduct_Identifier identifier;
EcoResEcoResProduct_ProductDimGroup prodDimGroup;
EcoResEcoResProduct_Product_Distinct distMaster;
EcoResEcoResProduct_StorageDimGroup storDimGroup;
EcoResEcoResProduct_TrackingDimGroup tracDimGroup;
InventTable inventTable;
erProdSvc = EcoResProductService::construct();
ecoResProd = new EcoResEcoResProduct();
if (_subType == EcoResProductSubtype::ProductMaster) //varyantlı ürün
{
prodMaster = new EcoResEcoResProduct_Product_Master();
prodMaster.parmDisplayProductNumber(itemId);
prodMaster.parmProductType(EcoResProductType::Item);
prodMaster.parmSearchName(nameAlias);
prodMaster.parmVariantConfigurationTechnology(EcoResVariantConfigurationTechnologyType::PredefinedVariants);
translation = prodMaster.createTranslation().addNew();
identifier = prodMaster.createIdentifier().addNew();
prodDimGroup = prodMaster.createProductDimGroup().addNew();
prodDimGroup.parmProduct(itemId);
prodDimGroup.parmProductDimensionGroup(dimGroup);
storDimGroup = prodMaster.createStorageDimGroup().addNew();
tracDimGroup = prodMaster.createTrackingDimGroup().addNew();
}
if (_subType == EcoResProductSubtype::Product) //varyantsız ürün
{
distMaster = new EcoResEcoResProduct_Product_Distinct();
distMaster.parmDisplayProductNumber(itemId);
distMaster.parmProductType(EcoResProductType::Item);
distMaster.parmSearchName(nameAlias);
translation = distMaster.createTranslation().addNew();
identifier = distMaster.createIdentifier().addNew();
storDimGroup = distMaster.createStorageDimGroup().addNew();
tracDimGroup = distMaster.createTrackingDimGroup().addNew();
}
translation.parmDescription(itemName);
translation.parmLanguageId(SystemParameters::getSystemLanguageId());
translation.parmName(itemName);
storDimGroup.parmProduct(itemId);
storDimGroup.parmStorageDimensionGroup(storeGroup);
tracDimGroup.parmProduct(itemId);
tracDimGroup.parmTrackingDimensionGroup(trackingGroup);
identifier.parmProductNumber(itemId);
if (_subType == EcoResProductSubtype::ProductMaster) //varyantlı ürün
ecoResProd.createProduct().add(prodMaster);
if (_subType == EcoResProductSubtype::Product) //varyantsız ürün
ecoResProd.createProduct().add(distMaster);
erProdSvc.create(ecoResProd);
EcoResProductReleaseManagerBase::releaseProduct(EcoResProduct::findByProductNumber(itemId).RecId,CompanyInfo::find().RecId);
}
private void updateProduct()
{
InventTableModule inventModule;
EcoResProductTranslation translation;
update_recordSet inventModule setting unitId = unitId
where inventModule.ItemId == itemId;
update_recordSet translation
setting Description = itemName,
Name = itemName
where translation.Product == itemRecId &&
translation.LanguageId == SystemParameters::getSystemLanguageId();
}
private void updateInventTable()
{
InventTable inventTable;
InventModelGroupItem modelGroup;
update_recordSet inventTable
setting NetWeight = netWeight,
TaraWeight = taraWeight,
GrossDepth = depth,
GrossWidth = width,
GrossHeight = height,
UnitVolume = volume
where
inventTable.Product == itemRecId;
if (inventModelGroupId == "")
delete_from modelGroup
where modelGroup.ItemId == itemId && modelGroup.ItemDataAreaId == curext() &&
modelGroup.ModelGroupDataAreaId == curext();
else
{
select firstOnly forUpdate modelGroup
where modelGroup.ItemId == itemId && modelGroup.ItemDataAreaId == curext() &&
modelGroup.ModelGroupDataAreaId == curext();
modelGroup.ItemId = itemId;
modelGroup.ItemDataAreaId = curext();
modelGroup.ModelGroupDataAreaId = curext();
modelGroup.ModelGroupId = inventModelGroupId;
if (modelGroup.RecId == 0)
modelGroup.insert();
else
modelGroup.update();
}
}
29 Eylül 2014 Pazartesi
AX 2012 - R3 Kurulum
Öncelikle minimum sistem gereksinimlerini kontrol edin. MS-SQL kurulumunuzun collate değeri turkish olmamalı. SAP ve Oracle'da da sorun olan meşhur "i" problemi sebebiyle AX kurulumu tamamlandıktan sonra database sync işleminiz patlar.
Kurulum için Microsoft'un uzun ve karmaşık kurulum dökümanı yerine Dilip's Blog'dan faydalandım. AX 2012 kurulumu çok basit veya bana öyle denk geldi.
Öncelikle Active Directory kurulum gerekiyor. Active Directory kurulumu çok basit ve Google'da anlatan çok fazla makale var.
Ben aynen Dilip'in yaptığı gibi SSRS vs.. kurulumları daha sonraya bırakarak temel AX 2012 kurdum. AX 2012 Setup gerekli yazılımların download linklerini veriyor ve yazılımları otomatik konfigüre ediyor. Kurulum esnasında hiç problem yaşamadım.
Daha sonra Microsoft'un demo datayı da yine bir blog sayfasından faydalanarak kurdum. Demo data kurulumu AX 2012 kurulumundan daha zor.
SQL Server SSRS eklentisini kurduktan sonra ayarlarını da yine bir blogdan faydalanarak yaptım. Bu arada SSRS rapor düzenleyebilmek için (Deploy için gerekmiyor) SQL Server Setup ile Business Intelligence Development Studio kurmayı unutmayın. SSRS ayarları oldukça basitti; sırasıyla Service account, Web service URL, Database, Report Manager URL tablarını varsayılan ayarlarıyla çalıştırmak yeterli oluyor.
Yine başka bir Dilip sayfasından faydalanarak AX 2012 SSRS kurulumunu yaptım. Burda da hiç sorun yaşamadım ve Dilip'in gösterdiği manuel kuruluma ihtiyacım olmadı, raporlarım otomatik deploy oldu.
Kurulum için Microsoft'un uzun ve karmaşık kurulum dökümanı yerine Dilip's Blog'dan faydalandım. AX 2012 kurulumu çok basit veya bana öyle denk geldi.
Öncelikle Active Directory kurulum gerekiyor. Active Directory kurulumu çok basit ve Google'da anlatan çok fazla makale var.
Ben aynen Dilip'in yaptığı gibi SSRS vs.. kurulumları daha sonraya bırakarak temel AX 2012 kurdum. AX 2012 Setup gerekli yazılımların download linklerini veriyor ve yazılımları otomatik konfigüre ediyor. Kurulum esnasında hiç problem yaşamadım.
Daha sonra Microsoft'un demo datayı da yine bir blog sayfasından faydalanarak kurdum. Demo data kurulumu AX 2012 kurulumundan daha zor.
SQL Server SSRS eklentisini kurduktan sonra ayarlarını da yine bir blogdan faydalanarak yaptım. Bu arada SSRS rapor düzenleyebilmek için (Deploy için gerekmiyor) SQL Server Setup ile Business Intelligence Development Studio kurmayı unutmayın. SSRS ayarları oldukça basitti; sırasıyla Service account, Web service URL, Database, Report Manager URL tablarını varsayılan ayarlarıyla çalıştırmak yeterli oluyor.
Yine başka bir Dilip sayfasından faydalanarak AX 2012 SSRS kurulumunu yaptım. Burda da hiç sorun yaşamadım ve Dilip'in gösterdiği manuel kuruluma ihtiyacım olmadı, raporlarım otomatik deploy oldu.
26 Eylül 2014 Cuma
AX 2012 - Batch joblar bir türlü başlamıyorsa?
Home->Inquiries->Batch jobs->My batch jobs 'a girince jobların başlamadığını görürseniz.
System administration->Setup->System->Server configuration'a girip Batch server schedule'de uygun saatlerde (00-23:59) kayıt olduğuna ve Maximum batch threads değerinin sıfırdan farklı olmasına dikkat edin.
Ayrıca sorun batch gruplarına hiç server atanmamasıyla da ilgili olabilir:
Administration -> setup -> Batch Groups
Buradaki boş batch group için Batch Servers tabına girip Selected server alanında doğru sunucu seçili mi onu da kontrol edin.
System administration->Setup->System->Server configuration'a girip Batch server schedule'de uygun saatlerde (00-23:59) kayıt olduğuna ve Maximum batch threads değerinin sıfırdan farklı olmasına dikkat edin.
Ayrıca sorun batch gruplarına hiç server atanmamasıyla da ilgili olabilir:
Administration -> setup -> Batch Groups
Buradaki boş batch group için Batch Servers tabına girip Selected server alanında doğru sunucu seçili mi onu da kontrol edin.
15 Eylül 2014 Pazartesi
AX 2012 - Tabloya bağlı yeni bir finansal boyut tanımlama
Microsoft'un ilgili white paper sayfasından faydalanan bir blogdan öğrendiğim bu işlem çok kolay:
1-AOT'dan DimAttribute adıyla başlayan viewlerden birini kopyala ve adı yine aynen DimAttribute ile başlasın.
2. Ana data sourcenin orijinal tablo adı ne olursa olsun adı data source adı BackingEntity olsun.
3.Viewdeki tanımlı alanların adı (orijinal isimleri farklı olabilir) şöyle olmak zorunda:
Key - Data source tablosunun Surrogate key field'ı. RecId gibi...
Value - Data source tablosunun primary key field'ı. AccountNum gibi...
Name - Açıklama alanı. Description gibi...
Bu boyutun geçerli olması için iki yol var:
AOS restart
veya
DimensionCache::clearAllScopes();
komutu.
1-AOT'dan DimAttribute adıyla başlayan viewlerden birini kopyala ve adı yine aynen DimAttribute ile başlasın.
2. Ana data sourcenin orijinal tablo adı ne olursa olsun adı data source adı BackingEntity olsun.
3.Viewdeki tanımlı alanların adı (orijinal isimleri farklı olabilir) şöyle olmak zorunda:
Key - Data source tablosunun Surrogate key field'ı. RecId gibi...
Value - Data source tablosunun primary key field'ı. AccountNum gibi...
Name - Açıklama alanı. Description gibi...
Bu boyutun geçerli olması için iki yol var:
AOS restart
veya
DimensionCache::clearAllScopes();
komutu.
11 Eylül 2014 Perşembe
AX 2012 - Bir LedgerDimension değerinden tek bir boyutun değerini almak
Bu konuyu oluştururken bir blogda bulduğum dimension hakkında çizilmiş data modelini kullandım. Malesef blogdaki kodu anlayamadım ve bu kodu yazdım:
DimensionDefault d = 5637183219;
DimensionAttributeValueCombination dimensionAttributeValueCombination;
DimensionAttributeValueGroupCombination dimensionAttributeValueGroupCombination;
DimensionAttributeValueGroup dimensionAttributeValueGroup;
DimensionAttributeLevelValue dimensionAttributeLevelValue;
DimensionAttributeValue dimensionAttributeValue;
DimensionAttribute dimensionAttribute;
select dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == d
join dimensionAttributeValueGroupCombination
where dimensionAttributeValueGroupCombination.DimensionAttributeValueCombination ==
dimensionAttributeValueCombination.RecId
join dimensionAttributeValueGroup
where dimensionAttributeValueGroup.RecId == dimensionAttributeValueGroupCombination.DimensionAttributeValueGroup
join dimensionAttributeLevelValue
where dimensionAttributeLevelValue.DimensionAttributeValueGroup == dimensionAttributeValueGroup.RecId
join dimensionAttributeValue
where dimensionAttributeValue.RecId == dimensionAttributeLevelValue.DimensionAttributeValue
join dimensionAttribute
where dimensionAttribute.RecId == dimensionAttributeValue.DimensionAttribute &&
DimensionAttribute.Name == "Proje";
info(DimensionAttributeLevelValue.DisplayValue);
Güncelleme:
Yukarıdaki bağlantı PurchTable defaultDimension alanı için çalışmadı.
Aşağıdaki kodu Andesoft'un web sitesinden aldım:
DimensionDefault d = 5637169331;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItem dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Common dimensionValueEntity;
DimensionValue dimensionValue;
DimensionAliasName dimensionName;
dimAttrValueSet = DimensionAttributeValueSet::find(D);
while select dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == dimAttrValueSet.RecId
{
dimAttrValue = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
dimAttr = DimensionAttribute::find(DimAttrValue.DimensionAttribute);
dimensionvalueentity = DimensionDefaultingControllerBase::findBackingEntityInstance(
curext(),DimAttr,dimAttrvalue.EntityInstance);
dimensionvalue = dimattrvalue.getValue();
info(strFmt("%1 %2",Dimensionvalue, DimAttr.Name));
}
DimensionDefault d = 5637183219;
DimensionAttributeValueCombination dimensionAttributeValueCombination;
DimensionAttributeValueGroupCombination dimensionAttributeValueGroupCombination;
DimensionAttributeValueGroup dimensionAttributeValueGroup;
DimensionAttributeLevelValue dimensionAttributeLevelValue;
DimensionAttributeValue dimensionAttributeValue;
DimensionAttribute dimensionAttribute;
select dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == d
join dimensionAttributeValueGroupCombination
where dimensionAttributeValueGroupCombination.DimensionAttributeValueCombination ==
dimensionAttributeValueCombination.RecId
join dimensionAttributeValueGroup
where dimensionAttributeValueGroup.RecId == dimensionAttributeValueGroupCombination.DimensionAttributeValueGroup
join dimensionAttributeLevelValue
where dimensionAttributeLevelValue.DimensionAttributeValueGroup == dimensionAttributeValueGroup.RecId
join dimensionAttributeValue
where dimensionAttributeValue.RecId == dimensionAttributeLevelValue.DimensionAttributeValue
join dimensionAttribute
where dimensionAttribute.RecId == dimensionAttributeValue.DimensionAttribute &&
DimensionAttribute.Name == "Proje";
info(DimensionAttributeLevelValue.DisplayValue);
Güncelleme:
Yukarıdaki bağlantı PurchTable defaultDimension alanı için çalışmadı.
Aşağıdaki kodu Andesoft'un web sitesinden aldım:
DimensionDefault d = 5637169331;
DimensionAttributeValueSet dimAttrValueSet;
DimensionAttributeValueSetItem dimAttrValueSetItem;
DimensionAttributeValue dimAttrValue;
DimensionAttribute dimAttr;
Common dimensionValueEntity;
DimensionValue dimensionValue;
DimensionAliasName dimensionName;
dimAttrValueSet = DimensionAttributeValueSet::find(D);
while select dimAttrValueSetItem
where dimAttrValueSetItem.DimensionAttributeValueSet == dimAttrValueSet.RecId
{
dimAttrValue = DimensionAttributeValue::find(dimAttrValueSetItem.DimensionAttributeValue);
dimAttr = DimensionAttribute::find(DimAttrValue.DimensionAttribute);
dimensionvalueentity = DimensionDefaultingControllerBase::findBackingEntityInstance(
curext(),DimAttr,dimAttrvalue.EntityInstance);
dimensionvalue = dimattrvalue.getValue();
info(strFmt("%1 %2",Dimensionvalue, DimAttr.Name));
}
10 Eylül 2014 Çarşamba
AX 2012 - Bir DefaultDimension değerinden tek bir boyutu almak
Bu kodu yazarken bir blogdan faydalandım:
DimensionAttributeValueSetStorage dimStorage;
Counter i;
DimensionAttribute dimAttributeCostCenter;
DimensionAttributeValue dimAttributeValue;
DimensionDefault d = 5637168596;
dimStorage = DimensionAttributeValueSetStorage::find(d);
info(dimStorage.getDisplayValueByDimensionAttribute(DimensionAttribute::findByName("Project").RecId));
DimensionAttributeValueSetStorage dimStorage;
Counter i;
DimensionAttribute dimAttributeCostCenter;
DimensionAttributeValue dimAttributeValue;
DimensionDefault d = 5637168596;
dimStorage = DimensionAttributeValueSetStorage::find(d);
info(dimStorage.getDisplayValueByDimensionAttribute(DimensionAttribute::findByName("Project").RecId));
AX 2012 - Default dimension verisine yeni bir dimension değeri eklemek
Bu kodu Eyüp Tezar'ın bir kodundan faydalanarak yazdım:
DimensionDefault DefDim;
DimensionAttribute dimensionAttribute;
DimensionAttributeValue newValue;
DimensionAttributeValueSetStorage dimensionStorage;
DefDim = mytable.Defaultdimension;
dimensionAttribute = DimensionAttribute::find(myDimRecid);
newValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
myDimValue,false,true);
dimensionStorage = DimensionAttributeValueSetStorage::find(DefDim);
dimensionStorage.addItem(newValue);
DefDim = dimensionStorage.save();
//------------------- another dimension ------------------------
dimensionAttribute = DimensionAttribute::findbyName("Project");
newValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
myDimValue2,false,true);
dimensionStorage = DimensionAttributeValueSetStorage::find(DefDim);
dimensionStorage.addItem(newValue);
DefDim = dimensionStorage.save();
DimensionDefault DefDim;
DimensionAttribute dimensionAttribute;
DimensionAttributeValue newValue;
DimensionAttributeValueSetStorage dimensionStorage;
DefDim = mytable.Defaultdimension;
dimensionAttribute = DimensionAttribute::find(myDimRecid);
newValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
myDimValue,false,true);
dimensionStorage = DimensionAttributeValueSetStorage::find(DefDim);
dimensionStorage.addItem(newValue);
DefDim = dimensionStorage.save();
//------------------- another dimension ------------------------
dimensionAttribute = DimensionAttribute::findbyName("Project");
newValue = DimensionAttributeValue::findByDimensionAttributeAndValue(dimensionAttribute,
myDimValue2,false,true);
dimensionStorage = DimensionAttributeValueSetStorage::find(DefDim);
dimensionStorage.addItem(newValue);
DefDim = dimensionStorage.save();
8 Eylül 2014 Pazartesi
AX 2012 - Taxtrans tablosunun değişen yapısı
AX 2012 ile birlikte eskiden taxtrans tablosunda olan bazı alanlar değişik tablolara dağıldı. Microsoft'un bu konuda açıklayıcı bir makalesi var. Aşağıda örnek bir join var:
select generalJournalAccountEntry
join generalJournalEntry
where generalJournalEntry.RecId == generalJournalAccountEntry.GeneralJournalEntry &&
generalJournalEntry.RecId == _RecId
join subledgerVoucherGeneralJournalEntry
where subledgerVoucherGeneralJournalEntry.GeneralJournalEntry == generalJournalEntry.RecId
join dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == generalJournalAccountEntry.LedgerDimension
join mainAccount
where mainAccount.RecId == dimensionAttributeValueCombination.MainAccount;
select generalJournalAccountEntry
join generalJournalEntry
where generalJournalEntry.RecId == generalJournalAccountEntry.GeneralJournalEntry &&
generalJournalEntry.RecId == _RecId
join subledgerVoucherGeneralJournalEntry
where subledgerVoucherGeneralJournalEntry.GeneralJournalEntry == generalJournalEntry.RecId
join dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == generalJournalAccountEntry.LedgerDimension
join mainAccount
where mainAccount.RecId == dimensionAttributeValueCombination.MainAccount;
AX 2012 - LedgerTrans nereye gitti?
AX 2012 ile LedgerTrans tablosunun yerine birkaç tablo geliyor. Bu tabloları join ile birleştirmek gerekiyor. Bu konu hakkında Microsoft'un açıklayıcı bir makalesi var. İsimleri değişen ve değişik tablolara dağılan alanların açıklamalarını buradan bulabilirsiniz. Aşağıda örnek bir join var:
select generalJournalAccountEntry
join generalJournalEntry
where generalJournalEntry.RecId == generalJournalAccountEntry.GeneralJournalEntry &&
generalJournalEntry.AccountingDate >= beginDate && generalJournalEntry.AccountingDate <= endDate
join subledgerVoucherGeneralJournalEntry
where subledgerVoucherGeneralJournalEntry.GeneralJournalEntry == generalJournalEntry.RecId
join dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == generalJournalAccountEntry.LedgerDimension
join mainAccount
where mainAccount.RecId == dimensionAttributeValueCombination.MainAccount &&
mainAccount.MainAccountId == myAccount
select generalJournalAccountEntry
join generalJournalEntry
where generalJournalEntry.RecId == generalJournalAccountEntry.GeneralJournalEntry &&
generalJournalEntry.AccountingDate >= beginDate && generalJournalEntry.AccountingDate <= endDate
join subledgerVoucherGeneralJournalEntry
where subledgerVoucherGeneralJournalEntry.GeneralJournalEntry == generalJournalEntry.RecId
join dimensionAttributeValueCombination
where dimensionAttributeValueCombination.RecId == generalJournalAccountEntry.LedgerDimension
join mainAccount
where mainAccount.RecId == dimensionAttributeValueCombination.MainAccount &&
mainAccount.MainAccountId == myAccount
3 Eylül 2014 Çarşamba
AX 2012 - LedgerJournalTrans tablosuna Voucher atamak
AXLedgerJournalTrans sınıfı kullanıldığında voucher otomatik atanır. Ancak direk tablodan kayıt eklendiğinde bunu kendiniz yapmalısınız:
numberSeq = numberSeq::newGetVoucherFromCode(NumberSequenceTable::find(ledgerJournalTable.ledgerJournalName().NumberSequenceTable).NumberSequence);
LedgerJournalTrans.Voucher = numberSeq.voucher();
numberSeq = numberSeq::newGetVoucherFromCode(NumberSequenceTable::find(ledgerJournalTable.ledgerJournalName().NumberSequenceTable).NumberSequence);
LedgerJournalTrans.Voucher = numberSeq.voucher();
Etiketler:
2012,
ax,
AXAPTA,
ledgerjournaltrans,
voucher
2 Eylül 2014 Salı
AX 2012 - Forma splitter eklemek
AX 2012'de splitter eklemek 2009'a göre çok daha kolay. Burada dikey splitter'i anlatacağım:
Formun üst parçası için bir grup oluşturun. Splitter için bir grup oluşturun. Ben Hsplitter adını verdim. AutoDeclaration = Yes olsun ve Style = SplitterHorizontalContainer olsun. Alt taraf için de bir grup oluşturun. Üst gruba bir isim verin. Burada ben TopGroup adını verdim, ayrıca bu grup için de AutoDeclaration = Yes olsun. Alt grup için Height Column Height olsun. Splitter grubu bu iki grubun arasında olsun.
Form classDeclaration'a bu satırı ekleyin:
SysFormSplitter_Y HorizontalSplitter;
Eğer yatay olacaksa SysFormSplitter_X olmalı. Form init metoduna da bu satırı ekleyin:
HorizontalSplitter = new SysFormSplitter_Y(HSplitter,TopGroup, element);
Yatay olacaksa new SysFormSplitter_X ... olmalı.
Hepsi bu...
Formun üst parçası için bir grup oluşturun. Splitter için bir grup oluşturun. Ben Hsplitter adını verdim. AutoDeclaration = Yes olsun ve Style = SplitterHorizontalContainer olsun. Alt taraf için de bir grup oluşturun. Üst gruba bir isim verin. Burada ben TopGroup adını verdim, ayrıca bu grup için de AutoDeclaration = Yes olsun. Alt grup için Height Column Height olsun. Splitter grubu bu iki grubun arasında olsun.
Form classDeclaration'a bu satırı ekleyin:
SysFormSplitter_Y HorizontalSplitter;
Eğer yatay olacaksa SysFormSplitter_X olmalı. Form init metoduna da bu satırı ekleyin:
HorizontalSplitter = new SysFormSplitter_Y(HSplitter,TopGroup, element);
Yatay olacaksa new SysFormSplitter_X ... olmalı.
Hepsi bu...
8 Ağustos 2014 Cuma
AX 2012 - CIL oluşturma esnasında XPPIL hatası
Açıklama: CIL generation: The given key was not present in the dictionary.
Yol: \XppIL
Satır: 1
Yöntem/Özellik adı: XppIL
Teşhis kodu: Err:351
Data Dictionary'i senkronize edin, hataları temizleyin.
AOS down yapın. Bu klasördeki alt klasörler hariç tüm dosyaları silin:
C:\Program Files\Microsoft Dynamics AX\60\Server\AX2012R2_Dev\bin\XppIL
Yol: \XppIL
Satır: 1
Yöntem/Özellik adı: XppIL
Teşhis kodu: Err:351
Data Dictionary'i senkronize edin, hataları temizleyin.
AOS down yapın. Bu klasördeki alt klasörler hariç tüm dosyaları silin:
C:\Program Files\Microsoft Dynamics AX\60\Server\AX2012R2_Dev\bin\XppIL
5 Ağustos 2014 Salı
AX 2012 - Forma default dimension eklemek
Nasıl yapıldığını anlamak için LedgerJournalTable formuna bakılabilir.
DimensionDefault EDTsi ile tabloya eklediğimiz alana DimensionAttributeValueSet tablosunun RecId alanıyla bir relation ekliyoruz.
Forma bir tab sayfası ekleyip adını tabFinancialDimensions yapıyoruz ve aşağıdaki property ayarlarını yapıyoruz:
AutoDeclaration = true
caption = @SYS101181
HideIfEmpty = No
NeedPermission = Manual
Formun classDeclaration metoduna aşağıdaki tanımlamayı yapıyoruz:
DimensionDefaultingController dimensionDefaultingController;
Formun init metoduna aşağıdaki kodları yazıyoruz:
public void init()
{
boolean allowEdit = true;
super();
dimensionDefaultingController = DimensionDefaultingController::constructInTabWithValues(false, true, allowEdit, 0, this, tabFinancialDimensions, "@SYS101181");
dimensionDefaultingController.parmAttributeValueSetDataSource(MyTable_ds, fieldStr(MyTable, DefaultDimension));
dimensionDefaultingController.parmValidateBlockedForManualEntry(true);
}
Tab sayfası kontrolüne bu metodu ekliyoruz:
public void pageActivated()
{
dimensionDefaultingController.pageActivated();
super();
}
Tablo data source metodlarını aşağıdaki gibi güncelliyoruz:
public void delete()
{
super();
DimensionDefaultingController.deleted();
}
public void write()
{
ttsBegin;
DimensionDefaultingController.writing();
super();
ttsCommit;
}
public int active()
{
int ret;
ret = super();
DimensionDefaultingController.activated();
return ret;
}
DimensionDefault EDTsi ile tabloya eklediğimiz alana DimensionAttributeValueSet tablosunun RecId alanıyla bir relation ekliyoruz.
Forma bir tab sayfası ekleyip adını tabFinancialDimensions yapıyoruz ve aşağıdaki property ayarlarını yapıyoruz:
AutoDeclaration = true
caption = @SYS101181
HideIfEmpty = No
NeedPermission = Manual
Formun classDeclaration metoduna aşağıdaki tanımlamayı yapıyoruz:
DimensionDefaultingController dimensionDefaultingController;
Formun init metoduna aşağıdaki kodları yazıyoruz:
public void init()
{
boolean allowEdit = true;
super();
dimensionDefaultingController = DimensionDefaultingController::constructInTabWithValues(false, true, allowEdit, 0, this, tabFinancialDimensions, "@SYS101181");
dimensionDefaultingController.parmAttributeValueSetDataSource(MyTable_ds, fieldStr(MyTable, DefaultDimension));
dimensionDefaultingController.parmValidateBlockedForManualEntry(true);
}
Tab sayfası kontrolüne bu metodu ekliyoruz:
public void pageActivated()
{
dimensionDefaultingController.pageActivated();
super();
}
Tablo data source metodlarını aşağıdaki gibi güncelliyoruz:
public void delete()
{
super();
DimensionDefaultingController.deleted();
}
public void write()
{
ttsBegin;
DimensionDefaultingController.writing();
super();
ttsCommit;
}
public int active()
{
int ret;
ret = super();
DimensionDefaultingController.activated();
return ret;
}
4 Ağustos 2014 Pazartesi
AX 2012 - SSRS ile sıfır yerine boşluk göstermek
Field yerine (örnekte PurchPrice) aşağıdaki gibi bir IIF fonksiyonu kullanabilirsiniz:
=IIF(Fields!PurchPrice.Value = 0 ,"",Fields!PurchPrice.Value)
=IIF(Fields!PurchPrice.Value = 0 ,"",Fields!PurchPrice.Value)
17 Temmuz 2014 Perşembe
AX 2012 - SSRS Report Geliştirirken Visual Studio Tablo Penceresi Kaybolursa?
View->Report Data
AX 2012 - VendInvoiceInfoTable Yeni Eklediğim Alanın Değeri Güncellemede Kayboluyor
VendInvoiceInfoTable tablosuna yeni bir alan ekledim. VendEditInvoice formu ile kaydı güncellemek istediğimde tabloya yeni eklediğim alanın içinin boş geldiğini gördüm. Uzun uğraşlar sonunda bu formun aslında kaydı yeni bir kayda kopyaladığını ve bu işlem esnasında beni alanımı da atladığını farkettim. Axapta kaydı kopyalarken copyFromHeader isimli tablo metodunu kullanıyor. Araya kendi satırımı ekledim:
this.VendorRequestedWorkerEmail = _header.VendorRequestedWorkerEmail;
//benim yeni alanım
this.myNewField = _header.myNewField;
sorun düzeldi. Bu tablonun satır tablosu VendInvoiceInfoLine da aynı şekilde çalışıyor.
this.VendorRequestedWorkerEmail = _header.VendorRequestedWorkerEmail;
//benim yeni alanım
this.myNewField = _header.myNewField;
sorun düzeldi. Bu tablonun satır tablosu VendInvoiceInfoLine da aynı şekilde çalışıyor.
Etiketler:
2012,
alan,
ax,
AXAPTA,
field,
güncellenme,
sorun,
vendinvoiceinfotable,
yeni
Kaydol:
Kayıtlar (Atom)
