Posts Tagged ‘ x++

Dynamics 365 Finance and Operations için yeni bir Build ortamı nasıl ayağa kaldırılır?

Bu yazıda Dynamics 365 Finance and Operations için yeni Build tipinde bir sanal makine nasıl ayağa kaldırılır adım adım anlatmaya çalışacağım.

Başlamadan önce eğer bir müşteri uyarlama projeniz varsa burada gelen SandBox Develop And Test ortamını Build olarak ayarlamanız öneriliyor. Çünkü bu ortama yakın zamanda admin giriş yetkisi kalkacak ve geliştirme için kullanmak pek mümkün olmayacak. Dolayısıyla Build olarak ayarlamakta fayda var. Ayrıca yine yakın zamanda çıkacak bir Agent sayesinde bütün bir VM ayırmadan Build yapabileceğiz.

Biz bu örnekte Cloud-hosted environment üzerinden yeni bir Build makine oluşturmayı göreceğiz. Sandbox ile aynı adımlara sahip dolayısıyla ikisini de kapsayacak bir yazı olacak. Öncelikle Lifecycle Services’a giriş yapıyoruz. Projemizi seçip hamburger menüden Cloud-hosted environments’ı seçiyoruz.

Resim-1

Read more

X++ :20- CrosCompany Nedir?

Bu yazıda X++ sorgu anahtar kelimelerinden crossCompany inceleyeceğim. Öncelikle uygulamanın şirket yönetimini anlamak gerekiyor.

Uygulamadan istediğiniz kadar şirket tanımlayabiliyorsunuz. Kullanıcılar uygulamaya girdiğinde bir şirkette işlem yapıyorlar. İstedikleri zaman şirket değiştirebiliyorlar. Tablolarda DataAreaId sayesinde verilerin hangi şirkete ait olduğu tutuluyor. Eğer bir tablonun verisi şirket bağımsız olsun diyorsanız ayarlayabiliyorsunuz. Ancak bu tip tabloların dışında yaptığınız bütün işlemler bulunduğunuz şirkette gerçekleşiyor. Bir sorgu yazıp verileri görmek istediğinizde siz Range olarak şirket vermezseniz bile sistem SQL’e giden koda otomatik bulunduğunuz şirketi ekliyor. Bazı durumlarda iki faklı şirketin verisini tek bir sorguda görmek isteyebilirsiniz. Bunun için crossCompany kullanılıyor. Bir örnek yapalım.

static void FDDataAccessCrossCompany1(Args _args)

{

CustTable custTable;

container companies;

;

companies = ["USMF", "USF", “DMR”]; // Kaç şirkette sorgu yapmak istiyorsam buraya ekleyebilirim.

while select crossCompany : companies custTable // crossCompany ile oluşturduğum Container’ı veriyorum

where custTable.AccountNum like “M00032*”

{

info(strFmt(“%1 : %2 : %3″, custTable.AccountNum, custTable.Name(), custTable.dataAreaId));

}

}

Bu sorgunun SQL kodunda or ile şirket kodlarının eklendiğini görürsünüz bu sayede eklenen şirketlerdeki veriler alınabilir.  Sistem şirketler arası birçok işlem yapmak gerekiyor bu yüzden bu yapıları iyi bilemek işiniz kolaylaştırır. crossCompany Query’de de kullanılır. Dolayısıyla birden çok şirket verisi gösteren View ve Form yapabilirsiniz.

Selamlar.

www.fatihdemirci.net

TAGs: X++, crossCompany, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

Dynamics 365 Finance and Operations için yeni bir X++ geliştirme sanal makinesi nasıl ayağa kaldırılır?

Bu yazıda yeni bir X++ geliştirmeleri için yeni bir sanal makine nasıl ayağa kaldırılır adım adım anlatmaya çalışacağım. Bu örnekte bir müşteri ortamında bunu asıl yapacağınızı anlatacağım. Partner veya eğitim amaçlı sanal makinelerde benzer bir mantığa sahip.

