neděle 23. srpna 2009
EP: X++ Web UI Framework končí
Ve starších verzích AX se webové uživatelské rozhraní vytváří v AOT pomocí WebForms apod. V AX2009 se objevil nový přístup a to vytváření komponent v ASP.NET (a mapování na DataSets v AOT).
Tento nový přístup má být v nové verzi AX jediný možný - a bude tedy třeba zmigrovat existující implementace postavené na původním frameworku.
Převzato z: Dilip's blog
The records buffer is NULL
Tento příspěvek dokumentuje jedno ne zrovna intuitivní chování Axapty.
Vezměme následující jednoduchou třídu:
class Test
{
public server static void main(Args args)
{
Test::recordOnClient();
}
public client static InventTable recordOnClient()
{
InventTable inventTable;
select firstOnly forUpdate inventTable;
return inventTable;
}
}
Tento kód (respektive pokus o vrácení hodnoty z metody recordOnClient()) vyhodí run-time výjimku Error executing code: The record buffer is NULL. Testováno v AX2009, AX3 jednoduše spadne (AX4 nemám po ruce). Právě vytvořením kódu sestřelujícího Axaptu 3 toto chování jeden můj kolega objevil.
Zajímavé je, že se tak děje pouze při volání client metody ze serveru a pokud metoda vrací buffer vybraný pro update. Všechny ostatní scénáře skončily bez chyby.
Doufal jsem, že se mi na základě chybové hlášky podaří najít více informací, ale nebyl jsem úspěšný. Zřejmě se to moc často vytvořit nepovede.
Doplnění: Pokud je na bufferu volán insert(), dostane buffer příznak forUpdate. Výše popsané chování tedy platí i v takovém případě.
Convergence 2009 Europe
Convergence je oficiální akce Microsoftu na téma Dynamics. Původně plánovaná celoevropská konference byla rozdělena do čtyř měst takto:
27.10.2009 Londýn
29.10.2009 Vídeň
03.11.2009 Frankfurt
05.11.2009 Rotterdam
Registrace začíná 1.9.2009, cena pro zákazníky je 150€, pro partnery dvojnásobek. Záznamy z akce pak budou přístupné nejen účastníkům, ale i všem partnerům a zákazníkům s BREP (Business Ready Enhancement Plan).
Oficiální stránky: Convergence 2009 Europe
Další info, vč. Breakout Sessions (PPT): Partner Update 20.8.2009
sobota 22. srpna 2009
Iterator vs. Enumerator
Pro procházení kolekcí lze v Axaptě využít dvě třídy - Iterator a Enumerator. Respektive, pro každou kolekci existuje specializovaný iterátor a enumerátor, např. SetIterator a SetEnumerator.
Použití iterátoru vypadá takto:
SetIterator iterator = new SetIterator(set);
while (iterator.more())
{
info(iterator.value());
iterator.next();
}
…a enumerátoru takto:
SetEnumerator enumerator = set.getEnumerator();
while (enumerator.moveNext())
{
info(enumerator.current());
}
Je best practice používat enumerátor namísto iterátoru. O tomto doporučení vím již dlouho, ale až tento týden jsem se dozvěděl jeden zásadní rozdíl: volání iterátoru totiž selže, pokud jsou iterátor a iterovaná kolekce na jiné vrstvě (ve smyslu klient/server). V takovém případě je vyhozena run-time výjimka s tím, že objekt iterátoru není inicializován.
Enumerator s touto situací počítá a vznikne na stejné vrstvě jako kolekce. Procházení všech prvků kolekce umístěné na jiné vrstvě zas může být výkonnostní problém, ale to už je jiná kapitola…
MSDN: ListEnumerator
MSDN: ListIterator
MSDN: MapEnumerator
MSDN: MapIterator
MSDN: SetEnumerator
MSDN: SetIterator
čtvrtek 20. srpna 2009
AxDecisions 2009
Virtuální konference jsou čím dál oblíbenější - je to zejména daleko lacinější varianta než "fyzická" konference. AX Decision 2009 je další taková virtuální konference a jak název naznačuje, půjde o Dynamics AX.
Bude se konat 14.10.2009 - více informací je k dispozici na webu AxDecisions. Z čistě vývojářského hlediska není zveřejněný program nijak lákavý, ale pro přehled o trendech a možných přístupech by mohl posloužit dobře. Za tu cenu… (je zdarma)
PS: Koho zajímá, jaktože je konference zdarma, doporučuji standardní postup: podívejte se, jak je prezentována potenciálním sponzorům. :-)
AxAssist
AxAssist je bezpochyby jeden z nejužitečnějších nástrojů, které jsou pro vývoj v Dynamics AX k dispozici. Není sice zdarma, ale přináší mnoho skvělých funkcí za rozumné peníze. Navíc je k dispozici třicetidenní zkušební verze, takže každý má možnost si AxAssist důkladně osahat.
Hned na úvod odkáži na oficiální stránky (AxAssist.com), protože je tam většina funkcí popsána a nechybí flashová videa, která přiblíží chování AxAssistu asi lépe než cokoli jiného. Mým cílem tedy není popsat všechna nastavení atd., spíše rychle prolétnout všechny funkce a podívat se na pár praktických zkušeností.
Jen jeden obrázek (z AX3) pro představu, o čem je řeč:
Doplňování kódu
Nejviditelnější a nejdůležitější shopností je doplňování kódu při psaní. MorphX sice dokáže nabídnout seznam metod objektu nebo polí tabulky a dokonce i seznam tříd či datových typů (pod různými záhadnými klávesovými zkratkami), ale AxAssist to dělá řádově lépe. Nabízí datové typy při deklaraci, proměnné vhodného datového typu v přiřazení nebo volání parametrické metody, nabízí i makra atd. atd. Navíc je toto chování konfigurovatelné, např. lze definovat, po kolika zapsaných znacích se má nabídka zobrazit.
Další příbuzná funkce je Acronyms, tedy zkratky. Slouží k nabízení datových typů a principem je „skákání po hrbech velblouda“, abych tak odkázal na velbloudí notaci. :-) Zkrátka nabídnou se ty typy, v nichž jsou v daném pořadí obsažena zadaná velká písmena. Například pro LJTI se (v AX3) nabídne LedgerJournalTrans_InventTrans (je-li povolena volba Extended Acronyms), LedgerJournalTransImport a LedgerJournalTypeId. Rozdíl v počtu znaků, které je nutné napsat, je evidentní.
Užitečná funkce je také možnost zadání ignorovaných prefixů. Pokud vaše firma například prefixuje objekty trojicí znaků XYZ, můžete nechat prefix XYZ ignorovat a typ XYZOrderId se nabídne po prostém zadání OI. Lze zadat i více prefixů, oddělených čárkou. Po nastavení prefixu budete pravděpodobně muset restartovat AX klienta.
Do nabídek lze přidat vlastní kusy kódu, tedy různé často zapisované konstrukce, komentáře dle firemních pravidel atd. Text nemusí být úplně statický, výsledná podoba je zkonstruována při spuštění AxAssist. Lze tedy např. předpřipravit komentář s vyplněným jménem přihlášeného uživatele apod.
A ještě jedna drobnost: rozbalovací nabídka také zobrazuje ToolTip pro aktuálně vybraný prvek (a v něm např. typ proměnné, předka typu, label apod.). Způsob vytváření těchto ToolTipů lze také libovolně modifikovat a přidávat tak další informace, měnit formátování atd.
Tlačítka
Ve výchozím nastavení AxAssist také přibyde šest tlačítek na hlavní lištu a do AOT a tři do lišty editoru kódu. Z první skupiny zaujme třeba možnost otevření datového typu pole v AOT (což lze volat i z definice datového zdroje formuláře apod.), v editoru je zásadní skvěle fungující Open in AOT (lze použít z definice i použití libovolné proměnné a její typ je otevřen v samostatném AOT okně).
Některá tlačítka mě příliš nezaujala z prostého důvodu, že všude používám Tabax a mám je tam (a třeba TableBrowser je v Tabaxu lepší ;)).
Funkce tlačítek může být měněna, mohou být přidávana další atd. Vyžaduje to drobné zásahy do kódu, ale je to popsáno na webu AxAssist a není na tom nic složitého.
Další změny v IDE
Do IDE dále přibylo:

