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.
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
Bom dia xará, tudo joia?
É o OLE_SetProperty junto com o OLE_SaveAsFile, que estão causando esse comportamento de gerar como PDF.
Nesse link tem um exemplo de gerar sem ser PDF: https://terminaldeinformacao.com/2019/01/02/gerando-um-arquivo-word-pelo-advpl-usando-integracao-modelos-dot/
Tenha uma ótima e abençoada quinta feira.
Um forte abraço.