Öncelikle Lifecycle Services’a giriş yapıyoruz. Projemizi seçip hamburger menüden Cloud-hosted environments’ı seçiyoruz.

Resim-1

Read more

X++ :18- Select Nasıl Yazılır?

Bu yazıda X++ ile sorgu nasıl yazılır anlatmaya çalışacağım. X++ sorguları SQL sorgularına çok benzer ama temelde birkaç fark var öncelikle TableBuffer denen bir kavram var. SQL de bir sorgu yazdığınızda direk veriyi görürsünüz ama X++ da bunun görselleştirilebilmesi için bir TableBuffer‘a ihtiyaç vardır. Temel bir sorguda kullanılan anahtar kelimeler bunlardır. Birkaç örnek yaparak açıklamaya çalışacağım.

[while] select [reverse] [firstfast]

[firstonly] [firstOnly10] [firstOnly100] [firstOnly1000]

[forupdate] [nofetch] [crosscompany]

[forcelitterals | forceplaceholders] [forcenestedloop]

[forceselectorder]

[repeatableRead] [validTimeState]

[ * | <fieldlist> from] <tablebuffer>

[ index [hint] <indexname> ]

[ group by {<field>} ]

[ order by {<field> [asc][desc]} ]

[ where <expression> ]

[ outer | exists | notexists ] join [reverse]

[ * | <fieldlist> from] <tablebuffer>

[ index <indexname> ]

[sum] [avg] [minof] [maxof] [count]

[ group by {<field>} ]

[ order by {<field> [asc][desc]} ]

[ where <expression> ]

]

<fieldlist> ::= <field> | <fieldlist> , <field>

<field> ::= fieldname | <function>(<field>)

Bir Job ile temel birkaç sorgu yazalım.

class FDDataAccess1

{

public static void main(Args _args)

{

CustTable custTable;

;

select * from custTable; // Müşteri tablosundaki tüm kayıtları seçer

info(strFmt(“1- %1 %2″, custTable.AccountNum, custTable.Currency));

select custTable; // // Müşteri tablosundaki tüm kayıtları seçer. * From a ihtiyaç duymaz

info(strFmt(“2- %1 %2″, custTable.AccountNum, custTable.Currency));

select Currency from custTable; // Müşteri tablosundaki sadece Currency  alanını seçer

info(strFmt(“3- %1 %2″, custTable.AccountNum, custTable.Currency));

select reverse custTable; //  Müşteri tablosundaki tüm kayıtları ters sırada seçer

info(strFmt(“4- %1 %2″, custTable.AccountNum, custTable.Currency));

select firstonly custTable; // Müşteri tablosundaki tek satır veriyi seçer

info(strFmt(“5- %1 %2″, custTable.AccountNum, custTable.Currency));

select firstonly custTable

where custTable.Currency != “TRY”; // TRY den faklı olan ilk satırı seçer.

info(strFmt(“6- %1 %2″, custTable.AccountNum, custTable.Currency));

select firstonly custTable

where custTable.Currency != “TRY” &&

custTable.CustGroup == “PROJE”;

info(strFmt(“7- %1 %2″, custTable.AccountNum, custTable.Currency));

select firstonly custTable

where custTable.Currency == “TRY” ||

custTable.CustGroup == “PROJE”;

info(strFmt(“8- %1 %2″, custTable.AccountNum, custTable.Currency));    }

}

Çalıştırdığımda bu çıktıyı veriyor.

Resim-1

Farklı bir örnek yapalım. Bu job benim eğitimlerde kullandığım bir örnek.

static void FDDataAccess2(Args _args)

