středa 22. prosince 2010

Verzování bez Team Serveru

Nedávno jsem chystal vývojové prostředí AX2009 využívající Team Foundation Server, ale použití Team Serveru (aka ID Server) by mi nic nepřineslo a jen by mi věci zkomplikovalo.

Jak tedy donutit AX2009, aby se spokojila se správou verzí bez Team Serveru?
Odpověď je jednoduchá:
SysVersionControlSystem.requireTeamServer() musí vracet false.
Sám jsem čekal něco komplikovanějšího… :-)

úterý 21. prosince 2010

AX2009 a TFS2010

Jak jistě víte, AX2009 může používat k ukládání zdrojových kódů Team Foundation Server. Co když ale máte TFS2010, který není podporovaný AX2009?
Nastěstí je řešení celkem jednoduché - budete potřebovat:
  1. Team Explorer 2008 - AX využívá jeho knihovny (a nejspíš ho budete používat i přímo).
    Ještě není vyhráno, protože Team Explorer 2008 nespolupracuje s TFS2010. Za druhé tedy potřebujete:
  2. VSTS 2008 SP1 Forward Compatibility Update for TFS2010 - díky němu se Team Explorer 2008 dokáže připojit k TFS2010.
    Jak napovídá i název, na Team Explorer musí být aplikován:
  3. Service Pack 1 (Visual Studio 2008).
    Zde se můžete dostat ještě do jednoho problému - pokud máte Visual Studio 2008 SP1 a doinstalujete Team Explorer, musíte přeinstalovat SP1. Teprv pak je možné aplikovat Forward Compatibility Update.

čtvrtek 9. prosince 2010

Verzování dokumentů v TortoiseSVN

Verzování zdrojových kódů se díky integraci do IDE (velmi) pomalu zabydluje i ve světě Dynamics AX, ale často se zapomíná na ostatní data. Přitom znát historii třeba funkčního designu, mít možnost porovnat změny mezi verzemi atd. je stejně tak potřebné jako v případě kódu.
Navíc jde i o zdrojový kód mimo AX, třeba SQL, XSLT, HTML a tak podobně.

Některé týmy používají nějakou podobu document managementu s verzováním, typicky v rámci SharePointu. Ale i toto řešení má své nedostatky, zejména komplikovanost práce s takovými soubory, a tak zůstává řada dokumentů mimo tyto systémy.

Kontextové menu TortoiseSVN
Dnes chci ukázat, že používat verzovací systém může být snadné a bezbolestné. A to tak, že můžete snadno verzovat úplně všechny soubory, u kterých to má nějaký smysl.
Nebudu tedy zabíhat do žádných detailů - pokud TortoiseSVN nebo podobný nástroj používáte, asi se toho mnoho nedozvíte.

Ikony souborů
Nejpřirozenější systém je takový, který vám umožní pracovat s verzovanými soubory z velké části tak, jak se soubory pracujete dnes, ale přidá další vrstvu pro práci s verzemi. Přesně to vám umožní TortoiseSVN, což jeden z mnoha klientů pro verzovací systém Subversion (existují také například Subversion pluginy pro Visual Studio, doma používám AnkhSVN).

Nejviditelnější věc na TortoiseSVN jsou dodatečné symboly na ikonách ve správci souborů (viz obrázek vpravo). Ty se samozřejmě nezobrazují všude, ale jen v adresářích, v kterých je verzování aktivní (hodně zjednodušeně řečeno).

Do takové složky je možné soubory přidávat, měnit, mazat atd. jako by zde žádný verzovací systém nebyl (řada lidí žije v představě, že používání verzování znamená provádět checkout před každou editací a proto se mu brání, tak to raději zdůrazňuji).

Ukládání do repozitáře
Jakmile jste se změnami spokojeni, uložíte (v jediném kroku) veškeré modifikované soubory do úložiště verzí (repozitáře) - a hotovo, soubory jsou uloženy a můžete dále pracovat s vědomím, že se k dané verzi kdykoli vrátíte, bude-li třeba.

Kontextové menu TortoiseSVN nabízí sice spoustu možností, ale zmiňme jen pár základních:
  • Update = načtení souborů z repozitáře
  • Commit = uložení do repozitáře
  • Show log = zobrazení hostorie
  • Rename = přejmenování souboru se zachováním historie
Historie verzí
Show log zobrazí okno se všemi verzemi zvoleného souboru nebo adresáře, obsah každé verze (přidané, smazané soubory atd.), komentáře k verzím a podobně. Můžete zde také vybrat verze k porovnání, přímo otevřít historickou verzi a tak dále. Při porovnání nejste omezeni na čistě textové porovnání, třeba Word a Excel jsou také podporované!

Instalace
Instalační soubor můžete stáhnout zde. Při výběru verze (32/64 bit) vezměte v potaz nejen verzi operačního systému, ale i správce souborů. Máte-li Windows 64bit a chcete používat TortoiseSVN jak ve Windows Exploreru (64bit), tak Total Commanderu (32bit), potřebujete nainstalovat obě varianty TortoiseSVN.

Po instalaci musíte vytvořit repozitář. Subversion opět nabízí spoustu možností, které budu okázale ingorovat. :-) Vytvořte adresář (ideálně na nějakém bezpečném serverovém disku, v horším případě lokálně), z kontextové nabídky na adresáři zvolte TortoiseSVN > Create repository here a potvrďte. Do tohoto adresáře v podstatě nemusíte vstupovat, takže volte spíš lokaci, kde vám nebude překážet.

