Dynamics AXBR

Blog destinado a usuários do Dynamics AX no Brasil.
Options:

Quando usar InventOnHand ou InventDimOnHand

A classe InventOnHand é um invólucro para a tabela InventSum que tem como único índice é a combinação do ItemId + InventDimId. Em outras palavras, a InventOnHand é usada para recuperar seu estoque disponível do item com uma dimensão específica. Por exemplo, se você precisa saber o estoque disponível para o item Bola, na cor Azul, tamanho Normal e que está no depósito 22, corredor 1, prateleira 4 então você deve usar a class InventOnHand.

Mas, se você quer por exemplo levantar o estoque disponível por localização no depósito, então a classe InventOnHand não pode lhe ajudar. Isso porque um endereço pode conter diferentes itens, ou até mesmo se você precisar do estoque disponível por palettes. E é neste caso que a classe InventDimOnHand deve ser usada, ou seja, quando você precisa saber o estoque disponível para uma Dimensão de Estoque (InventDim) especifico. A classe InventDimOnHand é mebra das classes InventDimOnHandMember, onde cada InventDimOnHandMember contem informações sobre o Item, Dimensões e Quantidade.

Já havia usado, sabia a diferença, mas achei aqui e resolvi postar.

[]s
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...


Problemas com o enum DateFlags

Pessoal,
tenho visto não só aqui no Brasil, como também em sites internacionais uma série de pessoas reclamando do problema relacionado ao DateFlags após a atualização do AX 2009 para o SP1.

O que acontece é que ao atualizar a AOS você também deve atualizar os clients! Sim, os clients! O problema é porque o client não está atualizado e por algum motivo, enquanto ele não é atualizado ele não consegue enxergar o novo enum e por consequencia vários problemas começam a acontecer.

Tenho visto algumas pessoas criando o enum na mão, sem entender o que de fato acontece e se eu pudesse dar um conselho a esses desenvolvedores, eu diria: “Em ERP não se coloca a mão sem saber o que esta fazendo!”.

Abraço,
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (4 votes, average: 4.00 out of 5)
Loading ... Loading ...


Macros – Definições e armadilhas.

Meu amigo Alexssander me pediu para escrever sobre macros e logo em seguida eu vi um post muito abrangente que trata justamente de macros e resolvi traduzi-lo, vamos lá.

O X++ prove macros de uma maneira fácil e expansiva. Com eles, você pode definir e usar valores para fazer compilações condicionais e etc… Neste artigo eu vou descrever a semantica da construção e prover modos para resolver alguns dos problemas que iniciantes e experts tem com os macros.

Macros não são estruturados tanto que eles não seguem a estrutura do X++. O tratamento dos macros acontece antes que o texto chegue ao compilador.

Macros podem ser usados em métodos, declarações de classes, jobs e em todos os outros lugares onde se há código X++.

A semântica de cada chave macro é descrita abaixo:

Construtores

#define
A sintaxe é: #define.MyName(SomeValue)

Isto define um macro chamado MyName com o valor SomeValue. Quando esta definição está em uso, qualquer referencia à #MyName será substituída pelo que há em SomeValue. A definição semântica não tem outro objetivo além de definir o símbolo MyName: O texto não atinge o próprio compilador. Quando a compilação do método atual acabar, o símbolo (MyName neste caso) não é mais lembrado. Se o símbolo já estava definido, o valor antigo é descartado e substituído pelo novo valor.

#globaldefine
A sintaxe é: #globaldefine.MyName(SomeValue)

Este tem a mesma semântica do define descrito acima.

#definc
A sintaxe é: #definc.MyName

Este construtor é usado só quando o valor é um inteiro. O pré processador incrementará o valor do símbolo por um. Se o valor não foi definido antes da instrução #definc é gerado um erro. Caso o valor não é um inteiro, o valor antigo será sobrescrito pelo valor 0 e então incrementado, tornado-se 1.

#defdec
A sintaxe é: #defdec.MyName

Este é o mesmo caso do anterior, no entanto o pré processador irá decrementar o valor do símbolo por um. Caso não exista, gerará um erro e caso exista e não seja um inteiro, será convertido para 0 e então decrementado por 1, o que retorna -1.

#undef
A sintaxe é: #undef.MyName

Como o nome já diz, ele remove a definição do símbolo e caso o símbolo não tenha sido previamente declarado, nada acontece.

#if … #endif
A sintaxe é:
#if.MySymbol

#endif

Ou

#if.MySymbol(SomeValue)

#endif

No primeiro caso o texto marcado com … nos exemplos acima é inserido dentro do fonte se o MySymbol foi préviamente definido, já no segundo caso, o conteúdo é inserido no fonte apenas se o valor definido for igual ao que está sendo validado.

O construtor #if pode ser usado em qualquer nível, mas não há um construtor #else.