{

InventTable inventTable;

InventTrans inventTrans;

;

//1. sistemimde tanımlı bütün stok kartlar (InventTable)

setprefix(“Sistemimde tanımlı bütün stok kartlar”);

while select inventTable

{

info(strFmt(“%1 %2″, inventTable.ItemId, inventTable.ItemName()));

}

//2. kaç stok kartım var

setPrefix(“kaç stok kartım var”);

select count(recId) from inventTable;

info(strFmt(“%1″, inventTable.recId));

// 3. Hareket gören stok kartlarım hangileri (sadece stok kartlarım)

setPrefix(“Hareket gören stok kartlarım”);

while select inventTable

exists join inventTrans

where inventTable.ItemId == inventTrans.ItemId

{

info(strFmt(“%1 %2 %3″, inventTable.ItemId,

inventTrans.Qty,

inventTrans.DatePhysical));

}

//4. stok kartı hareket bilgisi

setPrefix(“stok kartı hareket bilgisi”);

while select inventTable

join inventTrans

where inventTable.ItemId == inventTrans.ItemId

{

info(strFmt(“%1 %2 %3″, inventTable.ItemId,

inventTrans.Qty,

inventTrans.DatePhysical));

}

//5. Hiç hareket görmeyen stok kartlarım hangileri ve adedi

setPrefix(“Hiç hareket görmeyen stok kartlarım”);

while select inventTable

notexists join inventTrans

where inventTable.ItemId == inventTrans.ItemId

{

info(strFmt(“%1 %2 %3″, inventTable.ItemId,

inventTrans.Qty,

inventTrans.DatePhysical));

}

setPrefix(“Hiç hareket görmeyen stok kartlarımın adedi”);

select count(recId) from inventTable

notexists join inventTrans

where inventTable.ItemId == inventTrans.ItemId;

info(strFmt(“Hiç hareket görmeyen stok kartlarım : %1 adettir.”, inventTable.recId));

//6. Her bir stok kartı için en yüksek stok hareket miktarını içeren bilgi

setPrefix(“Her bir stok kartı için en yüksek stok hareket miktarını içeren bilgi”);

while select maxof(Qty)

from inventTrans

group by inventTrans.ItemId

{

info(strFmt(“%1 %2″, inventTrans.ItemId,

inventTrans.Qty));

}

}

Bu yazıda sorgu nasıl yazılır temel örneklerle anlatmaya çalıştım. Çok geniş bir konu ve çok ayrıntısı mevcut. Bunu iyi bilmek için veri tabanı yapısına ve temel SQL komutlarına hâkim olmak gerekiyor. SQL yazan birisi burada zorlanmaz. İleriki yazılarımda sorgunun diğer ayrıntılarına değinmeye devam edeceğim.

Selamlar.

www.fatihdemirci.net

TAGs: X++,Select, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :17- InitValue Metodu Ne İşe Yarar?

Bu yazıda Dynamics 365 Finance and Operations tablo metotlarından InitValue() metodunu anlatacağım. InitValue() kayıt oluşturulurken otomatik bir alana ilk değer atamaya yarayan bir metottur.  Bir örnek yapalım.

FDBookTable tablosunda metotlara sağ tıklayıp InitValue() metodunu Override ettim.

Resim-1

Kitap kapak tipinizi normal olarak atadım. Şimdi tablo tarayıcısını açıp yeni kayıt dediğim anda otomatik kapak tipi normal olarak gelecek.

Resim-2

Şimdi kod çalışma sırasını anlamak için örneğimizi devam ettirelim. Önceki yazılarımda FDBookTable adında bir form yapmıştım. Diyelim ki bu formdan sadece kapak tipi karton olan kitaplar oluşturulabilsin. Bu sefer formun initValue metodunu eziyorum

Resim-3

Bu metoda kapak tipi olarak karton ataması yapıyorum.

Resim-4

Şu anda Tabloda normal formda karton diye iki tane ön değer tanımladım hangisi geçerli olacak tabi ki nesne tabanlı programlamanın temel mantığına uygun olarak ezilen üst seviyedeki kod geçerli olacak yanı formda yazdığımız atamayı yapacak.

Resim-5

Bu yazıda InitValue metodundan bahsettim. İlk değer ataması için kullanılan bir metot. Bu metotla birlikte kod çalışma sırasına da biraz değindik. Tablo en alt seviye ve buraya yazılan kodlar form veya alt seviye tasarım nesnelerinden ezilmediği sürece geçerli olurlar. İkisi birlikte çalışsın da diyebiliriz. Bunların da örneklerini ilerleyen yazılarımda yazacağım.

