Rotina de Importação da SB6 em AdvPL

Olá pessoal…

Hoje vou mostrar um exemplo de rotina que criei para importação de Saldos de/em Terceiros no Protheus (SB6).


A importação ocorre em duas frentes, a primeira é a importação da nota de entrada e saída (a de saída é feita uma NF Manual) e em ambas é utilizada uma TES que controla o poder de/em Terceiros, após isso é necessário apenas rodar o Refaz Poder de Terceiros.

Ao acessar a rotina é mostrado um alerta de atenção.

Mensagem no início da rotina

Mensagem no início da rotina

Na tela principal, informe o arquivo csv, a TES e a série de importação das NFs (lembrando que será validado se a série existe, e se a TES controla poder de/em terceiros).

Tela principal

Tela principal

Caso seja clicado no botão Relação, será mostrado um help sobre a importação, com os campos e exemplo.

Relação de Importação

Relação de Importação

Se clicar no botão Importar, será rodado o processo de importação da NF, ao finalizar, será perguntado se deseja rodar o Refaz Poder De/Em Terceiros.

Pergunta sobre a execução do Refaz Poder de Terceiros

Pergunta sobre a execução do Refaz Poder de Terceiros

Caso seja confirmado, será mostrado a tela do Refaz, ai basta configurar os parâmetros (como produto de “ “ à “ZZZ”) e confirmar.

Tela principal do Refaz Poder de Terceiros

Tela principal do Refaz Poder de Terceiros

Se houver algum erro na importação, será mostrado um aviso ao usuário.

Erros na Importação

Erros na Importação

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

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

//Variáveis estáticas
Static cDirLog := "\x_logsb6\"

/*/{Protheus.doc} zImpSB6
Função para importar saldos de poder de/em terceiros
@author Atilio
@since 28/08/2015
@version 1.0
	@example
	u_zImpSB6()
/*/

User Function zImpSB6()
	Local cMsgAux := ""
	Local aArea := GetArea()
	Local aAreaB6 := SB6->(GetArea())
	//Dimensões da janela
	Local nJanAltu := 180
	Local nJanLarg := 650
	//Objetos da tela
	Local oGrpPar
	Local oGrpAco
	Local oBtnSair
	Local oBtnImp
	Local oBtnRela
	Local oBtnArq
	Private oSayArq, oGetArq, cGetArq := Space(99)
	Private oSayTes, oGetTes, cGetTes := Space(TamSX3('F4_CODIGO')[01])
	Private oSaySer, oGetSer, cGetSer := Space(TamSX3('F2_SERIE')[01])
	Private oDlgPvt
	
	//Mostrando mensagem de atenção ao usar a rotina
	cMsgAux := "

Cuidado!