- dolní lišta v AOT – zobrazuje definici (třídy, metody) nebo label (tabulky, formuláře, pole, EDT...)
- rozbalovací seznam metod v editoru
- panel v editoru (vlevo dole) – zobrazuje informaci o vybrané proměnné, včetně např. všech hodnot výčtového typu. I toto lze velmi snadno rozšiřovat a často se to hodí. Zobrazené hodnoty lze i kopírovat, typicky odtud kopíruji název datového typu.
- Jste-li firma, nemůžete zakoupit Single Developer License, vždy musíte koupit zakoupit Company License
- AxAssist se pořizuje pro každou verzi AX zvlášť, ale zároveň je hned zmíněna možnost slev (s čímž ovšem zkušenost nemám)
neděle 2. srpna 2009
Vyhledávání
Vyhledávání v kódu nebo v AOT je velice častá činnost. Hledáme použití proměnné, modelový kus kódu, objekty určitých vlastností atd. Přesto řada lidí neovládá některé užitečné funkce, které pro to Axapta nabízí. A právě na ty se nyní podíváme.
Spustit formulář pro vyhledávání v AOT jistě dokáže každý, ale tento formulář umí podstatně více než jen vyhledat zadaný řetězec. Přímo na formuláři jsou další pole pro upřesnění kritérií (ačkoli pro některé jsem dosud nenašel smysluplné využití) a dokonce možnost zapsat vlastní funkci, která se spustí pro každý TreeNode (jaké má mít metoda parametry se dočtete v nápovědě k formuláři).
Co už není tak očividné je možnost zadat regulární výraz do vyhledávacích polí. Syntaxe odpovídá metodě match() a je u ní zdokumentovaná. Takže např. následující příklad hledá přiřazení do proměnné i - jinak řečeno, proměnnou i následovanou libovolným počtem mezer a znakem =. Dohromady i: *=.
Obdobně lze hledat třeba metody, jejichž název odpovídá určitému regulárnímu výrazu (např. <check.*sales pro metody začínající check a pak kdekoli obsahující sales). V tomto případě pochopitelně umístíme regulární výraz do pole (Nazváno) Named.
Regulární výrazy lze využít i při vyhledávání labelů (což je mimochodem funkce k nezaplacení) a také v editoru kódu. V editoru hlavně pozor na to, že se vyhledává od pozice kurzoru do konce, to je dost matoucí. A kupodivu hledání v AOT a hledání v editoru pracuje jinak např. s koncem řádku…
Při hledání v AOT lze využít ještě jednu zajímavou funkci a to vyhledávání ve vlastnostech. Nejprv je nutné přepnout volbu Hledat (Search) na Vše (All nodes) - tím se zobrazí další záložka: Vlastnosti (Properties). Na ní si pak najdeme patřičné vlastnosti, označíme jako Selected a zadáme hodnotu. Ta má opět hodnotu regulárního výrazu. Může to vypadat třeba takto:


