Exemplos de geração de arquivo para o Excel via AdvPL

Olá pessoal…

Hoje vou mostrar exemplos de como gerar arquivos para o Excel, utilizando o AdvPL e as classes FWMsExcel e FWMSExcelEx.


Existem duas classes para geração de arquivos xml do Excel, a FWMsExcel e a FWMsExcelEx, a segunda tem mais opções de edição de atributos de uma célula.

Abaixo irei mostrar 4 exemplos:
– Exemplo simples de FWMsExcel
– Exemplo simples de FWMsExcelEx
– Exemplo de FWMsExcel com cores e fonte diferente
– Exemplo de FWMsExcel com colunas dinâmicas (Produtos por dias de venda)

Exemplo simples de FWMsExcel:

Exemplo simples de FWMsExcel

Exemplo simples de FWMsExcel

Abaixo o código fonte utilizado:

//Bibliotecas
#Include "Protheus.ch"
#Include "TopConn.ch"

//Constantes
#Define STR_PULA	Chr(13)+Chr(10)

/*/{Protheus.doc} zTstExc1
Função que cria um exemplo de FWMsExcel
@author Atilio
@since 06/08/2016
@version 1.0
	@example
	u_zTstExc1()
/*/

User Function zTstExc1()
	Local aArea		:= GetArea()
	Local cQuery		:= ""
	Local oFWMsExcel
	Local oExcel
	Local cArquivo	:= GetTempPath()+'zTstExc1.xml'

	//Pegando os dados
	cQuery := " SELECT "													+ STR_PULA
	cQuery += " 	SB1.B1_COD, "											+ STR_PULA
	cQuery += " 	SB1.B1_DESC, "										+ STR_PULA
	cQuery += " 	SB1.B1_TIPO, "										+ STR_PULA
	cQuery += " 	SBM.BM_GRUPO, "										+ STR_PULA
	cQuery += " 	SBM.BM_DESC, "										+ STR_PULA
	cQuery += " 	SBM.BM_PROORI "										+ STR_PULA
	cQuery += " FROM "													+ STR_PULA
	cQuery += " 	"+RetSQLName('SB1')+" SB1 "							+ STR_PULA
	cQuery += " 	INNER JOIN "+RetSQLName('SBM')+" SBM ON ( "		+ STR_PULA
	cQuery += " 		SBM.BM_FILIAL = '"+FWxFilial('SBM')+"' "		+ STR_PULA
	cQuery += " 		AND SBM.BM_GRUPO = B1_GRUPO "					+ STR_PULA
	cQuery += " 		AND SBM.D_E_L_E_T_='' "							+ STR_PULA
	cQuery += " 	) "														+ STR_PULA
	cQuery += " WHERE "													+ STR_PULA
	cQuery += " 	SB1.B1_FILIAL = '"+FWxFilial('SBM')+"' "			+ STR_PULA
	cQuery += " 	AND SB1.D_E_L_E_T_ = '' "							+ STR_PULA
	cQuery += " ORDER BY "												+ STR_PULA
	cQuery += " 	SB1.B1_COD "											+ STR_PULA
	TCQuery cQuery New Alias "QRYPRO"
	
	//Criando o objeto que irá gerar o conteúdo do Excel
	oFWMsExcel := FWMSExcel():New()
	
	//Aba 01 - Teste
	oFWMsExcel:AddworkSheet("Aba 1 Teste") //Não utilizar número junto com sinal de menos. Ex.: 1-
		//Criando a Tabela
		oFWMsExcel:AddTable("Aba 1 Teste","Titulo Tabela")
		//Criando Colunas
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col1",1,1) //1 = Modo Texto
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col2",2,2) //2 = Valor sem R$
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col3",3,3) //3 = Valor com R$
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col4",1,1)
		//Criando as Linhas
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{11,12,13,sToD('20140317')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{21,22,23,sToD('20140217')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{31,32,33,sToD('20140117')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{41,42,43,sToD('20131217')})
	
	
	//Aba 02 - Produtos
	oFWMsExcel:AddworkSheet("Aba 2 Produtos")
		//Criando a Tabela
		oFWMsExcel:AddTable("Aba 2 Produtos","Produtos")
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Codigo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Descricao",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Tipo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Grupo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Desc.Grupo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Procedencia",1)
		//Criando as Linhas... Enquanto não for fim da query
		While !(QRYPRO->(EoF()))
			oFWMsExcel:AddRow("Aba 2 Produtos","Produtos",{;
																	QRYPRO->B1_COD,;
																	QRYPRO->B1_DESC,;
																	QRYPRO->B1_TIPO,;
																	QRYPRO->BM_GRUPO,;
																	QRYPRO->BM_DESC,;
																	Iif(QRYPRO->BM_PROORI == '0', 'Não Original', 'Original');
			})
		
			//Pulando Registro
			QRYPRO->(DbSkip())
		EndDo
	
	//Ativando o arquivo e gerando o xml
	oFWMsExcel:Activate()
	oFWMsExcel:GetXMLFile(cArquivo)
		
	//Abrindo o excel e abrindo o arquivo xml
	oExcel := MsExcel():New() 			//Abre uma nova conexão com Excel
	oExcel:WorkBooks:Open(cArquivo) 	//Abre uma planilha
	oExcel:SetVisible(.T.) 				//Visualiza a planilha
	oExcel:Destroy()						//Encerra o processo do gerenciador de tarefas
	
	QRYPRO->(DbCloseArea())
	RestArea(aArea)
Return


Exemplo simples de FWMsExcelEx:

Exemplo simples de FWMsExcelEx

Exemplo simples de FWMsExcelEx

Abaixo o código fonte utilizado:

//Bibliotecas
#Include "Protheus.ch"
#Include "TopConn.ch"

//Constantes
#Define STR_PULA	Chr(13)+Chr(10)

/*/{Protheus.doc} zTstExc2
Função que cria um exemplo de FWMSExcelEx
@author Atilio
@since 06/08/2016
@version 1.0
	@example
	u_zTstExc2()
/*/

User Function zTstExc2()
	Local cArquivo	:= GetTempPath()+'zTstExc2c.xml'
	Local oFWMSEx		:= FWMsExcelEx():New()
	Local oExcel
	
	//Criando a Aba Teste 1
	oFWMSEx:AddworkSheet("Teste - 1")
		//Adicionando a tabela
		oFWMSEx:AddTable ("Teste - 1","Titulo de teste 1")
			//Adicionando as colunas
			oFWMSEx:AddColumn("Teste - 1","Titulo de teste 1","Col1",1,1)
			oFWMSEx:AddColumn("Teste - 1","Titulo de teste 1","Col2",2,2)
			oFWMSEx:AddColumn("Teste - 1","Titulo de teste 1","Col3",3,3)
			oFWMSEx:AddColumn("Teste - 1","Titulo de teste 1","Col4",1,1)
			
				//Alterando atributos da linha e adicionando
				oFWMSEx:SetCelBold(.T.)
				oFWMSEx:SetCelFont('Arial')
				oFWMSEx:SetCelItalic(.T.)
				oFWMSEx:SetCelUnderLine(.T.)
				oFWMSEx:SetCelSizeFont(10)
				oFWMSEx:AddRow("Teste - 1","Titulo de teste 1",{11,12,13,14},{1,3})
				
				//Alterando atributos da linha e adicionando
				oFWMSEx:SetCelBold(.T.)
				oFWMSEx:SetCelFont('Arial')
				oFWMSEx:SetCelItalic(.T.)
				oFWMSEx:SetCelUnderLine(.T.)
				oFWMSEx:SetCelSizeFont(15)
				oFWMSEx:SetCelFrColor("#FFFFFF")
				oFWMSEx:SetCelBgColor("#000666")
				oFWMSEx:AddRow("Teste - 1","Titulo de teste 1",{21,22,23,24},{1})
				
				//Alterando atributos da linha e adicionando
				oFWMSEx:SetCelBold(.T.)
				oFWMSEx:SetCelFont('Courier New')
				oFWMSEx:SetCelItalic(.F.)
				oFWMSEx:SetCelUnderLine(.T.)
				oFWMSEx:SetCelSizeFont(10)
				oFWMSEx:SetCelFrColor("#FFFFFF")
				oFWMSEx:SetCelBgColor("#000333")
				oFWMSEx:AddRow("Teste - 1","Titulo de teste 1",{31,32,33,34},{2,4})
				
				//Alterando atributos da linha e adicionando
				oFWMSEx:SetCelBold(.T.)
				oFWMSEx:SetCelFont('Line Draw')
				oFWMSEx:SetCelItalic(.F.)
				oFWMSEx:SetCelUnderLine(.F.)
				oFWMSEx:SetCelSizeFont(12)
				oFWMSEx:SetCelFrColor("#FFFFFF")
				oFWMSEx:SetCelBgColor("#D7BCFB")
				oFWMSEx:AddRow("Teste - 1","Titulo de teste 1",{41,42,43,44},{3})
	
	//Adicionando aba Teste 2
	oFWMSEx:AddworkSheet("Teste - 2")
		//Adicionando a tabela
		oFWMSEx:AddTable("Teste - 2","Titulo de teste 1")
			//Adicionando as colunas
			oFWMSEx:AddColumn("Teste - 2","Titulo de teste 1","Col1",1)
			oFWMSEx:AddColumn("Teste - 2","Titulo de teste 1","Col2",2)
			oFWMSEx:AddColumn("Teste - 2","Titulo de teste 1","Col3",3)
			oFWMSEx:AddColumn("Teste - 2","Titulo de teste 1","Col4",1)
			//Adicionando as linhas
			oFWMSEx:AddRow("Teste - 2","Titulo de teste 1",{11,12,13,stod("20121212")})
			oFWMSEx:AddRow("Teste - 2","Titulo de teste 1",{21,22,23,stod("20121212")})
			oFWMSEx:AddRow("Teste - 2","Titulo de teste 1",{31,32,33,stod("20121212")})
			oFWMSEx:AddRow("Teste - 2","Titulo de teste 1",{41,42,43,stod("20121212")})
			oFWMSEx:AddRow("Teste - 2","Titulo de teste 1",{51,52,53,stod("20121212")})
		
	//Criando o XML
	oFWMSEx:Activate()
	oFWMSEx:GetXMLFile(cArquivo)
	
	//Abrindo o excel e abrindo o arquivo xml
	oExcel := MsExcel():New() 			//Abre uma nova conexão com Excel
	oExcel:WorkBooks:Open(cArquivo) 	//Abre uma planilha
	oExcel:SetVisible(.T.) 				//Visualiza a planilha
	oExcel:Destroy()						//Encerra o processo do gerenciador de tarefas
Return


Exemplo de FWMsExcel com cores e fonte diferente:

Exemplo de FWMsExcel com cores e fonte diferente

Exemplo de FWMsExcel com cores e fonte diferente

Abaixo o código fonte utilizado:

//Bibliotecas
#Include "Protheus.ch"
#Include "TopConn.ch"

//Constantes
#Define STR_PULA	Chr(13)+Chr(10)

/*/{Protheus.doc} zTstExc3
Função que cria um exemplo de FWMsExcel utilizando outras cores e fontes
@author Atilio
@since 06/08/2016
@version 1.0
	@example
	u_zTstExc3()
/*/

User Function zTstExc3()
	Local aArea		:= GetArea()
	Local cQuery		:= ""
	Local oFWMsExcel
	Local oExcel
	Local cArquivo	:= GetTempPath()+'zTstExc3.xml'

	//Pegando os dados
	cQuery := " SELECT "													+ STR_PULA
	cQuery += " 	SB1.B1_COD, "											+ STR_PULA
	cQuery += " 	SB1.B1_DESC, "										+ STR_PULA
	cQuery += " 	SB1.B1_TIPO, "										+ STR_PULA
	cQuery += " 	SBM.BM_GRUPO, "										+ STR_PULA
	cQuery += " 	SBM.BM_DESC, "										+ STR_PULA
	cQuery += " 	SBM.BM_PROORI "										+ STR_PULA
	cQuery += " FROM "													+ STR_PULA
	cQuery += " 	"+RetSQLName('SB1')+" SB1 "							+ STR_PULA
	cQuery += " 	INNER JOIN "+RetSQLName('SBM')+" SBM ON ( "		+ STR_PULA
	cQuery += " 		SBM.BM_FILIAL = '"+FWxFilial('SBM')+"' "		+ STR_PULA
	cQuery += " 		AND SBM.BM_GRUPO = B1_GRUPO "					+ STR_PULA
	cQuery += " 		AND SBM.D_E_L_E_T_='' "							+ STR_PULA
	cQuery += " 	) "														+ STR_PULA
	cQuery += " WHERE "													+ STR_PULA
	cQuery += " 	SB1.B1_FILIAL = '"+FWxFilial('SBM')+"' "			+ STR_PULA
	cQuery += " 	AND SB1.D_E_L_E_T_ = '' "							+ STR_PULA
	cQuery += " ORDER BY "												+ STR_PULA
	cQuery += " 	SB1.B1_COD "											+ STR_PULA
	TCQuery cQuery New Alias "QRYPRO"
	
	//Criando o objeto que irá gerar o conteúdo do Excel
	oFWMsExcel := FWMSExcel():New()
	
	//Alterando atributos
	oFWMsExcel:SetFontSize(12)                 //Tamanho Geral da Fonte
	oFWMsExcel:SetFont("Arial")                //Fonte utilizada
	oFWMsExcel:SetBgGeneralColor("#000000")    //Cor de Fundo Geral
	oFWMsExcel:SetTitleBold(.T.)               //Título Negrito
	oFWMsExcel:SetTitleFrColor("#94eaff")      //Cor da Fonte do título - Azul Claro
	oFWMsExcel:SetLineFrColor("#d4d4d4")       //Cor da Fonte da primeira linha - Cinza Claro
	oFWMsExcel:Set2LineFrColor("#ffffff")      //Cor da Fonte da segunda linha - Branco
	
	//Aba 01 - Teste
	oFWMsExcel:AddworkSheet("Aba 1 Teste") //Não utilizar número junto com sinal de menos. Ex.: 1-
		//Criando a Tabela
		oFWMsExcel:AddTable("Aba 1 Teste","Titulo Tabela")
		//Criando Colunas
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col1",1,1) //1 = Modo Texto
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col2",2,2) //2 = Valor sem R$
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col3",3,3) //3 = Valor com R$
		oFWMsExcel:AddColumn("Aba 1 Teste","Titulo Tabela","Col4",1,1)
		//Criando as Linhas
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{11,12,13,sToD('20140317')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{21,22,23,sToD('20140217')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{31,32,33,sToD('20140117')})
		oFWMsExcel:AddRow("Aba 1 Teste","Titulo Tabela",{41,42,43,sToD('20131217')})
	
	
	//Aba 02 - Produtos
	oFWMsExcel:AddworkSheet("Aba 2 Produtos")
		//Criando a Tabela
		oFWMsExcel:AddTable("Aba 2 Produtos","Produtos")
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Codigo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Descricao",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Tipo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Grupo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Desc.Grupo",1)
		oFWMsExcel:AddColumn("Aba 2 Produtos","Produtos","Procedencia",1)
		//Criando as Linhas... Enquanto não for fim da query
		While !(QRYPRO->(EoF()))
			oFWMsExcel:AddRow("Aba 2 Produtos","Produtos",{;
																	QRYPRO->B1_COD,;
																	QRYPRO->B1_DESC,;
																	QRYPRO->B1_TIPO,;
																	QRYPRO->BM_GRUPO,;
																	QRYPRO->BM_DESC,;
																	Iif(QRYPRO->BM_PROORI == '0', 'Não Original', 'Original');
			})
		
			//Pulando Registro
			QRYPRO->(DbSkip())
		EndDo
	
	//Ativando o arquivo e gerando o xml
	oFWMsExcel:Activate()
	oFWMsExcel:GetXMLFile(cArquivo)
		
	//Abrindo o excel e abrindo o arquivo xml
	oExcel := MsExcel():New() 			//Abre uma nova conexão com Excel
	oExcel:WorkBooks:Open(cArquivo) 	//Abre uma planilha
	oExcel:SetVisible(.T.) 				//Visualiza a planilha
	oExcel:Destroy()						//Encerra o processo do gerenciador de tarefas
	
	QRYPRO->(DbCloseArea())
	RestArea(aArea)
Return


Exemplo de FWMsExcel com colunas dinâmicas (Produtos por dias de venda):

Exemplo de FWMsExcel com colunas dinâmicas (Produtos por dias de venda)

Exemplo de FWMsExcel com colunas dinâmicas (Produtos por dias de venda)

Abaixo o código fonte utilizado:

//Bibliotecas
#Include "Protheus.ch"
#Include "TopConn.ch"

//Constantes
#Define STR_PULA	Chr(13)+Chr(10)

/*/{Protheus.doc} zTstExc4
Função que cria um exemplo de FWMsExcel com colunas dinâmicas
@author Atilio
@since 06/08/2016
@version 1.0
	@example
	u_zTstExc4()
/*/

User Function zTstExc4()
	Local aArea		:= GetArea()
	Local cQryCol		:= ""
	Local cQryPro		:= ""
	Local cQryVen		:= ""
	Local nAux			:= 0
	Local oFWMsExcel
	Local oExcel
	Local cArquivo	:= GetTempPath()+'zTstExc4.xml'
	Local cWorkSheet	:= "Aba - Produtos"
	Local cTable		:= "Produtos x Datas"
	Local aColunas	:= {}
	Local dDataDe		:= sToD("20150101")
	Local dDataAt		:= sToD("20161231")
	Local aLinhaAux	:= {}
	
	//Buscando as datas que tiveram pedidos
	cQryCol := " SELECT DISTINCT "
	cQryCol += " 	C5_EMISSAO "
	cQryCol += " FROM "
	cQryCol += " 	"+RetSQLName('SC5')+" SC5 "
	cQryCol += " WHERE "
	cQryCol += " 	C5_FILIAL = '"+FWxFilial('SC5')+"' "
	cQryCol += " 	AND C5_TIPO = 'N' "
	cQryCol += " 	AND C5_EMISSAO >= '"+dToS(dDataDe)+"' "
	cQryCol += " 	AND C5_EMISSAO <= '"+dToS(dDataAt)+"' "
	cQryCol += " 	AND SC5.D_E_L_E_T_ = ' ' "
	cQryCol += " ORDER BY "
	cQryCol += " 	C5_EMISSAO "
	TCQuery cQryCol New Alias "QRY_COL"
	TCSetField("QRY_COL", "C5_EMISSAO", "D")

	//Compondo as colunas do relatório
	aAdd(aColunas, "Produto")
	aAdd(aColunas, "Descrição")
	While !QRY_COL->(EoF())
		aAdd(aColunas, dToC(QRY_COL->C5_EMISSAO))
		QRY_COL->(DbSkip())
	EndDo
	QRY_COL->(DbCloseArea())
	
	//Montando a consulta de produtos
	cQryPro := " SELECT "
	cQryPro += " 	B1_COD, "
	cQryPro += " 	B1_DESC "
	cQryPro += " FROM "
	cQryPro += " 	"+RetSQLName('SB1')+" SB1 "
	cQryPro += " WHERE "
	cQryPro += " 	B1_FILIAL = '"+FWxFilial('SB1')+"' "
	cQryPro += " 	AND B1_TIPO = 'PA' "
	cQryPro += " 	AND SB1.D_E_L_E_T_ = ' ' "
	cQryPro += " ORDER BY "
	cQryPro += " 	B1_COD "
	TCQuery cQryPro New Alias "QRY_PRO"
	
	//Criando o objeto que irá gerar o conteúdo do Excel
	oFWMsExcel := FWMSExcel():New()
	
	//Aba 01 - Teste
	oFWMsExcel:AddworkSheet(cWorkSheet) //Não utilizar número junto com sinal de menos. Ex.: 1-
		
		//Criando a Tabela
		oFWMsExcel:AddTable(cWorkSheet, cTable)
		
		//Criando Colunas
		For nAux := 1 To Len(aColunas)
			oFWMsExcel:AddColumn(cWorkSheet, cTable, aColunas[nAux], 1, 1)
		Next
		
		//Percorrendo os produtos
		While !QRY_PRO->(EoF())
			//Criando a linha
			aLinhaAux := Array(Len(aColunas))
			aLinhaAux[1] := QRY_PRO->B1_COD
			aLinhaAux[2] := QRY_PRO->B1_DESC
			For nAux := 3 To Len(aColunas)
				cQryVen := " SELECT "
				cQryVen += " 	ISNULL(SUM(C6_QTDVEN),0) AS TOT "
				cQryVen += " FROM "
				cQryVen += " 	"+RetSQLName('SC6')+" SC6 "
				cQryVen += " 	INNER JOIN "+RetSQLName('SC5')+" SC5 ON ( "
				cQryVen += " 		C5_FILIAL = '"+FWxFilial('SC5')+"' "
				cQryVen += " 		AND C5_NUM = C6_NUM "
				cQryVen += " 		AND C5_TIPO = 'N' "
				cQryVen += " 		AND C5_EMISSAO = '"+dToS(cToD(aColunas[nAux]))+"' "
				cQryVen += " 		AND SC5.D_E_L_E_T_ = ' ' "
				cQryVen += " 	) "
				cQryVen += " 	INNER JOIN "+RetSQLName('SB1')+" SB1 ON ( "
				cQryVen += " 		B1_FILIAL = '"+FWxFilial('SB1')+"' "
				cQryVen += " 		AND B1_COD = C6_PRODUTO "
				cQryVen += " 		AND B1_TIPO = 'PA' "
				cQryVen += " 		AND SB1.D_E_L_E_T_ = ' ' "
				cQryVen += " 	) "
				cQryVen += " WHERE "
				cQryVen += " 	C6_FILIAL = '"+FWxFilial('SC6')+"' "
				cQryVen += " 	AND C6_PRODUTO = '"+QRY_PRO->B1_COD+"' "
				cQryVen += " 	AND SC6.D_E_L_E_T_ = ' ' "
				TCQuery cQryVen New Alias "QRY_VEN"
				
				//Atribuindo o valor
				aLinhaAux[nAux] := QRY_VEN->TOT
				QRY_VEN->(DbCloseArea())
			Next
			
			//Adiciona a linha no Excel
			oFWMsExcel:AddRow(cWorkSheet, cTable, aLinhaAux)
			
			QRY_PRO->(DbSkip())
		EndDo
		
		//Tratativa para o Total
		aLinhaAux := Array(Len(aColunas))
		aLinhaAux[1] := "Total: "
		aLinhaAux[2] := ""
		For nAux := 3 To Len(aColunas)
			cQryVen := " SELECT "
			cQryVen += " 	ISNULL(SUM(C6_QTDVEN),0) AS TOT "
			cQryVen += " FROM "
			cQryVen += " 	"+RetSQLName('SC6')+" SC6 "
			cQryVen += " 	INNER JOIN "+RetSQLName('SC5')+" SC5 ON ( "
			cQryVen += " 		C5_FILIAL = '"+FWxFilial('SC5')+"' "
			cQryVen += " 		AND C5_NUM = C6_NUM "
			cQryVen += " 		AND C5_TIPO = 'N' "
			cQryVen += " 		AND C5_EMISSAO = '"+dToS(cToD(aColunas[nAux]))+"' "
			cQryVen += " 		AND SC5.D_E_L_E_T_ = ' ' "
			cQryVen += " 	) "
			cQryVen += " 	INNER JOIN "+RetSQLName('SB1')+" SB1 ON ( "
			cQryVen += " 		B1_FILIAL = '"+FWxFilial('SB1')+"' "
			cQryVen += " 		AND B1_COD = C6_PRODUTO "
			cQryVen += " 		AND B1_TIPO = 'PA' "
			cQryVen += " 		AND SB1.D_E_L_E_T_ = ' ' "
			cQryVen += " 	) "
			cQryVen += " WHERE "
			cQryVen += " 	C6_FILIAL = '"+FWxFilial('SC6')+"' "
			cQryVen += " 	AND SC6.D_E_L_E_T_ = ' ' "
			TCQuery cQryVen New Alias "QRY_VEN"
			
			//Atribuindo o valor
			aLinhaAux[nAux] := QRY_VEN->TOT
			QRY_VEN->(DbCloseArea())
		Next
		
		//Adiciona a linha no Excel
		oFWMsExcel:AddRow(cWorkSheet, cTable, aLinhaAux)
		
	//Ativando o arquivo e gerando o xml
	oFWMsExcel:Activate()
	oFWMsExcel:GetXMLFile(cArquivo)
		
	//Abrindo o excel e abrindo o arquivo xml
	oExcel := MsExcel():New() 			//Abre uma nova conexão com Excel
	oExcel:WorkBooks:Open(cArquivo) 	//Abre uma planilha
	oExcel:SetVisible(.T.) 				//Visualiza a planilha
	oExcel:Destroy()						//Encerra o processo do gerenciador de tarefas
	
	QRY_PRO->(DbCloseArea())
	RestArea(aArea)
Return


Referências:
tdn.totvs.com/display/public/mp/FWMsExcel
tdn.totvs.com/display/framework/FWMsExcelEx

Bom pessoal, por hoje é só.
Abraços e até a próxima.

Dan Atilio (Daniel Atilio)
Especialista em Engenharia de Software pela FIB. Entusiasta de soluções Open Source. E blogueiro nas horas vagas.

34 Responses

  1. George Allan disse:

    Ótimo post Daniel, bem explicado, com os exemplos, bem legal mesmo cara. Obrigado por compartilhar! 🙂

    George Allan
    http://www.userfunction.com.br

  2. Muito legal a dica, parabéns!

  3. Tiago Freitas disse:

    Muito Legal!!! Acabei de usar, otimo exemplo.

  4. Luis Gustavo disse:

    Legal o port Dan_Atilio, parabéns pela iniciativa.

    Recentemente utilizei para montar um KPI para área comercial, onde o mesmo é enviado todos os dias para diretoria e gerencia.
    Porém, não contente agora, o pessoal quer ver pelo celular antes de chegar na empresa.
    O xml gerado não abre no excel para celular por não ser compatível com o office 2013 e posteriores.

    Você sabe algum meio que possa converter esse arquivo xml em padrão office .xlsx?

    Abraços
    Luís Gustavo

  5. Ricardo Cassolatto disse:

    Qual a diferença entre :
    – FWMsExcel
    – FWMsExcelEx
    ?

    Nenhuma , ou é sútil ?

    Obrigado, ótimos post !

    • Dan_Atilio disse:

      Bom dia Ricardo.
      Conforme disse no começo da postagem:
      “Existem duas classes para geração de arquivos xml do Excel, a FWMsExcel e a FWMsExcelEx, a segunda tem mais opções de edição de atributos de uma célula”

      A segunda tem opções de você editar somente uma célula (como cor, fonte, fundo, etc), e não mudar a cor da planilha inteira.
      Espero ter ajudado.
      Abraços e muito obrigado.

  6. Erick disse:

    boa tarde, consegui gerar o arquivo, porem via schedule não gera, alguma dica ?
    da erro
    oExcel:Activate()

    invalid handle used in file C:\bamboo-agent-5.7.2\xml-data\build-dir\TP11-BUILDV1APPSRV-PROTHEUSWIN32\lib_base\diskman.cpp at line 265
    on FWMSEXCEL:GETXMLFILE(FWMSEXCEL.PRX) 09/12/2016 15:19:44 line : 467

    • Dan_Atilio disse:

      Boa noite Erick, tudo bem?
      Creio eu que a função não deve ter compatibilidade via Scheduler,
      Tente abrir um chamado na matriz e ver se há alguma forma paliativa de gerar.
      Abraços.

  7. Abel Ribeiro disse:

    Atilio, Boa Tarde

    Estou utilizando esse exemplo e na linha oExcel := MsExcel():New() , o sistema trava e nao abre a planilha,
    vc sabe o que pode ser?

    Att

    Abel

  8. Jose Ricardo disse:

    Boa tarde! Antes de mais nada parabéns pelo post, estou com a necessidade de inserir um imagem na Planilha ( logotipo da empresa), existe recurso para isto

    • Dan_Atilio disse:

      Bom dia Jose.
      Infelizmente acho que não é possível. Pois, a geração de arquivo do Excel via AdvPL, utliza XML e nele não tem como embutir uma imagem, mas você poderia abrir um chamado no Suporte da TOTVS perguntando se eles estão planejando adicionar esse recurso.
      Um grande abraço.

  9. Jose Santos disse:

    Parabéns pelo post!!! Um desenvolvedor novo conseguiu gerar um código com facilidade usando seu exemplo!!!
    Agora um dúvida… sabe de alguma forma de gerar um Excel com fórmulas nas células via AdvPL?

  10. narba disse:

    É possível colocar duas colunas diferentes na mesma planilha?
    Exemplo:
    Nome | CPF
    Joao 9999999999

    Codigo | Descrição | Valor

  11. Walmar De Freitas G disse:

    Bom Dia, parabéns Atilio.!! use seu exemplo hoje como guia, muito obrigado por compartilhar..!!

  12. Rogério disse:

    Boa noite

    Parabéns pelo conteúdo. Atendeu o que eu precisava.

    Uma dúvida! Estou usando o CpyS2T para copiar o arquivo de um diretório para o outro. (Isso funciona somente acessando via smartclient).

    Qual função posso usar para fazer isso via schedule, job ?

    Se for o caso, pode ser alguma função para gravar diretamente o .CSV / .XML no diretório também

    Obrigado e um grande abraço

  13. Alice disse:

    Boa tarde, parabéns pelo conteúdo atendeu o que eu precisava, mas se eu quiser colocar além da quantidade do produto, colocar tbm o valor pra cada mês, eu consigo fazer?

  14. Fernando Braga disse:

    Boa tarde

    Agora o sx3 fica no banco e pelo apsu só existe opção de salvar em ctree e txt, teria algum jeito mais fácil de geral em DBF ou Excel parte do sx3 tipo todo o conteúdo do SRA.

    Grato

  15. Luis disse:

    @Dan_Atilio parabéns e obrigado pelo exemplo!! Estou tentando colocar resultados de 2 query, uma em cada aba e não estou conseguindo. Em uma única aba dá certo, mas na segunda dá error.log
    THREAD ERROR ([9540], lakn, LAKN) 23/06/2021 15:32:14
    erro no parâmetroFWMSEXCEL: WorkSheet or Table out of range on FWMSEXCEL:ADDROW(FWMSEXCEL.PRX) 08/04/2021 17:34:09 line : 470

    Este é o código que estou tentando
    //Bibliotecas
    #Include “Protheus.ch”
    #Include “TopConn.ch”

    //Constantes
    #Define STR_PULA Chr(13)+Chr(10)

    User Function OXGPE033()
    Local aArea := GetArea()
    Local cQuery,cQuery2 := “”
    Local oFWMsExcel
    Local oExcel
    Local cArquivo := GetTempPath()+’OXGPE033.xml’

    //Pegando os dados

    cQuery := ” select RB_MAT Matricula,RA_NOME Nome,COUNT(RB_COD) QtdeFilhos,RA_CC+’-‘+CTT_DESC01 As CentrodeCusto”
    cQuery += ” from SRB010 SRB, SRA010 SRA, CTT010 CTT(NOLOCK)”
    cQuery += ” where SRB.D_E_L_E_T_ ‘*'”
    cQuery += ” and CTT.D_E_L_E_T_ = ””
    cQuery += ” and RA_FILIAL = CTT_FILIAL”
    cQuery += ” and RA_CC = CTT_CUSTO”
    cQuery += ” and SRA.D_E_L_E_T_ ‘*'”
    cQuery += ” and RB_FILIAL = RA_FILIAL”
    cQuery += ” and RB_MAT = RA_MAT”
    cQuery += ” and RA_SITFOLH ‘D'”
    cQuery += ” and RB_GRAUPAR = ‘F'”
    cQuery += ” and RA_SEXO = ‘M'”
    cQuery += ” group by RB_MAT, RA_NOME, RA_CC, CTT_DESC01, RA_SITFOLH”
    cQuery += ” order by RA_NOME”
    TCQuery cQuery New Alias “QRYPRO”

    //Criando o objeto que irá gerar o conteúdo do Excel
    oFWMsExcel := FWMSExcel():New()
    /*
    //Aba 01 – Teste
    oFWMsExcel:AddworkSheet(“Aba 1 Teste”) //Não utilizar número junto com sinal de menos. Ex.: 1-
    //Criando a Tabela
    oFWMsExcel:AddTable(“Aba 1 Teste”,”Titulo Tabela”)
    //Criando Colunas
    oFWMsExcel:AddColumn(“Aba 1 Teste”,”Titulo Tabela”,”Col1″,1,1) //1 = Modo Texto
    oFWMsExcel:AddColumn(“Aba 1 Teste”,”Titulo Tabela”,”Col2″,2,2) //2 = Valor sem R$
    oFWMsExcel:AddColumn(“Aba 1 Teste”,”Titulo Tabela”,”Col3″,3,3) //3 = Valor com R$
    oFWMsExcel:AddColumn(“Aba 1 Teste”,”Titulo Tabela”,”Col4″,1,1)
    //Criando as Linhas
    oFWMsExcel:AddRow(“Aba 1 Teste”,”Titulo Tabela”,{11,12,13,sToD(‘20140317’)})
    oFWMsExcel:AddRow(“Aba 1 Teste”,”Titulo Tabela”,{21,22,23,sToD(‘20140217’)})
    oFWMsExcel:AddRow(“Aba 1 Teste”,”Titulo Tabela”,{31,32,33,sToD(‘20140117’)})
    oFWMsExcel:AddRow(“Aba 1 Teste”,”Titulo Tabela”,{41,42,43,sToD(‘20131217′)})

    */
    //Aba 02 – FUNCIONARIOS QUE SAO PAIS
    oFWMsExcel:AddworkSheet(“PAIS”)
    //Criando a Tabela
    oFWMsExcel:AddTable(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”)
    oFWMsExcel:AddColumn(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”,”Matricula”,1)
    oFWMsExcel:AddColumn(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”,”Nome”,1)
    oFWMsExcel:AddColumn(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”,”QtdeFilhos”,1)
    oFWMsExcel:AddColumn(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”,”CentrodeCusto”,1)
    //Criando as Linhas… Enquanto não for fim da query
    While !(QRYPRO->(EoF()))
    oFWMsExcel:AddRow(“PAIS”,”FUNCIONARIOS QUE SAO PAIS”,{;
    QRYPRO->Matricula,;
    QRYPRO->Nome,;
    QRYPRO->QtdeFilhos,;
    QRYPRO->CentrodeCusto;
    })

    //Pulando Registro
    QRYPRO->(DbSkip())
    EndDo
    QRYPRO->(DbCloseArea())
    RestArea(aArea)

    cQuery2 := ” select RB_MAT Matricula,RA_NOME Nome,COUNT(RB_COD) QtdeFilhos,RA_CC+’-‘+CTT_DESC01 As CentrodeCusto”
    cQuery2 += ” from SRB010 SRB, SRA010 SRA, CTT010 CTT(NOLOCK)”
    cQuery2 += ” where SRB.D_E_L_E_T_ ‘*'”
    cQuery2 += ” and CTT.D_E_L_E_T_ = ””
    cQuery2 += ” and RA_FILIAL = CTT_FILIAL”
    cQuery2 += ” and RA_CC = CTT_CUSTO”
    cQuery2 += ” and SRA.D_E_L_E_T_ ‘*'”
    cQuery2 += ” and RB_FILIAL = RA_FILIAL”
    cQuery2 += ” and RB_MAT = RA_MAT”
    cQuery2 += ” and RA_SITFOLH ‘D'”
    cQuery2 += ” and RB_GRAUPAR = ‘F'”
    cQuery2 += ” and RA_SEXO = ‘F'”
    cQuery2 += ” group by RB_MAT, RA_NOME, RA_CC, CTT_DESC01, RA_SITFOLH”
    cQuery2 += ” order by RA_NOME”
    TCQuery cQuery2 New Alias “QRYPRO2”

    //Aba 02 – FUNCIONARIOS QUE SAO MAE
    oFWMsExcel:AddworkSheet(“MAES”)
    //Criando a Tabela
    oFWMsExcel:AddTable(“MAES”,”FUNCIONARIAS QUE SAO MAES”)
    oFWMsExcel:AddColumn(“MAES”,”FUNCIONARIAS QUE SAO MAES”,”Matricula”,1)
    oFWMsExcel:AddColumn(“MAES”,”FUNCIONARIAS QUE SAO MAES”,”Nome”,1)
    oFWMsExcel:AddColumn(“MAES”,”FUNCIONARIAS QUE SAO MAES”,”QtdeFilhos”,1)
    oFWMsExcel:AddColumn(“MAES”,”FUNCIONARIAS QUE SAO MAES”,”CentrodeCusto”,1)
    //Criando as Linhas… Enquanto não for fim da query
    While !(QRYPRO2->(EoF()))
    oFWMsExcel:AddRow(“MAES”,”FUNCIONARIAS QUE SAO MAE”,{;
    QRYPRO2->Matricula,;
    QRYPRO2->Nome,;
    QRYPRO2->QtdeFilhos,;
    QRYPRO2->CentrodeCusto;
    })

    //Pulando Registro
    QRYPRO2->(DbSkip())
    EndDo

    //Ativando o arquivo e gerando o xml
    oFWMsExcel:Activate()
    oFWMsExcel:GetXMLFile(cArquivo)

    //Abrindo o excel e abrindo o arquivo xml
    oExcel := MsExcel():New() //Abre uma nova conexão com Excel
    oExcel:WorkBooks:Open(cArquivo) //Abre uma planilha
    oExcel:SetVisible(.T.) //Visualiza a planilha
    oExcel:Destroy() //Encerra o processo do gerenciador de tarefas

    QRYPRO2->(DbCloseArea())
    //QRYPRO2->(DbCloseArea())

    RestArea(aArea)
    Return

    • Bom dia Luis, tudo bem?
      Que estranho, olhando por cima, a sintaxe parece correta.
      Se possível, nos envie por e-Mail o log completo e o código fonte completo também, ai eu consigo rastrear onde e em que linha deu o erro exato.
      Grande abraço.

  16. Luis Nagasako disse:

    BOm dia, pessoal, estou com esse trecho do fonte, onde está dando Syntax error na última linha no }), alguém tem alguma ideia?

    While !(QRY->(EoF()))
    wvalliq := QRY->F2_VALBRUT – QRY->IPI – QRY->PRODUTOX – QRY->D2_VALIMP5 – QRY->D2_VALIMP6
    wvallitro := wvalliq/QRY->D2_QTSEGUM
    wvalltdolar := wvallitro/QRY->C5_ZDOLAR

    oFWMsExcel:AddRow(“Campanhas PRODUTOYYYY”,”Campanhas PRODUTOYYYY”,{;
    QRY->D2_DOC,;
    QRY->D2_SERIE,;
    QRY->QRY->F2_EMISSAO,;
    QRY->D2_COD,;
    QRY->B1_DESC,;
    QRY->D2_UM,;
    QRY->D2_QUANT,;
    QRY->D2_SEGUM,;
    QRY->D2_QTSEGUM,;
    QRY->E1_VALOR,;
    QRY->F2_VALBRUT,;
    QRY->D2_VALIMP6,;
    QRY->D2_VALIMP5,;
    QRY->IPI,;
    QRY->PRODUTOX,;
    wvalliq,;
    wvallitro,;
    QRY->C5_ZDOLAR,;
    wvalltdolar,;
    QRY->E1_NOMCLI,;
    QRY->E1_VENCREA,;
    QRY->D2_NUMPCOM,;
    QRY->D2_PEDIDO,;
    QRY->C5_ZCAMPAN,;
    QRY->F2_ZMUNTRO;
    })

Deixe uma resposta