Integração com o Word através das funções OLE_* – Maratona AdvPL e TL++ 374

Nesse vídeo demonstraremos a utilização das funções OLE_* (OLE_CreateLink, OLE_SetDocumentVar, OLE_UpdateFields, etc), que servem para criar uma integração com um arquivo do Word.

Abaixo o código fonte desenvolvido para o exemplo em vídeo acima:

//Bibliotecas
#Include "TOTVS.ch"

/*/{Protheus.doc} User Function zExe374
Realiza a integração com o Microsoft Word, populando um arquivo de modelo dot
@type Function
@author Atilio
@since 28/03/2023
@see https://tdn.totvs.com/display/public/framework/OLE_CreateLink e https://tdn.totvs.com/display/public/framework/OLE_NewFile e https://tdn.totvs.com/pages/releaseview.action?pageId=603118924
@obs 

    Função OLE_CreateLink
    Parâmetros
        + cOLETypeLink   , Caractere    , String que representa a conexão com Word
        + cOnError       , Caractere    , Compatibilidade
        + lCabec         , Lógico       , Permite habilitar a edição de campos também no cabeçalho e rodapé do modelo do Word
    Retorno
        + hOleLink       , Numérico     , Handle criado

    Função OLE_NewFile
    Parâmetros
        + hOleLink       , Numérico     , Handle criado através da OLE_CreateLink
        + cDocTemplate   , Caractere    , Caminho com o modelo do documento do Word
    Retorno
        Função não tem retorno

    Função OLE_SetDocumentVar
    Parâmetros
        + hOleLink       , Numérico     , Handle criado através da OLE_CreateLink
        + cVariable      , Caractere    , Nome da variável dentro do modelo do Word
        + cValue         , Caractere    , Valor a ser atribuído
    Retorno
        Função não tem retorno

    Função OLE_UpdateFields
    Parâmetros
        + hOleLink       , Numérico     , Handle criado através da OLE_CreateLink
    Retorno
        Função não tem retorno
    
    Função OLE_SaveAsFile
    Parâmetros
        + hOleLink       , Numérico     , Handle criado através da OLE_CreateLink
        + cFileName      , Caractere    , Nome do arquivo que será salvo
        + cPassword      , Caractere    , Senha do arquivo do Word (caso haja)
        + cWritePassword , Caractere    , Senha que será definida na escrita do Word
        + lReadOnly      , Lógico       , Atributo se o arquivo será somente leitura
    Retorno
        Função não tem retorno

    **** Apoie nosso projeto, se inscreva em https://www.youtube.com/TerminalDeInformacao ****
/*/

User Function zExe374()
    Local aArea     := FWGetArea()
    Local aPergs    := {}
	Local cProduto  := Space(TamSX3('B1_COD')[1])
    
    //Adicionando os parametros do ParamBox
    aAdd(aPergs, {1, "Produto",  cProduto,  "", ".T.", "SB1", ".T.", 80,  .F.}) // MV_PAR01
    
    //Se a pergunta for confirma, cria as definicoes do relatorio
    If ParamBox(aPergs, "Informe os parâmetros", , , , , , , , , .F., .F.)
        Processa({|| fMontaRel()}, "Processando...")
    EndIf
     
    FWRestArea(aArea)
Return

Static Function fMontaRel()
    Local nHandWord  := 0
    Local cPastaTmp  := GetTempPath()
    Local cArqOrigi  := "\x_dots\produto.dotx"
    Local cArqLocal  := cPastaTmp + "produtos.dotx"
    Local cArqPDF    := cPastaTmp + "produtos.pdf"

    DbSelectArea("SB1")
    SB1->(DbSetOrder(1)) // Filial + Produto
    If SB1->(MsSeek(FWxFilial("SB1") + MV_PAR01))

        //Copia o dot do servidor para a máquina local
        __CopyFile(cArqOrigi, cArqLocal)

        //Cria um ponteiro e já chama o arquivo
        nHandWord := OLE_CreateLink()
        OLE_NewFile(nHandWord, cArqLocal)
        
        //Setando o conteúdo das DocVariables
        OLE_SetDocumentVar(nHandWord, "CodProduto",  Alltrim(SB1->B1_COD))
        OLE_SetDocumentVar(nHandWord, "DescProduto", Alltrim(SB1->B1_DESC))
        OLE_SetDocumentVar(nHandWord, "UnidProduto", Alltrim(SB1->B1_UM))
        OLE_SetDocumentVar(nHandWord, "DataGeracao", dToC(Date()))
        OLE_SetDocumentVar(nHandWord, "HoraGeracao", Time())
        
        //Atualizando campos
        OLE_UpdateFields(nHandWord)
        
        //Gera o PDF do documento
        OLE_SetProperty(nHandWord,'208',.F.)
        OLE_SaveAsFile( nHandWord, cArqPDF, , , .F., 17 )

        //Fechando o arquivo e o link
        OLE_CloseFile(nHandWord)
        Sleep(1000)
        OLE_CloseLink(nHandWord)

        //Abre o PDF
        ShellExecute("OPEN", cArqPDF, "", cPastaTmp, 1 )

    Else
        FWAlertError("Produto não encontrado!", "Falha")
    EndIf