Reflexe - AOT
Třída TreeNode představuje uzel AOT, tedy objekty, metody, pole ale i "adresáře" jako třeba Forms. S její pomocí pak můžeme provádět akce, na jaké jsme zvyklí při ruční práci s AOT. Například tento kód vytvoří novou třídu a spustí ji:
#AOT
TreeNode nodeClasses = TreeNode::findNode(#ClassesPath);
TreeNode nodeClass;
TreeNode nodeMethod;
;
nodeClass = nodeClasses.AOTadd('NovaTrida');
nodeMethod = nodeClass.AOTadd('main');
nodeMethod.AOTsetSource(
'public static void main(Args _args){;info("Bezi");}', true);
nodeClass.AOTsave();
nodeClass.AOTcompile();
nodeClass.AOTrun();
Příklad asi nepotřebuje mnoho komentáře. Makro #AOT obsahuje cesty k různým prvkům (nebo části cest, jako třeba '\%1\\Fields\\\%2'). Skupinu všech tříd, novou třídu i její metodu reprezentuje třída TreeNode.
Díky této funkcionalitě lze například snadno vytvářet generátory kódu apod.
Další užitečná věc je práce s vlastnostmi (Properties). Vlastnost vyhledáme podle jejího názvu a v tom nám pomůže další makro - #Properties.
#AOT
#Properties
TreeNode nodeBOM = TreeNode::findNode(#TablesPath + #AOTDelimiter + tableStr(BOM));
;
info(nodeBOM.AOTgetProperty(#PropertyCachelookup));
Obdobně lze vlastnosti i nastavovat:
tableNode.AOTsetProperty(
#PropertyFormRef,
menuitemDisplayStr(Form1));
tableNode.AOTsave();
Často je také potřeba procházet iterovat přes větší množství AOT uzlů. K tomu se hodí tyto třídy:
- TreeNode - metody AOTfindChild(), AOTfirstChild(), AOTnextSibling() atd.
- TreeNodeIterator - prochází přímé potomky. Lze získat voláním AOTiterator() na TreeNode.
- TreeNodeTraverser - prochází potomky včetně nepřímých.
- TreeNodeTraverserSource - potomek TreeNodeTraverser; prochází jen uzly obsahující zdrojový kód.
Přihlásit se k odběru:
Příspěvky (Atom)