Outro dia estava estudando a classe syscompare e, pesquisando mais sobre ela na net, acabei descobrindo um job que resolve o problema daqueles objetos que ficam em negrito (sinalizando uma modificação na camada corrente) mas que no final não tem nenhuma modificação quando é comparado com uma camada inferior. Acabamos dando o nome para esses objetos de objetos “chapados” hehehe.

Aqui está o post do Fred Shen onde ele demonstra como automatizar esse processo:

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
28
29
30
31
32
33
34
35
36
37
38
39
40
41
static void FindAndDeleteIdenticalObjects(Args _args)
{
    SysTreeNode     comparable1, comparable2;
    TreeNode          curLevelTreeNode, upperLevelTreeNode;
    UtilIdElements    utilElements, joinUtilElements;
    ;
 
    while select UtilElements
        where UtilElements.utilLevel        == UtilEntryLevel::var &&
              (
                UtilElements.recordType     == UtilElementType::Form         ||
                Utilelements.recordType     == UtilElementType::Report      ||
                Utilelements.recordType     == UtilElementType::Table        ||
                Utilelements.recordType     == UtilElementType::Class         ||
                Utilelements.recordType     == UtilElementType::Enum        ||
                Utilelements.recordType     == UtilElementType::ExtendedType
              )
    {
        //Should use join if for a normal table, but not applicable for UtilElements
        //Performance hit if use exists join
        select firstonly recid from joinUtilElements
            where joinUtilElements.utilLevel     !=  UtilElements.utilLevel    &&
                  joinUtilElements.name            == UtilElements.name        &&
                  joinUtilElements.recordType   == UtilElements.recordType;
        if (joinUtilElements.RecId)
        {
            //Thanks for Jim Shepherd here
            curLevelTreeNode      = SysTreeNode::findNodeInLayer(UtilElements.recordType, UtilElements.name, UtilElements.parentId, UtilElements.utilLevel);
 
            upperLevelTreeNode  = SysTreeNode::getLayeredNode(curLevelTreenode, 1);
            comparable1              = SysTreeNode::newTreeNode(curLevelTreeNode);
            comparable2              = SysTreeNode::newTreeNode(upperLevelTreeNode);
            if (SysCompare::silentCompare(comparable1, comparable2))
            {
                info(strFmt("Element name: %1, Element type: %2", UtilElements.name, enum2str(UtilElements.recordType)));
                //Remove the node
                curLevelTreeNode.AOTdelete();
            }
       }
   }
}

TESTANDO

Overview dos passos que vamos realizar:

1) Criar um job na camada VAR e simular um objeto idêntico (o objeto “chapado”) na camada VAP
2) Alterar o job original do Fred Shen para verificar a camada VAP e procurar apenas elements do tipo job
3) Executar o job e verificar resultados

Passos

1) Entre no AX com a camada VAR, crie um job e coloque um código qualquer. Esse é o job que utilizei:

1
2
3
4
5
6
7
static void Job2(Args _args)
{
    int a = 10;
    ;
    print a;
    pause;
}

Nesse momento teremos um objeto job2 na camada VAR. Agora entre no AX com a camada VAP e execute esses passos:

a) Altere uma linha do job. No exemplo, alterei a linha que declara e atribui o valor 10 para a variável ‘a’:

int a = 10 ;

b) salve
c) Volte a alteração que fez

int a = 10;

d) salve
e) Compare o objeto entre as camadas VAR e VAP – o resultado esperado é a mensagem “Nenhuma diferença foi encontrada”.

2) Com o ax na camada VAP ainda, altere o job original e execute. Segue o código:

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
28
29
30
31
32
33
34
35
36
37
38
static void FindAndDeleteIdenticalObjects(Args _args)
{
    SysTreeNode     comparable1, comparable2;
    TreeNode          curLevelTreeNode, upperLevelTreeNode;
    UtilIdElements    utilElements, joinUtilElements;
    ;
 
    while select UtilElements
        where UtilElements.utilLevel        == UtilEntryLevel::vap && //aqui a camada VAP
              (
                //Queremos apenas jobs
                UtilElements.recordType     == UtilElementType::Job
              )
    {
        //Should use join if for a normal table, but not applicable for UtilElements
        //Performance hit if use exists join
        select firstonly recid from joinUtilElements
            where joinUtilElements.utilLevel     !=  UtilElements.utilLevel    &&
                  joinUtilElements.name            == UtilElements.name        &&
                  joinUtilElements.recordType   == UtilElements.recordType;
        if (joinUtilElements.RecId)
        {
            //Thanks for Jim Shepherd here
            curLevelTreeNode      = SysTreeNode::findNodeInLayer(UtilElements.recordType, UtilElements.name, UtilElements.parentId, UtilElements.utilLevel);
 
            upperLevelTreeNode  = SysTreeNode::getLayeredNode(curLevelTreenode, 1);
            comparable1              = SysTreeNode::newTreeNode(curLevelTreeNode);
            comparable2              = SysTreeNode::newTreeNode(upperLevelTreeNode);
            if (SysCompare::silentCompare(comparable1, comparable2))
            {
                info(strFmt("Element name: %1, Element type: %2", UtilElements.name, enum2str(UtilElements.recordType)));
                //Remove the node
                curLevelTreeNode.AOTdelete();
            }
       }
   }
 
}

3) Depois de executar o job, saia do ax, entre novamente na camada VAP e verifique se o objeto foi removido.

Abraços e até a próxima.