Dále vyberte místo, kde budete chtít pracovat se svými verzovanými soubory. Zvolte SVN Checkout a zadejte cestu k repozitáři (jako file://ServerName/path/to/repos/ nebo file:///C:/repo). Těchto pracovních adresářů můžete mít kolik chcete a můžete si nějaký vytvořit kdykoli, kdy potřebujete svá data a máte dokážete číst z adresáře s repozitářem (serverový disk přístupný přes VPN je skvělá volba).

Nastavení

Nastavení můžete měnit v TortoiseSVN > Settings.

Z obsáhlého kontextového menu si můžete vybrat často používané položky a umístit je hned přímo do hlavní kontextové nabídky, tedy tam, kde je defaultně SVN Update atd. Mně například dost chyběl příkaz Add.
(General > Context menu)

V Icons Overlays můžete nastavit, na jakých druzích disků (síťové, přenostné atd.) se mají zobrazovat stavové ikonky TortoiseSVN. Chcete-li vidět ikony i v jiných aplikacích, než jen ve Widnows Exploreru (typicky v jiném souborovém manageru), odšktněte zde Show overlays and context menu only in explorer.
Pokud používáte konkrétně Total Commander, musíte mít v jeho konfiguraci zaškrtnuté Show overlay icons (Configuration > Options > Icons).

Užitečné je také nastavit, jaké soubory má Subversion ignorovat (v General > Global ignore pattern), například soubory začínající "~" (mj. pracovní soubory MS Office).

středa 8. prosince 2010

AX Business Intelligence Team blog

Dynamics AX Business Intelligence Team blog byl spuštěn před pár dny a obsahuje (v tuto chvíli) dvacet videí o používání SQL Server Reporting Services v Dynamics AX. Každé video má jen pár minut a na základní seznámení nejsou vůbec špatná.

čtvrtek 25. listopadu 2010

Tabulky v Table map

Řekněme, že píšete třídu, která bude schopná pracovat s libovolnou tabulkou z určité mapy (třeba PBAItemLine, v mém případě). V objektu typu Args vám přijde buffer, a vy byste rádi zkontrolovali, zda patří mezi tabulky definované v dané mapě.

K tomu lze využít metodu SysDictTable::isTableMapped(); konkrétní přiklad by vypadal takto:

if (SysDictTable::isTableMapped(tableNum(PBAItemLine), _args.dataset()))

Implementace metody isTableMapped() je trochu ošklivá (dívá se přímo do AOT na obsah uzlu Mappings),  inteligentní podpora zřejmě v API chybí.

Mimochodem, instance třídy DictTable může reprezentovat nejen "klasickou" tabulku, ale i Map nebo View.

pondělí 15. listopadu 2010

Implementace metod definovaných rozhraním

Při přípravě jiného článku jsem narazil na dost… osobité chování Axapty při implementaci rozhraní. Navzdory veškerým očekáváním Axapta nekontroluje, zda má implementující třída správné veřejné rozhraní (proto interface), ale jen že má metody shodných názvů, jaké má i rozhraní.

Ukažme si to na příkladu. Definuji následující rozhraní:
interface Rozhrani
{
    int rychlost(int _rychlost){}
}
Předpokládal bych, že každá třída implementující toto rozhraní musí obsahovat metodu rychlost() s parametrem a návratovou hodnotou typu int.

Následující třída jde nejen zkompilovat, ale kód v metodě main() i bez chyby proběhne, včetně přiřazení do proměnné.
class ImplementujiciTrida implements Rozhrani
{
    //Správný název metody, ale nesprávný typ parametru i návratové hodnoty
    void rychlost(str _slovniPopisRychlosti)
    {}

    public static void main(Args _args)
    {
        Rozhrani trida = new ImplementujiciTrida();
        //Instance nemá metodu akceptující číselný parameter a vracející hodnotu,
        //přesto toto volání proběhně.
        int i = trida.rychlost(5);
    }
}
Metoda rychlost() obdrží hodnotu překonvertovanou do řetězce a vrátí hodnotu 0 (případná hodnota v proměnné i v main() by byla přepsána), přestože má návratový typ void.
Pokud by implementace metody rychlost() obsahovala parametr, pro který neexistuje implicitní konverze (např. Object _o), dojde k chybě za běhu aplikace.

Rozhraní má poskytnout jistotu, že instance každé implementující třídy "rozumí" určitému způsobu komunikace, tedy že je možné zavolat nějakou metodu s předem danými typy parametrů. Když se třída hlásí k určitému veřejnému rozhraní (= implementuje interface), kompilátor by měl zajistit, že tomu tak skutečně je. Kompilátor Axapty to ale nedělá - a výsledkem chyby, kterou měla odhalit první kompilace, může být runtime exception nebo opravdu nepochopitelné chování aplikace.

Tímto nechci říct, že se v X++ nemají rozhraní používat. Naopak si myslím, že se používají málo (a místo nich se vytváří sporné hierarchie dědičnosti apod.). Ale nelze se spoléhat na kompilátor, že korektní implementaci rozhraní vynutí.

pátek 22. října 2010

Decisions Fall 2010

O virtuální konferenci Decisions jsem zde již několikrát psal, ale o Decisions Fall 2010 jsem se příliš nezajímal, protože jarní Decision Spring pro mě byla spíše zklamáním.

Nicméně program AX bloku (1.11.2011) nevypadá špatně (například Agilní vývoj softwaru v AX nebo Performance Monitoring), na záznamy se určitě podívám.

čtvrtek 21. října 2010

Dědění od třídy Object

Třída Object stojí na vrcholu hierarchie tříd a každá třída od ní je - přímo či nepřímo - odvozena. Tak to alespoň tvrdí Strom aplikační hierarchie, DictClass.extend() nebo MSDN.
Object definuje několik finálních metod (např. handle()) a čtyři překrytelné (equal(), toString(), wait() a xml()). Znamená to tedy, že každý objekt obsahuje tyto metody? Překvapivě… nikoli.

Zkuste si vytvořit novou třídu, zkonstruovat její instanci a zavolat její metodu toString(). Takový kód vůbec nejde zkompilovat! Pokud tuto instanci přiřadíte do proměnné typu Object, přiřazení je sice korektní a Object obsahuje metodu toString(), takže kompilace proběhne v pořádku, nicméně volání metody vyhodí runtime výjimku.
Object o = new MyClass();
o.toString(); //runtime chyba
Metodu toString() můžete ve své třídě sami naimplementovat a kód bude pochopitelně fungovat. Ale pozor - zde vytváříte nové metody, nepřekrýváte ty ze třídy Object. To má dva zřejmé efekty - zaprvé nemá smysl snažit se volat super() (to platí i pro konstruktor(!)) a za druhé můžete vytvořit metodu stejné signatury jako má některá z finálních metod třídy Object.

Chování, které byste asi očekávali od začátku, je nutné vynutit explicitním uvedením extends Object v classDeclaration vaší třídy. Pak můžete na jejích instancích volat všechny metody zděděné z Object, překrytelné metody se objeví v kontextové nabídce (viz obrázek), můžete volat jejich implementaci ve třídě Object pomocí super() a tak dále.


Řešení pomocí extends Object používají zřejmě veškeré systémové třídy (tzn. třídy v uvedené v System Documentation) a také některé třídy definované v X++, například RunBase.

Zajímavé je, že z pohledu Stromu aplikační hierarchie a DictClass tříd vypadají třídy s i bez extends Object zcela stejně. Popsané chování je také zcela v rozporu s MSDN dokumentací, která například říká: "Methods in the Object class can be called for any object.", tedy "Metody ve třídě Object mohou být volány pro libovolný objekt.".

Zajímavých dopadů by se našlo jistě více, mě napadají tyto:
  • Nelze vytvářet generickou funkcionalitu předpokládající, že všechny objekty v Axaptě mají určitou metodu (třeba equal()), protože to prostě není nijak zaručeno
  • Pokud není třída výslovně deklarována jako potomek Object, může implementovat i finální metody a ty budou zavolány (!!!). Takto lze například vracet libovolně zvolené číslo v handle() - a znamená to, že ani na finální metody třídy Object se nelze stoprocentně spolehnout.
Od této chvíle doporučuji v deklaraci třídy vždy výslovně uvádět extends Object.

čtvrtek 7. října 2010

Nová podoba community.dynamics.com

Právě před chvílí jsem se přihlásil na community.dynamics.com a nestačil jsem se divit. Celý web se totiž od včerejšího večera podstatně změnil a to nejen vizuálně, ale i po funkční stránce. Například fórum (schované pod položkou Ask The Community) už umí RSS. (Původně jsem tu psal, že není možné zobrazit náhled příspěvku, ale platí to jen pro plain text.)
Obecně mi přijde, že je stránka více zaplácaná spoustou "related" obsahu, a ve výsledku se na ní vejde méně informací (na výpisu příspěvků na fóru je to obvzlášť patrné), ale snad je to jen věc zvyku.

sobota 2. října 2010

Microsoft Newsgroups definitivně končí

Pokud navštěvujete Microsoftí Usenet pravidelně, jistě víte, že již dříve bylo oznámeno zrušení všech newsgroups a jejich nahrazení webovými fóry. Vzápětí opravdu zmizela řada skupin, ale ty týkající se Axapty se stále držely. Nicméně všechno jednou končí a v několika příštích dnech budou uzavřeny.

Náhradou jsou samozřejmě fóra na community.dynamics.com, která už jsou celkem zaběhlá, na druhou stranu bych tam uvítal členění na application/development, jak tomu je na Usenetu (kde je skupin naopak zbytečně moc, viz třeba localization). Obecně mi přijde přechod od léta vyvíjených klientů k nějakému nepříliš propracovanému webovému rozhraní jako ztráta, ale chápu, že už to byl pro Microsoft tak trochu relikt. Naštěstí jsem si už na komunitní fórum zvykl, ale chvilku mi to trvalo (asi tak rok :)).

K webovému fóru dám jeden tip - pod tlačítkem More options si můžete mimo jiné nastavit zobrazování jen nepřečtených vláken.

středa 29. září 2010

Technical Conference 2011

17.-20. ledna 2011 se v Redmondu koná Microsoft Dynamics AX Technical Conference 2011. Je to samozřejmě trochu drahý výlet, ale teď to zmiňuji z jiného důvodu. Na stránkách konference se objevily první konkrétní informace o programu (link) a lze tam získat další informace o chystané funkcionalitě AX2011.

Kromě dříve zmiňovaných modelů, změn v ID elementů (MS slibuje konec ID konfliktů) a změn v architektuře formulářů (do vrstvy by se neměl ukládat formulář jako celek), mě zaujaly například tyto body:
  • podpora eventů v X++
  • nový security model postavený na rolích
  • lepší podpora integrace WPF a WinForm elementů
  • nový programovací model pro reporty
  • změna práce s labely při používání (file-based) správy verzí
V oblasti aplikační funkcionality dojde ke změnám například v produktech, datovém modelu Global Address Book, konfiguraci OLAP kostek atd. Přednášky dalé pokrývají třeba novou funkcionality pro veřejný sektor (ta byla rovněž ohlašována dlouho dopředu).

sobota 4. září 2010

Odlehčené licence

Od 1.9. jsou v platnosti nové, odlehčené licence pro Dynamics produkty. Konkrétně to jsou tyto:
  • Employee Self-Service (ESS) - opravňuje uživatele přistupovat do systému (ale ne pomocí klasického AX klienta) a modifikovat data "o sobě", například uživatelský profil, cestovní výkazy a podobně.
  • Light User (vlastně to není tak úplně novinka, je to přejmenovaná licence Microsoft Dynamics Client for Microsoft Office) - licence pro přístup k AX datům, ale opět pouze nepřímo (pomocí SharePointu, mobilních zařízení atd.)
  • Limited Device - licence pro zařízení zprostředkovávají vstup (např. skener) XOR zobrazení dat z AX (tiskárna), které je připojeno jinak než pomocí AX klienta
Více informací najdete na PartnerSource, zejména pak v licenční příručce (doporučuji i kvůli informacím o licencování AX for Retail). Price sheet je samozřejmě také aktualizován.

čtvrtek 2. září 2010

Convergence 2010 - Praha

Konference Convergence 2010 Europe se koná v říjnu v Londýně, Haagu a 18.-19.10. také v Praze. Od dnešního dne je otevřena registrace, tak se pojďme podívat, co se bude dít.

Pondělí 18. října je určeno pro Microsoft partnery, řeč bude pochopitelně o plánech do budoucna, o nových produktech a také o Microsoft Partner Network (program je na PartnerSource).

Úterý 19. října je otevřeno všem (platícím), ohledně AX bude na programu například AX for Retail, upgrady AX nebo archivace dat. Krom AX bude řeč také o Dynamics NAV a CRM (program zde).

Webové stránky akce naleznete zde. Cena je 100€ za Partner Day, 299€ za druhý den a 374€ za oba (bez DPH).

Já osobně se tam nejspíš neobjevím, ale můžete mě potkat za dva týdny na Microsoft Days 2010!

Dynamics AX Management Pack pro SCOM 2007

Nedávno jsem si konečně našel čas na vyzkoušení produktu s (opravdu dlouhým) názvem Microsoft Dynamics AX 2009 Management Pack for System Center Operations Manager 2007. System Center Operations Manager (SCOM) slouží k monitorování počítačů - dokáže vyhledat požadované objekty (třeba aplikační servery) v síti, sledovat stav služeb, různých parametrů včetně výkonnostních, spouštět automatizovaně reakce na události a tak podobně.

Hlavní okno SCOM 2007

Pro SCOM existuje celá řada balíčků (tzv. Management Packs), které obsahují specializované objekty pro jednotlivé produkty, například Windows Server OS, SQL Server nebo třeba SharePoint. Podpora pro Dynamics AX 2009 je tedy samozřejmě implementována právě v podobě takového Management Packu.

Instalace