Selamlar.

www.fatihdemirci.net

TAGs: X++, InitValue, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :16- ModifiedField Metodu Ne İşe Yarar?

Bu yazıda Dynamics 365 Finance and Operations tablo metotlarından ModifiedField () metodunu anlatacağım. ModifiedField () bir alanın verisi değiştirildiğinde eğer bir işlem yapmak gerekiyorsa bu metotta yapabilirsiniz. Doğrulama metodu olan validateField() bu metottan önce çalışacaktır. Metodun tetiklenmesi için alandan odağın çıkması gerekir. Bir örnek yapalım.

FDBookTable tablosunda metotlara sağ tıklayıp ModifiedField () metodunu Override ettim. Kapak tipi değiştirildiğinde kitabın adını boşaltan bir kod yazdım. Şöyle bir mantık eğer kapak tipi değişirse kitap adında bir değişiklik yapılması şarttır diye düşünüp örneklendirdim. Metot parametre olarak alan kodu alıyor ona uygun bir Switch Case yazmak lazım.

Resim-1

Derleyip tablo tarayıcısıyla açalım. Kapak tipini değiştirdiğimde Kitap adının boşaldığını göreceksiniz.

Resim-2

Bu yazıda ModifiedField() metodunun mantığını anlatmaya çalıştım. Bu metotları mantığına uygun kullanırsanız çok rahat edersiniz. Ama mantığını uygun olmayan kodları buraya yazdığınızda uygulama içinden çıkılmaz bir hal alıyor.

Selamlar.

www.fatihdemirci.net

TAGs: X++, ModifiedField, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :21- ChangeCompany Nedir?

Bu yazıda X++ sorgu anahtar kelimelerinden changeCompany inceleyeceğim. Öncelikle uygulamanın şirket yönetimini anlamak gerekiyor.

Uygulamadan istediğiniz kadar şirket tanımlayabiliyorsunuz. Kullanıcılar uygulamaya girdiğinde bir şirkette işlem yapıyorlar. İstedikleri zaman şirket değiştirebiliyorlar. Tablolarda DataAreaId sayesinde verilerin hangi şirkete ait olduğu tutuluyor. Eğer bir tablonun verisi şirket bağımsız olsun diyorsanız ayarlayabiliyorsunuz. Ancak bu tip tabloların dışında yaptığınız bütün işlemler bulunduğunuz şirkette gerçekleşiyor. Bir sorgu yazıp verileri görmek istediğinizde siz Range olarak şirket vermezseniz bile sistem SQL’e giden koda otomatik bulunduğunuz şirketi ekliyor. Eğer faklı kodunuz farklı şirkette çalışsın istiyorsanız bunun için changeCompany kullanabilirsiniz. Bir örnek yapalım.

static void Dmr_FD_ChangeCompany(Args _args)

{

DmrAuthorTable  authorTable;

DmrBookTable    bookTable;

;

changeCompany(“USF”) // Şu anda USMF şirketindeyim ve çalıştırdığım kodlar burada çalışacak. Ancak changeCompany ile şirket değiştirip bu kod bloğunda USF’te çalışsın diyorum.

{

while select authorTable

notexists join  bookTable

where authorTable.AuthorId ==  bookTable.AuthorId

{

info(strFmt(“%1 %2 %3 %4″, bookTable.BookId , authorTable.AuthorId,

authorTable.FirstName ,  bookTable.Title));

}

}

}

changeCompany çok kullanılan hayat kurtaran bir özellik ancak genelde yanlış kullanıldığını görüyorum. Örnek 3 faklı şirkette 1000 satır veri aktarımına benzer bir kodunuz var diyelim. Arkadaş bu veriyi gruplamadan her bir satıra changeCompany yazıyor ve bunun hızlı çalışmasını bekliyor. Olmaz changeCompany zaman alan bir koddur ve mümkün olduğunca az kullanılmalıdır. changeCompany bloğunda yazılan her kod sanki değiştirdiğiniz şirkette çalışır sadece select değil Insert Update Delete işlemlerinde yapabilirsiniz.