" cMsgAux += "Rotina para importação de Poder de/em Terceiros, será
" cMsgAux += "executado apenas a importação das NFs.
" cMsgAux += "Após a importação, rode o refaz saldos Poder Terceiro!
" MsgAlert(cMsgAux, "Atenção") //Se não existir o diretório de logs, gera If !ExistDir(cDirLog) MakeDir(cDirLog) EndIf //Criando a janela DEFINE MSDIALOG oDlgPvt TITLE "zImpSB6 - Importação Poder de/em Terceiros" FROM 000, 000 TO nJanAltu, nJanLarg COLORS 0, 16777215 PIXEL //Grupo Parâmetros @ 003, 003 GROUP oGrpPar TO 060, (nJanLarg/2) PROMPT "Parâmetros: " OF oDlgPvt COLOR 0, 16777215 PIXEL //Caminho do arquivo @ 013, 006 SAY oSayArq PROMPT "Arquivo:" SIZE 060, 007 OF oDlgPvt PIXEL @ 010, 070 MSGET oGetArq VAR cGetArq SIZE 240, 010 OF oDlgPvt PIXEL oGetArq:bHelp := {|| ShowHelpCpo( "cGetArq",; {"Arquivo CSV que será importado."+STR_PULA+"Exemplo: C:\teste.csv"},2,; {},2)} @ 010, 311 BUTTON oBtnArq PROMPT "..." SIZE 008, 011 OF oDlgPvt ACTION (fPegaArq()) PIXEL //Tipo de Importação @ 028, 006 SAY oSayTes PROMPT "TES:" SIZE 060, 007 OF oDlgPvt PIXEL @ 025, 070 MSGET oGetTes VAR cGetTes SIZE 100, 010 OF oDlgPvt PIXEL F3 'SF4' oGetTes:bHelp := {|| ShowHelpCpo( "cGetTes",; {"Tipo de TES que será processada para importação dos saldos."},2,; {},2)} //Simula antes de importar @ 043, 006 SAY oSaySer PROMPT "Série:" SIZE 070, 007 OF oDlgPvt PIXEL @ 040, 070 MSGET oGetSer VAR cGetSer SIZE 100, 010 OF oDlgPvt PIXEL F3 '01' oGetSer:bHelp := {|| ShowHelpCpo( "cGetSer",; {"Série que será utilizada para importação."},2,; {},2)} //Grupo Ações @ 063, 003 GROUP oGrpAco TO (nJanAltu/2)-3, (nJanLarg/2) PROMPT "Ações: " OF oDlgPvt COLOR 0, 16777215 PIXEL //Botões @ 070, (nJanLarg/2)-(63*1) BUTTON oBtnSair PROMPT "Sair" SIZE 60, 014 OF oDlgPvt ACTION (oDlgPvt:End()) PIXEL @ 070, (nJanLarg/2)-(63*2) BUTTON oBtnImp PROMPT "Importar" SIZE 60, 014 OF oDlgPvt ACTION (Processa({|| fImport() }, "Aguarde...")) PIXEL @ 070, (nJanLarg/2)-(63*3) BUTTON oBtnRela PROMPT "Relação" SIZE 60, 014 OF oDlgPvt ACTION (fRelacao()) PIXEL ACTIVATE MSDIALOG oDlgPvt CENTERED //Se confirmar a pergunta, chama a rotina de refaz poder de terceiros If MsgYesNo("Deseja executar a rotina de Refaz Poder de Terceiros?", "Atenção") Mata216() EndIf RestArea(aAreaB6) RestArea(aArea) Return /*---------------------------------------------------------------------* | Func: fPegaArq | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função para pegar o arquivo txt a ser importado | *---------------------------------------------------------------------*/ Static Function fPegaArq() Local cArqAux := "" cArqAux := cGetFile( "Arquivo Texto *.csv* | *.csv*",; //Máscara "Arquivo...",; //Título ,; //Número da máscara ,; //Diretório Inicial .F.,; //.F. == Abrir; .T. == Salvar GETF_LOCALHARD,; //Diretório full. Ex.: 'C:\TOTVS\arquivo.xlsx' .F.) //Não exibe diretório do servidor //Caso o arquivo não exista ou estiver em branco ou não for a extensão txt If Empty(cArqAux) .Or. !File(cArqAux) .Or. SubStr(cArqAux, RAt('.', cArqAux)+1, 3) != "csv" MsgStop("Arquivo inválido!", "Atenção") //Senão, define o get Else cGetArq := PadR(cArqAux,99) oGetArq:Refresh() EndIf Return /*---------------------------------------------------------------------* | Func: fImport | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que realiza a importação dos dados | *---------------------------------------------------------------------*/ Static Function fImport() Local lMovEstoq := .F. Local cMsgAux := "" DbSelectArea('SF4') SF4->(DbSetOrder(1)) //F4_FILIAL+F4_CODIGO SF4->(DbGoTop()) DbSelectArea('SX5') SX5->(DbSetOrder(1)) //X5_FILIAL+X5_TABELA+X5_CHAVE SX5->(DbGoTop()) //Caso o arquivo não exista ou estiver em branco ou não for a extensão txt If Empty(cGetArq) .Or. !File(cGetArq) .Or. SubStr(cGetArq, RAt('.', cGetArq)+1, 3) != "csv" MsgStop("Arquivo inválido!", "Atenção") Return EndIf //Valida se TES existe If SF4->(DbSeek(FWxFilial('SF4') + cGetTes)) //Somente irá prosseguir se for Remessa ou Devolução If SF4->F4_PODER3 $ 'R;D' lMovEstoq := (SF4->F4_ESTOQUE == 'S') //Se movimenta estoque, mostra mensagem perguntando se quer continuar If lMovEstoq cMsgAux := "Essa TES, movimenta ESTOQUE, certifique-se de ter saldo disponível!
Deseja prosseguir?" If !MsgYesNo(cMsgAux, "Atenção") Return EndIf EndIf //Senão, mostra mensagem que tes não movimenta poder de/em terceiros Else MsgStop("TES não movimenta poder de/em Terceiros!", "Atenção") Return EndIf //Se não conseguir posicionar, retorna erro Else MsgStop("TES não encontrada!", "Atenção") Return EndIf //Valida se a Série existe If ! SX5->(DbSeek(FWxFilial('SX5') + '01' + cGetSer)) MsgStop("Série não encontrada!", "Atenção") Return EndIf //Se for Saída If SF4->F4_TIPO == 'S' fImpSB6SF2() //Se for Entrada ElseIf SF4->F4_TIPO == 'E' fImpSB6SF1() EndIf MsgInfo("Importação concluída!", "Atenção") Return /*---------------------------------------------------------------------* | Func: fImpSB6SF2 | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que importa as NF de Saída, para geração da SB6 | *---------------------------------------------------------------------*/ Static Function fImpSB6SF2() Local aArea := GetArea() Local aAreaF2 := SF2->(GetArea()) Local aAreaD2 := SD2->(GetArea()) Local aAreaB6 := SB6->(GetArea()) Local nTotalReg := 0 Local nLinAtu := 0 Local cErroImp := "" Local cBuffer := "" Local nLinAtu := 0 Local aDadAux := {} Local aLinAux := {} Local aCabSF2 := {} Local aIteSD2 := {} Local cSerAux := cGetSer Local cNFAux := '' Local cTipAux := 'N' Local nLinNF := 0 Local cIteAtu := StrTran(Space(TamSX3('D2_ITEM')[01]), ' ', '0') Local cLogAtu := "" Local cNomLog := "" Local nAux := 0 Local aLogAuto:= {} Local nQtdVen := 0 Local nPrcVen := 0 Local nValTot := 0 Local cCliAtu := "" Local cLojAtu := "" //Abrindo o arquivo Ft_FUse(cGetArq) nTotalReg := Ft_FLastRec() nLinAtu := 0 ProcRegua(nTotalReg) //Indo ao topo e percorrendo os registros Ft_FGoTop() While !Ft_FEoF() .And. nLinAtu <= FT_FLastRec() //Pegando a linha atual cBuffer := Ft_FReadLn() nLinAtu++ IncProc("[SIMULAÇÃO] Analisando linha "+cValToChar(nLinAtu)+" de "+cValToChar(nTotalReg)+"...") //Pegando os dados, conforme caracter delimitador aDadAux := StrTokArr(cBuffer, ';') //Se a primeira posição for '1' é cabeçalho If aDadAux[1] == '1' .And. Len(aCabSF2) == 0 nLinNF := nLinAtu cCliAtu := aDadAux[3] cLojAtu := aDadAux[4] //Pegando a próxima nota dessa série cNFAux := NxtSX5Nota(cSerAux) DbSelectArea('SA1') SA1->(DbSetOrder(1)) //A1_FILIAL+A1_COD+A1_LOJA SA1->(DbSeek(FWxFilial('SA1') + cCliAtu + cLojAtu)) //Adicionando dados no cabeçalho aAdd(aCabSF2,{"F2_FILIAL", FWxFilial("SF2"), Nil}) aAdd(aCabSF2,{"F2_TIPO", cTipAux, Nil}) aAdd(aCabSF2,{"F2_DOC", cNFAux, Nil}) aAdd(aCabSF2,{"F2_SERIE", cSerAux, Nil}) aAdd(aCabSF2,{"F2_EMISSAO", cToD(aDadAux[2]), Nil}) aAdd(aCabSF2,{"F2_CLIENTE", cCliAtu, Nil}) aAdd(aCabSF2,{"F2_LOJA", cLojAtu, Nil}) aAdd(aCabSF2,{"F2_CLIENT", cCliAtu, Nil}) aAdd(aCabSF2,{"F2_LOJENT", cLojAtu, Nil}) aAdd(aCabSF2,{"F2_TIPOCLI", SA1->A1_TIPO, Nil}) aAdd(aCabSF2,{"F2_ESPECIE", aDadAux[5], Nil}) //Senão, se a primeira posição for '2' é item ElseIf aDadAux[1] == '2' .And. Len(aCabSF2) != 0 aLinAux := {} cIteAtu := Soma1(cIteAtu) nQtdVen := Val(aDadAux[3]) nPrcVen := Val(aDadAux[4]) nValTot := nQtdVen * nPrcVen //Adicionando o item atual aAdd(aLinAux,{"D2_FILIAL", FWxFilial("SD2"), Nil}) aAdd(aLinAux,{"D2_DOC", cNFAux, Nil}) aAdd(aLinAux,{"D2_SERIE", cSerAux, Nil}) aAdd(aLinAux,{"D2_CLIENTE", cCliAtu, Nil}) aAdd(aLinAux,{"D2_LOJA", cLojAtu, Nil}) aAdd(aLinAux,{"D2_ITEM", cIteAtu, Nil}) aAdd(aLinAux,{"D2_COD", aDadAux[2], Nil}) aAdd(aLinAux,{"D2_QUANT", nQtdVen, Nil}) aAdd(aLinAux,{"D2_PRCVEN", nPrcVen, Nil}) aAdd(aLinAux,{"D2_TOTAL", nValTot, Nil}) aAdd(aLinAux,{"D2_X_MOTOR", aDadAux[5], Nil}) aAdd(aLinAux,{"D2_TES", cGetTes, Nil}) aAdd(aIteSD2, aLinAux) //Senão, se a terceira posição for '3' é o final dessa Nota, para importação dos dados ElseIf aDadAux[1] == '3' .And. Len(aCabSF2) != 0 .And. Len(aIteSD2) != 0 //Iniciando transação Begin Transaction lMsErroAuto := .F. lAutoErrNoFile := .T. lMsErroAuto := .F. l920Inclui := .T. //Chamando a inclusão automática MSExecAuto({|x, y, z| Mata920(x, y, z)}, aCabSF2, aIteSD2, 3) //Se houve erro If lMsErroAuto cLogAtu := "Houveram erros na importação da NF, na linha "+cValToChar(nLinNF)+":" + STR_PULA cNomLog := "linha_"+cValToChar(nLinNF)+"_"+StrTran(dToC(dDataBase), '/', '-')+"_"+StrTran(Time(), ':', '-')+".txt" //Pegando log do ExecAuto aLogAuto := GetAutoGRLog() For nAux:=1 To Len(aLogAuto) cLogAtu += aLogAuto[nAux] + STR_PULA Next MemoWrite(cDirLog+cNomLog, cLogAtu) cErroImp += "- Linha "+cValToChar(nLinNF)+" - log está em '"+cDirLog+cNomLog+"';"+STR_PULA DisarmTransaction() EndIf End Transaction //Voltando as variáveis nLinNF := 0 cNFAux := '' cCliAtu := '' cLojAtu := '' aCabSF2 := {} aIteSD2 := {} cIteAtu := StrTran(Space(TamSX3('D2_ITEM')[01]), ' ', '0') EndIf Ft_FSkip() EndDo //Se houve erros, mostra mensagem ao usuário If !Empty(cErroImp) cErroImp := "Houve erro(s) na importação."+STR_PULA+STR_PULA+"---"+STR_PULA+"Log: "+STR_PULA+cErroImp Aviso('Atenção', cErroImp, {'Ok'}, 03) EndIf //Fechando o arquivo Ft_FUse() RestArea(aAreaB6) RestArea(aAreaD2) RestArea(aAreaF2) RestArea(aArea) Return /*---------------------------------------------------------------------* | Func: fImpSB6SF1 | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que importa as NF de Entrada, para geração da SB6 | *---------------------------------------------------------------------*/ Static Function fImpSB6SF1() Local aArea := GetArea() Local aAreaF1 := SF1->(GetArea()) Local aAreaD1 := SD1->(GetArea()) Local aAreaB6 := SB6->(GetArea()) Local nTotalReg := 0 Local nLinAtu := 0 Local cErroImp := "" Local cBuffer := "" Local nLinAtu := 0 Local aDadAux := {} Local aLinAux := {} Local aCabSF1 := {} Local aIteSD1 := {} Local cSerAux := cGetSer Local cNFAux := '' Local cTipAux := 'N' Local nLinNF := 0 Local cIteAtu := StrTran(Space(TamSX3('D1_ITEM')[01]), ' ', '0') Local cLogAtu := "" Local cNomLog := "" Local nAux := 0 Local aLogAuto:= {} Local nQtdVen := 0 Local nPrcVen := 0 Local nValTot := 0 Local cForAtu := "" Local cLojAtu := "" Local nModBkp := 0 //Abrindo o arquivo Ft_FUse(cGetArq) nTotalReg := Ft_FLastRec() nLinAtu := 0 ProcRegua(nTotalReg) //Indo ao topo e percorrendo os registros Ft_FGoTop() While !Ft_FEoF() .And. nLinAtu <= FT_FLastRec() //Pegando a linha atual cBuffer := Ft_FReadLn() nLinAtu++ IncProc("[SIMULAÇÃO] Analisando linha "+cValToChar(nLinAtu)+" de "+cValToChar(nTotalReg)+"...") //Pegando os dados, conforme caracter delimitador aDadAux := StrTokArr(cBuffer, ';') //Se a primeira posição for '1' é cabeçalho If aDadAux[1] == '1' .And. Len(aCabSF1) == 0 nLinNF := nLinAtu cForAtu := aDadAux[3] cLojAtu := aDadAux[4] //Pegando a próxima nota dessa série cNFAux := NxtSX5Nota(cSerAux) DbSelectArea('SA2') SA2->(DbSetOrder(1)) //A2_FILIAL+A2_COD+A2_LOJA SA2->(DbSeek(FWxFilial('SA2') + cForAtu + cLojAtu)) //Adicionando dados no cabeçalho aAdd(aCabSF1,{"F1_FILIAL", FWxFilial("SF1"), Nil}) aAdd(aCabSF1,{"F1_TIPO", cTipAux, Nil}) aAdd(aCabSF1,{"F1_DOC", cNFAux, Nil}) aAdd(aCabSF1,{"F1_SERIE", cSerAux, Nil}) aAdd(aCabSF1,{"F1_EMISSAO", cToD(aDadAux[2]), Nil}) aAdd(aCabSF1,{"F1_FORNECE", cForAtu, Nil}) aAdd(aCabSF1,{"F1_LOJA", cLojAtu, Nil}) aAdd(aCabSF1,{"F1_TIPOCLI", SA2->A2_TIPO, Nil}) aAdd(aCabSF1,{"F1_ESPECIE", aDadAux[5], Nil}) aAdd(aCabSF1,{"F1_FORMUL", 'N', Nil}) aAdd(aCabSF1,{"F1_COND", aDadAux[6], Nil}) //Senão, se a primeira posição for '2' é item ElseIf aDadAux[1] == '2' .And. Len(aCabSF1) != 0 aLinAux := {} cIteAtu := Soma1(cIteAtu) nQtdVen := Val(aDadAux[3]) nPrcVen := Val(aDadAux[4]) nValTot := nQtdVen * nPrcVen //Adicionando o item atual aAdd(aLinAux,{"D1_FILIAL", FWxFilial("SD1"), Nil}) aAdd(aLinAux,{"D1_DOC", cNFAux, Nil}) aAdd(aLinAux,{"D1_SERIE", cSerAux, Nil}) aAdd(aLinAux,{"D1_FORNECE", cForAtu, Nil}) aAdd(aLinAux,{"D1_LOJA", cLojAtu, Nil}) aAdd(aLinAux,{"D1_ITEM", cIteAtu, Nil}) aAdd(aLinAux,{"D1_COD", aDadAux[2], Nil}) aAdd(aLinAux,{"D1_QUANT", nQtdVen, Nil}) aAdd(aLinAux,{"D1_VUNIT", nPrcVen, Nil}) aAdd(aLinAux,{"D1_TOTAL", nValTot, Nil}) aAdd(aLinAux,{"D1_TES", cGetTes, Nil}) aAdd(aIteSD1, aLinAux) //Senão, se a terceira posição for '3' é o final dessa Nota, para importação dos dados ElseIf aDadAux[1] == '3' .And. Len(aCabSF1) != 0 .And. Len(aIteSD1) != 0 //Iniciando transação Begin Transaction lMsErroAuto := .F. lAutoErrNoFile := .T. lMsErroAuto := .F. nModBkp := nModulo nModulo := 2 //Chamando a inclusão automática MSExecAuto({|x, y, z| Mata103(x, y, z)}, aCabSF1, aIteSD1, 3) //Se houve erro If lMsErroAuto cLogAtu := "Houveram erros na importação da NF, na linha "+cValToChar(nLinNF)+":" + STR_PULA cNomLog := "linha_"+cValToChar(nLinNF)+"_"+StrTran(dToC(dDataBase), '/', '-')+"_"+StrTran(Time(), ':', '-')+".txt" //Pegando log do ExecAuto aLogAuto := GetAutoGRLog() For nAux:=1 To Len(aLogAuto) cLogAtu += aLogAuto[nAux] + STR_PULA Next MemoWrite(cDirLog+cNomLog, cLogAtu) cErroImp += "- Linha "+cValToChar(nLinNF)+" - log está em '"+cDirLog+cNomLog+"';"+STR_PULA DisarmTransaction() EndIf nModulo := nModBkp End Transaction //Voltando as variáveis nLinNF := 0 cNFAux := '' cForAtu := '' cLojAtu := '' aCabSF1 := {} aIteSD1 := {} cIteAtu := StrTran(Space(TamSX3('D1_ITEM')[01]), ' ', '0') EndIf Ft_FSkip() EndDo //Se houve erros, mostra mensagem ao usuário If !Empty(cErroImp) cErroImp := "Houve erro(s) na importação."+STR_PULA+STR_PULA+"---"+STR_PULA+"Log: "+STR_PULA+cErroImp Aviso('Atenção', cErroImp, {'Ok'}, 03) EndIf //Fechando o arquivo Ft_FUse() RestArea(aAreaB6) RestArea(aAreaD1) RestArea(aAreaF1) RestArea(aArea) Return /*---------------------------------------------------------------------* | Func: fRelacao | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que exporta a relação dos campos para TReport | *---------------------------------------------------------------------*/ Static Function fRelacao() Local cMsgAux := "" //Mensagem que será impressa no TReport cMsgAux := 'Leiaute de importação de Saldos de/em Poder de Terceiros
' cMsgAux += '
' cMsgAux += ' Os campos deverão ser separados com ponto e vírgula (";"), e gerados na extensão .csv.
' cMsgAux += ' Abaixo a explicação dos Saldos de/em Poder de Terceiros:
' cMsgAux += ' O controle do poder de terceiros do SIGA-ADVANCED foi concebido para controlar o envio e o recebimento de materiais que recebem algum tipo de beneficiamento.
' cMsgAux += ' Existem duas situacoes bastante claras e distintas que sao relatadas a seguir:
' cMsgAux += '
' cMsgAux += ' Quando "EU BENEFICIO" - O processo se inicia no recebimento do material enviado por um cliente:
' cMsgAux += ' - NF de entrada com tipo "B" p/ apresentar cliente e TES com F4_PODER3 = "R" (Remessa).
' cMsgAux += ' Apos a execucao do servico de beneficiamento, o material deve ser devolvido ao cliente:
' cMsgAux += ' - NF de saida com tipo "N" p/ apresentar cliente e TES como F4_PODER3 = "D" (Devolucao).
' cMsgAux += ' Note que o servico prestado tambem deve constar desta nota, porem nao tem tratamento de poder de terceiros, simplesmente é vendido.
' cMsgAux += '
' cMsgAux += ' Quando "EU MANDO BENEFICIAR" - O processo se inicia quando o material deve ser enviado para um fornecedor, que ira fazer o beneficiamento:
' cMsgAux += ' - NF de saida com tipo "B" p/ apresentar fornecedor e TES com F4_PODER3 = "R" (Remessa).
' cMsgAux += ' Apos a execucao do servico de beneficiamento, o material é devolvido pelo fornecedor:
' cMsgAux += ' - NF de entrada com tipo "N" p/ apresentar fornecedor e TES como F4_PODER3 = "D" (Devolucao).
' cMsgAux += ' Note que o servico prestado tambem deve constar desta nota, porem nao tem tratamento de poder de terceiros, simplesmente é comprado.
' cMsgAux += '
' cMsgAux += ' Link: http://tdn.totvs.com/display/public/mp/Controle+de+Poder+de+Terceiros;jsessionid=8E86724A96E413F71334FBAA092EF916
' cMsgAux += '
' cMsgAux += '+=========================================+
' cMsgAux += 'Abaixo o Layout para Saldos em Terceiros:
' cMsgAux += ' Linha de Cabeçalho:
' cMsgAux += ' - Caracter "1", indicando cabeçalho;
' cMsgAux += ' - F2_EMISSAO - Data de Emissão da NF de Saída (padrão DD/MM/YYYY);
' cMsgAux += ' - F2_CLIENTE - Código do Cliente;
' cMsgAux += ' - F2_LOJA - Loja do Cliente;
' cMsgAux += ' - F2_ESPECIE - Espécie da NF de Saída (ex.: "NF").
' cMsgAux += '
' cMsgAux += ' Linha de Itens:
' cMsgAux += ' - Caracter "2", indicando item;
' cMsgAux += ' - D2_COD - Código do Produto;
' cMsgAux += ' - D2_QUANT - Quantidade do Produto;
' cMsgAux += ' - D2_PRCVEN - Preço do Produto;
' cMsgAux += ' - D2_X_MOTOR - Número do Motor.
' cMsgAux += '
' cMsgAux += ' Finalização do Documento atual
' cMsgAux += ' - Caracter "3", indicando o final da NF de Saída.
' cMsgAux += '
' cMsgAux += ' Exemplo:
' cMsgAux += ' 1;28/08/2015;CL0001;01;NF
' cMsgAux += ' 2;F00001;45;2.85;TST1
' cMsgAux += ' 2;F00002;10;3;TST2
' cMsgAux += ' 2;F00003;27;1.64;TST3
' cMsgAux += ' 3;
' cMsgAux += '+=========================================+
' cMsgAux += 'Abaixo o Layout para Saldos de Terceiros:
' cMsgAux += ' Linha de Cabeçalho:
' cMsgAux += ' - Caracter "1", indicando cabeçalho;
' cMsgAux += ' - F1_EMISSAO - Data de Emissão da NF de Entrada (padrão DD/MM/YYYY);
' cMsgAux += ' - F1_FORNECE - Código do Fornecedor;
' cMsgAux += ' - F1_LOJA - Loja do Fornecedor;
' cMsgAux += ' - F1_ESPECIE - Espécie da NF de Saída (ex.: "NF");
' cMsgAux += ' - F1_COND - Condição de pagamento (ex.: "001").
' cMsgAux += '
' cMsgAux += ' Linha de Itens:
' cMsgAux += ' - Caracter "2", indicando item;
' cMsgAux += ' - D1_COD - Código do Produto;
' cMsgAux += ' - D1_QUANT - Quantidade do Produto;
' cMsgAux += ' - D1_VUNIT - Preço do Produto.
' cMsgAux += '
' cMsgAux += ' Finalização do Documento atual
' cMsgAux += ' - Caracter "3", indicando o final da NF de Saída.
' cMsgAux += '
' cMsgAux += ' Exemplo:
' cMsgAux += ' 1;28/08/2015;FR0001;01;NF;001
' cMsgAux += ' 2;F00001;45;2.85
' cMsgAux += ' 2;F00002;10;3
' cMsgAux += ' 2;F00003;27;1.64
' cMsgAux += ' 3;
' fImpRel(cMsgAux) Return /*-------------------------------------------------------------------------------* | Func: fImpRel | | Autor: Daniel Atilio | | Data: 12/08/2015 | | Desc: Função que imprime a relação das variáveis | *-------------------------------------------------------------------------------*/ Static Function fImpRel(cMsgAux, aDadAux) Local oReport Private cMensagem := cMsgAux //Definindo as seções e gerando a impressão oReport := fReportDef() oReport:PrintDialog() Return /*-------------------------------------------------------------------------------* | Func: fReportDef | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que monta a definição do relatório | *-------------------------------------------------------------------------------*/ Static Function fReportDef() Local oReport Local oSectMsg Local oSectDad Local oFunTotDad //Criação do componente de impressão oReport := TReport():New( "zImpSB6",; //Nome do Relatório "Relação de Dados",; //Título ,; //Pergunte {|oReport| fRepPrint(oReport)},; //Bloco de código que será executado na confirmação da impressão ) //Descrição oReport:SetLandscape(.T.) //Define a orientação de página do relatório como paisagem ou retrato. .F.=Retrato; .T.=Paisagem oReport:SetTotalInLine(.F.) //Define se os totalizadores serão impressos em linha ou coluna If !Empty(oReport:uParam) Pergunte(oReport:uParam,.F.) EndIf //Criando a seção de mensagem oSectMsg := TRSection():New( oReport,; //Objeto TReport que a seção pertence "",; //Descrição da seção {""}) //Tabelas utilizadas, a primeira será considerada como principal da seção oSectMsg:SetTotalInLine(.F.) //Define se os totalizadores serão impressos em linha ou coluna. .F.=Coluna; .T.=Linha //Células da seção mensagem TRCell():New( oSectMsg, "XX_MENS", "", "", "", 200, /*lPixel*/, /*{|| code-block de impressao }*/) Return oReport /*-------------------------------------------------------------------------------* | Func: fRepPrint | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função que imprime o relatório | *-------------------------------------------------------------------------------*/ Static Function fRepPrint(oReport) Local oMsg := Nil Local oDados := Nil Local nAtual Local aAux := {} Local nAux := 0 //Pegando as seções do relatório oMsg := oReport:Section(1) //Quebrando a mensagem aAux := {} fMemoToArr(cMensagem, @aAux, 200, '
') //Percorrendo e imprimindo oMsg:Init() For nAux := 1 To Len(aAux) oMsg:Cell("XX_MENS"):SetValue(aAux[nAux]) oMsg:PrintLine() Next oMsg:Finish() Return /*-------------------------------------------------------------------------------* | Func: fRepPrint | | Autor: Daniel Atilio | | Data: 28/08/2015 | | Desc: Função para quebrar uma string em várias linhas | *-------------------------------------------------------------------------------*/ Static Function fMemoToArr(cTexto, aTexto, nMaxCol, cCaracter) Local nPosAtual := 1 //Posição Atual Local nPosFim := nMaxCol //Posição Final Local nMaxLin := 1 //Número de Linhas Local aTexto:={} Local aAux:={} Local nI := 0 Default cCaracter := Chr(13) //Se o texto não tiver em branco If ! Empty(cTexto) //Quebrando o Array, conforme -Enter- aAux:= Separa(cTexto, '
') //Correndo o Array e retirando o tabulamento For nI:=1 TO Len(aAux) aAux[nI]:=StrTran(aAux[nI],Chr(10),'') Next //Correndo as linhas quebradas For nI:=1 To Len(aAux) //Se o tamanho de Texto, for maior que o número de colunas If(Len(aAux[nI]) > nMaxCol) //Enquanto o Tamanho for Maior While (Len(aAux[nI]) > nMaxCol) //A última posição, será o último espaço em branco nUltPos:=Rat(' ',SubStr(aAux[nI],1,nMaxCol)) //Se não encontrar espaço em branco, a última posição será a coluna máxima If(nUltPos==0) nUltPos:=nMaxCol EndIf //Adicionando Parte da Sring (de 1 até a Úlima posição válida) aAdd(aTexto,SubStr(aAux[nI],1,nUltPos)) //Quebrando o resto da String aAux[nI]:=SubStr(aAux[nI],nUltPos+1,Len(aAux[nI])-nUltPos) EndDo //Adicionando o que sobrou aAdd(aTexto,aAux[nI]) Else //Se for menor que o Máximo de colunas, adiciona o texto aAdd(aTexto,aAux[nI]) EndIf Next EndIf //Se não tiver nada para retornar, fixa como espaço em branco If Len(aTexto) == 0 aTexto := {""} EndIf //Pegando o número máximo de Linhas nMaxLin:=Len(aTexto) Return nMaxLin

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.

Deixe uma resposta

Terminal de Informação