Instalace byla trochu problematická, protože moje virtuální AX prostředí je postavené nad SQL Serverem 2008 R2, který není SCOM 2007 R2 podporován (více zde). Nicméně se mi podařilo tento problém obejít pomocí přímého zavolání DBCreateWizard ([Instalační disk]:\SupportTools\i386\DBCreateWizard.exe) a vše funguje bez problémů. Vytvořil jsem doménový účet pro Action Account a úspěšně dokončil instalaci SCOM.

Dalším nezbytným krokem je přidání management packů. Ty stáhnete například z Microsoft katalogu; přímý link na Dynamics AX Management Pack je zde.

Postup instalace management packu do SCOM je pak následující:

  • Spusťte SCOM konzoli
  • Z menu v levé části okna vyberte Administration
  • V pravé části zvolte Import management packs
  • Vyberte patřičné management packy (*.mp) a naimportujte

Zde jen krátce poznamenám, že některé balíky obsahují management packy pro více verzí produktu, takže např. pro Windows Server 2008 je nutné nainstalovat objekty společné pro všechny verze (Microsoft.Windows.Server.Library.mp) a pak (nebo zároveň) management packy specifické pro Win Server 2008.

Konfigurace Dynamics AX Management Packu obnáší ještě několik kroků. Postupoval jsem takto:

  • Vytvořil jsem doménový účet pro monitoring AX.
  • Účtu jsem nastavil práva na čtení tabulek sysclientsessions, sysserversessions, sysserverconfig, userinfo, batch, batchjob v Dynamics AX databázi (z toho mimochodem plyne, jaké informace bude mít SCOM k dispozici).
  • Tento účet jsem přidal do Run As Account (SCOM konzole > Administration > Accounts > Create Run As Account…)
  • Vytvořený Run As účet jsem přiřadil k Run As profilu Microsoft Dynamics AX 2009 User Account (SCOM konzole > Administration > Profiles)

Použití

SCOM začne v pravidelných intervalech hledat AOS v síti (to jsem si nevyzkoušel, pracoval jsem jen s jedním serverem). Informace o nalezených instancích jsou pak zobrazeny v Monitoring > Microsoft Dynamics AX 2009. Zde naleznete informace o stavu jednotlivých aplikací, o přihlášených uživatelích, batch úlohách, o důležitých událostech. Přímo z tohoto místa je také možné ručně spouštět a zastavoval aplikační servery.

Podívejte se na pár obrázků:

AOS úspěšně běží, 2 uživatelé jsou on-line
Varování: aplikační server se zastavil
Server (po manuálním spuštění z prostředí SCOM) úspěšně naběhl. Mimochodem, Task Output nápadně připomíná PowerShell.

V sekci Administration lze nastavovat upozornění na určité události (e-mail, IM zpráva apod.), v Authoringu lze měnit chování mnoha objektů, psát skripty reagující na události a tak dále. SCOM také nabízí Management Shell, což je PowerShell rozšířený o řadu cmdletů potřebných pro práci se SCOM objekty.

Musím se přiznat, že jsem od Management Packu pro Dynamics AX očekával trochu více, zejména co se týče akcí přímo spustitelných z prostředí SCOM. Na druhou stranu, SCOM jako takový se mi rozhodně zalíbil a je třeba vzít v úvahu, že správa Dynamics AX zahrnuje také databázové servery, hlídání místa na discích, Active Directory a tak dále. A v tom všem může být SCOM extrémně užitečný. Pozitivně hodnotím také rozšiřitelnost, včetně možnosti vytvářet vlastní management packy.

pátek 20. srpna 2010

Vyhledávač datových referencí - Beta

Vyhledávač datových referencí je nástroj pro AX, jehož primitivní podobu jsem vyvinul pro upgrade v Británii. Bylo totiž potřeba přesunout celý jeden modul do jiné vrstvy a krom změn ID objektů (což není problém) bylo také třeba zjistit, zda jsou původní ID použita někde v databázi (typicky relace alternativních adres nebo řízení dokumentů). Právě pro toto hledání jsem si napsal program, vlastní aktualizaci jsem pak implementoval jako data upgrade script.

Protože jsem měl spoustu jiné práce a také dovolenou, dotažení implementace a refaktoring se trochu protáhli, nicméně nyní považuji práci za dokončenou. Výjimkou je podpora různých verzí AX, protože nyní je připravena pouze verze pro AX2009. To je sice u nástroje primárně určeného pro upgrady trochu nevýhoda, ale rád bych provedl základní testování na jedné verzi a pak teprve vytvořil paralelní verze pro starší Axapty. Pár věcí podporovaných AX2009 ve starších verzích chybí, je tedy třeba udělat nějaké změny v kódu.

Kolega Dan, který mi dělal alfa-testera, se hlasitě dožadoval dokumentace, což jsem nakonec vyslyšel. Pro podrobnější popis programu tedy odkazuji na dokumentaci (odkaz níže). Dokumentace zatím nebyla nikým testována, nejvíc chyb proto očekávám tam.

Pokud se rozhodnete Vyhledávač datových referencí vyzkoušet a naleznete nějakou chybu, nezapomeňte mi dát vědět. Předem díky!

Odkazy

úterý 17. srpna 2010

Podpora SharePointu 2010

Vcelku čerstvá zpráva ze Sustained Engineering blogu hovoří o tom, že SharePoint 2010 je oficiálně kompatibilní s Dynamics AX 2009 SP1. Je třeba si od Microsoftu vyžádat hotfix 2278963 a doporučený je také Hotfix Rollup 5.
Pár dalších informací, například o prerekvizitách, naleznete v originálním příspěvku.

str2num

Dnes mě vyvedl z konceptu kolega, který potřeboval převést řetězcovou reprezentaci reálného čísla na typ real. Problém byl, jak jinak, ve formátu čísla. Já jsem ovšem také netušil, že ačkoli funkce num2str() umožňuje zadat znak pro oddělení tisíců a pro oddělení desetinných míst, inverzní funkce str2num() nic takového nepodporuje. Oddělovač tisíců (",") tedy konverze považovala za desetinnou čárku a bylo zle. Dost nás překvapilo, že jsme přímo v Axaptě žádné rozumné řešení nenašli (prosté nahrazení tečky čárkou nepovažuji za dostatečně robustní).

Záchranu jsme nakonec našli v System.Single::Parse().

úterý 20. července 2010

Dynamics AX for Retail

1. srpna tohoto roku má být zveřejněn produkt s názvem Dynamics AX for Retail. Není to vlastně úplně nový systém, protože jej Microsoft odkoupil od původního výrobce (LS Retail), ale pokud jste s ním (podobně jako já) nikdy nepracovali, je stručný přehled určitě na místě.

Dynamics AX for Retail se skládá ze dvou částí:
  1. Dynamics AX 2009 (jiná verze není podporována), samozřejmě s dodatečnou funkcionalitou
  2. Samostatný .NET klient (POS klient), komunikující s Dynamics AX
V Dynamics AX se konfigurují položky, ceny, sklady a další obchodní data. Dále se přímo v Axaptě nastavuje GUI POS klienta a funkce tlačítek, k čemuž slouží grafický designer (cool!). Vzhled a funkce POS klienta mohou být specifické pro konkrétního uživatele či terminál.
 
POS klient podporuje platby kartou, slevy, dárkové certifikáty, věrnostní programy a spoustu dalších funkcí. Jednotlivé funkční bloky jsou implementovány v .NET a partneři je mohou rozšiřovat, nahrazovat, nebo samozřejmě dodávat vlastní. Detaily o .NET části implementace bohužel neznám.

Co se technické stránky týká, POS klient má vlastní databázi a některé informace si udržuje lokálně a s Dynamics AX si je vyměňuje dávkově (změna dat na straně AX, přenos informací o transakcích do AX na konci pracovní doby), jiná data si POS vyžaduje z AX v reálném čase.

Verze, která vyjde 1. srpna, bude podporovat 16 zemí (např. USA, UK, Kanada, Austrálie), dalších 22 zemí (včetně České republiky) má být podporováno od prosince.

Zajímavou prezentaci (cca 1 hod.) je možné najít na stránkách Convergence 2010. Asi nejpodrobnější dostupné informace jsou obsaženy ve dvousetstránkovém tréninkovém materálu (CustomerSource).

čtvrtek 15. července 2010

dynamicsaxtraining.com

Na stránce www.dynamicsaxtraining.com můžete najít popisy některých nastavení a procesů v oblastech Obchod & logistika a výroba. Není toho příliš mnoho, ale i tak se to může hodit.
Pochopitelně opět nepotěším nikoho, kdo neovládá angličtinu.

úterý 13. července 2010

Microsoft Days 2010

Vyhraďte si 14. a 15. září, protože v pražském Kongresovém centru se bude pořádat konference Microsoft Days 2010. Podstatná informace je také ta, že se v dalším roce nebudou pořádat menší akce jako Developer Days, Partnerská konference apod., vše má být koncentrováno do Microsoft Days. Bližší (i když stále skromné) informace naleznete na MSDN blogu.

pátek 2. července 2010

Platy v Dynamics

Možná jste byli také před časem (~ říjen 2009) osloveni ohledně účasti v anketě Dynamics Salary Survey 2009, zabývající se platy v oblasti Microsoft Dynamics. Já jsem se této ankety nezúčastnil a možná je to škoda - mohl jsem totiž dostat závěrečnou zprávu. Anketu jsem dávno pustil z hlavy, ale před pár dny zveřejnil Dilip na svém blogu shrnutí některých výsledků (odkaz) a je to poměrně zajímavé - víte třeba, zda (průměrně) platí programátory lépe MS partneři nebo zákazníci?

Jaké security klíče musím zapnout?