Selamlar.

www.fatihdemirci.net

TAGs: X++, changeCompany, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :15- ValidateField Metodu Ne İşe Yarar?

Bu yazıda Dynamics 365 Finance and Operations tablo metotlarından validateField() metodunu anlatacağım. validateField() bir alanın verisi değiştirildiğinde doğrulamaların yapıldığı metottur. Metodun tetiklenmesi için alandan odağın çıkması gerekir. Bir örnek yapalım.

FDBookTable tablosunda metotlara sağ tıklayıp validateField () metodunu Override ettim.

Resim-1

Metoda parametre olarak alan kodu geliyor ona bağlı bir Switch Case yazdım. BookCount Sıfır olarak güncellenmeye çalışıldığında hata verdin diye bir kod yazdım. Hata mesajı için CheckFailed() kullandım.

Resim-2

Tablo tarayıcısıyla açtım ve BookCount sıfır olarak güncellemeye çalıştım ve hata mesajını ekranda gördüm. Bu hatayı düzeltmeden kaydetme veya başka işlem yapamazsınız.

Resim-3

boolean validateField(FieldId p1)

{

boolean                     ret;

#isoCountryRegionCodes

int                         lengthAgencyLocationCode;

ret = super(p1);

if (ret)

{

switch (p1)

{

case fieldNum(CustTable, CreditMax) :

if (this.CreditMax < 0)

{

ret = checkFailed(“@SYS69970″);

}

break;

case fieldNum(CustTable, InventLocation) :

ret = this.InventStorageDimMap::validateField(fieldNum(InventStorageDimMap, InventLocationId));

break;

case fieldNum(CustTable, Rfc_MX) :

if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoMX]))

{

ret = taxRegistrationValidator.validateRFC(this.Rfc_MX, this.CompanyType_MX);

}

break;

case fieldNum(CustTable, MainContactWorker) :

if (this.MainContactWorker)

{

ret = smmUtility::isValidWorkerInCurrentCompany(this.MainContactWorker);

}

break;

case fieldNum(CustTable, Blocked) :

ret = this.validateBlocked(this.Blocked);

break;

case fieldNum(CustTable, EinvoiceEANNum):

if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoDK]))

{

ret = CustTable::checkEInvoiceEAN(this.EinvoiceEANNum);

}

break;

}

}

return ret;

}

CustTable  validateField () metodunu inceleyelim. Burada uzun validasyonların metotlara taşındığını ve genelde tek satırlı kontroller olduğunu görüyoruz. checkFailed direk veya metotların içinde kullanılıyor. validateField () metodu sadece girişi bitip başka bir nesneye odaklanmak istediğinizde çalışır. Genelde o nesneden ayrılmadan çalışması isteniz ancak bu mümkün değil.

Selamlar.

www.fatihdemirci.net

TAGs: X++, validateField, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :14- ValidateWrite Metodu Ne İşe Yarar?

Bu yazıda Dynamics 365 Finance and Operations tablo metotlarından validateWrite() metodunu anlatacağım. validateWrite () bir kaydın DB’ye Insert veya Update işlemelerinden önce çalışan doğrulamaların yapıldığı metottur. Bir örnek yapalım.

FDBookTable tablosunda metotlara sağ tıklayıp validateWrite () metodunu Override ettim.

Resim-1

Şöyle bir kontrol yazalım. Eğer BookCount == 0 ise hata versin. Bunun için checkFailed() kullanılır. Otomatik olarak info verip hata döndüren bir koddur.

Resim-2

Kaydedip tablo tarayıcısını açalım. Sıfır girip kaydetmeye çalıştığımızda hata mesajını alırız.

Resim-3

boolean validateWrite()