Return

Bom pessoal, por hoje é só.

Abraços e até a próxima.

Dan (Daniel Atilio)
Cristão de ramificação protestante. Especialista em Engenharia de Software pela FIB, graduado em Banco de Dados pela FATEC Bauru e técnico em informática pelo CTI da Unesp. Entusiasta de soluções Open Source e blogueiro nas horas vagas. Autor e mantenedor do portal Terminal de Informação.

2 Responses

  1. Boa Tarde, estou tentando utlizar estas funções porem não gerar um arquivo .DOC ou .DOCx, somente consigo gravar como .PDF. o que estou fazendo de errado?

    segue o fonte:

    Static Function fMontaRel()
    Local nHandWord := 0
    Local cPastaTmp := GetTempPath()
    Local cPath := Alltrim(GetMV(“MV_QPATHWD”)) //path padrao dos modelos \SYSTEM\MODELOS\
    // Local cPathWT := Alltrim(GetMV(“MV_QPATHWT”)) //path do diretorio temp do windows C:\TEMP\
    // Local cArqOrigi := ” ”
    Local cArqLocal := cPastaTmp
    Local cArqPDF := cPastaTmp
    Local cArqGERAR := “Contrato_”
    Local cQrysCN9 := “”
    Local ix := 0
    Local aLinha := {}
    Local aPrazo := {}
    Local cNomeEmp := ” //FWCompanyName()s
    Local aCampos := { ;
    “M0_CODIGO”,; //Posição [1]
    “M0_CODFIL”,; //Posição [2]
    “M0_NOMECOM”,; //Posição [3]
    “M0_CGC”,; //Posição [4]
    “M0_INSCM”,; //Posição [5]
    “M0_CIDENT”,; //Posição [6]
    “M0_ESTENT”,; //Posição [7]
    “M0_ENDENT”,; //Posição [8]
    “M0_BAIRENT”,; //Posição [9]
    “M0_CEPENT”,; //Posição [10]
    “M0_COMPENT”,; //Posição [11]
    “M0_TEL”; //Posição [12]
    }
    //Busca os campos da filial “01”
    aEmpresa := FWSM0Util():GetSM0Data(, cFilAnt, aCampos)

    //Se encontrou, monta uma mensagem e exibe
    If Len(aEmpresa) > 0
    cNomeEmp := aEmpresa[3][2]
    EndIf

    cArqGERAR:= cArqGERAR+MV_PAR01
    cArqPDF := cPastaTmp +cArqGERAR+”.pdf”
    cArqDoc := cPastaTmp +cArqGERAR+”.doc”
    cQrySCN9 := “SELECT CN9_NUMERO,CN9_DTINIC,CN9_DTFIM,CN9_CODOBJ,CN9_TPCTO,CN9_VLATU,CNB_PRODUT,CNB_DESCRI,CNB_UM,CNB_QUANT,CNC_CODIGO,CNC_LOJA,A2_NOME,A2_END,A2_NR_END,A2_BAIRRO,A2_PAIS,YA_DESCR,YA_SIGLA,YA_PAIS_I,CNB_DTCAD,CN9_VIGE,CN9_UNVIGE ”
    cQrySCN9 += “FROM ” + RetSqlName(“CN9″) + ” CN9 ”
    cQrySCN9 += ” INNER JOIN ” + RetSqlName(“CNB”) + ” CNB ON CNB_CONTRA = CN9_NUMERO AND CNB_FILIAL = ‘”+ xFilial(“CNB”) + “‘ AND CNB.D_E_L_E_T_ ‘*’
    cQrySCN9 += ” INNER JOIN ” + RetSqlName(“CNC”) + ” CNC ON CNC_NUMERO = CN9_NUMERO AND CNC_FILIAL = ‘”+ xFilial(“CNC”) + “‘ AND CNC.D_E_L_E_T_ ‘*’ ”
    cQrySCN9 += ” INNER JOIN ” + RetSqlName(“SA2″) + ” SA2 ON A2_COD+A2_LOJA = CNC_CODIGO+CNC_LOJA AND SA2.D_E_L_E_T_ ‘*’ ”
    cQrySCN9 += ” INNER JOIN ” + RetSqlName(“SYA”) + ” SYA ON YA_CODGI = A2_PAIS AND SYA.D_E_L_E_T_ ‘*’ ”
    cQrySCN9 += “WHERE CN9_FILIAL = ‘”+ xFilial(“CN9”) + “‘ AND CN9.D_E_L_E_T_ ‘*’ AND CN9_NUMERO = ‘” +MV_PAR01+”‘ ”

    If Select(“TMPCN9”) > 0
    TMPCN9->(DbCloseArea())
    Endif

    Tcquery cQrySCN9 New Alias “TMPCN9”
    if !TMPCN9->(Eof())
    TMPCN9->(DbGoTop())
    WHILE !TMPCN9->(Eof())
    do case
    case alltrim(TMPCN9->YA_SIGLA) $ ‘MEX’
    cArqDOT := Alltrim(“M_CONTRATO_MEXICO.dotx”) //nome do arquivo .DOT
    Case alltrim(TMPCN9->YA_SIGLA) ‘MEX’
    cArqDOT := Alltrim(“Modelo_contrato.dotx”) //nome do arquivo .DOT
    Endcase
    cPathDOT := cPath + cArqDOT
    cArqLocal:= cPastaTmp+cArqDOT
    cNpj := substring(alltrim(aEmpresa[4][2]),1,2)+’.’+substring(alltrim(aEmpresa[4][2]),3,3)+’.’+substring(alltrim(aEmpresa[4][2]),5,3)
    cNpj += ‘/’+substring(alltrim(aEmpresa[4][2]),9,4)+’-‘+substring(alltrim(aEmpresa[4][2]),13,2)
    // 04400995000309
    //04.400.995/0003-09

    cFornGDP := alltrim(cNomeEmp)+’ E ‘+alltrim(TMPCN9->A2_NOME)
    cFornGDI := alltrim(cNomeEmp)+’ AND ‘+alltrim(TMPCN9->A2_NOME)

    cForncedp := alltrim(TMPCN9->A2_NOME)
    cForncedi := alltrim(TMPCN9->A2_NOME)
    cEndeForp := alltrim(TMPCN9->A2_END)+’ ‘+alltrim(TMPCN9->A2_NR_END)+’ ‘+alltrim(TMPCN9->A2_BAIRRO)+’ ‘+alltrim(TMPCN9->YA_DESCR)+’ ‘+alltrim(TMPCN9->YA_SIGLA)
    cEndeFori := alltrim(TMPCN9->A2_END)+’ ‘+alltrim(TMPCN9->A2_NR_END)+’ ‘+alltrim(TMPCN9->A2_BAIRRO)+’ ‘+alltrim(TMPCN9->YA_PAIS_I)+’ ‘+alltrim(+TMPCN9->YA_SIGLA)

    cNomeEmpp := alltrim(cNomeEmp)
    cNomeEmpi := alltrim(cNomeEmp)
    cEndeEmpp := ‘Localizada na ‘+alltrim(aEmpresa[8][2])+’,’+alltrim(aEmpresa[9][2])+’,’+alltrim(aEmpresa[6][2])+’,’+alltrim(aEmpresa[7][2])
    cEndeEmpp += ‘ Brasil, inscrita no CNPJ/MF sob nº ‘+ alltrim(cNpj)+’ ‘
    cEndeEmpI := ‘Located in ‘+alltrim(aEmpresa[8][2])+’, ‘+alltrim(aEmpresa[9][2])+’, ‘+alltrim(aEmpresa[6][2])+’,’+alltrim(aEmpresa[7][2])
    cEndeEmpI += ‘ Brasil, Registered in CNPJ/MF under nº ‘+ alltrim(cNpj)+’ ‘

    SYP->(dbsetorder(1)) //YP_FILIAL+YP_CHAVE+YP_SEQ
    IF SYP->(DBSeek(xFilial(“SYP”)+TMPCN9->CN9_CODOBJ))
    WHILE !SYP->(EOF()) .AND. SYP->YP_CHAVE = TMPCN9->CN9_CODOBJ
    aadd(aLinha,{SYP->YP_TEXTO })
    SYP->(dbSkip())
    enddo
    Endif
    aLinha:=AjustLin(aLinha)
    aPrazo := gdDtExten(TMPCN9->CN9_VIGE,TMPCN9->CN9_UNVIGE)

    datainP:= cValToChar(Day(stod(TMPCN9->CN9_DTINIC)))+ ” de “+ MesExtenso(stod(TMPCN9->CN9_DTINIC))+ ” de “+ cValToChar(Year(stod(TMPCN9->CN9_DTINIC)))
    datainI:= cMONTH(stod(TMPCN9->CN9_DTINIC))+” “+alltrim(str(day(stod(TMPCN9->CN9_DTINIC))))+”th, “+alltrim(str(year(stod(TMPCN9->CN9_DTINIC))))
    datafip:= cValToChar(Day(stod(TMPCN9->CN9_DTFIM)))+ ” de “+ MesExtenso(stod(TMPCN9->CN9_DTFIM))+ ” de “+ cValToChar(Year(stod(TMPCN9->CN9_DTFIM)))
    DataFiI:= cMONTH(stod(TMPCN9->CN9_DTFIM))+” “+alltrim(str(day(stod(TMPCN9->CN9_DTFIM))))+”th, “+alltrim(str(year(stod(TMPCN9->CN9_DTFIM))))
    QtdMesP:= aPrazo[1][1]+aPrazo[1][2]
    QtdMesI:= aPrazo[1][1]+aPrazo[1][3]
    Valor := transform(TMPCN9->CN9_VLATU,”@e 9,999.99″)
    exvalorP := Extenso(TMPCN9->CN9_VLATU,.f.,1,,”1″)
    ExvalorI := Extenso(TMPCN9->CN9_VLATU,.f.,1,,”3″)
    DataATp := cValToChar(Day(stod(TMPCN9->CNB_DTCAD)))+ ” de “+ MesExtenso(stod(TMPCN9->CNB_DTCAD))+ ” de “+ cValToChar(Year(stod(TMPCN9->CNB_DTCAD)))
    DataATi := cMONTH(stod(TMPCN9->CNB_DTCAD))+” “+alltrim(str(day(stod(TMPCN9->CNB_DTCAD))))+”th, “+alltrim(str(year(stod(TMPCN9->CNB_DTCAD))))

    //Copia o dot do servidor para a máquina local
    __CopyFile(cPathDOT, cArqLocal)

    //Cria um ponteiro e já chama o arquivo
    nHandWord := OLE_CreateLink()
    OLE_NewFile(nHandWord, cArqLocal)

    //Setando o conteúdo das DocVariables
    OLE_SetDocumentVar(nHandWord, “FornGDP”,cFornGDP)
    OLE_SetDocumentVar(nHandWord, “FornGDI”,cFornGDI)

    OLE_SetDocumentVar(nHandWord,”Forncedp”,cForncedp)
    OLE_SetDocumentVar(nHandWord,”Forncedi”,cForncedi)
    OLE_SetDocumentVar(nHandWord,”EndeForp”,cEndeForp)
    OLE_SetDocumentVar(nHandWord,”EndeFori”,cEndeFori)

    OLE_SetDocumentVar(nHandWord,”NomeEmpp”,cNomeEmpp)
    OLE_SetDocumentVar(nHandWord,”NomeEmpi”,cNomeEmpi)
    OLE_SetDocumentVar(nHandWord,”EndeEmpp”,cEndeEmpp)
    OLE_SetDocumentVar(nHandWord,”EndeEmpI”,cEndeEmpI)
    FOR IX := 1 to LEN(aLinha)
    cObjeto:=’cObj’+StrZero(ix,2)
    OLE_SetDocumentVar(nHandWord,cObjeto,aLinha[ix][1])
    Next

    OLE_SetDocumentVar(nHandWord,”cdatainP” ,datainP)
    OLE_SetDocumentVar(nHandWord,”cdatainI” ,datainI)
    OLE_SetDocumentVar(nHandWord,”cdatafip” ,datafip)
    OLE_SetDocumentVar(nHandWord,”cDataFiI” ,DataFiI)
    OLE_SetDocumentVar(nHandWord,”cQtdMesP” ,QtdMesP)
    OLE_SetDocumentVar(nHandWord,”cQtdMesI” ,QtdMesI)
    OLE_SetDocumentVar(nHandWord,”cValor” ,Valor)
    OLE_SetDocumentVar(nHandWord,”cexvalorP”,exvalorP)
    OLE_SetDocumentVar(nHandWord,”cExvalorI”,ExvalorI)

    OLE_SetDocumentVar(nHandWord,”cDataATp”,DataATp)
    OLE_SetDocumentVar(nHandWord,”cDataATi”,DataATi)

    //Atualizando campos
    OLE_UpdateFields(nHandWord)
    //OLE_OPENFILE(oWord,”C:\WINDOWS\TEMP\EXEMPLO.DOC”,lReadOnly,”SENHAXXX”,”SENHAWWW”)
    OLE_SaveAsFile( nHandWord, cArqDoc, , , .T., 17 )
    OLE_OPENFILE(nHandWord,cArqDoc,.T.,,)

    //Gera o PDF do documento
    OLE_SetProperty(nHandWord,’208’,.T.)
    OLE_SaveAsFile( nHandWord, cArqDoc, , , .T., 17 )
    //Fechando o arquivo e o link
    OLE_CloseFile(nHandWord)
    Sleep(1000)
    OLE_CloseLink(nHandWord)
    //Abre o PDF
    ShellExecute(“OPEN”, cArqPDF, “”, cPastaTmp, 1 )

    TMPCN9->(DbSkip())
    Enddo

Deixe uma resposta

Terminal de Informação