Como exportar uma tabela diretamente para excel

Discussão em 'Progress 4GL' iniciado por rbaselio, Janeiro 26, 2011.

  1. rbaselio

    rbaselio Membro Participativo

    Talvez isso possa ajudar alguem.

    eu criei uma rotina que exporta uma tabela/temp-table diretamente para excel apenas informando o nome da tabela/temp-table, para isso é preciso ter esta include:

    Código:
    /****************FUNیES PARA EXCEL**********************/
    /*variaveis excel*/
    DEFINE VARIABLE chExcelApplication  as COM-HANDLE.
    DEFINE VARIABLE arquivo             AS COM-HANDLE.
    DEFINE VARIABLE aba                 AS COM-HANDLE.
    DEFINE VARIABLE lin                 AS INTEGER INIT 1    NO-UNDO.
    DEFINE VARIABLE colu                 AS INTEGER INIT 1    NO-UNDO.
    
    
    /*fun‡Æo para converter colunas em letras para o excel*/
    FUNCTION letra RETURNS CHAR (INPUT valor AS INT):
        IF valor <= 26 THEN RETURN CHR(valor + 64).
        ELSE IF valor MOD 26 = 0 THEN RETURN letra(int(TRUNCATE(((valor - 1) / 26), 0))) + letra(26).
        RETURN letra(int(TRUNCATE((valor / 26), 0))) + letra(valor MOD 26).
    END FUNCTION.
    
    /*inicia aplica‡Æo*/
    FUNCTION ini-excel RETURNS LOGICAL (INPUT dt AS char ):
        CREATE 'Excel.Application' chExcelApplication.
        ASSIGN
            chExcelApplication:VISIBLE = FALSE
            chExcelApplication:DisplayAlerts  = FALSE
            chExcelApplication:ScreenUpdating = FALSE
            arquivo = chExcelApplication:Workbooks:add(dt).
        IF dt = "" THEN DO:
            DO WHILE arquivo:sheets:COUNT > 1:
                arquivo:sheets:item(arquivo:sheets:COUNT):DELETE.
            END.
        END.
        aba = arquivo:sheets:ITEM(1).
        aba:activate.
        aba:Range("a1"):SELECT.
        RETURN TRUE.
    END FUNCTION.
    
    /*congela na linha selecionada para gerar cabe‡alhos fixos*/
    FUNCTION congelar RETURNS LOGICAL (INPUT linha AS int):
        aba:Range("a" + STRING(linha + 1)):SELECT.
        ASSIGN
            chExcelApplication:ActiveWindow:FreezePanes = TRUE.
        aba:Range("a1"):SELECT.
        RETURN TRUE.
    END FUNCTION.
    
    /*retorna um celula */
    FUNCTION celula RETURNS CHAR (INPUT coluna AS INT, INPUT linha AS INT):
        RETURN letra(coluna) + STRING(linha).
    END FUNCTION.
    
    /*retonna um range de celulas*/
    FUNCTION range RETURNS CHAR (INPUT colunaini AS INT, INPUT linhaini AS INT, INPUT colunafim AS INT, INPUT linhafim AS INT):
        RETURN celula(colunaini, linhaini) + ":" + celula(colunafim, linhafim).
    END FUNCTION.
    
    /*centraliza cria bordas e colore as celulas*/
    FUNCTION alinhar RETURNS LOGICAL (INPUT lin-ini AS INT, INPUT colu AS INT, INPUT lin-fim AS INT):
       DEFINE VARIABLE cor AS LOGICAL  INIT yes   NO-UNDO.
       DEFINE VARIABLE i AS INTEGER     NO-UNDO.
       IF lin-fim > 0 THEN DO:
           aba:range(range(1, 1, colu, lin-fim)):EntireColumn:AutoFit.
           aba:ROWs("1:" + STRING(lin-fim)):EntireRow:AutoFit.
           aba:range(range(1, 1, colu, lin-fim)):VerticalAlignment = 2.
           DO i = lin-ini TO lin-fim:
               ASSIGN
                   cor = NOT cor
                   aba:range(range(1, i, colu, i)):interior:colorindex = INT(cor) * 20
                   aba:range(range(1, i, colu, i)):Borders(8):LineStyle = 1
                   aba:range(range(1, i, colu, i)):Borders(2):LineStyle = 1
                   aba:range(range(1, i, colu, i)):Borders(4):LineStyle = 1
                   aba:range(range(1, i, colu, i)):Borders(1):LineStyle = 1.
           END.
       END.
       RETURN TRUE.
    END FUNCTION.
    
    /*finaliza aplica‡Æo*/
    FUNCTION fim-excel RETURNS LOGICAL ():
        aba = arquivo:sheets:ITEM(1).
        aba:activate.
        aba:Range("a1"):SELECT. 
        ASSIGN
            chExcelApplication:VISIBLE = TRUE
            chExcelApplication:DisplayAlerts  = true
            chExcelApplication:ScreenUpdating = true.
        RELEASE OBJECT arquivo.
        RELEASE OBJECT aba.
        RELEASE OBJECT chExcelApplication.
        RETURN TRUE.
    END FUNCTION.
    
    
    /**********************exportar tabela direto para excel**************************************/
    FUNCTION goto-excel RETURNS LOGICAL (INPUT tabela AS CHARACTER, INPUT inicio AS INT, INPUT clausula AS c):
        DEFINE VARIABLE i      AS INTEGER     NO-UNDO.
        DEFINE VARIABLE qh     AS HANDLE.
        DEFINE VARIABLE bh     as handle.
        DEFINE VARIABLE iCont  as int.
    
    
        CREATE QUERY qh.
        CREATE BUFFER bh FOR TABLE tabela.
        qh:SET-BUFFERS(bh). 
        qh:QUERY-PREPARE("for each " + tabela + " " + clausula).
        qh:QUERY-OPEN.
    
        ASSIGN
            lin = inicio
            colu = 1.
        do iCont = 1 to bh:num-fields:
            ASSIGN
                aba:Range(celula(colu,lin)):VALUE =  "'" + bh:buffer-field(iCont):label
                colu = colu + 1.
        END.
        ASSIGN
            colu = 1
            lin = lin + 1.
        DO WHILE (qh:GET-NEXT = YES):
            REPEAT i = 1 TO bh:num-fields.
                ASSIGN
                    aba:Range(celula(colu,LIN)):VALUE = STRING(bh:BUFFER-FIELD(i):BUFFER-VALUE)
                    colu = colu + 1.
            END.
            ASSIGN
                colu = 1
                lin = lin + 1.
        END.
        alinhar(inicio, bh:num-fields, lin).
    
    END FUNCTION.

    Para testar crie um programa assim:
    Código:
    {caminho\include.i} /*– caminho com a include onde esta a função*/
    
    ini-excel(""). /*– função para iniciar o Excel devendo informar o nome do arquivo ou uma string em branco para arquivo novo.*/
    
    congelar(1). /*– função para congelar linhas do cabeçalho, deve ser passado como parâmetro a linha onde será congelada*/
    
    goto-Excel("cod-rejeicao", 1, "where cod-rejeicao.codigo-rejei >= 100"). /*–  função que exporta a tabela, deve-se informar o nome da tabela, */
                                                                             /*a linha inicial igual a linha da função congelar e a clausula where, */
                                                                             /*se não houver passe uma string em branco.*/
    
    fim-Excel(). /*–  esta função encerra e mostra a relatório.*/
    Espero que esta função seja util.
  2. Rodrigo Rossetto

    Rodrigo Rossetto Membro Participativo

    Você também pode usar aba:cells(<lin>,<col>):value = "".
    Asim não precisa fazer conversão de range, apenas quando for uma área maior que uma celula.
  3. Rodrigo Rossetto

    Rodrigo Rossetto Membro Participativo

    Bom tópico! :ugeek:
  4. magsoa

    magsoa Sem Pontuação

    Bom dia,

    este programa é ótimo, parabéns por compartilhá-lo.

    Agora vamos aos problemas. Rodei o mesmo para a tabela TEXTO (EMS206) para extrair os registros TIPO "CC", que são aproximadamente 61000 registros e esta apresentando erro:
    ----------------
    Error ocurred while accessing component property/method: VALUE
    Exception occurred.
    Errod code: 0x80020009 goto-excel \\...\...\blablabla.ped (5890)
    ----------------
    Unable to set com-handle property. (5677)
    ----------------

    Att,

    Marco
  5. rbaselio

    rbaselio Membro Participativo

    Esse erro ocorre geralmente quando o excel não compreende o tipo da informação.

    logo abaixo de ini-excel("").

    inseira este comando e veja exatamente onde ele para
    ASSIGN
    chExcelApplication:VISIBLE = true
    chExcelApplication:DisplayAlerts =true
    chExcelApplication:ScreenUpdating = true.
  6. magsoa

    magsoa Sem Pontuação

    Adicionei os comandos mas não consegui debugar... mas ele executa até o fim mesmo assim..

Compartilhe esta Página