<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2790782254362923606</id><updated>2024-09-21T04:05:00.468+02:00</updated><category term="Dynamics AX"/><category term="X++"/><category term="axapta"/><category term="GIS"/><category term="action script"/><category term="flash"/><category term="flex"/><category term="programowanie"/><category term=".NET"/><category term="CSV"/><category term="CultureInfo"/><category term="EXCEL"/><category term="NumSeqReference"/><category term="NumberFormatInfo"/><category term="UnitTest"/><category term="XLS"/><category term="breakpoint"/><category term="clicked"/><category term="debugger"/><category term="google API"/><category term="google maps"/><category term="nip"/><category term="numerator"/><category term="performance"/><category term="powitanie"/><category term="rss"/><category term="separator dziesiętny"/><category term="skorowidz"/><category term="testy jednostkowe"/><category term="tutorial"/><category term="walidacja"/><category term="wydajność"/><category term="zagadnienia programistyczne"/><title type='text'>DEV Index</title><subtitle type='html'>dynamics AX, flex, php, c#, oracle apex</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>10</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-3610965825763325698</id><published>2013-08-12T20:13:00.001+02:00</published><updated>2013-08-14T01:35:29.905+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="performance"/><category scheme="http://www.blogger.com/atom/ns#" term="programowanie"/><category scheme="http://www.blogger.com/atom/ns#" term="wydajność"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Wydajność Dynamics AX 2009 - przyśpieszenie ładowania się formularzy</title><content type='html'>&lt;span class=&quot;fullpost&quot;&gt;
Pomimo, że nowym produktem jest już Dynamics AX 2012, często użytkownicy końcowi starszych instancji systemu w wersji 2009 mają problem z &quot;zawieszaniem&quot; się systemu przy otwieraniu formularzy lub raportów. Zwisy pojawiają się przy obciążonym serwerze bazy danych i po części mogą wynikać z zapisywania informacji do &quot;Dziennika użycia elementu&quot;, który znajduje się w tabeli &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/cc617934(v=ax.50).aspx&quot;&gt;SysUtilElementsLog&lt;/a&gt;.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;fullpost&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;fullpost&quot;&gt;W zasadzie informacje o użyciu formularzy mogą stanowić źródło informacji statystycznych np. dla projektantów systemu (raport Administracja =&amp;gt; Raporty =&amp;gt; System =&amp;gt; Dziennik użycia elementu), ale w wersji produkcyjnej moim zdaniem jest wielce nieefektywne zapisywać liczniki uruchomień formularzy, szczególnie jeśli konstrukcja AX wymusza często korzystanie z wielu okien.&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;fullpost&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;fullpost&quot;&gt;Jak sobie poradzić z tym problemem i jak przyśpieszyć system? Przełączyć właściwość &lt;b&gt;Temporary &lt;/b&gt;na &lt;b&gt;Yes&lt;/b&gt;. Spowoduje to, że tabela będzie tymczasowa i nie będzie &quot;zapychała&quot; serwera bazy danych niepotrzebnymi insertami lub update&#39;ami i może przynieść chociażby minimalną ulgę ciężko eksploatowanym systemom :)&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;fullpost&quot;&gt;&lt;br /&gt;&lt;/span&gt;
&lt;span class=&quot;fullpost&quot;&gt;&lt;b&gt;Uwaga! Zanim zdecydujesz się włączyć tryb tymczasowy na środowisku produkcyjnym przetestuj rozwiązanie w środowisku testowym.&lt;/b&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/3610965825763325698/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2013/08/wydajnosc-dynamics-ax-2009.html#comment-form' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/3610965825763325698'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/3610965825763325698'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2013/08/wydajnosc-dynamics-ax-2009.html' title='Wydajność Dynamics AX 2009 - przyśpieszenie ładowania się formularzy'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-7486676926616405189</id><published>2010-12-10T12:49:00.005+01:00</published><updated>2011-01-09T20:10:59.844+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="rss"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Czytnik RSS</title><content type='html'>Kolejnym artykułem postanowiłem się podzielić z Wami, kiedy natknąłem się na swój przykład prostej aplikacji z czasów nauki programowania w &lt;b&gt;Dynamics AX&lt;/b&gt; :) Aplikacja ta jest prostym czytnikiem kanałów &lt;a href=&quot;http://pl.wikipedia.org/wiki/RSS&quot;&gt;RSS&lt;/a&gt;. Przykład w środowiskach &lt;b&gt;AX &lt;/b&gt;może niepraktyczny, ale pomimo to można wykonać np. wyświetlanie najważniejszych informacji firmowych czy agregację najświeższych wiadomości ze świata biznesu. Dla Pani Kazi z księgowości można wyświetlać wiadomości o nowych przepisach ze świata finansów czy podatkach z portali branżowych,&amp;nbsp; a także aktualne kursy walut ... Zastosowań jak się okazuje może być mnóstwo i jest to &quot;bajer&quot;, który może być wielu użytkownikom przydatny.&lt;br /&gt;
&lt;br /&gt;
Cała aplikacja zbudowana będzie z jednej tabeli i dwóch formularzy.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
1. Na początek założymy tabelę &lt;b&gt;RSSTable&lt;/b&gt;, gdzie będziemy przechowywać listę kanałów &lt;b&gt;RSS &lt;/b&gt;w podziale na użytkowników:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8L9dpFDRKVRVV4snPjQ93CtYzw6mO6bP3DA1FjQVQwsSN1AIwTJ1pocUqsJwDLypOp8Z5P6qSSpRvvVKEwj-8ZvM6eErSWOm_hBAL0prt1BW24ohjaXWKsJv_jmpwcG0ynLJRCbenxxE/s1600/rsstable.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8L9dpFDRKVRVV4snPjQ93CtYzw6mO6bP3DA1FjQVQwsSN1AIwTJ1pocUqsJwDLypOp8Z5P6qSSpRvvVKEwj-8ZvM6eErSWOm_hBAL0prt1BW24ohjaXWKsJv_jmpwcG0ynLJRCbenxxE/s1600/rsstable.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Należy dodać pola jak powyżej, a ich typy rozszerzone (Extended Data Types) nazywają się tak samo. Na tablicy oczywiście można stworzyć grupę pól składającą się np. z &lt;b&gt;URL &lt;/b&gt;i &lt;b&gt;Name&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
2. Następnie stworzymy prosty formularz, gdzie będzie można uzupełniać dane kanałów. W tym celu tworzymy nowy formularz i do &lt;b&gt;DataSource &lt;/b&gt;przeciągamy tablicę &lt;b&gt;RSSTable&lt;/b&gt;, następnie do Grida na formularzu przeciągamy stworzoną grupę pól. Kreatywni mogą pokusić się o bardziej zaawansowane rozwiązania, lecz do moich celów w zupełności efekt końcowy jest zadowalający:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLNyNcGxwvnRWxrKmTKdGkkJrXbybMVWu8Ye6Duwsj2ugd90Iw73AoCjkv7Rl5f0fLWef21niwmpRINmU_v1DDzeQ_ic-AanLftQRx2Hz1YSYybDZ6s1Tr8Daa0RSIAqgcRy3DnWulMVw/s1600/rsscanal.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;163&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLNyNcGxwvnRWxrKmTKdGkkJrXbybMVWu8Ye6Duwsj2ugd90Iw73AoCjkv7Rl5f0fLWef21niwmpRINmU_v1DDzeQ_ic-AanLftQRx2Hz1YSYybDZ6s1Tr8Daa0RSIAqgcRy3DnWulMVw/s320/rsscanal.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Dla przykładu dodałem wiadomości z portalu &lt;a href=&quot;http://www.gazeta.pl/pub/rss/wiadomosci.xml&quot;&gt;Gazeta.pl&lt;/a&gt; i serwisu &lt;a href=&quot;http://www.microsoft.com/poland/rss/RssFeed.aspx?developer&quot;&gt;Microsoft&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
3. Czas przejść do bardziej zaawansowanego formularza, który będzie wyświetlał wiadomości z wprowadzonych kanałów RSS. W tym celu założymy nowy formularz &lt;b&gt;RSS &lt;/b&gt;i dodamy do niego komponenty &lt;b&gt;Tree &lt;/b&gt;i &lt;b&gt;ActiveX&amp;nbsp; &lt;/b&gt;- &lt;b&gt;Microsoft Web Broswer&lt;/b&gt;:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1ihylIHqAJsIk9QVtXknSEfRSOaWi3bsKBdLnudICKo6aS2wLCCtDnAA5J45UjIjrd-JBOZGtTg2K3VvJ8GyAEVj3hGtIe6NZ8APjMAfoizU7rD8vZMgLZaIQQVU7ncKG8sHiLKMzEu4/s1600/rss.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1ihylIHqAJsIk9QVtXknSEfRSOaWi3bsKBdLnudICKo6aS2wLCCtDnAA5J45UjIjrd-JBOZGtTg2K3VvJ8GyAEVj3hGtIe6NZ8APjMAfoizU7rD8vZMgLZaIQQVU7ncKG8sHiLKMzEu4/s1600/rss.PNG&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Komponent Tree będzie służył do wyświetlania kanałów wraz z nagłówkami wiadomości, a po kliknięciu na odpowiednią gałąź do przeglądarki zostanie załadowana strona z pełną zawartością artykułu.&lt;br /&gt;
&lt;br /&gt;
4. Pobieranie zawartości RSS w postaci pliku XML z internetu można zrealizować na dwa sposoby:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;pierwszy sposób za to pobieranie pliku pomocą klasy WiniInet, która już nie występuje w AX2009: &lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;private XmlDocument getRssXmlOld(str url)
{
    XmlDocument rss;
    WinInet inet;
    int handle;
    TextBuffer textBuffer = new TextBuffer();

    ;

    // pobieramy xml&#39;a
    inet = new WinInet();
    handle = inet.internetOpenUrl(url);

    textBuffer.appendText(inet.internetReadFile(handle));
    inet.internetCloseHandle(handle);

    // wczytujemy do XmlDocument
    rss = new XmlDocument();
    rss.loadXml(textBuffer.getText());

    return rss;
}&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;drugi sposób to pobranie pliku za pomocą klas .NET - działa pod AX 4 i 5: &lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;private XmlDocument getRssXml(str url)
{
    XmlDocument rss;
    TextBuffer textBuffer = new TextBuffer();
    System.Net.WebRequest webrequest;
    System.Net.HttpWebResponse httpresponse;
    System.IO.Stream stream;
    System.IO.StreamReader streamReader;
    str string;
    ;

    webrequest = System.Net.WebRequest::Create(url);
    httpresponse = webrequest.GetResponse();

    stream = httpresponse.GetResponseStream ();
    streamReader = new System.IO.StreamReader (stream);

    string = streamReader.ReadToEnd ();

    streamReader.Close();
    stream.Close();
    httpResponse.Close();

    textBuffer.appendText(string);
    // wczytujemy do XmlDocument
    rss = new XmlDocument();
    rss.loadXml(textBuffer.getText());

    return rss;
}&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;5. Kolejnym etapem jest wypełnienie naszego komponentu &lt;b&gt;Tree&lt;/b&gt; nagłówkami kanałów:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot;&gt;void setTree()
{
    FormTreeItem rssAddress;
    FormTreeItem header;
    XmlDocument rss;
    XmlNode root;
    XmlNodeList headerList;
    XmlNode message;
    XmlNode quickMessage;
    XmlNode title;
    XmlNode link;

    int i, j, nodeIndex;

    ;

    while select rssTable where rssTable.UserID == curUserID()
    {
        // pobieramy listę wiadomości z kanału rss
        root = this.getRssXml(rssTable.url).documentElement();

        try
        {
            if (root != null)
            {
                headerList = root.selectNodes(&quot;//item//link&quot;);
                rssAddress = new FormTreeItem(rssTable.Name, 0, headerList.length(), &quot;&quot;);
                nodeIndex = tree.addItem(0 ,0, rssAddress);

                for ( i =0; i &amp;lt; headerList.length(); i++)
                {
                    title = headerList.item(i).selectSingleNode(strfmt(&quot;//item[link=&#39;%1&#39;]//title&quot;, headerList.item(i).text()));
                    link = headerList.item(i).selectSingleNode(strfmt(&quot;//item[link=&#39;%1&#39;]//link&quot;, headerList.item(i).text()));
                    header = new FormTreeItem(title.text(), 0, 0,link.text());

                    tree.addItem(nodeIndex, i, header);

                }
             }
         }
         catch
         {
            error(&quot;Wystąpił błąd tworzenia drzewa.&quot;);
         }
    }
}&lt;/pre&gt;&lt;br /&gt;
Aby zrozumieć szerzej powyższą funkcję należałoby zrozumieć budowę pliku XML i polecenia XPath. Do tego celu polecam ciekawe lektury mojego ulubionego wydawnictwa:&lt;br /&gt;
&lt;div style=&quot;display:table;width:100%;&quot;&gt;&lt;div style=&quot;display:table-row;&quot;&gt;&lt;div style=&quot;display:table-cell;padding-left:10%;width:50%;&quot;&gt;&lt;script src=&quot;http://helion.pl/plugins/new/ksiazkasm.phi?id=xmlnap&amp;amp;nr=5094w&amp;amp;double=double&quot;&gt;
&lt;/script&gt;&lt;/div&gt;&lt;div style=&quot;display:table-cell;padding-left:10%;width:50%;&quot;&gt;&lt;script src=&quot;http://helion.pl/plugins/new/ksiazkasm.phi?id=ppxml&amp;amp;nr=5094w&amp;amp;double=double&quot;&gt;
&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;6. Aby zrealizować otwieranie strony w przeglądarce po wybraniu nagłówka, należy przeciążyć metodę &lt;b&gt;selectionChange &lt;/b&gt;na komponencie &lt;b&gt;Tree&lt;/b&gt;: &lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;public void selectionChanged(FormTreeItem _OldItem, FormTreeItem _NewItem, FormTreeSelect _how)
{
   super(_OldItem, _NewItem, _how);

   if (_newItem.data() != &quot;&quot;)
   {
        ActiveX.Navigate(_newItem.data());
   }

}&lt;/pre&gt;7. Ostatnim etapem jest dodanie wywołania metody &lt;b&gt;setTree &lt;/b&gt;do przeciążonej metody run na formularzu: &lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;public void run()
{
    this.setTree();
    super();
}
&lt;/pre&gt;&lt;br /&gt;
Tak wygląda&lt;b&gt; czytnik RSS &lt;/b&gt;dla &lt;b&gt;Dynamics AX&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXxl_BhNqvd3oBTj-OUtQ9xTZrNMnpLUQ7kHuJmGacevaYRRefBFYYDw0uJcT2tIwcvED112BohFyU2FVqqtZkwsQctCw8LNJ9abh4EvelhHam7YfvF-XIrGTaiopWVbBNbK1NfKFMgeo/s1600/rssreader.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;181&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXxl_BhNqvd3oBTj-OUtQ9xTZrNMnpLUQ7kHuJmGacevaYRRefBFYYDw0uJcT2tIwcvED112BohFyU2FVqqtZkwsQctCw8LNJ9abh4EvelhHam7YfvF-XIrGTaiopWVbBNbK1NfKFMgeo/s320/rssreader.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Teraz kiedy szef patrzy możemy oglądać wiadomości w DAX ;)</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/7486676926616405189/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/12/dynamics-ax-czytnik-rss.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/7486676926616405189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/7486676926616405189'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/12/dynamics-ax-czytnik-rss.html' title='Dynamics AX: Czytnik RSS'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8L9dpFDRKVRVV4snPjQ93CtYzw6mO6bP3DA1FjQVQwsSN1AIwTJ1pocUqsJwDLypOp8Z5P6qSSpRvvVKEwj-8ZvM6eErSWOm_hBAL0prt1BW24ohjaXWKsJv_jmpwcG0ynLJRCbenxxE/s72-c/rsstable.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-5817521479527772527</id><published>2010-12-02T16:12:00.002+01:00</published><updated>2011-09-15T12:24:01.853+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="nip"/><category scheme="http://www.blogger.com/atom/ns#" term="walidacja"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Walidacja NIP</title><content type='html'>W kolejnym artykule dotyczącym systemu &lt;b&gt;Dynamics AX&lt;/b&gt; (Axapta) postaram przedstawić budowę brakującej cegiełki systemu w lokalizacji polskiej. Jakież było moje zdziwienie, kiedy zobaczyłem, że w systemie ERP sprzedawanym na polskim rynku nie ma walidacji podstawowego numeru wykorzystywanego w celu identyfikacji podatkowej - &lt;b&gt;NIP&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Jest jednak na to rada. W DAX istnieje klasa o nazwie &lt;b&gt;TaxVATNumValidate&lt;/b&gt;, która posiada klasy potomne dla poszczególnych krajów (Polski brak). W celu zlokalizowania weryfikatora należy utworzyć klasę TaxVATNumValidatePL:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;class TaxVATNumValidatePL extends TaxVATNumValidate
{

}&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
następnie przeciążyć metodę &lt;b&gt;validateVATNum&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;// implementacja w x++ wg ogolnodostepnych algorytmow
boolean validateVATNum(VATNum _VATNum)
{
    int idx;
    int w[9];
    int wk;
    int i;
    int k;
    int len = strlen(VATNum);
    ;

    if (len &amp;amp;&amp;amp; !(len &amp;lt; 10 || len &amp;gt; 13))
    {
 
        while(strfind(_VATNum, &#39;-&#39;, 1, strlen(_VATNum)))
        {
            idx = strfind(_VATNum, &#39;-&#39;, 1, strlen(_VATNum));
            nip = strdel(_VATNum, idx, 1);
        }

         if(_VATNum == &quot;&quot;)
            return false;

        //obliczamy sume kontrolna
        w[1] = 6;
        w[2] = 5;
        w[3] = 7;
        w[4] = 2;
        w[5] = 3;
        w[6] = 4;
        w[7] = 5;
        w[8] = 6;
        w[9] = 7;

        wk = 0;

        for (i = 1; i &amp;lt;= 9; i++)
        {
            wk = (wk + str2int(substr(_VATNum, i, 1)) * w[i]) mod 11;
        }
        k = wk mod 11;
        
        if (str2int(substr(_VATNum, 10, 1)) == k) 
            return true;

    }

    return false;
    
}
&lt;/pre&gt;&lt;br /&gt;
Metoda walidująca już jest. Teraz trzeba spowodować, żeby była wykorzystywana przez Dynamicsa. W tym celu zaingerujemy w klasę bazową &lt;b&gt;TaxVATNumValidate &lt;/b&gt;i metodę construct. Należy tam dodać wywołanie nowo stworzonej klasy, kiedy krajem walidacji będzie Polska: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;// ...
case #isoPL :
   taxVATNumValidate = new TaxVATnumValidatePL();
   break;
// ...
&lt;/pre&gt;&lt;br /&gt;
Ostatnim etapem jest włączenie walidacji. Należy wejść w Podstawowe =&amp;gt; Ustawienia =&amp;gt; Adresy =&amp;gt; Kraj / Region, wybrać kraj PL i na zakładce Ogólne zaznaczyć opcję &quot;Sprawdź numer identyfikacji podatkowej&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilfPifKpf-pDcqLtofS2hnzI9tIv7msYvDVO4vM9CqlhEI3DhKHyXbRlNM3d26aN9gFTi7qSLrrf-9RdOrPZW5Jdlcqq0ujrxK1H6XZvw4gV6q5ryRzRuUZaUPCVKHVv3i2VIJ5SE2ZSA/s1600/nip-coountry-region.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;146&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilfPifKpf-pDcqLtofS2hnzI9tIv7msYvDVO4vM9CqlhEI3DhKHyXbRlNM3d26aN9gFTi7qSLrrf-9RdOrPZW5Jdlcqq0ujrxK1H6XZvw4gV6q5ryRzRuUZaUPCVKHVv3i2VIJ5SE2ZSA/s320/nip-coountry-region.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Od tego momentu możemy się cieszyć sprawdzaniem numeru NIP w &quot;polskich warunkach&quot; :)</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/5817521479527772527/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/12/dynamics-ax-walidacja-nip.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/5817521479527772527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/5817521479527772527'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/12/dynamics-ax-walidacja-nip.html' title='Dynamics AX: Walidacja NIP'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilfPifKpf-pDcqLtofS2hnzI9tIv7msYvDVO4vM9CqlhEI3DhKHyXbRlNM3d26aN9gFTi7qSLrrf-9RdOrPZW5Jdlcqq0ujrxK1H6XZvw4gV6q5ryRzRuUZaUPCVKHVv3i2VIJ5SE2ZSA/s72-c/nip-coountry-region.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-5576434659060966327</id><published>2010-11-30T16:13:00.001+01:00</published><updated>2010-12-11T23:35:25.996+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="action script"/><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="flash"/><category scheme="http://www.blogger.com/atom/ns#" term="flex"/><category scheme="http://www.blogger.com/atom/ns#" term="GIS"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Mapa Google do sprawdzania lokalizacji odbiorców - tutorial cz. 2</title><content type='html'>W &lt;b&gt;drugiej &lt;/b&gt;części tutoriala pokażę, jak zintegrować komponent Flash z systemem Microsoft Dynamics AX (przykład zademonstruję na wersji 4.0, ale z powodzeniem można go zastosować do nowszych wersji).&lt;br /&gt;
&lt;br /&gt;
Jeśli pominąłeś część pierwszą, a chcesz zacząć od początku to zapraszam &lt;a href=&quot;http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania.html&quot;&gt;tutaj&lt;/a&gt;. &lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
6. Rozpoczniemy od założenia w &lt;b&gt;Dynamics AX&lt;/b&gt; nowego projektu i dodania do niego formularza Odbiorców (&lt;b&gt;CustTable&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoqfX_Azm21nQxQZtlkhsLAGqDV6mDZbroHdFpDjqACa6Q_B-Cx5HVtkUphQdIUqYkmtafROq2MgiaFgYbTaTx8it7yO4NgjxLkbnnuDODTEaPaHF1O1FHRT5qRiJuDL88IYjbTEWm42k/s1600/dax-new-project.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;301&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoqfX_Azm21nQxQZtlkhsLAGqDV6mDZbroHdFpDjqACa6Q_B-Cx5HVtkUphQdIUqYkmtafROq2MgiaFgYbTaTx8it7yO4NgjxLkbnnuDODTEaPaHF1O1FHRT5qRiJuDL88IYjbTEWm42k/s320/dax-new-project.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
7. Do formularza odbiorców na zakładce &quot;&lt;b&gt;Adres&lt;/b&gt;&quot; ( Tab=&amp;gt; TabAddress) dodajemy nową grupę - nazwijmy ją &lt;b&gt;GoogleGroup&lt;/b&gt;. Następnie w grupie tej dodajemy komponent ActiveX i na liście dostępnych komponentów wybieramy &lt;b&gt;Shockwave Flash Object&lt;/b&gt; (jeśli nie ma go na tej liście, musimy zadbać o to, żeby się tam znalazł :) )&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj94YGWDgrnVGL2uT7h_YyfoFrnqqK0JUg3PiPvSFWSpXbLU7dvjN05FjFEcti-5IED_gvRH3zlaHBpQIQ_ulh8ItuXCpR9v-a8KzZs1stMXeG9N1XmWYkZ46cYetmBxOCF5Cz7MbV-Gzs/s1600/add-new-activex-component.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;152&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj94YGWDgrnVGL2uT7h_YyfoFrnqqK0JUg3PiPvSFWSpXbLU7dvjN05FjFEcti-5IED_gvRH3zlaHBpQIQ_ulh8ItuXCpR9v-a8KzZs1stMXeG9N1XmWYkZ46cYetmBxOCF5Cz7MbV-Gzs/s320/add-new-activex-component.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
8. Po potwierdzeniu informacji o bezpieczeństwie komponentu ActiveX, system dodaje go do drzewka. Teraz musimy wczytać w niego plik SWF, który jest wynikiem kompilacji aplikacji z poprzedniej części tutoriala. W tym celu w metodzie init na formularzu wstawiamy kod nie zapominając o zastąpieniu ścieżki do pliku *.&lt;b&gt;swf&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;ActiveX.LoadMovie(0, @&quot;C:\dokumenty\flex\projects\GoogleMapsFlex4\bin\GoogleMapsFlex4.swf&quot;);
ActiveX.GotoFrame(1);&amp;nbsp;&lt;/pre&gt;&lt;br /&gt;
Jeśli wszystko przebiegło pomyślnie wynikiem działania powinno być okienko mapy na formularzu Odbiorców w zakładce Adres:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxmGXum-6XrzEdEOUP5rKPz-5y5ZlQdMAIqHlH99Xg6fj44i3BYCHKE0hfsxU1yUsRi1H5UtivJRav_bue81a3SslwlsRbbqMUwUD6ka3XW4n35FTvlUVIbXmeltJ2LCG6lVn5PJ3NbqA/s1600/custTable1.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;128&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxmGXum-6XrzEdEOUP5rKPz-5y5ZlQdMAIqHlH99Xg6fj44i3BYCHKE0hfsxU1yUsRi1H5UtivJRav_bue81a3SslwlsRbbqMUwUD6ka3XW4n35FTvlUVIbXmeltJ2LCG6lVn5PJ3NbqA/s320/custTable1.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
9. Jak widać domyślnie wyświetlanym adresem jest Warszawa, al. Jerozolimskie - z aplikacji Flexowej należy usunąć kod wstawiony w poprzedniej części do celów testowych. Zmniejsza to niepotrzebnie limit ilości geokodowań. Z tego też tytułu zamiast automatycznie wczytywać mapę dla każdego klienta wraz z każdym rekordem (ActiveRecord), użyjemy przycisku do odszukiwania adresu. Przycisk najlepiej dodać w tej samej grupie. W metodzie &lt;b&gt;clicked &lt;/b&gt;wstawiamy następujący kod: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;void clicked()
{
    super();
    ActiveX.CallFunction(strfmt(&quot;&amp;lt;invoke name=\&quot;doGeocode\&quot; returntype=\&quot;xml\&quot;&amp;gt;&amp;lt;arguments&amp;gt;&amp;lt;string&amp;gt;%1&amp;lt;/string&amp;gt;&amp;lt;/arguments&amp;gt;&amp;lt;/invoke&amp;gt;&quot;,custTable.Address));
}
&lt;/pre&gt;&lt;br /&gt;
Wywoływana jest tutaj funkcja &lt;b&gt;doGeocode&lt;/b&gt; i przekazywany jest do niej adres. Argumentem funkcji &lt;b&gt;CallFunction &lt;/b&gt;jest łańcuch znaków w postaci XML.&lt;br /&gt;
&lt;br /&gt;
Próba generalna kończy się jednak błędem:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TXOJImm_MZTpaCxxJpU2PQ3AmRIX-GvNFWnny2QM8B2_w6rAfl-cP-bnwcwQQ4w2xansswGbMOkSBLfT9KD0X2o9UfHZlnDC2ffVVf3Gq9vvGDyv3ifj_ix6yn36rwElVlkOk_LOwQk/s1600/error.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;236&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_TXOJImm_MZTpaCxxJpU2PQ3AmRIX-GvNFWnny2QM8B2_w6rAfl-cP-bnwcwQQ4w2xansswGbMOkSBLfT9KD0X2o9UfHZlnDC2ffVVf3Gq9vvGDyv3ifj_ix6yn36rwElVlkOk_LOwQk/s320/error.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;a wszystko przez to, ze w projekcie &lt;b&gt;Flexowym &lt;/b&gt;brakuje &quot;uzewnętrznienia&quot; metody &lt;b&gt;doGeocode&lt;/b&gt;. W celu publikacji tej metody należy w metodzie &lt;b&gt;init &lt;/b&gt;dodać linijkę kodu:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;ExternalInterface.addCallback(&quot;doGeocode&quot;, doGeocode);
&lt;/pre&gt;&lt;br /&gt;
Działa! :)&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;Podsumowanie&lt;/h2&gt;&lt;br /&gt;
Jak widać wstawienie interesującego komponentu Flash do AX jest banalnie proste. Tak zbudowaną aplikację opartą o integrację z Flashem można oczywiście rozbudowywać, np. o zwracanie współrzędnych geograficznych do tabeli CustTable i wyświetlanie adresu z pominięciem geokodowania, na który jest limit. Można też wykorzystać Flasha do urozmaicenia Dynamicsa o efektowne komponenty np. wykresy Gantta, kalendarze itp. Może macie jakieś pomysły? Czekam na komentarze.&lt;br /&gt;
&lt;br /&gt;
Zainteresowanych przeglądem możliwości komponentów w technologii Flex zapraszam na &lt;a href=&quot;http://www.adobe.com/devnet-apps/flex/tourdeflex/web/&quot;&gt;http://www.adobe.com/devnet-apps/flex/tourdeflex/web/&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/5576434659060966327/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania_30.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/5576434659060966327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/5576434659060966327'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania_30.html' title='Dynamics AX: Mapa Google do sprawdzania lokalizacji odbiorców - tutorial cz. 2'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgoqfX_Azm21nQxQZtlkhsLAGqDV6mDZbroHdFpDjqACa6Q_B-Cx5HVtkUphQdIUqYkmtafROq2MgiaFgYbTaTx8it7yO4NgjxLkbnnuDODTEaPaHF1O1FHRT5qRiJuDL88IYjbTEWm42k/s72-c/dax-new-project.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-8331819454639293124</id><published>2010-11-26T14:47:00.003+01:00</published><updated>2011-01-09T20:26:35.974+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="action script"/><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="flash"/><category scheme="http://www.blogger.com/atom/ns#" term="flex"/><category scheme="http://www.blogger.com/atom/ns#" term="GIS"/><category scheme="http://www.blogger.com/atom/ns#" term="google API"/><category scheme="http://www.blogger.com/atom/ns#" term="google maps"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Mapa Google do sprawdzania lokalizacji odbiorców - tutorial cz. 1</title><content type='html'>W tym artykule pokażę jak zintegrować system &lt;b&gt;Microsoft Dynamics AX&lt;/b&gt; z mapą &lt;b&gt;Google &lt;/b&gt;na przykładzie lokalizacji odbiorców. W części pierwszej opisana zostanie część jaką należy wykonać, aby stworzyć aplikację w technologii &lt;b&gt;Flex / Flash&lt;/b&gt;, w drugiej natomiast zajmiemy się integracją tej aplikacji w systemie &lt;b&gt;Dynamics AX&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Co nam będzie potrzebne do realizacji tego zadania?&lt;br /&gt;
&lt;br /&gt;
1. Darmowe środowisko &lt;a href=&quot;http://www.flashdevelop.org/community/viewtopic.php?f=11&amp;amp;t=7368&quot;&gt;FlashDevelop&lt;/a&gt; lub inne komercyjne środowisko programistyczne do tworzenia aplikacji w technologii Flex. Korzystając z FlashDevelopa należy pamiętać o pobraniu &lt;a href=&quot;http://opensource.adobe.com/wiki/display/flexsdk/Downloads&quot;&gt;Flex SDK&lt;/a&gt;.&lt;br /&gt;
2. &lt;a href=&quot;http://code.google.com/intl/pl/apis/maps/documentation/flash/&quot;&gt;Google Maps API for Flash&lt;/a&gt; i &lt;a href=&quot;http://code.google.com/intl/pl/apis/maps/signup.html&quot;&gt;Google Maps API Key&lt;/a&gt;&lt;br /&gt;
3. System Microsoft Dynamics AX ... :)&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;UWAGA!&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;span style=&quot;color: #990000;&quot;&gt;Jako, że Google w licencji do korzystania z Google Maps API nakazuje stosowanie swojego mechanizmu w aplikacjach łatwo dostępnych dla użytkownika końcowego, poniższy tutorial stanowi tylko pokaz możliwości integracji systemu Dynamics AX z komponentami w technologii Flash. Pozostałe wykorzystanie informacji zawartych w tym tutorialu może naruszać prawa korzystania z&amp;nbsp; licencji oprogramowania udostępnionego przez firmę Google. Dla zainteresowanych komercyjnym wykorzystaniem integracji z mapami oferowanymi przez Google istnieje płatna wersja API. Ponadto w wersji bezpłatnej istnieje limit dzienny na &lt;a href=&quot;http://pl.wikipedia.org/wiki/Geokodowanie&quot;&gt;geokodowanie&lt;/a&gt;.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
1. Na początku trzeba zainstalować i odpowiednio skonfigurować &lt;b&gt;FlashDevelopa &lt;/b&gt;do pracy. Osoby, które posiadają już to narzędzie lub korzystają z innego środowiska mogą pominąć ten punkt. Jednak początkującym adeptom sztuki programowania komponentów &lt;b&gt;Flash &lt;/b&gt;może przysporzyć nie lada problemów.&lt;br /&gt;
Jeśli masz pragnienie zapoznać się bliżej z technologią Flex polecam dwie ciekawe książki:&lt;br /&gt;
&lt;div style=&quot;display: table; width: 100%;&quot;&gt;&lt;div style=&quot;display: table-row;&quot;&gt;&lt;div style=&quot;display: table-cell; padding-left: 10%; width: 50%;&quot;&gt;&lt;script src=&quot;http://helion.pl/plugins/new/ksiazkasm.phi?id=acs3bi&amp;amp;nr=5094w&amp;amp;double=double&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;div style=&quot;display: table-cell; padding-left: 10%; width: 50%;&quot;&gt;&lt;script src=&quot;http://helion.pl/plugins/new/ksiazkasm.phi?id=fl4op1&amp;amp;nr=5094w&amp;amp;double=double&quot;&gt;&lt;/script&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;br /&gt;
Przed instalacją samego FlexDevelopa najlepiej rozpakować wcześniej &lt;b&gt;Flex SDK&lt;/b&gt;, a na chwilę pisania artykułu występuje w wersji 4.5. Po instalacji w opcjach programu w zakładce &lt;b&gt;AS3Context&amp;nbsp; &lt;/b&gt;wskazujemy ścieżkę do zainstalowanego frameworka:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNYFwXSONrT5lkQ8Gtl0LCJIay5tXw0U61aXB8JpnbGjt_2na7y82Q4baNUq6ouH1zddlC6VRjdaqW4QCHNOWwXoiB3l0F57Cnwxhg9epcTvG6DOuu1-wmuEV_oKisdT-cw9ilXuN3pyk/s1600/configure-flex-sdk-in-fleshdevelop.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;232&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNYFwXSONrT5lkQ8Gtl0LCJIay5tXw0U61aXB8JpnbGjt_2na7y82Q4baNUq6ouH1zddlC6VRjdaqW4QCHNOWwXoiB3l0F57Cnwxhg9epcTvG6DOuu1-wmuEV_oKisdT-cw9ilXuN3pyk/s320/configure-flex-sdk-in-fleshdevelop.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
2. W następnym kroku zakładamy nowy projekt &lt;b&gt;Flex 4 Project&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEYzpB3JTDMoTWYirIHNF3fwRaK4FwTQL_FDhVAraVmCaCtDr9Met_54NXzwtYK7GO1ULmYY6HQZjQfPUQb_R-OT-RBZ7pNSPZi3i7UXG7_hA6xXXLZUdV65iTfOI7yuCyzZ9cYPOTlFo/s1600/flashdevelop-new-project.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;278&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEYzpB3JTDMoTWYirIHNF3fwRaK4FwTQL_FDhVAraVmCaCtDr9Met_54NXzwtYK7GO1ULmYY6HQZjQfPUQb_R-OT-RBZ7pNSPZi3i7UXG7_hA6xXXLZUdV65iTfOI7yuCyzZ9cYPOTlFo/s320/flashdevelop-new-project.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
W wyniku założenia projektu powinna zostać stworzona struktura katalogów zawierająca skompilowane pliki (bin), biblioteki (lib) i źródła (src). Powinien też zostać utworzony pierwszy, główny plik źródłowy aplikacji o nazwie &quot;&lt;b&gt;Main.mxml&lt;/b&gt;&quot; zawierający podstawową strukturę aplikacji:&lt;br /&gt;
&lt;pre class=&quot;brush: xml;&quot; name=&quot;code&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;
&amp;lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
      xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
      xmlns:mx=&quot;library://ns.adobe.com/flex/mx&quot;&amp;gt;
 
 &amp;lt;fx:Declarations&amp;gt;
  &amp;lt;!-- Place non-visual elements (e.g., services, value objects) here --&amp;gt;
 &amp;lt;/fx:Declarations&amp;gt;
&amp;lt;/s:Application&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
2. W następnym kroku do projektu dodajemy bibliotekę ze ściągniętego SDK &lt;b&gt;Google Maps API for Flash&lt;/b&gt;. Plik &quot;&lt;b&gt;map_flex_1_20.swc&lt;/b&gt;&quot; najlepiej rozpakować w katalogu &lt;b&gt;lib&lt;/b&gt; projektu i z menu kontekstowego dostępnego pod prawym przyciskiem myszki zaznaczyć opcję &quot;&lt;b&gt;Add to library&lt;/b&gt;&quot;:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6xI0WbwUReCM_oziunIJ888hydgBdQjI_kOgut8NaPf8W6zNSdat7rz7lcs3ZQWjPgBTsFFdNEgeERCC1dUKBFqHT-S_6rbyATb0GT_is-xs35RzCWjTGwx4o85Rn8CdnRieP-RIlr9w/s1600/add-to-library.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6xI0WbwUReCM_oziunIJ888hydgBdQjI_kOgut8NaPf8W6zNSdat7rz7lcs3ZQWjPgBTsFFdNEgeERCC1dUKBFqHT-S_6rbyATb0GT_is-xs35RzCWjTGwx4o85Rn8CdnRieP-RIlr9w/s1600/add-to-library.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;UWAGA&lt;/b&gt;! &lt;span style=&quot;color: #990000;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;color: #990000;&quot;&gt;W Google Maps API for Flash występują dwie biblioteki: &lt;/span&gt;&lt;b style=&quot;color: #990000;&quot;&gt;map_flex_1_20.swc i &lt;/b&gt;&lt;b style=&quot;color: #990000;&quot;&gt;map_1_20.swc. &lt;/b&gt;&lt;span style=&quot;color: #990000;&quot;&gt;Tę pierwszą użyjemy w projekcie Flexowym, tą drugą można użyć jeśli robimy prezentację w typowym Flashu.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
3. Do aplikacji musimy teraz dodać komponent mapy i wyświetlić go w całym obszarze roboczym. W tym celu dodamy blok xml&#39;owy &lt;b&gt;SCRIPT&lt;/b&gt;, gdzie można zagnieździć kod w języku &lt;b&gt;Action Script 3 &lt;/b&gt;wewnątrz dokumentu &lt;b&gt;MXML&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:xml;&quot; name=&quot;code&quot;&gt;&amp;lt;fx:Script&amp;gt;
   &amp;lt;![CDATA[  
                 
   ]]&amp;gt;
&amp;lt;/fx:Script&amp;gt;
&lt;/pre&gt;&lt;br /&gt;
Następnie dodamy funkcję w języku &lt;b&gt;ActionScript3&lt;/b&gt;, która będzie wywołana na początku działania aplikacji:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;import com.google.maps.Map;
private var map:Map;

public function init():void
{
   map = new Map();
   map.key = &quot;KLUCZ_GOOGLE_MAPS_API&quot;;
   map.height = this.height;
   map.width = this.width;
   map.addEventListener(MapEvent.MAP_READY, onMapReady);
   this.addElement(map);
}&lt;/pre&gt;&lt;br /&gt;
oraz funkcję, która uruchomi się po pełnym wczytaniu obiektu &lt;b&gt;map&lt;/b&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;private function onMapReady(event:Event):void {
   map.enableScrollWheelZoom();
   map.enableContinuousZoom();
   map.addControl(new ZoomControl());
}
&lt;/pre&gt;Przed deklaracją funkcji &lt;b&gt;init &lt;/b&gt;należy dokonać dołączenia biblioteki z &lt;b&gt;Google Maps&lt;/b&gt; poleceniem &lt;b&gt;import&lt;/b&gt;.&lt;br /&gt;
Funkcja &lt;b&gt;init&lt;/b&gt; inicjuje obiekt &lt;b&gt;Map&lt;/b&gt; i przypisuje mu klucz, który należy pobrać na stronie &lt;b&gt;Google Maps API&lt;/b&gt;. Następnie ustalane są rozmiary tego komponentu do rozmiarów okna aplikacji i dodawana jest obsługa zdarzenia &lt;b&gt;MapEvent.MAP_READY&lt;/b&gt;. Metodą &lt;b&gt;addElement &lt;/b&gt;dodawany jest ten komponent do kontenera aplikacji. Aby metoda init zadziałała potrzebne jest jeszcze zdefiniowanie zdarzenia &lt;b&gt;creationComplete &lt;/b&gt;w drugiej linijce kodu:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:xml;&quot; name=&quot;code&quot;&gt;&amp;lt;s:Application xmlns:fx=&quot;http://ns.adobe.com/mxml/2009&quot;
      xmlns:s=&quot;library://ns.adobe.com/flex/spark&quot;
      xmlns:mx=&quot;library://ns.adobe.com/flex/mx&quot; creationComplete=&quot;init()&quot;  &amp;gt;
&lt;/pre&gt;&lt;br /&gt;
W funkcjo onMapReady włączana jest możliwość korzystania ze scrolla wbudowanego w myszkę oraz dodawana jest możliwość powiększania i pomniejszania mapy wraz z kontrolką &lt;b&gt;ZoomControl&lt;/b&gt;.&lt;br /&gt;
&lt;br /&gt;
Tak skonstruowana aplikacja &lt;b&gt;Flexowa &lt;/b&gt;powinna nam się skompilować i uruchomić. Jeśli jednak wystąpiły problemy proponuję jeszcze wspomóc się tymi linkami:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt; &lt;a href=&quot;http://groups.google.com/group/google-maps-api-for-flash/browse_thread/thread/952dfbde3deb7865/f06623a03ba664e8?pli=1&quot;&gt;http://groups.google.com/group/google-maps-api-for-flash/browse_thread/thread/952dfbde3deb7865/f06623a03ba664e8?pli=1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/intl/pl/apis/maps/documentation/flash/tutorial-flex.html#DeclaringMaps&quot;&gt;http://code.google.com/intl/pl/apis/maps/documentation/flash/tutorial-flex.html#DeclaringMaps&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.jamesrichards.com/post/2009/09/30/Use-Open-Source-FlashDevelop-IDE-with-Google-Maps-API-for-Flash.aspx&quot;&gt;http://www.jamesrichards.com/post/2009/09/30/Use-Open-Source-FlashDevelop-IDE-with-Google-Maps-API-for-Flash.aspx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.flashdevelop.org/community/viewtopic.php?f=9&amp;amp;t=4101&quot;&gt;http://www.flashdevelop.org/community/viewtopic.php?f=9&amp;amp;t=4101&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;Na wyjściu powinniśmy ujrzeć taką mapę:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-POBPckziaIx3rgavH65d4a7_GTnSwR9NbhyD24P6em5E7jkLS0xmjxkeJmj_EMOahz3YeYbl6XTwKl7qKTHiGoeZAiUjixWMylbHSwmJERGNuXRSuX1dBj77J9vQ56x_qM33B49rdQ/s1600/mapaGoogle.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;184&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA-POBPckziaIx3rgavH65d4a7_GTnSwR9NbhyD24P6em5E7jkLS0xmjxkeJmj_EMOahz3YeYbl6XTwKl7qKTHiGoeZAiUjixWMylbHSwmJERGNuXRSuX1dBj77J9vQ56x_qM33B49rdQ/s320/mapaGoogle.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Na ekranie widać, że komponent sugeruje byśmy uzupełnili właściwość &lt;b&gt;sensor&lt;/b&gt;. Jeśli chcemy wykorzystywać mapy Google do śledzenia za pomocą odbiorników &lt;b&gt;GPS&lt;/b&gt;, właściwość tą ustawiamy na TRUE, jeśli nie to FALSE. Niestety nie jest dla mnie zrozumiałe, dlaczego akurat ta właściwość jest typu &lt;b&gt;String&lt;/b&gt;, a nie &lt;b&gt;Boolean&lt;/b&gt;, no ale nie wymagajmy od Google cudów ;), w końcu dwa dodatkowe cudzysłowy i błąd kompilacji to jeszcze nie koniec świata:&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;map.sensor = &#39;false&#39;;
&lt;/pre&gt;&lt;br /&gt;
4. Czas na funkcję geokodującą, czyli zamieniającą dane adresowe na współrzędne. Warto tutaj jeszcze raz przypomnieć, że w darmowej wersji Google nakłada ograniczenia na geokodowanie w ilości 1000 zapytań w ciągu dnia. Przed dodaniem odpowiednich funkcji musimy dołączyć (zaimportować) referencje do odpowiednich klas, których użyjemy:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;import com.google.maps.overlays.Marker;
import com.google.maps.services.ClientGeocoder;
import com.google.maps.services.GeocodingEvent;
import com.google.maps.MapMouseEvent;
import com.google.maps.MapType;
import com.google.maps.InfoWindowOptions; 
import com.google.maps.controls.ZoomControl;
import mx.controls.Alert;
&lt;/pre&gt;&lt;br /&gt;
Następnie dodajemy dwie metody doGeocode i geocodeSuccess:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;private function doGeocode(address:String):void
  {
   var geocoder:ClientGeocoder = new ClientGeocoder();

   // obsługa sukcesu geokodowania
   geocoder.addEventListener(GeocodingEvent.GEOCODING_SUCCESS, geocodeSuccess);

   // obsługa błędu geokodowania
   geocoder.addEventListener(
     GeocodingEvent.GEOCODING_FAILURE,
     function(event:GeocodingEvent):void {
    Alert.show(&quot;Geocoding failed&quot;);
     });
     
   // uruchomienie funkcji geokodującej
   geocoder.geocode(address);
  }
   
  private function geocodeSuccess(event:GeocodingEvent):void
  {
    var placemarks:Array = event.response.placemarks;
    if (placemarks.length &amp;gt; 0) {
   map.setCenter(placemarks[0].point, 14, MapType.NORMAL_MAP_TYPE);
   var marker:Marker = new Marker(placemarks[0].point);
   
   marker.addEventListener(MapMouseEvent.CLICK, function (event:MapMouseEvent):void {
    marker.openInfoWindow(new InfoWindowOptions({content: placemarks[0].address}));
   });
   map.addOverlay(marker);
    }
  }
&lt;/pre&gt;&lt;br /&gt;
5. Na koniec części pierwszej tutoriala, możemy sprawdzić jak działa geokodowanie. Dla takich testów w metodzie onMapReady wprowadzimy przykład użycia metody doGeocode:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:c-sharp;&quot; name=&quot;code&quot;&gt;private function onMapReady(event:MapEvent):void {
 map.enableScrollWheelZoom();
 map.enableContinuousZoom();
 map.addControl(new ZoomControl());
    
 this.doGeocode(&quot;Warszawa, ul. Aleje Jerozolimskie&quot;);
}
&lt;/pre&gt;&lt;br /&gt;
A taki jest wynik po skompilowaniu i uruchomieniu aplikacji:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAkAT7008-aJG0nlL2LPz3cenfeCyBmGidjlWIAy4mr93HgcMAAVe2gDS_lrRlMciRoBo5Pgl9PLMy4Pok0x-5lYH7bmgk_CpkI0lB6f8n29AZrcZv7oPdWc0RJKk4MgZ85-qwYpn06kM/s1600/mapaGoogle2.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;183&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiAkAT7008-aJG0nlL2LPz3cenfeCyBmGidjlWIAy4mr93HgcMAAVe2gDS_lrRlMciRoBo5Pgl9PLMy4Pok0x-5lYH7bmgk_CpkI0lB6f8n29AZrcZv7oPdWc0RJKk4MgZ85-qwYpn06kM/s320/mapaGoogle2.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
Koniec części 1. &lt;a href=&quot;http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania_30.html&quot;&gt;Część 2.&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/8331819454639293124/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8331819454639293124'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8331819454639293124'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-mapa-google-do-sprawdzania.html' title='Dynamics AX: Mapa Google do sprawdzania lokalizacji odbiorców - tutorial cz. 1'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNYFwXSONrT5lkQ8Gtl0LCJIay5tXw0U61aXB8JpnbGjt_2na7y82Q4baNUq6ouH1zddlC6VRjdaqW4QCHNOWwXoiB3l0F57Cnwxhg9epcTvG6DOuu1-wmuEV_oKisdT-cw9ilXuN3pyk/s72-c/configure-flex-sdk-in-fleshdevelop.PNG" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-2969602700005470075</id><published>2010-11-26T12:37:00.002+01:00</published><updated>2011-01-09T21:08:31.367+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="breakpoint"/><category scheme="http://www.blogger.com/atom/ns#" term="clicked"/><category scheme="http://www.blogger.com/atom/ns#" term="debugger"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Debugowanie metody clicked</title><content type='html'>Wielu programistów &lt;b&gt;X++&lt;/b&gt; myśli, że nie jest możliwe debugowanie metod zdarzeniowych np. w metodach &lt;b&gt;clicked&lt;/b&gt;. Są w błędzie :) Dzięki koledze &lt;a href=&quot;http://lisowski-michal.pl/&quot;&gt;Michałowi Lisowskiemu&lt;/a&gt; dowiedziałem się, że jednak jest to wykonalne:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;void  clicked()
{
    breakpoint;
    // ... action
}
&lt;/pre&gt;&lt;br /&gt;
Dzięki słowu kluczowemu &quot;&lt;b&gt;breakpoint&lt;/b&gt;&quot; jest uruchamiany debugger.&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Tematycznie polecam:&lt;br /&gt;
&lt;script src=&quot;http://helion.pl/plugins/new/ksiazkasm.phi?id=debugo&amp;amp;nr=5094w&amp;amp;double=double&quot;&gt;
&lt;/script&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/2969602700005470075/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-debugowanie-metody-clicked.html#comment-form' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/2969602700005470075'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/2969602700005470075'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-debugowanie-metody-clicked.html' title='Dynamics AX: Debugowanie metody clicked'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-8818036352822044839</id><published>2010-11-26T10:42:00.000+01:00</published><updated>2010-12-01T21:14:46.889+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term=".NET"/><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="CSV"/><category scheme="http://www.blogger.com/atom/ns#" term="CultureInfo"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="EXCEL"/><category scheme="http://www.blogger.com/atom/ns#" term="NumberFormatInfo"/><category scheme="http://www.blogger.com/atom/ns#" term="separator dziesiętny"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><category scheme="http://www.blogger.com/atom/ns#" term="XLS"/><title type='text'>Dynamics AX: Odczytywanie separatora dziesiętnego</title><content type='html'>W kolejnym poście, tym razem krótkim, przedstawię jak pobrać separator dziesiętny z ustawień systemowych. Często przy imporcie/eksporcie plików &lt;b&gt;CSV &lt;/b&gt;lub &lt;b&gt;XLS &lt;/b&gt;występuje problem odpowiedniej konwersji liczb typu &lt;b&gt;real&lt;/b&gt;. Oto kod, który za pomocą klas &lt;b&gt;.NET&lt;/b&gt; wyciąga separator:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;System.Globalization.CultureInfo ci = System.Globalization.CultureInfo::get_CurrentCulture();
System.Globalization.NumberFormatInfo ni;
str systemDecimalSeparator 
;
 
ni = ci.get_NumberFormat();
systemDecimalSeparator = any2str(CLRInterop::getAnyTypeForObject(ni.get_CurrencyDecimalSeparator()));
&lt;/pre&gt;&lt;br /&gt;
Zmienną &lt;b&gt;systemDecimalSeparator &lt;/b&gt;możemy użyć do konwersji przed zapisem lub odczytem liczb w plikach tekstowych lub w &lt;b&gt;Excelu&lt;/b&gt;.</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/8818036352822044839/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-odczytywanie-separatora.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8818036352822044839'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8818036352822044839'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-odczytywanie-separatora.html' title='Dynamics AX: Odczytywanie separatora dziesiętnego'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-8392000364222091563</id><published>2010-11-25T12:47:00.001+01:00</published><updated>2010-12-11T23:37:08.782+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="numerator"/><category scheme="http://www.blogger.com/atom/ns#" term="NumSeqReference"/><category scheme="http://www.blogger.com/atom/ns#" term="tutorial"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Numerator - tutorial</title><content type='html'>Numerator w systemie&lt;b&gt; Dynamics AX&lt;/b&gt; doświadczonemu programiście nietrudno dodać, lecz często przy natłoku zadań można zapomnieć co gdzie jeszcze dodać, żeby od razu działało jak należy :) Ten tutorial ma w tym pomóc. Do dzieła!&lt;br /&gt;
&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
1. Dodajemy typ rozszerzony (&lt;b&gt;string&lt;/b&gt;) i dziedziczymy po typie &lt;b&gt;Num &lt;/b&gt;(właściwość Extends):&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNnxoznBoEEnUo6WF0sRCPORKygDcHs4_hR7fq_FQpzbm9KLIXZfp_vqLANVNLMTIz0vOSFULxPJyTOfbLDBtKwkcoDO9OOsWEMn0odnWKNZSbEZMaR6PLmZj4AYcZ5hR-SiGDnoSwX3M/s1600/create-extended-data-type.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;155&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNnxoznBoEEnUo6WF0sRCPORKygDcHs4_hR7fq_FQpzbm9KLIXZfp_vqLANVNLMTIz0vOSFULxPJyTOfbLDBtKwkcoDO9OOsWEMn0odnWKNZSbEZMaR6PLmZj4AYcZ5hR-SiGDnoSwX3M/s320/create-extended-data-type.png&quot; width=&quot;320&quot; /&gt;&amp;nbsp;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;2. Do tabeli, gdzie chcemy użyć&amp;nbsp; numeratora dodajemy pole o typie utworzonym w pkt. 1:&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWwuX9IoOSv0unkZntZnTtGz8wIkoy6mFyuP1gljwTsl4wERXh5BBFjfpSHDwJs8Ky38_4tKXVAmRJFEW7wFFl2aSGS_K_mTKjkmAy_XRxeaPeAXXxOuDhVkrDBLsfdezCZ6waP_L-qkU/s1600/create-field-in-table.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;170&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWwuX9IoOSv0unkZntZnTtGz8wIkoy6mFyuP1gljwTsl4wERXh5BBFjfpSHDwJs8Ky38_4tKXVAmRJFEW7wFFl2aSGS_K_mTKjkmAy_XRxeaPeAXXxOuDhVkrDBLsfdezCZ6waP_L-qkU/s320/create-field-in-table.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;&lt;/div&gt;3.W typie rozszerzonym należy zdefiniować relację do tabeli głównej numeratora.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCuICtMPzWPNV1AUaktjE4uahwLeOAESDrYvFOfKPXQO8kWUiDefAPIGccFyWiSinv1UJVRwqgTkmauuAiZiNEiWUcSIgoVDaGP5fkn40OfwqKlgD7H3tNSGDFNZP-eQBAt2ITmSbIKw/s1600/create-relation-in-extended-data-type.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;117&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiNCuICtMPzWPNV1AUaktjE4uahwLeOAESDrYvFOfKPXQO8kWUiDefAPIGccFyWiSinv1UJVRwqgTkmauuAiZiNEiWUcSIgoVDaGP5fkn40OfwqKlgD7H3tNSGDFNZP-eQBAt2ITmSbIKw/s320/create-relation-in-extended-data-type.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
4. Następnie w jednej z klas dziedziczących po klasie &lt;b&gt;NumSeqReference &lt;/b&gt;należy w metodzie &lt;b&gt;loadModule&lt;/b&gt; wstawić kawałek kodu rejestrującego numerator nie zapominając zmienić nazwy na swój numerator i etykiety:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;numRef.DataTypeId = typeId2ExtendedTypeId(typeid(DevIndexId)); // tutaj nazwa rozszerzonego typu
        numRef.ReferenceHelp = literalstr(&quot;@etykieta&quot;); // należy wybrać etykietę dla numeratora
        numRef.WizardContinuous = false;
        numRef.WizardManual = NoYes::No;
        numRef.WizardAllowChangeDown = NoYes::No;
        numRef.WizardAllowChangeUp = NoYes::No;
        numRef.WizardHighest = 99999999;
        numRef.SortField = 1;
        
        this.create(numRef);
&lt;/pre&gt;&lt;br /&gt;
Klasę dziedziczącą po &lt;b&gt;NumSeqReference &lt;/b&gt;należy wybrać wg swojego zastosowania. Np. numerator dotyczący klientów znajdzie się w klasie &lt;b&gt;NumberSeqReference_Customer&lt;/b&gt;. Można też oczywiście stworzyć swoją klasę dla swojego modułu.&lt;br /&gt;
&lt;br /&gt;
5. W tabeli parametrów modułu (np. &lt;b&gt;CustParameters&lt;/b&gt;), w którym wstawiamy numerator należy zdefiniować nową metodę:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;server static NumberSequenceReference numRefDevIndexId)
 {
  ;
  return NumberSeqReference::findReference(typeId2ExtendedTypeId(typeid(DevIndexId)));
 }
&lt;/pre&gt;&lt;br /&gt;
6. W formularzu &lt;b&gt;Podstawowe &lt;/b&gt;=&amp;gt; &lt;b&gt;Ustawienia &lt;/b&gt;=&amp;gt; &lt;b&gt;Sekwencje numerów&lt;/b&gt; (&lt;b&gt;identyfikatorów&lt;/b&gt;) =&amp;gt; &lt;b&gt;Sekwencje numerów&lt;/b&gt; (lub w AX2009&lt;b&gt; identyfikatorów&lt;/b&gt;)&lt;b&gt; - &lt;/b&gt;należy dodać nowy numerator:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjApDwAMCK4L2OIhy71bHCJSx4wJaqeJfL4-iIBazfZcfQiPIZGG-AoU6dykMvToOOZh-EUdU-YTjDPFoIJQCV4E1uAUGXK9WuSBddMUQxWGS_mslw7i4eEY8mMB67C0Ttaleh7CGSoPx8/s1600/create-num-seq-code.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;79&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjApDwAMCK4L2OIhy71bHCJSx4wJaqeJfL4-iIBazfZcfQiPIZGG-AoU6dykMvToOOZh-EUdU-YTjDPFoIJQCV4E1uAUGXK9WuSBddMUQxWGS_mslw7i4eEY8mMB67C0Ttaleh7CGSoPx8/s320/create-num-seq-code.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&amp;nbsp;7. W &lt;b&gt;Podstawowe &lt;/b&gt;=&amp;gt; &lt;b&gt;Ustawienia &lt;/b&gt;=&amp;gt; &lt;b&gt;Sekwencje numerów&lt;/b&gt; (&lt;b&gt;identyfikatorów&lt;/b&gt;) =&amp;gt; &lt;b&gt;Odwołania &lt;/b&gt;- należy znaleźć nowo dodane odwołanie i przypisać numerator stworzony w poprzednim punkcie. W moim przypadku numerator będzie się znajdował w module &quot;&lt;b&gt;Rozrachunki z odbiorcami&lt;/b&gt;&quot; i będzie posiadał etykietę &quot;@etykieta&quot;: &lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWbtJQySl8PuB0BAUGS624UkxVIg4Sd_z7_ZqX0fekr8tkRekc6VwL6V0WUcn1VNNeUpRUllSGELxaVU_zjGgWL5li1To0jH0brexZ_VEqGaSo1bfiUwmx1BDMp1NasViz18EXJzKAtYk/s1600/create-reference.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;187&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWbtJQySl8PuB0BAUGS624UkxVIg4Sd_z7_ZqX0fekr8tkRekc6VwL6V0WUcn1VNNeUpRUllSGELxaVU_zjGgWL5li1To0jH0brexZ_VEqGaSo1bfiUwmx1BDMp1NasViz18EXJzKAtYk/s320/create-reference.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
8.&amp;nbsp; Jeśli powyższy krok wykonamy bez żadnych problemów numerator powinien być prawidłowo stworzony i skonfigurowany. Teraz wystarczy go użyć np. w metodzie insert na tabeli głównej:&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;NumberSeq numberSeq;
    ;

    ttsbegin;
    numberSeq = NumberSeq::newGetNum(CustParameters::numRefDevIndexId());

    this.DevIndexId = numberSeq.num();

    super();
    numberSeq.used();
    ttscommit;
&lt;/pre&gt;&lt;br /&gt;
9. Teraz powinniśmy cieszyć się nowym numeratorem, po wstawieniu rekordu do tabeli i zapisaniu go, system powinien przydzielić nowy numer:&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2mJAtzTBcJlWJPcyvQvJz8QH942sJCe3s3TiZ8oMZBZSi4CAyiR2gXWNb6ej6Qi5ZM-iWTxJlWO-RdrF7jd-2vsMAWMi9bWlknfg9zfClHa-im5if-Rq7DvWHTj_zwDpB_7KiDMDSUFg/s1600/create-record.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;201&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2mJAtzTBcJlWJPcyvQvJz8QH942sJCe3s3TiZ8oMZBZSi4CAyiR2gXWNb6ej6Qi5ZM-iWTxJlWO-RdrF7jd-2vsMAWMi9bWlknfg9zfClHa-im5if-Rq7DvWHTj_zwDpB_7KiDMDSUFg/s320/create-record.PNG&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;b&gt;Życzę miłego tworzenia numeratorów :)&lt;/b&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/8392000364222091563/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-numerator-tutorial.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8392000364222091563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/8392000364222091563'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-numerator-tutorial.html' title='Dynamics AX: Numerator - tutorial'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNnxoznBoEEnUo6WF0sRCPORKygDcHs4_hR7fq_FQpzbm9KLIXZfp_vqLANVNLMTIz0vOSFULxPJyTOfbLDBtKwkcoDO9OOsWEMn0odnWKNZSbEZMaR6PLmZj4AYcZ5hR-SiGDnoSwX3M/s72-c/create-extended-data-type.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-6457474663649330737</id><published>2010-11-25T10:15:00.001+01:00</published><updated>2010-12-11T23:37:41.478+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="axapta"/><category scheme="http://www.blogger.com/atom/ns#" term="Dynamics AX"/><category scheme="http://www.blogger.com/atom/ns#" term="testy jednostkowe"/><category scheme="http://www.blogger.com/atom/ns#" term="UnitTest"/><category scheme="http://www.blogger.com/atom/ns#" term="X++"/><title type='text'>Dynamics AX: Pozbycie się komunikatów w testach jednostkowych</title><content type='html'>Kto kiedyś pisał testy jednostkowe (unit test) w &lt;b&gt;X++&lt;/b&gt; lub został postawiony przed takim faktem, natknął się lub natknie na uporczywe komunikaty - jeśli w testowanym kodzie takie wystąpią. Załóżmy teoretycznie, że testujemy kod w stylu:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;while(condition ...)
{
 if (Box::YesNo( arguments ...))
 {
  // action
 }
}
&lt;/pre&gt;&lt;br /&gt;
&lt;a name=&#39;more&#39;&gt;&lt;/a&gt;&lt;br /&gt;
Z odsieczą przychodzi modyfikacja klasy &lt;b&gt;Box&lt;/b&gt; będącej odpowiedzialną za wyświetlanie komunikatów maści wszelakiej. Poniżej kod ze zmodyfikowaną metodą yesNo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;public client static DialogButton yesNo(
    str             _text,
    DialogButton    _defaultButton,
    str             _title          = &quot;@SYS11132&quot;,
    str             _bottomText     = &#39;&#39;)
{
    Container con;
    str retCon;

    if (clientKind() == ClientType::COMObject)
        return _defaultButton;


    // modyfikacja mająca na celu usprawnienie testów jednostkowych
    if (global::hasSecuritykeyAccess(securitykeynum(SysDevelopment), AccessType::View))
    {
        con = xSession::xppCallStack();
        retCon = conpeek(con, conlen(con) - 1);
        if (strscan(retCon, &quot;SysTest&quot;, 1, strlen(retCon)))
        {
            return _defaultButton;
        }
    }

    return  new DialogBox(DialogBoxType::YesNoBox,
                          _text,
                          _title,
                          _bottomText,
                          _defaultButton).retval();
}
&lt;/pre&gt;&lt;br /&gt;
Jak widać istnieje tutaj zabezpieczenie dla środowiska produkcyjnego. Kod nie powinien wykonać się wtedy kiedy użytkownik nie ma uprawnień do modyfikacji programistycznych. &lt;br /&gt;
&lt;br /&gt;
Powyższa modyfikacja to jedynie propozycja rozwiązania problemu. Ambitniejsi mogą pokusić się o próbę implementacji dynamicznego ustalenia, który przycisk ma być symulowany w testach.&lt;br /&gt;
&lt;br /&gt;
W &lt;b&gt;Dynamics AX 2009&lt;/b&gt; Microsoft wprowadził podobny mechanizm na potrzeby rejestratora zadań (&lt;b&gt;SysTaskRecorder&lt;/b&gt;), na którym i w tym przypadku można się wzorować:&lt;br /&gt;
&lt;pre class=&quot;brush: c-sharp;&quot; name=&quot;code&quot;&gt;if( SysTaskRecorderEventManager::parmRecording() )
        return SysTaskRecorderGlobal::handleDialogButton(DialogBoxType::YesNoBox, _text, _title, _bottomText, _defaultButton);
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/6457474663649330737/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-pozbycie-sie-komunikatow-w.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/6457474663649330737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/6457474663649330737'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/dynamics-ax-pozbycie-sie-komunikatow-w.html' title='Dynamics AX: Pozbycie się komunikatów w testach jednostkowych'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2790782254362923606.post-4163404967534501827</id><published>2010-11-25T00:06:00.000+01:00</published><updated>2010-11-30T22:07:01.600+01:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="powitanie"/><category scheme="http://www.blogger.com/atom/ns#" term="programowanie"/><category scheme="http://www.blogger.com/atom/ns#" term="skorowidz"/><category scheme="http://www.blogger.com/atom/ns#" term="zagadnienia programistyczne"/><title type='text'>Powitanie</title><content type='html'>&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWC-gXC7A9RctfKZ6Ss1qC4eRdh2dquIhNU3RPM7KeC76J4cAJejflUkPy6-r96p704yTJaV0zZkk-k4ibCocvUfpl2p5fKEuP9O2ZnvCIzfmNomvOGzzIHfbswAgmIQeyC6ig0cfgz_k/s1600/devindex.png&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWC-gXC7A9RctfKZ6Ss1qC4eRdh2dquIhNU3RPM7KeC76J4cAJejflUkPy6-r96p704yTJaV0zZkk-k4ibCocvUfpl2p5fKEuP9O2ZnvCIzfmNomvOGzzIHfbswAgmIQeyC6ig0cfgz_k/s1600/devindex.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;Od dłuższego czasu zwlekałem z wystartowaniem tego bloga i tak naprawdę do końca nie wiedziałem na jaki temat mogę pisać. Wreszcie nadeszła ta wiekopomna chwila kiedy pewien impuls zachęcił mnie do dzielenia się wiedzą jaką mam przyjemność przetwarzać na co dzień. Blog ten oprócz funkcji propagowania informacji ze świata programowania, ma mi służyć jako &quot;skorowidz operacji wykonanych&quot; :) - czyli indeks z reguły krótkich zagadnień programistycznych do których często powracam, a które czasami niejednokrotnie spędzają sen z powiek. Chyba każdy kto zawodowo zajmuje się programowaniem w pewnym momencie swojej pracy dostrzega powtarzalność i rodzące się pytania z charakterystycznym drapaniem się po głowie: &quot;jak ja to wtedy zrobiłem?&quot; ;) Mam nadzieję, że ten blog przyczyni się do oświecenia wielu potrzebujących. Koniec gadania, do pracy :)</content><link rel='replies' type='application/atom+xml' href='http://devindex.blogspot.com/feeds/4163404967534501827/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://devindex.blogspot.com/2010/11/powitanie.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/4163404967534501827'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2790782254362923606/posts/default/4163404967534501827'/><link rel='alternate' type='text/html' href='http://devindex.blogspot.com/2010/11/powitanie.html' title='Powitanie'/><author><name>Piotr Broniszewski</name><uri>http://www.blogger.com/profile/01664761877447903112</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='22' height='32' src='//blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh629QPqK36MAAKa2dawASYicmtN6G6U4n58kU_wJZlz0rCtGIGgFlPVshizY2iewsNOg4eqXwWVzAxs-4v1DCi-FDrA3vYpljJyLhnyqgy3gf1r1tltUgXktDZESks_A/s220/c9b2656412.jpeg'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWC-gXC7A9RctfKZ6Ss1qC4eRdh2dquIhNU3RPM7KeC76J4cAJejflUkPy6-r96p704yTJaV0zZkk-k4ibCocvUfpl2p5fKEuP9O2ZnvCIzfmNomvOGzzIHfbswAgmIQeyC6ig0cfgz_k/s72-c/devindex.png" height="72" width="72"/><thr:total>0</thr:total></entry></feed>