Criar ferramenta para buscar e compilar programas em progress ABL

Vou apresentar como criar um programa onde poderemos buscar arquivos/programas a partir de um diretório, filtrar arquivos que contenham uma palavra chave no conteúdo (normalmente uso o nome de uma tabe por exemplo) e compilar esses arquivos caso sejam extensão .w ou .p do progress.

Para exemplificar, imagine que foi alterado o índice de uma tabela que usamos em vários programas, agora todos esses programas estão dando erro de “CRC” que é quando o dicionário da tabela no programa compilado não bate com o estado atual na base de dados.

Com esta ferramenta vamos buscar todos os programas que contenham alguma relação com esta tabela usando o nome dela como chave de busca e com um simples clicar de um botão vamos compilar todos eles.

Não sei se posso compartilhar o programa por termos legais, então o que vou fazer é mostrar parte do processo de criação do programa e as principais rotinas dele sendo a de busca e filtro de arquivos e a rotina de compilação.

Primeiramente vamos criar um novo programa no AppBuilder e escolhemos a template “window”:

Vamos colocar um fill-in para a chave de busca e um para informar o diretório onde a busca vai ser realizada.
Também vamos inerir check-box para selecionar as extensões de arquivo que desejamos filtrar.

Deve ficar mais ou menos assim:

Agora vamos definir uma tabela temporária para armazenar os programas localizados e uma para armazenar erros no processo de compilação:

define temp-table ttProgramas
    field caminho as character format "x(60)"
    field dt-mod  as date
    field tipo    as character
    field nm-comp as character format "x(60)"
    field nome    as character format "x(15)".

define temp-table ttErro
    field linha as character
    field coluna as character
    field erro as character.

Com a tabela definida vamos inserir um browse na tela para exibir os dados, definimos esse browse como freeform, assim podemos exibir os dados de uma tabela temporária e ainda formatar a forma de exibição:

Estamos com parte da tela concluída, pelo menos para fazer a busca dos arquivos, na trigger do botão de busca vamos usar o seguinte código:

