Fala pessoal beleza?
Vamos lá, não vi exemplos ainda na internet sobre isso e acho que vai ser legal todos saberem.
Todos sabem, que para acessar o datasource do formulário coloca-se um sufixo “_ds” após o nome do datasource.
Para acessar diretamente o objeto “Query” ou o objeto “QueryRun” pode-se usar o sufixo “_q” ou “_qr” conforme o exemplo abaixo:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| //Inicio <DynamicsAXBR>
void accessObjects()
{
;
//Acessando a Query diretamente
InventTable_q.dataSourceTable(tablenum(InventTable)).clearRanges();
InventTable_q.dataSourceTable(tablenum(InventTable)).addRange(.....);
//Acessando o objeto QueryRun
while(InventTable_qr.next())
{
}
}
//Fim <DynamicsAXBR> |
É isso galera, se alguém tiver algum dúvida só COMETAR.
Abraços,
Peterson Ferreira
Fala galera, beleza??
Estava dando uma olhada no MSDN e sem querer encontrei dois links que me chamaram muito a atenção e tenho certeza que muitos irão gostar.
Microsoft Dynamics AX Design Patterns
Microsoft Dynamics AX Class Design Patterns
Vale a pena dar uma lida.
Abraços,
Peterson Ferreira
Boa noite galera,
Estava fuçando os blogs de AX e encontrei um post bem interessante falando sobre boas práticas ao se criar classes no DAX.
Não vou traduzir aqui pra vocês porque o post é um pouco extenso, mas tenho certeza que vale muito a pena dar uma olhada:
www.artofcreation.be
Por hoje é isso pessoal, desculpem a falta de atualização no blog, em breve colocarei posts bem interessantes.
Abraço,
Peterson Ferreira
Fala pessoal beleza?
Ontem estava lendo no Axaptapedia um artigo que falava sobre a classe de imagens.
Tentei fazer os exemplo que estavam disponíveis mas nenhum funcionou direito. Então resolvi criar um que mostra exatamente a funcionalidade da classe IMAGE do dynamics ax.
Quem tiver interesse, basta baixar o XPO aqui.
Os exemplos ficaram bem fáceis de entender, espero que gostem e qualquer dúvida COMENTEM!!!
Abrs,
Peterson Ferreira
Fala pessoal…
Vou postar hoje uma dica bem legal que fiquei me debatendo como fazer ontem, e pode ser a dúvida de outros.
É bem simples, mas como falei pode ser a dúvida de outros…
1
2
3
| //Inicio <DynamicsAXBR>
DataSource_ds.queryRun().query();
//Fim <DynamicsAXBR> |
Com issso você pode instânciar um objeto QueryRun e fazer o loop nos resultados, assim:
1
2
3
4
5
6
7
8
9
10
| //Inicio <DynamicsAXBR>
QueryRun queryRun;
;
queryRun = new QueryRun(new Query(InventTable_ds.queryRun().query()));
while(queryRun.next())
{
//Faça
}
//Fim <DynamicsAXBR> |
Abrs,
Peterson Ferreira
Fala galera…
É com muita alegria que venho falar para vocês que a Microsoft disponibilizou hoje o pacote de atualização do Ax2009 contendo a integração do Ax diretamente com a SEFAZ para emissão da NF-e.
Mais informações www.daxdev.com.br
Fiquem ligados no blog que passei acima que em breve terão mais informações!!!
Abrs,
Peterson Ferreira
No blog do Joel Pereira ele está divulgando vagas para desenvolvimento de AX segue o link.
Fala galera, hoje vou falar de um assunto bem interessante, e não encontrei ainda na net. Dei uma pesquisada fiz uns testes e espero que gostem.
Vamos lá…
Como todos sabem o Microsoft Dynamics AX possue as Security Keys que controlam o acesso de usuários.
Com a security key bem configurada é possível dar acesso diferenciado em alguns campos ou até mesmo fazer validações diferentes de acordo com cada usuário.
Vou colocar logo abaixo algumas validações que podem ser feitas no “X++”, levando em consideração as security keys.
1
2
3
4
5
6
| //Inicio <DynamicsAXBR>
if (hasSecurityKeyAccess(securitykeyNum(BasicLedger), AccessType::View))
{
//Executa o código se o usuário tiver acesso.
}
//Fim <DynamicsAXBR> |
Para verificar se o usuário tem acesso a uma determinada tabela existe também uma função pré determinada assim como os campos de uma tabela também veja:
1
2
3
4
5
6
| //Inicio <DynamicsAXBR>
if (hasTableAccess (TableNum (custTable) AccessType::Edit))
{
//Executa o código se o usuário tiver acesso.
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
| //Inicio <DynamicsAXBR>
if (hasFieldAccess (TableNum (custTable fieldnum) (custTable, AccountNum) AccessType::Delete))
{
//Executa o código se o usuário tiver acesso.
}
//Fim <DynamicsAXBR> |
O Base Enum “AccessType”, determina o tipo de acesso que o usuário terá.
Todos os métodos estão na classe Global, sendo assim estes métodos podem ser chamados em qualquer momento no X++.
PS: Galera, desculpa o tempo sem postar, é que mudei de trampo e ta uma correira danada! Mas enfim, espero que gostem.
Abrs,
Peterson Ferreira
Fala pessoal,
Hoje vamos lançar um diário utilizando o X++, sei que será bem útil pois desde que comecei a trabalhar com o Dynamics AX ja precisei fazer isso várias vezes.
Então mãos a obra…
Como todos sabem a tabela que armazena os diários e suas transções são respectivamente a LedgerJournalTable e a LedgerJournalTrans, e para que o exemplo abaixo funcione perfeitamente, é necessário que você tenha preenchido um tableBuffer da LedgerJournalTable (Cabeçalho do diário).
Existem duas classes que é possível fazer isso a LedgerJournalCheckPost e a LedgerJournalPost, que posteriormente chama a LedgerJournalCheckPost, mas faz alguma verificações como tipo de diário e outras.
Neste exemplo irei utilizar a LedgerJournalPost.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| //Inicio <DynamicsAXBR>
static void postJournal(Args _args)
{
LedgerJournalTable ledgerJournalTable;
;
//Pega a primeira linha da JournalTable, independente do tipo de Diário
select firstonly ledgerJournalTable
where ledgerJournalTable.Posted == NoYes::No;
//Lança o diário independento do tipo de diário
//parâmetro1 = tableBuffer da LedgerJournalTalbe
//parâmetro2 = indica se os erros devem ou não ser jogados em um novo diário
LedgerJournalPost::postJournal(ledgerJournalTable, NoYes::No);
}
//Fim <DynamicsAXBR> |
Se tivessemos usado a classe LedgerJournalCheckPost, seria preciso especificar qual seria o tipo de diário, com a classe LedgerJournalPost ele se encarrega de verificar qual é o tipo de diário e aplicar uma regra para cada tipo.
OBS: Quem quiser saber mais procure a classe LedgerJournalEngine que é a encarregada de definir as regras para cada tipo de diário.
Existe um Enum que carrega todos os tipos de diário ele se chama LedgerJournalType.
É isso ai pessoal, caso reste alguma dúvida estou as ordens para responder!!COMENTEM!!!
Abrs,
Peterson Ferreira
Fala pessoal,
Continuando o post anterior, vamos fazer um exemplo prático de utilização da AxClass.
Vamos lá…
Primeiramente crie uma tabela com a seguinte estrutura:

Após ter criado a tabela, vamos criar a AxClass que irá manipular os dados desta tabela.
O nome da class será AxTimesFutebol (de acordo com a nomenclatura), e a mesma extende a AxInternalBase que é o base deste Framework.
Antes de continuar preciso citar os métodos que são necessários para que o framework seja implementado corretamente.
Alguns são extendidos da AxInternalBase e outros serão criados por você!
Os métodos são:
- currentRecord() (Extendido da AxInternalBase) – Pega e recebe o registro atual da Ax[Tabela].
- emptyRecord() (Extendido da AxInternalBase) – Retorna um registro em branco para a tabela que a Ax[Tabela] se refere.
- setField() (Extendido da AxInternalBase) – Atribui um valor para um campo na currentRecord() que é atribuído à Ax[Tabela].
- Os métodos parm referente a cada campo de sua tabela (por ele que que você insere os dados)
- E uma método que será seu tableBuffer dentro do framework
Vamos começar:
1
2
3
4
5
6
| //Inicio <DynamicsAXBR>
class AxTimesFutebol extends AxInternalBase
{
TimesFutebol timesFutebol;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
| //Inicio <DynamicsAXBR>
public TimesFutebol currentRecord(TimesFutebol _timesFutebol = timesFutebol)
{
if (!prmisdefault(_timesFutebol))
{
currentRecordIsSet = true;
}
return _timesFutebol;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
| //Inicio <DynamicsAXBR>
protected TimesFutebol emptyRecord()
{
TimesFutebol localTimesFutebol;
;
return localTimesFutebol;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
| //Inicio <DynamicsAXBR>
public AddressCity parmCidade(AddressCity _cidade = '')
{
if (!prmisdefault(_cidade))
{
this.setField(fieldnum(TimesFutebol, Cidade), _cidade);
}
return timesFutebol.Cidade;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
| //Inicio <DynamicsAXBR>
public AddressStateId parmEstado(AddressStateId _estado = '')
{
if (!prmisdefault(_estado))
{
this.setField(fieldnum(TimesFutebol, Estado), _estado);
}
return timesFutebol.Estado;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
| //Inicio <DynamicsAXBR>
public Name parmNome(Name _nome = '')
{
if (!prmisdefault(_nome))
{
this.setField(fieldnum(TimesFutebol, Nome), _nome);
}
return timesFutebol.Nome;
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| //Inicio <DynamicsAXBR>
protected void setField(fieldId _fieldId, anytype _anytype)
{
timesFutebol currentRecord = this.currentRecord();
;
if (fieldTouched.exists(_fieldId))
{
if (this.inputStatus() == InternalExternal::Internal && fieldTouched.lookup(_fieldId) == InternalExternal::External)
{
return ;
}
}
currentRecord.(_fieldId) = _anyType;
this.setFieldAsTouched(_fieldId);
}
//Fim <DynamicsAXBR> |
1
2
3
4
5
6
7
8
9
10
11
| //Inicio <DynamicsAXBR>
public TimesFutebol timesFutebol(TimesFutebol _timesFutebol = timesFutebol)
{
if (!prmisdefault(_timesFutebol))
{
currentRecordIsSet = true;
}
return _timesFutebol;
}
//Fim <DynamicsAXBR> |
Após ter criado a classe com os métodos acima, vamos criar um Job para testar as funcionalidades da AxClass:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| //Inicio <DynamicsAXBR>
static void jobAxTimesFutebol(Args _args)
{
AxTimesFutebol axTimesFutebol = new AxTimesFutebol();
;
//Primeiro pegamos todos os valores utilizando os parms da classe criada;
axTimesFutebol.parmNome("Internacional");
axTimesFutebol.parmEstado("RS");
axTimesFutebol.parmCidade("Porto Alegre");
//Caso tenha validação ele valida os campos;
axTimesFutebol.validateInput(true);
//Salva o registro na tabela;
axTimesFutebol.save();
}
//Fim <DynamicsAXBR> |
Bom pessoal espero tenham gostado. E caso tenha restado alguma dúvida COMENTEM sua dúvida que terei o prazer em responder.
Mais informações sobre a classe AxInternalBase no msdn
Abrs,
Peterson Ferreira