#ifnot … #endif
A sintaxe é: #ifnot.MySymbol

#endif

Ou

#ifnot.MySymbol(SomeValue)

#endif

É exatamente igual ao anterior, no entanto, negativo. Equivale ao != usado em ifs.

#macrolib
A sintaxe é: #macrolib.MyName

Neste caso, o nome deve referenciar um macro existente na AOT. O texto do Macro é então processado pelo pré processador. O valor da macro é inserido no código fonte onde a diretiva aparece. Caso o Macro não exista na AOT um erro será gerado.

#macro / #localmacro

As chaves #macro e #localmacro são intercambiáveis, não há diferença na semântica das duas. O construtor é usado para definir um símbolo para detonar um conteúdo que possivelmente usará várias linhas.

A sintaxe é:
#localmacro.MySymbol
….
#endmacro

Exemplo:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyBaseClass extends Runbase
{
     int v1;
     #define.myMacro(“Hello world”)
     #localmacro.currentlist
        v1
     #endmacro
 
     public container pack()
     {
         return [#currentlist];  // #currentlist expande-se para v1
     }
 
     public void run()
     {
         print #myMacro;   // #myMacro expande-se para “Hello world”
     }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MyDerivedClass extends myBaseClass
{
    int v2;
    #localmacro.currentlist
       v2
    #endmacro
 
 
    public container pack()
    {
        return [super(), #currentlist];  // #currentlist expande-se para v2
    }
 
    public void run()
    {
        print #myMacro;  // #myMacro expande-se para “Hello world”
    }
}

#MySymbol
A sintaxe é: #MySymbol

Insere o valor do símbolo no código e é um erro se referir a um símbolo que não foi definido. Se o nome denotar um Macro definido na AOT, o texto do nó será processado pelo pré processador (neste caso, #MySymbol é um atalho para #macrolib.MySymbol).

Problemas comuns

Nesta parte do post, eu gostaria de descrever alguns dos problemas que os desenvolvedores tem quando utilizam macros.

Macros e parâmetros

Isto parece ser um fato pouco conhecido e a origem de certa confusão: Os valores dos símbolos podem receber os placeholders % como os usados no strfmt e caso nenhum parâmetro seja passado uma string nula é usada. Ou seja #define.MyString(“Hello World from %1″) definirá um macro chamado MyString com um parâmetro. Se o macro for expandido conforme abaixo:

#MyString(X++)

o resultado será:

“Hello World from X++”

Veja que no exemplo acima não usamos aspas para passar o valor X++ como argumento. Caso usado, irá gerar um erro de compilação!

A confusão também pode acontecer por causa da notação % também é usada como parâmetro de substituição na função strFmt. E como sabem, esta função tem uma lista de parâmetros com comprimento variável, e cada referencia de %n no primeiro parâmetro (a string) será expandida para conter a representação informada no argumento n, conforme podemos ver abaixo:

print strfmt(“The value is %1″, theValue);

Agora, alguns programadores tentarão fazer isto:

#define.TheText(“The value is %1″)
print strfmt(#TheText, theValue);

Mas a substituição em macros acontece antes do compilador passar pelo código. A substituição do macro não irá encontrar o parâmetro para ser colocado onde o %1 encontra-se, então o compilador encontrará:

print strfmt(“The value is “, theValue);

o que provavelmente não é a intenção do desenvolvedor.

Macros nas declarações de classes

Algumas confusões surgem em situações que os macros são definidos na declaração das classes. Para entender como isto é tratado é necessário rever o que o compilador faz quando ele compila um método. O processo inicia por calcular a sequencia das derivações da classe que a classe faz parte. Então o processo analisa cada declaração da classe com a primeira derivação primeiro, preenchendo sua tabela interna de símbolos. Após compilar a declaração da classe o compilador compila os métodos. Qualquer símbolo definido em qualquer classe derivada será subseqüentemente disponível para uso nos métodos. Símbolos definidos na declaração da classes talvez sejam substituídos por valores definidos em mais de uma derivação da classe.

Parênteses dentro das strings nos macros

O scanner que trata com as strings nos macros é muito simplista. Ele não ira tratar a situação onde onde parênteses forem incluídosa string, ou seja

#define.Another(“(This is text in parenthesis)”)

irá gerar um erro léxico. Se você precisar fazer isto, você deve usar no lugar a diretiva #localmacro:

#localmacro.Another
“(This is text in parenthesis)”
#endmacro

Neste caso, o fim do macro é sinalizado pela string #endmacro e não no parêntese direito.

Fonte.

Aqui acaba a tradução.

Se navegarem pela AOT vocês vão ver exemplos de macros mais compostos e complexos, que é o exemplo do macro InventDimSelect que implementa:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
select
 
    #ifnot.empty(%4)
        %4
    #endif
 
    %1
 
    #ifnot.empty(%5)
        index hint %5
    #endif
 
    #ifnot.empty(%6)
        order by %6
    #endif
 
    where (%1.ConfigId          == %2.ConfigId              || ! %3.ConfigIdFlag)           &&
          (%1.InventSizeId      == %2.InventSizeId          || ! %3.InventSizeIdFlag)       &&
          (%1.InventColorId     == %2.InventColorId         || ! %3.InventColorIdFlag)      &&
          (%1.InventSiteId      == %2.InventSiteId          || ! %3.InventSiteIdFlag)       &&
          (%1.InventLocationId  == %2.InventLocationId      || ! %3.InventLocationIdFlag)   &&
          (%1.InventBatchId     == %2.InventBatchId         || ! %3.InventBatchIdFlag)      &&
          (%1.WMSLocationId     == %2.WMSLocationId         || ! %3.WMSLocationIdFlag)      &&
          (%1.WMSPalletId       == %2.WMSPalletId           || ! %3.WMSPalletIdFlag)        &&
          (%1.InventSerialId    == %2.InventSerialId        || ! %3.InventSerialIdFlag)
 
#InventDimDevelop

e é utilizado em vários lugares para se fazer algumas consultas as dimensões de estoque. Veja que ele válida se alguns parâmetros foram passados e com isso consegue fazer if no meio de instruções SQL, o que é muito útil já que em uma instrução ‘normal’, você não conseguiria.

Existem outras possibilidades, alias, as possibilidades nos usos de macros são infinitas, vai da criatividade de cada um! Eu tenho outro amigo (Daniel Zanni) que usa os macros para verificar se determinada custom está ativa nas configuration keys e caso sim, aplica a custom no que diz respeito a código.

É isso ai pessoal, espero que tenha ajudado.

Abraço,
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
Loading ... Loading ...


Problemas entre webservices do PR e NF-e do Ax – Parte 1

http://daxdev.com.br/blog/problemas-entre-webservices-do-pr-e-nf-e-do-ax-ndash-parte-1/

[]s
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (2 votes, average: 5.00 out of 5)
Loading ... Loading ...


Global Address Book White Paper

Download.

[]s
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...


Rollup 5 do Dynamics AX 2009 é liberado.

Hoje saiu o rollup 5 do ax 2009, e como os rollups são cumulativos, você só precisa baixar o último.

Dynamics AX 2009 RTM RU-5 KB (65MB)
Dynamics AX 2009 SP1 RU-5 KB (146MB)

Abraço,
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...


Como sobrescrever os campos do sistema em uma tabela

Pessoal,
Saiu uma publicação que achei interessante no blog do Sasha onde mostra como subrescrever um campo de sistema em uma tabela, no exemplo abaixo, copiado do original o autor faz uma alteração em um registro e troca o usuário que modificou o registro ao invés do sistema salvar o real.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
static void job_overwireSystemFiledInTable(Args _args)
{
    SalesTable salesTable;
    ;
    ttsbegin;
 
    salesTable = SalesTable::find("mySalesId", true);
 
    if(salesTable.RecId != 0)
    {
        salesTable.overwriteSystemfields(true);
        salesTable.(fieldNum(SalesTable, createdBy)) = "NewUserId";
        salesTable.update();
    }
 
    ttscommit;
}

É isso ai…

Obs.: Tenho recebido alguns comentários via e-mail de que estou deixando o blog de lado, mas a verdade é que me faltam assuntos, o que deveria acontecer é vocês mandarem suas questões e assim podemos escrever! Por favor, mandem suas duvidas / sugestões de artigos.

Abraço,
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...


kkk, bom d+! Java 4-Ever Trail…

kkk, bom d+! Java 4-Ever Trailer
http://www.youtube.com/watch?v=A1zySeNpW20



1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...


Adicionei um vídeo como favor…

Adicionei um vídeo como favorito do YouTube — Java 4-Ever Trailer http://youtu.be/A1zySeNpW20?a



1 Star2 Stars3 Stars4 Stars5 Stars (No Ratings Yet)
Loading ... Loading ...


O novo editor X++ em ação.

Prezados,
O Vicent postou em seu blog um video de como é o novo editor X++ e finalmente vamos ter algo mais próximo do Visual Studio.

Eu achei que ficou show!

Clique aqui para ver o vídeo!

Clique aqui para ver o post original!

[]s
Pichler



1 Star2 Stars3 Stars4 Stars5 Stars (1 votes, average: 5.00 out of 5)
Loading ... Loading ...


RSS



Categorias

Data do post

September 2010
S M T W T F S
« Aug    
 1234
567891011
12131415161718
19202122232425
2627282930  
Dynamics Community

Arquivo

Latest Visitor Loactions

Rio De Janeiro, Brazil 2
Osasco, Brazil 1
Curitiba, Brazil 1
Amman, Jordan 1
São Paulo, Brazil 1