Jedním z důležitých úkolů při nasazování AX je správné nastavení přístupových práv. Pro porozumění tomu, jaké security klíče je třeba nastavit, vytvořil Microsoft nástroj nazvaný Security Profiler.

Security Profiler je implementován v X++ a jeho použití je velmi jednoduché - administrátor spustí formulář Security Profiler a a klikne na Start Profiling. Od této chvíle se zaznamenávají potřebné security klíče, administrátor tedy provede nějaké akce (spuštění formuláře, tisk sestavy) a ukončí sledování tlačítkem Stop Profiling. Výsledkem je seznam security klíčů, které byly pro akci nějakým způsobem vyžadovány - a které je třeba vzít v potaz při nastavování uživatelských účtu s omezenými právy.

Security Profiler je zatím bohužel ve vývoji a není normální cestou k dispozici, lze si ho ale vyžádat přes support. Nicméně je pravděpodobné, že v budoucnu bude standardní součástí Dynamics AX.

O něco více informací (včetně obrázků) lze najít zde.

úterý 15. června 2010

Kompilace

Čas od času se setkávám s představou, že AX aplikaci není třeba kompilovat jako celek a že kompilace změněných objektů je dostačující. Na takových projektech pak dochází k záhadnému chování aplikace, na chyby se přichází až v průběhu nasazování a podobně. Jak je to možné?

Je to proto, že změněné objekty mají další závislosti. Například:

  1. Programátor přidá nový parametr metody, ale opomene změnit některá její volání.
  2. Programátor přidá nový parametr metody, ale neví, že třída má potomka překrývajícího danou metodu.
  3. Programátor přidá instanční proměnnou třídy, ale nezkompiluje předky a potomky (kompilace dopředu mnohdy nestačí!). V tomto případě je kód v pořádku, ale aplikace se nechová správně, což je právě to záhadné chování.
  4. Dva programátoři vytvoří samostatně funkční, ale konfliktní modifikace apod.

Nejjednodušší způsob, jak tyto problémy odhalit (a některé i vyřešit), je pravidelně kompilovat celou aplikaci (a kontrolovat výsledky!). Ačkoli lze kompilaci spouštět manuálně, pro pravidelný běh je daleko výhodnější použít plánovanou úlohu, například takto:

Ax32.exe konfigurace.axc -logdir=C:\log -startupCmd=CompileAll_+

Následovat může synchronizace databáze, odeslání výsledků kompilace e-mailem a podobně. Kompilační log lze naimportovat zpět do AX, na druhou stranu s ním občas trochu bojují webové prohlížeče (je to totiž XML s transformací do HTML).

Podíváme-li se ještě jednou na příklady 1. a 2., vidíme, že jde o chyby vývojáře. Aby bylo možné tyto chyby minimalizovat, je nezbytně nutné udržovat aktuální křížové reference. Bylo by ale naivní předpokládat, že na projektech, kde nepovažují za nutné aplikaci ani kompilovat, pravidelně aktualizují křížové reference. Osobně považuji prostředí bez aktuálních referencí za nezpůsobilé k vývoji.

Zrovna dnes mi na jednom projektu zakázal jakýsi tamní Project Engineer zkompilovat aplikaci s tím, že jde o velmi neobvyklý krok. Pokud je pro ně neobvyklý, není to dobré znamení. Na posledním projektu, kde mi tvrdili, že kompilace je zbytečná, selhalo hned první nasazení právě kvůli nezkompilované rodičovské třídě…

úterý 8. června 2010

AX6: Editor kódu

Následující sedmiminutové video ukazuje nové vlastnosti editoru kódu v Dynamics AX 2011. Je velmi názorné, takže doporučuji zhlédnout, i pokud angličtnou nevládnete.

Rychlé shrnutí novinek
  • Více barev pro zvýrazňování syntaxe. Nic revolučního, ale určitě pomůže pro orientaci v kódu.
  • IntelliSense s nápovědným oknem (zobrazují se zde také informace z XML dokumentace, což by mohl být silný impulz pro její intenzivnější vytváření).
  • Automatické vytváření šablony pro XML dokumentaci (pro metodu doplní konkrétní názvy proměnných).
  • Číslování řádků. Ale že jsem se načekali…
  • Barevný okraj označující změněný kód (stejně jako ve Visual Studiu).
  • Lupa.
  • Sloupcová editace - umožňuje mazat nebo psát kód na více řádcích, ale stejném sloupci.
  • Zobrazní popisu kompilační chyby v tooltipu nad patřičnou řádkou kódu.
  • Text label v tooltipu nad ID labelu.

pátek 4. června 2010

AX.NET for Visual Studio

ProISV (autoři AX.NET) zveřejnili video, ve kterém předvádějí práci s AOT přímo v prostředí Visual Studia - vyhledávání v AOT, vytváření nových objektů, změnu vlastností a podobně. Tyto funkce budou dostupné v AX.NET v2.
Také zmiňují, že možná dojde i na editaci X++ kódu ve Visual Studiu!

čtvrtek 3. června 2010

Virtual Convergence 2010

Na webu vepexp.microsoft.com/convergence2010 jsou ode dneška k dispozici přednášky z konference Convergence 2010 (předpokládám, že jen z Atlanty).
Přednášky pojednávají o Dynamics produktech, stejně jako o Office, serverových řešeních a podobně. Zatím jsem neměl čas na detailní zkoumání, zhlédl jsem jen jedno (hodinové) video Inside Microsoft Dynamics X++ a to mohu vřele doporučit. Věnuje se poněkud opomíjenému tématu garbage collectoru, zmiňuje problematická místa X++, ukazuje breakpoint podmíněný určitou hodnotou v callstacku atd. Konečně jsem se také dozvěděl, proč mají volání CLRInterop onu režiji (protože .NETové metody volají pomocí reflexe). V závěru videa se se také dozvíte, o čem se nesmí mluvit… :-)
Jen mě mrzí, že není k dispozici download. Mohl jsem využít zítřejších šesti hodin ve vlaku.

středa 26. května 2010

Microsoft Competencies

Od května platí pro nové požadavky pro dosažení kompetencí v Partner programu. To sice není zrovna oblast mého hlavního zájmu, nicméně vzhledem k mírné panice mezi některými partnery považuji za vhodné alespoň upozornit, že se něco takového děje.

Celý proces je v přechodné fázi a tak pro stejnou kompetenci třeba platí různé požadavky nyní a od října tohoto roku. Každá kompetence má svůj vyšší level, Advanced Competency, ale ty budou také dostupné až v říjnu.

Informace o požadavcích, benefitech, mapování současných kompetencí na nové atd. naleznete v dokumentu The Value of Earning a Microsoft Competency. Kompetence ERP začíná na straně 36, ISV na straně 51.

Pro Dynamics AX kompetenci se počítají lidé, kteří mají všech pět následujících certifikací (požadavky na verze jsou velmi mírné - počítá se i třeba AX 2.5, ale jen do října!):

  • Implementace a správa SQL Serveru
  • Instalace a konfigurace AX
  • Finance v AX
  • Vývoj AX
  • Obchod a logistika v AX

Takže mě čekají SQL Server a finance…

úterý 25. května 2010

DEV_SysTableBrowser a DEV_CreateNewProject

Vanya Kashperuk zveřejnil nové verze dvou svých nástrojů, nyní oficiálně podporujících AX2009. DEV_SysTableBrowser je extrémně užitečný nástroj, který rozšiřuje prohlížeč tabulek zejména o možnost řazení polí dle názvu (standardně jsou řazena dle ID) a možnost zvolit, jaká pole budou zobrazena. Pro popis dalších vlastnostím, download atd. viz článek na Axaptapedii. Původní DEV_SysTableBrowser bylo možné používat v AX2009 po několika drobných změnách (souvisejících s UtcDateTime), ale před hotfix rollupem 3 byla velkým problémem rychlost - a na tom se zřejmě nic nezměnilo, tudíž pozor na verzi vaší Axapty. DEV_CreateNewProject pomáhá vyvářet projekty - můžete si zadefinovat prefix projektů a snadno vytvářet větve v projektu odpovídající struktuře AOT (a to i v již existujícím projektu). Narozdíl od DEV_SysTableBrowser jsem ho nikdy moc nepoužíval, ale aktuálně pracuji na implementaci, kde mají AOT projekty (poněkud zvrhlý) devítipísmenný prefix, takže asi začnu. Stránka o DEV_CreateNewProject na Axaptapedii.

pátek 21. května 2010

Dojmy z Decision Spring 2010

Tentokrát jsem si na virtuální konferenci Decision Spring 2010 trochu času našel. Příliš jsem od toho neočekával… a přesto jsem byl celkem zklamán. Přednášky ani brožurky popisující partnerská řešeni mi mnoho nedaly a textový chat nemůže ani v nejmenším nahradit face-to-face rozhovory na "nevirtuálních" konferencích.

Kvalita doručovaného kódu