{

#isoCountryRegionCodes

boolean                     ret;

DirPartyType                type;

ret = super();

// Warn user if this customer lacks a tax exempt number, but do not fail to save the revision.

if (!this.OneTimeCustomer && TaxVATNumTable::isVATNumMandatory(CustParameters::find().MandatoryVATNum, this))

{

warning(“@SYS54494″);

}

if (ret)

{

if (PaymTerm::isCashAccount(this.PaymTermId) && this.PaymSched)

{

ret = checkFailed(“@SYS25074″);

}

}

// Add check MandatoryTaxGroup is set on CustParameters.

if (ret && CustParameters::find().MandatoryTaxGroup && !this.TaxGroup)

{

ret = checkFailed(“@SYS113299″);

}

if (SysCountryRegionCode::isLegalEntityInCountryRegion([#isoMX]))

{

taxRegistrationValidator = TaxRegistrationValidator_MX::construct(this);

ret = taxRegistrationValidator.validateCustomerTaxRegistration() && ret;

}

if (this.MainContactWorker)

{

ret = ret && smmUtility::isValidWorkerInCurrentCompany(this.MainContactWorker);

}

if (ret && !CustVendTable::validateContactForParty(true, this.ContactPersonId, this.Party))

{

ret = checkFailed(“@SCM:InvalidPrimaryContactErrorMessage”);

}

return ret;

}

CustTable ValidateWrite() metodunu inceleyelim. checkFailed kullanımını görebilirsiniz. Eğer birkaç satırdan uzun bir kod gerekiyorsa ayrı metot yazıp buradan onu çağırmak genel yaklaşımdır.

Selamlar.

www.fatihdemirci.net

TAGs: X++,validateWrite, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

X++ :19- Insert, Update, Delete Nasıl Kullanılır?

Bu yazıda X++ DataManupulation nasıl yapılır anlatmaya çalışacağım. Veri oluşturma güncelleme ve silme işlemleri ERP için en temel fonksiyonalardır. X++ ile nasıl yapılır bir örnek yapalım. Önceki yazılarımda kullandığım FDBookTable’ı kullanacağım.

class FDDataManupulation

{

public static void main(Args _args)

{

FDBookTable bookTable;

FDBookTable bookTableUp;

;

bookTable.clear(); // TableBuffer’ı temizliyoruz.

bookTable.BookId    = “B005″;

bookTable.BookName  = “Book 1″;

bookTable.insert(); // Yeni kayıt oluşturma

bookTable.clear();

bookTable.BookId    = “B006″;

bookTable.BookName  = “Book 2″;

if(bookTable.validateWrite()) // Kodla insert yaptığınızda validasyon çalışmaz bu yüzden koda eklemek gerekiyor.

{

bookTable.insert();

}

// Güncelleme yapalım. Öncelikle güncellemek istediğimiz kaydı seçmeliyiz ve Transaction bloğu oluşturmalıyız. Bunun sebebi eğer güncelleme sırasında bir hata olursa geri alma yapabilmektir.

ttsbegin;

select forupdate bookTableUp

where bookTableUp.BookId == “B006″;

bookTableUp.BookName = “Book 3″;

bookTableUp.update(); // Tek bir satır günceller

ttscommit;

ttsbegin;

while select forupdate bookTableUp

where bookTableUp.BookId == “B006″

{

bookTableUp.updare(); // Yine tek bir satır günceller ama eğer sorgudan daha çok kayıt gelseydi mesela kapak tipine göre filtre verseydim gelen tüm kayıtları güncellerdi.

}

ttscommit;

// Kayıt silme

delete_from

where bookTableUp.BookId == “B006″; En temel kullanımı budur ama Delete metoduyla da silebilirsiniz.

while select forupdate bookTableUp

where bookTableUp.BookId == “B006″

{

bookTableUp.delete(); // Kaydı siler

}

}

}

Bu yazıda temel Insert Update Delete nasıl yapılır anlatmaya çalıştım. Performans açısından bunları doğru yapmak çok önemli. Birde bunları Bulk halinde yapabilmeniz mümkün onları da ayrıca anlatacağım.

Selamlar.

www.fatihdemirci.net

TAGs: X++,Insert,Update,Delete, Azure, Azure DevOps, Microsoft Dynamics 365, MsDyn365FO, MsDyn365CE, MsDyn365

Page 3 of 131234510...Last »