SSRS ve SysOperation class yapısı birbirine çok benzer bir şekilde çalışmaktadır. Contract classındaki bir paramerenin görünmesini istemediğimizde SysOperationControlVisibilityAttribute(false) kodundan yararlanıyoruz.
Örnek :
[DataMemberAttribute,SysOperationDisplayOrderAttribute('3'), SysOperationControlVisibilityAttribute(false)]
public ETGCollateralNum parmCollateralNum(ETGCollateralNum _collateralNum = collateralNum)
{
;
collateralNum = _collateralNum;
return collateralNum;
}
Dynamics Ax'ta geliştirme yapmayı öğrenin!!! Hem de Türkçe!!!
SysOperation etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
SysOperation etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
15 Eylül 2014 Pazartesi
8 Eylül 2014 Pazartesi
SysOperation Framework VS RunBaseBatch
SysOperation Framework
Nedir, ne zaman kullanılır.
Danışmanların
hazırladıkları dökümanlarda aşağıdaki cümleleri sıkça duyarız
·
Butona
basınca bir ekran açılsın , raporlarda olduğu gibi solda tarih vs.. alanlar
seçebilsin , sağda ise CustTable dan müşterileri seçebilsin. Oklediğinde
seçtiği müşteriler için ……. İşlemleri yapılsın.
·
Bir işlem
olsun günlük ,saatlik olarak kendi kendine çalışsın. Müşterilere kendi
ekstrelerini her pazartesi mail atsın gibi.
Bu tür kendi kendine
tekrar eden işler veya özellikle seç butonundan kullanıcının belli kayıtları
filtrelemesi gibi istekler için çözüm Ax içerisinde mevcuttur.
AX 2012 de böyle bir
yapıyı kurmak için kullanacağımız yapının ismi SysOperation Framework tür. Çok
basit ve öğrenmesi çok kolaydır. çünkü
bir rapor için kullandığımız Contract UIBuilder classları çok benzer şekilde bu
frameworkte kullanılmaktadır. DP class ının bir benzeri burada Service classı
olarak geçer. Bunun detaylarına ilerleyen bölümlerde değineceğiz.
AX 2009 da ise bu yapıyı
RunBase ve RunBaseBatch classları ile yapabiliriz. AX 2012 dede RunBase
yapıları bulunmaktadır fakat sonraki versiyonda desteklenmeyeceği için bu
yapıyı AX 2012 de kullanmamalıyız.
Dynamics 2012
ETGTutorialSysOperationQueryContract
[DataContractAttribute]
class ETGTutorialSysOperationQueryContract
{
Name name;
BirthDate birthDate;
str packedQuery;
}
public Query getQuery()
{
return new Query(SysOperationHelper::base64Decode(packedQuery));
}
[DataMemberAttribute
,SysOperationLabelAttribute(literalStr("Doğum Tarihi"))]
public BirthDate parmBirthDate(BirthDate _birthDate = birthDate)
{
birthDate = _birthDate;
return birthDate;
}
[DataMemberAttribute,SysOperationLabelAttribute(literalStr("Ad Soyad"))]
public Name parmName(Name _name = name)
{
name = _name;
return name;
}
[DataMemberAttribute,
AifQueryTypeAttribute('_packedQuery', querystr(CustTable))
]
/*
QUERY KENDİ QUERYNE GÖRE AYARLA
*/
public str parmQuery(str _packedQuery = packedQuery)
{
packedQuery = _packedQuery;
return packedQuery;
}
public void setQuery(Query _query)
{
packedQuery = SysOperationHelper::base64Encode(_query.pack());
}
ETGTutorialSysOperationQueryController
class ETGTutorialSysOperationQueryController extends SysOperationServiceController
{
}
protected ClassDescription defaultCaption()
{
// This will be the dialog's caption
return 'SysOperation demo';
}
protected void new()
{
// This tells the controller what method it should execute as the service. In this case, we'll run SysOperationDemoService.performDemo()
super(classStr(ETGTutorialSysOperationQueryService), methodStr(ETGTutorialSysOperationQueryService, process), SysOperationExecutionMode::Synchronous);
}
public void run()
{
info('Run method has been called');
super();
}
protected boolean validate()
{
ETGTutorialSysOperationQueryContract contract;
boolean ret = true;
contract = this.getDataContractObject();
if (contract.parmBirthDate()> DateTimeUtil::date(DateTimeUtil::addYears(DateTimeUtil::utcNow(), -18)))
{
// Failing the validate will not close the dialog, and the user will have another chance of inputting the correct values
ret = checkFailed('The user is underage!');
}
return ret;
}
public static ETGTutorialSysOperationQueryController construct()
{
ETGTutorialSysOperationQueryController controller;
controller = new ETGTutorialSysOperationQueryController();
controller.parmShowDialog(true); // Actually the default value
controller.parmShowProgressForm(false);
return controller;
}
public static void main(Args _args)
{
ETGTutorialSysOperationQueryController controller;
controller = ETGTutorialSysOperationQueryController::construct();
controller.startOperation();
}
ETGTutorialSysOperationQueryService
class ETGTutorialSysOperationQueryService extends SysOperationServiceBase
{
}
public str process(ETGTutorialSysOperationQueryContract _contract)
{
str info = strFmt('%1 was born in %2', _contract.parmName(), _contract.parmBirthDate());
QueryRun queryRun;
CustTable custTable;
;
// create a new queryrun object
queryRun = new queryRun(_contract.getQuery());
// loop all results from the query
while(queryRun.next())
{
custTable = queryRun.get(tableNum(custTable));
// display the accountnum
info(custTable.AccountNum);
}
info(info);
return info;
}
Dynamics 2009
Bu class bir görevi toplu çalıştırmak için kullanılmaktadır. Örnek olarak Tutorial_RunbaseForm
classını inceleyelim. (Bknz.Resim 03)
Tutorial_RunbaseForm classını çalıştırdığımızda aşağıdaki ekran çıktısı alınmaktadır. Ekranda baktığımızda tarih ve müşteri hesabının seçildiği bir parametreler grubu bulunmaktadır ve ayrıca bir Query üzerinde seçim yapabileceğimiz bir seç butonu bulunmaktadır.
Resim 03
Aşağıda AX’ın standartında olan bir toplu görev işlemini yapan bir class bulunmaktadır. Tutorial_RunbaseForm görüntüsü bulunmatadır. (Bknz. Resim 04)
Resim 04
Kendimize ait bir çalışma yapacak olursak, Tutorial_RunbaseForm classını sağ tıklayıp Çoğalt(Duplicate) yaparak CopyTutorial_RunbaseForm yapabiliriz. Çoğaltılan classın adını ETGRunbaseFormEgitim olarak değiştirelim.
RunBaseBatch Class
class ETGRunbaseFormEgitim extends RunBaseBatch
{
// Packed
TransDate transDate;
CustAccount custAccount;
SysQueryRun queryrun;
DialogField dlgtransDate;
#define.CurrentVersion(1)
#define.Version1(1)
#localmacro.CurrentList
transDate,
custAccount
#endmacro
}
public boolean canGoBatch()
{
return true;
}
{
return true;
}
public Object dialog()
{
DialogRunbase dialog = Dialog::newFormnameRunbase(formstr(ETGRunbaseFormEgitim),this);
;
dialog = this.dialogInternal(dialog);
dlgtransDate = dialog.addField(extendedTypeStr(TransDate));
dlgtransDate.value(transDate);
return dialog;
}
{
DialogRunbase dialog = Dialog::newFormnameRunbase(formstr(ETGRunbaseFormEgitim),this);
;
dialog = this.dialogInternal(dialog);
dlgtransDate = dialog.addField(extendedTypeStr(TransDate));
dlgtransDate.value(transDate);
return dialog;
}
public boolean getFromDialog()
{
boolean ret;
ret = super();
transDate = dlgtransDate.value();
// custAccount is handled via the edit method on the form
return ret;
}
{
boolean ret;
ret = super();
transDate = dlgtransDate.value();
// custAccount is handled via the edit method on the form
return ret;
}
public void initParmDefault()
{
this.initQuery();
super();
}
{
this.initQuery();
super();
}
void initQuery()
{
Query query = new Query();
;
query.addDataSource(tablenum(InventTable));
queryrun = new SysQueryRun(query);
}
{
Query query = new Query();
;
query.addDataSource(tablenum(InventTable));
queryrun = new SysQueryRun(query);
}
protected void new()
{
super();
}
{
super();
}
public container pack()
{
return [#CurrentVersion,#CurrentList,queryrun.pack()];
}
{
return [#CurrentVersion,#CurrentList,queryrun.pack()];
}
CustAccount parmCustAccount(CustAccount _custAccount = custAccount)
{
;
custAccount = _custAccount;
return custAccount;
}
{
;
custAccount = _custAccount;
return custAccount;
}
QueryRun queryrun()
{
return queryrun;
}
{
return queryrun;
}
public boolean runsImpersonated()
{
return true;
}
{
return true;
}
public boolean showQueryValues()
{
return true;
}
{
return true;
}
public boolean unpack(container packedClass)
{
Version version = RunBase::getVersion(packedClass);
container queryCon;
switch (version)
{
case #CurrentVersion;
[version,#CurrentList,queryCon] = packedClass;
if (SysQuery::isPackedOk(queryCon))
queryrun = new QueryRun(queryCon);
else
this.initQuery();
break;
default:
return false;
}
return true;
}
{
Version version = RunBase::getVersion(packedClass);
container queryCon;
switch (version)
{
case #CurrentVersion;
[version,#CurrentList,queryCon] = packedClass;
if (SysQuery::isPackedOk(queryCon))
queryrun = new QueryRun(queryCon);
else
this.initQuery();
break;
default:
return false;
}
return true;
}
server static ETGRunbaseFormEgitim construct()
{
return new ETGRunbaseFormEgitim();
}
{
return new ETGRunbaseFormEgitim();
}
server static void main(Args args)
{
ETGRunbaseFormEgitim ETGRunbaseFormEgitim = ETGRunbaseFormEgitim::construct();
if (ETGRunbaseFormEgitim.prompt())
ETGRunbaseFormEgitim.run();
}
{
ETGRunbaseFormEgitim ETGRunbaseFormEgitim = ETGRunbaseFormEgitim::construct();
if (ETGRunbaseFormEgitim.prompt())
ETGRunbaseFormEgitim.run();
}
Dialog Ekranı
Ax 2012 üzerinde dialog ile işlemler yapmak için birden fazla yöntem bulunmaktadır. Bunların en basiti bir metod içerinde dialog alanlarının oluşturup dialog.run() metodunun çalıştırılmasıyla olur. Daha komplike dialog işlemleri için “RunBaseBatch”ten türetilen classlar yapılabilir. (RunBaseBatch in asıl amacı arka tarafta bir batch(toplu iş) işlemi çalıştırmak için kullanır. Ancak Ax 2012 de kullanılırlığı azalmıştır RunBaseBatch yerine Ax 2012 ile gelen SysOperation Framework classları kullanır. Bu iki yönetemede ilerki konularda bahsetmeye çalışacağız.)
Aşağıdaki örnekte örnek bir Job ile dialog nasıl çalıştırılır göstereceğiz. Bu işlemi bir butonun click methoduna yazarakta butonun tıklandığında ekrana dialog çıkarma işlemini yapabilirsiniz.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
| static void Erkn_DialogOrnek(Args _args){ Dialog dialog; dialogfield dfCustAccount; dialogfield dfLineNum; dialogfield dfIsActive; dialogfield dfTransDate; CustAccount custAcc; int lineNum; boolean isActivce; TransDate transDate; dialog = new dialog("Örnek Dialog"); //dialogDeğişkeni = dialog.addField(extendedTypeStr("Extended Data Type yazılır),"Etiket yazılır(Label)"); dfCustAccount = dialog.addField(extendedTypeStr(CustAccount),"Müşteri"); dfLineNum = dialog.addField(extendedTypeStr(integer),"Sıra No"); dfIsActive = dialog.addField(extendedTypeStr(NoYesId),"Aktif"); dfTransDate = dialog.addField(extendedTypeStr(TransDate),"İşlem Tarihi"); //DialogDeğişkeni.Value("Varsayılan değer"); dfTransDate.value(systemDateGet()); //Varsayılan değer atamak için kullanılır dfIsActive.value(NoYes::Yes); //dfIsActive.active(false); //active metodu alanı pasif hale getirerek müdahaleye kapatır. if(dialog.run()) { //Dialogdan gelen değerleri tutmak için aşağıdaki değişkenler kullanılır custAcc = dfCustAccount.value(); lineNum = dfLineNum.value(); isActivce = dfIsActive.value(); transDate = dfTransDate.value(); }}Dialogdan dönen değerleri tutmak için kullanılan değişkenleri formda “classDeclarationa” tanımlarsanız gelen değerleri formun her yerinde kullanabilirsiniz. |
Etiketler:
AX,
AX 2012,
Axcapta,
Dialog,
Microsoft Dynamics,
RunBaseBatch,
SysOperation,
X++
Kaydol:
Kayıtlar (Atom)