Upgrade projektu v UK jsem dokončil a jsem již zpět v ČR (sopka ani voda mě nezastavily), ale chci se o tomto projektu ještě zmínit. Konkrétně o dojmech z kódu, který dodali další partneři. Zákazník využívá dva moduly vytvořené třetími stranami, od výrobců jsme si tedy vyžádali "nové" (AX4 SP2) verze. První partner dokázal dodat zkompilovatelnou verzi až na třetí pokus (nějaké soubory chyběly, nějaké přebývaly…). I finálně dodaná verze obsahovala "užitečné" objekty jako Form1, CopyOf* apod. a také řadu objektů určených jen pro vývoj (např. EditorScripts). Aplikace se navíc jen hemžila povzbudivými poznámkami typu "tato funkce není hotova" a počet TODO dosáhl takového množství, že jsem musel vlastní TODO prefixovat, abych je byl vůbec schopen najít. Druhý partner dodal zkompilovatelný kód, dokonce i dokumentaci k instalaci, nicméně výtky ohledně objektů určených pro vývojáře a TODO platí i v tomto případě. V jejich řešení byl dále zakomentován kus standardního kódu (pravděpodobně z nějakých testovacích důvodů), což bránilo vytvoření některých číselných řad. Celé to na mě působí tak, že partneři mají jakási vývojová prostředí, na vyžádání z nich vyexportují (plus mínus všechny) objekty a odešlou zákazníkovi. Ani neověří, zda je možné z odesílaných souborů sestavit aplikaci. O nějakém řízení kvality ani nemluvím. Co si má pak zákazník myslet? A máme se my těšit na další spolupráci a doporučovat moduly těchto partnerů svým zákazníkům? Přitom by to nebylo tolik práce - nastavit kritéria pro publikovaný kód a kontrolovat (!) jejich splnění (typicky za použití Best Practice checku) a pokusně nainstalovat aplikaci z instalačních souborů. Dokud se nezmění zdrojové soubory, lze takto připravený instalační balíček rovnou použít pro další zákazníky. Oddělení business logiky a nástrojů pro vývoj se obvykle řeší oddělenými vrstvami. Pak je jen třeba dávat pozor, jaké objekty se exportují (nebo distribuovat rovnou .aod). Na tom, že ona první firma nemá připravé otestované verze svých modulů pro AX4, mě zaráží hlavně fakt, že AX4 SP2 byla vydána již před třemi lety…

pátek 14. května 2010

Decision Spring 2010

MSDynamicsWorld.com pořádá 19. a 20. května 2010 virtuální konferenci Decision Spring 2010. Registrace je zdarma (jen počítejte s trochou spamu v mailu ;-)), program naleznete zde. Loni jsem o této konferenci (pod jménem AxDecision) také psal, ale nakonec jsem se nezúčastnil, tudíž nemohu bohužel referovat. Letos bych to rád absolvoval, abych viděl, co zajímavého jiní partneři vymysleli…

čtvrtek 13. května 2010

Uvolnění zamčených souborů v aplikačním adresáři

V průběhu upgradu (AX3 → AX4) se mi dvakrát podařilo sestřelit AOS takovým způsobem, že zůstaly uzamčené soubory v aplikačním adresáři (umístěné na jiném stroji než AOS). Nebylo pak možné přepsat vrstvy, smazat aplikační index a podobně. Soubory lze uvolnit tak, že na daném serveru spustíte Administrative Tools > Computer Management a zvolíte System Tools > Shared Folders > Open Files. Ze seznamu otevřených souborů vyberete ty, které patří do příslušného aplikačního adresáře, a uzavřete je pomocí Close Open File (v kontextovém menu nebo v menu Action). Testováno na Windows Serveru 2003 SP2.

středa 12. května 2010

Synchronizace databáze v AX 4

Aktuálně dokončuji upgrade jedné implementace z AX3 na AX4 a odnesl jsem si z toho pár postřehů. První postřeh je staronový - postupně totiž zapomínám, co jak funguje ve starých verzích AX. Pokud selže synchronizace databáze v AX2009, objeví se formulář se seznamem problémů. V AX4 se obvykle dozvíte jen Cannot execute a data definition language command on (). The SQL database has issued an error. A nevíte ani, která tabulka to způsobila. Následující job umožní zjistit jména problémových tabulek. Bylo by možné modifikovat přímo dbSynchronize(), ale implementace nezávislého jobu je jednodušší.
Dictionary dict = new Dictionary();
TableId tableId;
;

setPrefix("Synchronizace DB");
tableId = dict.tableNext(0);

while (tableId)
{
    setPrefix(tableId2Name(tableId));
    try
    {
        appl.dbSynchronize(tableId, false);
    }
    catch {}
    tableId = dict.tableNext(tableId);
}

Tyto komplikace vidím to jako další argument, proč raději upgradovat přímo na AX2009…

čtvrtek 15. dubna 2010

SharePoint 2010 na Windows 7

Teď trochu odbočím od Dynamics AX, ale zas ne až tak daleko. Vazby SharePointu a Dynamics produktů se stále prohlubují a na změnu trendu to rozhodně nevypadá, takže to sem rozhodně patří. Přípravy SharePointu 2010 finišují a pokud je mi známo, měl by být představen 12. května (spolu s Microsoft Office 2010), k dispozici je ale samozřejmě betaverze (odkazy na konci). SharePoint 2010 je možné (pro vývojové účely) provozovat i na klientských operačních systémech, konkrétně Windows 7 a Vista SP1, a přesně to jsem chtěl vyzkoušet. Nechci zde opakovat nutné prerekvizity a podobně (vše najdete v odkazech), spíše popsat jednu konkrétní konfiguraci a problémy, které mě na ní potkaly. Instaloval jsem SharePoint Foundation 2010 na stroj s Windows 7 Enterprise x64, z relevantních aplikací jsem měl naistalován SQL Server 2008 R2, Visual Studio 2010 RC1 a Office 2007 x86. Postup instalace je popsán v tomto dokumentu a toho jsem se také snažil držet. Dočtete se v něm, že instalátor prerekvizit je připraven pouze pro Windows Server 2008 a na jiných systémech budete muset udělat několik kroků ručně. První problém nastal při povolování ASP.NET (chyba v aspnetca.exe). Vygooglil jsem cosi o duplikovaných ISAPI filtrech v IIS po upgradu z XP na W7 (což by se mě teoreticky mohlo týkat), ale nakonec stačilo zastavit IIS. Na druhý problém jsem narazil při povolování WCF non-HTTP activation (NetTcpPortSharing service failed to start). Kombinace EventLog + Google odhalila problém s .NET 4.0 a po jeho odstranění se instalace konečně podařila. Po instalaci SharePointu jsem spustil SharePoint Products Configuration Wizard a ten skončil zprávou, že nemohl nalézt sestavení Microsoft.IdentityModel. Tento problém vyřešila instalace Geneva Frameworku (download) - v prerekvizitách je uvedený, ale na ty je vždycky dost času. ;) Opětovné spuštění Configuration Wizardu proběhlo bez problémů a tím byla instalace úspěšně dokončena. Ještě se chci zmínit o instalaci SharePoint Designeru. Stáhnutí Designeru se mi samo nabídlo při pokusu o editaci knihovny (což mě potěšilo) a já jsem zvolil 64-bitovou verzi. Ta se ovšem nesnese s mými 32-bitovými Office 2007 a já musel stáhnout ještě 32-bitový Designer. A to jsem si už stejným způsobem naběhl s Visiem 2010… Tak hodně úspěchů s SharePointem 2010! [Užitečné odkazy] SharePoint Foundation 2010 Beta Hardware and software requirements (SharePoint Foundation 2010) SharePoint Server 2010 Beta Hardware and software requirements (SharePoint Server 2010) Setting Up the Development Environment for SharePoint Server MSTV.CZ: Technet konference: Sharepoint 2010 a Office 2010

středa 7. dubna 2010

AX.NET

Podle názvu byste možná řekli, že AX.NET má něco společného s Dynamics AX a .NET. A skutečně! AX.NET je nástroj usnadňující vývoj .NET aplikací, které volají aplikační logiku AX pomocí Business Connectoru. A v čem je to usnadnění? Zejména v tom, že AX.NET vytvoří z AOT .NET sestavení, obsahující všechny třídy, tabulky, enumy atd. Toto sestavení je pak přidáno do projektu ve Visual Studiu a objekty jsou připraveny k použití - lze volat metody tříd, přiřazovat hodnoty do polí v tabulkách atd. To vše s podporou všech schopností Visual Studia - IntelliSense, typová kontrola a spousta dalších. To proto, že díky AX.NET je Axapta jen další .NET sestavení. Skvělé řešení! AX.NET také podporuje LINQ dotazy (Language-Integrated Query, speciální syntaxe pro psaní dotazů), které překládá do X++ a spouští přes Business Connector (takže se opět použije veškerá AX aplikační logika). Praktickou ukázku můžete vidět například v tomto videu. Na AX.NET jsem narazil v podstatě okamžitě, co se objevili první zprávy, ale čekal jsem, zda se to podaří realizovat a jen jsem občas zkontrolovat, co na mě vypadlo z RSS. Ale zřejmě je na čase vzít tento projekt vážně, protože oficiální vydání má být právě dnes! Jen bych asi měl dodat, že jde o komerční projekt. Více informací o AX.NET naleznete na proisv.com.

úterý 6. dubna 2010

Odhady pracnosti