ON CHOOSE OF btn-buscar IN FRAME DEFAULT-FRAME /* Buscar arquivos */
DO:
    DEFINE VARIABLE tipoArquivo AS CHARACTER NO-UNDO.
    DEFINE VARIABLE pathBusca AS CHARACTER NO-UNDO.
    DEFINE VARIABLE vAux AS CHARACTER NO-UNDO.
    DEFINE VARIABLE linha AS CHARACTER NO-UNDO.
    DEFINE VARIABLE contemTexto AS LOGICAL NO-UNDO.

    /* Limpa tabela de programas */
    empty temp-table ttProgramas.
    
    /* caminho onde vamos buscar os arquivos */
    assign pathBusca = edt-dir-compilacao:screen-value in frame {&frame-name}.

    if pathBusca = "" then do:
        MESSAGE 
            "Informe um diretório para busca!"
            VIEW-AS ALERT-BOX INFORMATION BUTTONS OK.
        return.
    end.

    /* Se não foi informado "\" no fim do caminho vamos adicionar */
    if substring(pathBusca,length(pathBusca) - 1, 1) <> "\" then do:
        assign pathBusca = pathBusca + "\".
    end.

    /* Extenções de arquivos que vamos considerar na busca */
    if ch-tp-r:CHECKED in frame {&frame-name} then
        assign tipoArquivo = tipoArquivo + "*.r,".

    if ch-tp-w:CHECKED in frame {&frame-name} then
        assign tipoArquivo = tipoArquivo + "*.w,".

    if ch-tp-p:CHECKED in frame {&frame-name} then
        assign tipoArquivo = tipoArquivo + "*.p,".

    if ch-tp-i:CHECKED in frame {&frame-name} then
        assign tipoArquivo = tipoArquivo + "*.i,".

    /* Vamos usar comando do DOS para listar os arquivos no diretório */
    INPUT  THROUGH  VALUE("dir /b/s " + pathBusca + tipoArquivo).
    REPEAT:
        /* o comando dir vai retornar o caminho completo do arquivo localizado
           ao executar o import o sistema está registrando essa informação na primeira coluna de nossa tabela
           que no caso é ttProgramas.caminho */
        create ttProgramas.
        IMPORT ttProgramas no-error.
        if NOT ERROR-STATUS:ERROR then do:
            /* agora que temos o path completo do arquivo podemos usar o file-info para obter dados deste arquivo */
            ASSIGN FILE-INFO:FILE-NAME = ttProgramas.caminho.

            assign ttProgramas.dt-mod  = DATE(FILE-INFO:FILE-MOD-DATE) no-error. /* Data de modificação */
            /* estraindo o nome entre a ultima barra e o ultimo ponto antes da extenção do arquivo */
            assign vAux = substring(ttProgramas.caminho, r-index(ttProgramas.caminho, '\') + 1).
            assign vAux = substring(vAux, 1, r-index(vAux, '.') - 1).
            assign ttProgramas.nome  = vAux.

            /* Obter a extensão do programa */
            assign vAux = ttProgramas.caminho.
            assign vAux = substring(vAux, r-index(vAux, '.'), (length(vAux) - (r-index(vAux, '.') - 1))).
            assign ttProgramas.tipo  = vAux.
        end.
    END.                                                                                          
    INPUT CLOSE.

    /* Vamos buscar arquivos que contenham um texto em especifico, como o nome de uma tabela por exemplo */
    if edt-contemTexto:screen-value in frame {&frame-name} <> "" then do:

        for each ttProgramas
            where ttProgramas.caminho <> "":
            assign contemTexto = false.
            /* carrega o conteúdo do arquivo */
            input from value(ttProgramas.caminho).
            repeat:
                /* carrega linha a linha do arquivo */
                import UNFORMATTED linha .
                /* se encontrar a chave na linha */
                if index(linha, edt-contemTexto:screen-value in frame {&frame-name}) > 0 then do:
                    assign contemTexto = true.
                    leave.
                end.
            end.
            input close.
            /* Se não encontrar nada então remove o arquivo da lista */
            if contemTexto = false then 
                delete ttProgramas.
        end.
    end.

    for each ttProgramas
        where trim(ttProgramas.caminho) = ""
        :
        delete ttProgramas.
    end.

    /* Atualizar os registros no browse */
    {&OPEN-QUERY-brw-programas}

END.

Com isso o programa deve ser capaz de listar os programas localizados no diretório informado e filtrar caso uma palavra chave tenha sido informada.

Agora vamos preparar a parte que vai compilar os programas listados.

ON CHOOSE OF btn-compilar IN FRAME DEFAULT-FRAME /* Compilar programas */
DO:
    define variable i        as integer no-undo initial 0.

    for each ttProgramas
        where lookup(ttProgramas.tipo,".w,.p") > 0 /* Vamos compilar apenas arquivos .w e .p */
        :
        /* Executa a compilação do programa */
        compile value(ttProgramas.caminho) save no-error.
        if compiler:error then do:
            do i = 1 to compiler:num-messages:
                create ttErro.
                assign
                    ttErro.linha = string(compiler:get-error-row(i))
                    ttErro.coluna = string(compiler:get-error-column(i))
                    ttErro.erro = compiler:get-message(i).
            end.
        end.
    end.
    
    {&OPEN-QUERY-brw-erro-compilacao}
END.

Como pode ser notado neste ponto: {&OPEN-QUERY-brw-erro-compilacao}, foi inserido mais um browse para listar os erros que possam ter ocorrido durante o processo de compilação.

Neste ponto o programa deve ficar mais ou menos assim:

Como expliquei no inicio do guia não vou postar o programa pronto mas com esses códigos e uma breve explicação já é possível fazer um programa muito útil pra muitos dos desenvolvedores em progress.

Novos recursos podem ser trabalhados como:

  • listar programas compilados na pasta dos fonte (caso separem os dois).
  • eliminar registros selecionados ou todos registros listados no browse.
  • após compilado, já carregar os arquivos e mover para uma pasta destino, pra isso bastaria colocar um fill-in na tela para informar o destino e usar o comando “MOVE” do DOS para mover os arquivos.
  • Executar o programa selecionado.
  • Abrir o arquivo selecionado em um editor.

E centena de outras possibilidades.

One thought on “Criar ferramenta para buscar e compilar programas em progress ABL

  1. Excelente como sempre.
    Gostaria de agradecer por todas as publicações e informações contidas nesse Site.

    Ajudam muito mesmo.

Deixe um comentário

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.