O odhadech pracnosti při tvorbě softwaru už byla napsána řada knih a já ani nemám ambici přinést tímto článkem něco nového. Přesto… povědomí vývojářů, konzultantů, projekt manažerů (a všech ostatních ;)) o zkušenostech, které softwarový průmysl nasbíral za desítky let své existence, je mimořádně nízké, takže trocha opakování snad neuškodí. V tomto článku chci ukázat, jak dělám odhady programátorských prací já osobně a upozornit na některé časté chyby. Můj osobní přístup nelze samozřejmě považovat za univerzálně platný. Pro další postupy, lepší vysvětlení, teoretické podklady, statistiky atd. musíte zapátrat v odborné literatuře. V češtině nelze než doporučit Odhadování softwarových projektů (možná znáte originální název Software Estimation: Demystifying the Black Art). Cíl odhadu Nejprve je třeba si ujasnit, k čemu má odhad sloužit. Z toho pak plyne, v jaké fázi projektu odhad potřebujeme, s jakou přesností atd. Někdy stačí velmi vágní odhady (projekty typu až to bude, tak to dodáme) jindy je třeba dělit práci do iterací, volit variantu, která se stihne do fixního data atd. Odhad by měl poskytnout data dostatečná pro plánování a řízení projektu, nemůže poskytnout přesné číslo, jak dlouho bude práce trvat (tuším McConnell to nazývá „předpovídání budoucnosti“). Přesto je nalezení tohoto magického čísla cílem odhadů na mnoha projektech – a asi nepřekvapí, že v předpovídání budoucnosti lidstvo velký pokrok neudělalo. :-) Jednou z nejčastějších chyb je přímá kalkulace ceny projektu z odhadu (odhad v hodinách × hodinová sazba). To je také zřejmě důvodem, proč jsou tak často požadovány „předpovědi budoucnosti“. Krom negativních dopadů na konstrukci ceny má tento přístup také dopad na tvorbu odhadu – místo aby se udělal co nejpřesnější odhad a cena se stanovila nezávisle, vytváří se tlak na změnu odhadu. Problém je v tom, že takto modifikovaný odhad (ať už kterýmkoli směrem) může být těžko použit pro plánování projektu. Byl jsem dokonce svědkem snah přenést zodpovědnost za dodržení „odhadu“ na vývojáře. Nutným důsledkem by pak bylo dohadování mezi vývojářem (snažícím se nadsadit odhad tak, aby se do něj vždy vešel) a projekt managerem (snažícím se stlačit termín). Skutečný odhad by v takovém procesu figuroval jen zcela okrajově. Kdy odhadovat Projekt lze odhadovat v kteroukoli fázi, ale dosažitelná přesnost je limitována množstvím informací, které jsou k dispozici. Například pokud odhadujete pracnost na základě pouhého uživatelského požadavku, nemá podle mého názoru smysl větší přesnost než Malá/Střední/Velká náročnost (a i tak se to často nepodaří trefit). Pokud chcete získat (relativně) přesný odhad, potřebujete znát všechny funkční požadavky i způsob implementace. Protože v Dynamics AX většinou zasahujete do existujícího kódu, je nutné vědět, jaké části již existují a bude je možné využít a jaké je třeba nově naimplementovat. Někdy je také vhodné vytvořit prototypy nejasných částí ještě před odhadem pracnosti. To všechno si pochopitelně vyžádá určitý čas, se kterým musí být počítáno v projektovém plánu. Jak odhadovat První a nejdůležitější částí odhadu je dekompozice na menší části. Tyto části je nutné nejprve vůbec identifikovat (do té doby jen tušíte, co všechno bude asi tak třeba udělat), ověřit, zda pokrývají všechny požadavky, a nakonec je postupně odhadnout. Často nejsou všechny potřebné informace k dispozici, ale je možné odhadnout alespoň některé části a ke zbylým se vrátit později. Já projekt člením po (relativně) samostatně funkčních blocích realizovatelných v řádu hodin čí dnů (dnů v případech, kdy je v odhadu příliš mnoho nejistoty). Odhady rozepisované podle jednotlivých objektů (tedy ne podle funkcí) považuji za hůře členitelné a nerespektující skutečný postup práce při vývoji. Ke každému funkčnímu bloku zapisuji vše, co je třeba udělat, ale tyto detaily neodhaduji samostatně. Seznam pak používám i v průběhu vývoje ke kontrole, zda je vše naimplementováno, a k vykazování stavu implementace. V mém případě vypadá popis bloku nějak takto: Parametrizační tabulka (EDTs, help texty, tabulka, formulář, menu item, do menu) Členění na menší části má ještě několik dalších výhod. Zejména je jasné, co je vlastně do odhadu zahrnuto, a v případě změn lze snadno přidat/odebrat určité bloky, popř. zpětně vysledovat, jaká práce chyběla v odhadu a přesto se musela udělat. Když už víte, co všechno se bude programovat, zbývá jen udělat odhad. Na většině projektů (alespoň co mohu soudit z mé zkušenosti) je odhad číslo popisující za jak dlouho by se práce mohla stihnout. Pak se pár věcí zkomplikuje a výsledek se oproti odhadu liší i o stovky procent. Odpovědí na tento problém (a nejen na něj) je definice odhadu jako rozsahu, do kterého výsledná pracnost s vysokou pravděpodobností padne. Když jsem o tomto přístupu poprvé četl (v praxi jsem ho nikdy neviděl), nedovedl jsem si to moc představit. V praxi se ale ukázalo, že je to postup velmi přirozený a rychle se na něj zvyká. Prostě odhadnete optimistickou variantu (to je to výše zmíněné za jak dlouho se to dá stihnout) a naopak pesimistickou. Odhad pak daleko lépe popisuje, jaké situace mohou nastat a zabraňuje zaměňování odhadu za termín, kdy bude práce určitě hotova. U jednočíselných odhadů se také často projevuje tlak na jejich snížení – zde to nepředstavuje problém, protože optimistická varianta je zahrnuta, ale zároveň je zřejmé, že to skutečná pracnost bude pravděpodobně větší. Na závěr Doufám, že jsem něco málo z problematiky odhadování odhalil a ne zamlžil. Vědomě jsem pominul celou řadu důležitých věcí, třeba využívání dřívějších odhadů (a jejich úspěšnosti), ale domnívám se, že začít je třeba výše uvedeným. A pak už jen zlepšovat…

pátek 2. dubna 2010

Generátor přístupových metod pro AX4

Pomalu se zabydluji ve svém novém působišti ve Velké Británii a tak se zas pokusím trochu vyprázdnit buffer věcí, o které bych se chtěl podělit. První z nich je velmi stručná - jelikož můj aktuální projekt běží na AX 4.0, připravil jsem .xpo generátoru přístupových metod i pro tuto verzi AX. Stahovat můžete zde.

středa 17. března 2010

Intelligent Data Management Framework

Na PartnerSource se objevila pre-release verze velmi zajímavé aplikace. Intelligent Data Management Framework for Microsoft Dynamics AX (IDMF) slouží ke správě databáze Dynamics AX, zejména archivaci a odstraňování historických záznamů, samozřejmě při zachování konzistence databáze. Taková funkcionalita byla zákazníky dlouhodobě (a oprávněně) žádána, protože z hlediska výkonu je vhodné udržovat co nejmenší transakční databázi. IDMF podporuje AX ve verzích 3 - 5 a SQL Server 2005/2008 (pravděpodobně kvůli Integration Services). Před archivací/vyčištěním dat je nutné definovat, které tabulky spolu souvisí a mají být zpracovány společně (to je úloha kritická pro zachování konzistence databáze). IDMF dohledává tyto informace pomocí křížových referencí a díky tomu stačí zadat „kořenovou“ tabulku a související tabulky jsou přidány automaticky (manuální změny jsou možné). Na základě tohoto stromu (Purge Object/Archive Object v originální terminologii) je pak prováděna vlastní archivace/vyčištění dat. Dalším krokem je definice filtru dat - například plně zaúčtované záznamy za loňský rok. Takto definovanou operaci je možné spustit jednorázově, nebo přímo v IDMF nastavit opakované spouštění. Z dalších schopností IDMF bych zmínil:
  • Předpřipravené objekty - není tedy nutné (a ani doporučené) začínat od nuly.
  • Analýza DB - informace o velikosti databáze, fragmentaci indexů atd., ale i např. počtu ukončených skladových objednávek. Lze také sledovat změny v čase.
  • Restore - archivované záznamy je v případě potřeby možné vrátit zpět do produkční databáze.
Sice jsem neměl zatím možnost IDMF vyzkoušet prakticky, ale vypadá rozhodně velmi užitečně. Pokud vás také zaujal, doporučuji prostudovat Installation Guide a Administration Guide.

čtvrtek 4. března 2010

PowerShell - informace o AX aplikaci

Snažíte se psát skripty pro manipulaci s AX a nechce se vám udržovat informace o jménech aplikací, cestách k adresářům a podobně? Mně se tedy nechce a tak jsem si řekl, že bych mohl všechno zjistit automatizovaně jen na základě .axc souboru. Výstup mého skriptu vypadá následovně:
AppLocalPath       : C:\Program Files\Microsoft Dynamics AX\50\Application\Appl\JmenoAplikace
AosName            : JmenoAOS
AosNumber          : 03
AosServiceInstance : System.ServiceProcess.ServiceController
AosPort            : 2714
AosComputerName    : JmenoPocitaceSAos.domena
AppUncPath         : \\JmenoPocitaceSAos\C$\Program Files\(...)\Appl\JmenoAplikace
Základní informace o AOS zjistím se zadaného .axc souboru, instanci služby pomocí Get-Service a cestu k aplikačnímu adresáři z registrů počítače, kde je nainstalované AOS. Z toho také plyne, že je třeba mít nakonfigurovaný PowerShell remoting. Podrobnosti zde nebudu rozepisovat, zájemci si pročtou kód a nezájemci ušetří čas :-). Skript stahujte zde.

pondělí 1. března 2010

SysQueryRangeUtil

Třída SysQueryRangeUtil obsahuje několik užitečných metod, pomocí kterých lze vytvářet hodnoty filtrů (nad Query objekty). Jsou to například metody currentEmployeeId() nebo dayRange(). Ve všech případech jde o statické metody vracející řetezec a řada z nich má nepovinné parametry (pro určení rozsahů apod.). Tyto metody lze použít při vytváření Query v X++ kódu, třeba takto:
queryBuildRange.value(SysQueryRangeUtil::day());
To by nebylo nic zajímavého, vtip je v tom, že je lze použít i při filtrování dotazu pomocí dialogu (na formuláři, v RunBase třídách a podobně): a také v Queries v AOT: Jediná finta je v tom, že jejich volání musí být uzavřeno do závorek. Do třídy SysQueryRangeUtil lze také přidat další metody - ať už kvůli dodatečné funkcionalitě (např. weekRange()), nebo pro přidání aliasů metod (např. me() jako alias currentUserId()).

Hotfix Impact Analysis

Microsoft zveřejnil nový nástroj pro Dynamics AX, který pomáhá identifikovat, jaké mohou být dopady změněných objektů. Hlavní částí je formulář Impact Analysis (viz obrázek), který v horní části zobrazuje zvolené objekty a v dolní části křížové reference pro označený objekt. Formulář lze spustit z kontextového menu (Add-Ins > Impact analysis) pro jeden nebo více AOT objektů, pro jeden nebo více projektů, nebo z instalátoru hotfixu. Podívejme se na funkce, které lze z tohoto formuláře vyvolat:
  • Compare - porovná různé vrstvy objektu. Narozdíl od "normálního" porovnání zobrazí dva panely vedle sebe (takže lze zároveň zobrazit např. porovnání SYP×Old SYP a SYP×VAR), naopak nejsou přístupné volby jako zobrazení čísel řádků).
  • Load - zde se nachází funkce pro přidání objektů do analýzy - lze vybrat objekt z AOT nebo z projektu (a přetáhnout myší), přidat celé .xpo nebo dříve uložený stav.
  • Remove - odebere označený objekt z analýzy
  • Save - uloží seznam objektů (vybraných pro analýzu) do XML. Tento soubor lze pak nahrát funkcí Load > Load Impact Analysis State.
  • Export - umožňuje exportovat seznam objektů nebo křížových referencí do XML.
Tlačítka v dolní části zpřístupňují standardní funkce pro křížové reference. Jak jsem již zmínil, analýzu dopadu je možné spustit přímo z instalátoru hotfixu: V následujícím kroku instalátoru je zobrazena stručná informace o zasažených objektech a je možné pomocí tlačítka přejít do výše popsaného formuláře v AX. Po analýze dopadu je možné pokračovat v instalaci hotfixu. Nástroj Impact Analysis je k dispozici jako samostatný hotfix (tak jsem ho získal já) a od dnešního dne by měl údajně být součástí veškerých nových hotfixů. Další informace: KB974255 (Impact Analysis feature for Dynamics AX 2009)

čtvrtek 25. února 2010

Cachování edit metod

Na blogu Dynamics AX Daily jsem se dočetl, že v AX2009 je možné na formuláři cachovat i edit metody (link). Samozřejmě jsem si to hned otestoval a… opravdu to funguje! Tahle schopnost AX2009 mi byla do dneška utajena. Stejně jako v případě display metod musí být i edit metoda definována na tabulce a cachování se aktivuje pomocí cacheAddMethod() na datovém zdroji formuláře.

Serializace objektů - úvod

Úvod Serializace objektů je v Dynamics AX intenzivně využívaná, ale obvykle je tak dobře skrytá, že si ji mnoho vývojářů příliš neuvědomuje. Pochopení její implementace je ale v některých situacích nezbytné a v opačném případě vznikají zbytečné a často i poněkud záhadné chyby. Podívejme se na tedy serializaci trochu podrobněji. Co to je? Serializace objektu znamená uložení jeho stavu do podoby, kterou je možné uložit nebo někam přenést. Objekt je pak možné obnovit (deserializovat) do původního stavu. Jako příklad použití v Dynamics AX lze uvést:
  • Ukládání uživatelského nastavení (dříve použité hodnoty v dialogových oknech, vlastní nastavení formulářů apod.).
  • Ukládání objektů pro pozdější použití (úlohy spouštěné v určitém čase, uložení dotazu (např. pro Zabezpečení na úrovni záznamů))
  • Klient/server optimalizace (spuštění dialogu serverové třídy na klientu)
Realizace Cílem serializace je převést referenční datové typy (což jsou fakticky odkazy na místo v paměti) na hodnotové. A protože v Dynamics AX patří mezi hodnotové typy i kontejner, je pro účely serializace jasnou volbou. Příklad: Mějme třídu Class1, obsahující instanční proměnné str retezec1 a real cislo1 (ty představují stav objektu). Uložit stav tohoto objektu do kontejneru lze snadno pomocí speciální syntaxe pro vytváření kontejnerů: [retezec1, cislo1]. Takto jsme získali kontejner, obsahující string a real – všechno hodnotové typy. Tento kontejner může být přímo uložen do databáze, předán jako parametr metody mezi klientem a serverem a podobně. Deserializace objektu provedeme tak, že vytvoříme novou instanci Class1 a hodnoty jejích proměnných naplníme z kontejneru. Opět můžeme využít speciální syntaxe a provést přiřazení jako [retezec1, cislo1] = kontejner; Pokud přidáme nebo odebereme proměnnou, musíme změnit serializační i deserializační kód. K tomu, aby to nebylo nutné dělat ručně, se v Dynamics AX používají makra, což je pro řadu vývojářů asi nejobtížnější část problému. Makra jsou (zjednodušeně řečeno) speciální příkazy, které ovlivňují, jak se zdrojový kód zkompiluje. Lze například – v závislosti na hodnotě parametru – zkompilovat aplikaci jednou s ladícími příkazy a podruhé bez nich. V AX jsou uvozeny znakem # a nejčastěji se používají pro definici konstant, ale lze vytvářet i podmíněně kompilovaný kód, makra s parametry atd. Více na MSDN. Pro téma serializace stačí vědět, že kód definovaný pomocí klauzule #define, #localmacro apod. se před kompilací vloží na místo, kde je makro použito. Vytvoříme-li makro #define.CurrentList(retezec1, cislo1), můžeme kontejner s proměnnými vytvořit prostým voláním [#CurrentList] (protože to je pro kompilátor to samé jako [retezec1, cislo1]). Obdobně deserializaci zapíšeme jako [#CurrentList] = kontejner;. Příště se podíváme na verzování serializovaných objektů a některá konkrétní použití serializace v AX.

pátek 19. února 2010

Certifikace Trade & Logistics

Dnes jsem úspěšně složil certifikační zkoušku AX 2009: Trade & Logistics!

čtvrtek 11. února 2010

Enterprise Portal Development Cookbook

Na blogu EP teamu se nedávno objevila "kuchařka" pro vývoj Enterprise Portálu. Protože se EP vůbec nevěnuji, nejsem schopen zhodnotit její kvality. Ale nepochybuji, že se někomu bude hodit. Přímý odkaz zde.

úterý 9. února 2010

AX6: modely

Na konci minulého roku zveřejnil Michael Freurgaard Pontoppidan (mfp) několik příspěvků o nové funkci, chystané do Dynamics AX 6, zvané Modely (Models). Protože tyto modely významně ovlivní způsob nasazování AX aplikací, rozhodl jsem se sepsat stručné shrnutí v češtině. A protože nemám připravovanou verzi AX k dispozici, vypůjčil jsem si obrázky s Michaelovým svolením přímo z jeho blogu. Vezměte prosím na vědomí, že verze 6 je stále ve vývoji, a také že některé podstatné informace nebyly publikovány. Na definitivní podobu si prostě musíme ješte počkat. Co je to ten model? Model je určité seskupení aplikačních objektů uvnitř vrstvy a v jedné vrstvě jich může existovat libovolné množství. Model usnadňuje organizaci objektů a je ho možné exportovat, instalovat, odinstalovat atd. Protože AX verze 6 již nebude obsahovat AOD soubory, budou modely hlavním prostředkem distribuce zdrojového kódu. Práce s modely v prostředí AX velmi připomíná práci s vrstvami; mimo AX zajištuje vetšinu funkcí samostatná aplikace AxUtil. Model je implementován jako řízené sestavení (managed assembly). Vytvoření modelu Model je možné vytvořit pomocí příkazu:
AxUtil create /model:"My Model" /Layer:USR
Všimněte si, že model je vytvářen v konkrétní vrstvě. Bylo by také možné určit databázi, vůči které se příkaz provede. Výběr modelu Obdobně jako vrstvu lze učit také výchozí model. Model ale může být změněn, narozdíl od vrstvy, i za běhu aplikace. Zvolit lze samozřejmě jen model patřící do aktuální vrstvy. Aktivní model je zobrazen ve stavovém panelu (a je ho odtud možné i změnit). Vývoj v modelu Modifikace objektů v AOT jsou automaticky přiřazeny k právě aktivnímu modelu. V jakém modelu je modifikace umístěna lze zobrazit přímo v AOT (pro každý element je zobrazen pouze model z nejvyšší vrstvy): V kontextovém menu přibyde také možnost přesunout element do jiného modelu. Export Modely je možné exportovat do souboru, což umožnuje přenést jen část vrstvy, aniž by bylo nutné sáhnout po exportu do .xpo. Díky modelům lze také lépe členit vyvíjenou aplikaci nebo dokonce vyvíjet několik (dostatečně izolovaných) rešení v jednom AX prostředí. Export se provádí opět pomocí AxUtil:
AxUtil export /model:"My Model" /file:MyModel.axmodel
Velkou výhodou exportovaného modelu je manifest. Manifest je obsažen přímo v souboru s modelem a obsahuje informace jako je jméno modelu, jeho verze, zdrojová vrstva a podobně. Manifest lze zobrazit:
AxUtil list /model:"My Model"
a případně změnit:
AxUtil edit /model:"MyModel" /manifest:Version="2.0.0.0",Publisher="MFP",Description="My first model"
Exportovaný model lze také opatřit elektronickým podpisem. Podpis pak může využít například zákazník k ověření, zda nebyl soubor během přenosu mofikován. Import Modely uložené do souboru je pochopitelně možné importovat do AX:
AxUtil import /file:MyModel.axmodel
Do jedné vrstvy lze importovat více modelů, například řešení od dvou různých dodavatelů, což je dnes vcelku nepříjemný úkol (a noční můra při upgradech). Při takovém importu se mohou vyskytnout dva hlavní problémy:
  • Elementy mají stejné ID – MFP bez dalších podrobností tvrdí, že by tento problém měl být v AX 6 eliminován. Zatím je známo jen to, že rozsah ID bude řádově zvětšen.
  • Elementy mají stejný název (typicky: obě řešení mění nějaký standardní objekt) – tomu samozřejmě nelze zabránit (ačkoli často lze zásahy do standardního kódu minimalizovat vhodným návrhem aplikace). Vývojáři AX 6 chtějí snížit množství těchto konfliktů jemnějším členěním některých typů objektů (dnes je například „jednotkou modifikace“ celý objekt typu Menu a pokud dvě řešení přidají menu item do stejného menu, dojde ke konfliktu).
Importu lze říct, jak se má zachovat v případě, že narazí na konflikt. K dispozici jsou tyto tři možnosti:
  • Import modelu je zrušen.
  • Původní objekty jsou přepsány. Protože by následné odinstalování tohoto modelu mohlo zanechat aplikaci v nekonzistentím stavu, budou spolu s tímto modelem odinstalovány i modely, jejichž objekty byly importem přepsány.
  • Model je naimportován a konfliktní objekty jsou umístěny do nového modelu ve vyšší vrstvě (např. BUS→BUP), kde je možné konflikty vyřešit.
Mazání modelu K odebrání modelu opět poslouží AxUtil:
AxUtil delete /model:"My Model"
Závěr Mfp uvádí o něco více podrobností, takže v případě zájmu navštivte jeho blog. Nicméně dokud není AX 6 hotova, stejně není nic definivní. Až bude zveřejněna, určitě se na modely a jejich implementaci podívám podrobněji.

pátek 5. února 2010

Pole na dialogu

Někdy je potřeba umístit na dialog pole (tzn. datový typ s Array elementy). Zdrojový kód je triviální:
Dialog      dialog = new Dialog("Dimenze");
;
dialog.addField(typeId(Dimension));
dialog.run();
Pokud je dále třeba nastavit nějakou vlastnost, například AllowEdit, nabízel by se takovýto zápis:
Dialog      dialog = new Dialog("Dimenze");
DialogField field;
;

field = dialog.addField(typeId(Dimension));
field.allowEdit(false);

dialog.run();
Jenže… výsledek není správný. Znepřístupněné je jen první políčko: Na formuláři totiž ve skutečnosti vznikne více políček (Fld1_1, Fld1_2 a Fld1_3) a proměnná field ukazuje pouze na první z nich. Je nutné projít všechny všechná příslušná políčka a nastavit požadovanou vlastnost každému zvlášť.
Dialog                  dialog = new Dialog("Dimenze");
DialogField             field;
SysDictType             dictType;
FormBuildStringControl  control;
int i;
;

field = dialog.addField(typeId(Dimension));

dictType = new DictType(typeId(Dimension) >> 16);

for (i = 1; i <= dictType.arraySize(); i++)
{
   control = dialog.dialogForm().buildControl(field.fieldname(i));
   control.allowEdit(false);
}

dialog.run();
Výsledný dialog pak má všechny dimenze neaktivní, jak bylo požadováno.

středa 27. ledna 2010

Seznam přihlášených uživatelů

Dnešní příspěvek je opravdu dlouhý, ale ve skutečnosti popisuje vcelku jednoduchou věc - PowerShellový skript pro snadné získání seznamu přihlášených uživatelů. Taková informace je při údržbě AX prostředí potřeba dost často, pokud chcete brát ohledy na přihlášené uživatele a nevypínat jim služby pod rukama. Lze se samozřejmě přihlásit do AX, otevřít modul Administrace, formulář Uživatelé online a tam ověřit, zda je někdo přihlášený. To ale dost zdržuje a tak jsem si tento úkol trochu zjednodušil skriptem, který umožní zvolit konfigurační soubor Dynamics AX, připojí se pomocí Business Connectoru a vypíše přihlášené uživatele do konzolového okna. Trochu blíže k předpokladům pro tento skript:
  • Konfigurační soubory (.axc) pro všechna prostředí jsou uložena v jednom adresáři (viz proměnnou $configurationPath) a týkají se Dynamics AX 2009. V tomto ohledu jsem jen využil existující systém v naší firmě, vy si možná budete muset skript upravit.
  • Nainstalovaný Business Connector
  • PowerShell 2.0
  • .NET 3.0+ (kvůli WPF)
První skript příjmá jako parametr ($args[0]) jméno konfiguračního souboru. Načte sestavení BussinessConnectorNet.dll, vytvoří objekt typu Axapta a zaloguje se pomocí konfiguračního souboru (v něm je adresa AOS atd.). V dalším kroku se dotáže na uživatelská připojení (tabulka SysClientSessions), popř. další informace o uživateli a AOS. Tyto informace zabalí do objektu (což usnadňuje další zpracování) a ten předá na výstup. Ukázka výsledku: Zdrojový kód vypadá takto (některé řádky byly kvůli přehlednosti zalomeny):
$connectorDllPath = 'C:\Program Files\Microsoft Dynamics AX\50\' `
    + 'Client\Bin\Microsoft.Dynamics.BusinessConnectorNet.dll'
$configurationPath = 'D:\CONFIGURATIONS'
$configurationName = $args[0]
$configFile = Join-Path $configurationPath $configurationName

if (!(Test-Path $configFile))
{
    throw "Konfigurace $configFile nebyla nalezena"
}

#zalogování do AX pomocí Business Connectoru
try
{
    [void][reflection.Assembly]::Loadfile($connectorDllPath)
    $ax = New-Object Microsoft.Dynamics.BusinessConnectorNet.Axapta
    $ax.logon('', '', '', $configFile)
}
catch
{
    throw 'Přihlášení pomocí Business Connectoru se nezdařilo'
}

#objekty představující AX tabulky
$sysClientSessions = $ax.CreateAxaptaRecord('SysClientSessions');
$sysServerSessions = $ax.CreateAxaptaRecord('SysServerSessions');

#dotaz na aktivní uživatele přihlášené přes GUI
$sysClientSessions.ExecuteStmt('select * from %1 where %1.Status == 1 ' `
    + '&& %1.ClientType == 0');
if (!$sysClientSessions.Found)
{
    '0 aktivních uživatelů'
}

#iterace přes uživatele, získaní podrobných informací a zabalení do objektu
while ($sysClientSessions.Found)
{
    $userId = $sysClientSessions.get_Field('UserId')
    $userName = $ax.CallStaticClassMethod('UserInfoHelp', 'userName', $userId)

    $sysServerSessions.ExecuteStmt('select * from %1 where %1.ServerId == ' `
       + $sysClientSessions.get_Field('ServerId'))
    $aosInstanceName = $sysServerSessions.get_Field('AOSId')

    #zabalení do objektu
    New-Object PSObject -Property @{
       AosName = $aosInstanceName
       UserId = $userId
       UserName = $userName}

   [void]$sysClientSessions.Next();
}
#odhlášení z AX
[void]$ax.logoff()
Druhý skript slouží k výběru konfigurace AX a jméno této konfigurace předává prvnímu skriptu. Seznam konfigurací je zobrazen v grafickém okně, protože kliknutí mi přišlo jako nejrychlejší způsob výběru. GUI je vytvořeno pomocí WPF (Windows Presentation Foundation) a vypadá takto (s tím rozdílem, že já tam mám konfigurací celkem 42): Seznam konfigurací je naplněn pomocí příkazu Get-ChildItem (alias dir). Zvolená konfigurace ($listBox.SelectedItem) je použita jako parametr pro výše uvedený skript a daný kód je umístěn v obsluze kliknutí na tlačítko ($button.add_Click()).
$configurationPath = 'D:\CONFIGURATIONS'
Add-Type –assemblyName PresentationFramework
Add-Type –assemblyName PresentationCore

Add-Type –assemblyName WindowsBase

$window = New-Object Windows.Window
$window.Title = 'AX konfigurace'
$window.SizeToContent = 'WidthAndHeight'
$label = New-Object Windows.Controls.Label
$label.Content = 'Seznam konfigurací:'

$listBox = New-Object Windows.Controls.Listbox
$listBox.ItemsSource = (% {Get-ChildItem $configurationPath -Include *.axc -Name})

$button = New-Object Windows.Controls.Button
$button.Content = 'Zobraz přihlášené uživatele'
$button.add_Click(
{
    if ($listBox.SelectedItem)
    {
        $window.Hide()
        Write-Host $listBox.SelectedItem

        try
        {
            #volání samostatného skriptu na získání informace o uživatelích
            $activeUsers = (absolutníCesta\prvníSkript.ps1 $listBox.SelectedItem)
        }
        catch
        {
            Write-Host $error[0] -ForegroundColor Red
            exit
        }
   }
})

$stackPanel = New-Object Windows.Controls.StackPanel
$stackPanel.Orientation = 'Vertical'

[void]$stackPanel.Children.Add($label)
[void]$stackPanel.Children.Add($listbox)
[void]$stackPanel.Children.Add($button)

$window.Content = $stackPanel

[void]$window.ShowDialog()

$textbox.Text
$activeUsers
Protože WPF okno vyžaduje běh v STA módu (Single-Threaded Apartment; neznám smysluplný překlad), nelze tento skript spustit běžným způsob. Jednou (a nejjednoduší) možností je zavolání PowerShellu s parametrem -STA, takže spuštěcí příkaz lze napsat (a uložit do .lnk) třeba takto:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe
-STA
-noexit
-command cesta\jmenoSkriptu.ps1