Dias atrás um amigo perguntou se era possível fazer importação de um arquivo texto no qual se era possível importar diversas linhas para a rotina movimentação interna modelo 2 (Movimentação Múltipla).
Iremos usar o Ponto de Entrada da rotina MATA241
Sintaxe: MSExecAuto({|X,Y,Z| MATA241(X,Y,Z)}, aCabecalho, aItens, nOpção)
Onde:
aCabecalho = Array contendo os dados do cabeçalho
aItens = Array contendo os dados do item
nOpção = 3 para inclusão, 4 para alteração e 5 para exclusão.
O processo de importação de um arquivo texto, continua sendo sempre o mesmo, um formato simples é no formato CSV separando por ponto e virgula cada coluna. Usando a função fOpen (https://www.blogadvpl.com/importando-arquivo-texto) para abrir o arquivo texto e a função ParamBox (https://www.blogadvpl.com/inputbox-no-protheus/) para mostrar a tela que irá selecionar o arquivo.
User Function AEST003 Local cTitulo := "[AEST003] Importar Registros" Local nOpcao := 0 Local aButtons := {} Local aSays := {} Private cArea := GetArea() Private cPerg := Padr("AEST003",10) Private lMsErroAuto := .F. Private lMsHelpAuto := .T. AADD(aSays,OemToAnsi("Esta rotina tem como objetivo de importar os produtos vindos de um arquivo CSV.")) AADD(aSays,"") AADD(aSays,OemToAnsi("Clique no botão PARAM para informar o arquivo que será importado.")) AADD(aSays,"") AADD(aSays,OemToAnsi("Após isso, clique no botão OK.")) AADD(aButtons, { 1,.T.,{|o| nOpcao:= 1,o:oWnd:End()} } ) AADD(aButtons, { 2,.T.,{|o| nOpcao:= 2,o:oWnd:End()} } ) AADD(aButtons, { 5,.T.,{|| ajustaSx1(cPerg) } } ) //Para mostrar uma mensagem na tela e as opções disponíveis para o usuário. (https://tdn.totvs.com/pages/viewpage.action?pageId=24346908) FormBatch( cTitulo, aSays, aButtons,,200,530 ) if nOpcao = 1 //Para montar uma barra de progresso vou usar a função Processa() Processa({|| AEST003I(MV_PAR01,MV_PAR02)},"Aguarde....") endif RestArea(cArea) ReturnNa função abaixo irei importar o arquivo texto e a gravação na tabela SD3 usando a rotina automática. O arquivo texto é bem simples, no exemplo o usuário passou a seguinte estrutura: Primeira linha será o cabeçalho com as colunas: filial; tipo de movimentação;centro de custo Da segunda linha em diante, está definido: produto; armazem; quantidade; endereço; número de série
Static Function AEST003I(cArquivo,cRenomear) Local cLinha := "" Local nI := 0 Local nHdl Local nTamArq Local nTamLinha Local nLinhas Local aDadCab := {} Local aDadItens := {} Local nCont Local cErro := "" Local lAchou := .F. Local aCabecalho := {} Local aItens := {} Local cProduto := "" Local cLocal := "" Local nQtde := 0 Local cEndereco := "" Local cSerie := "" Local y Default cRenomear:= "1" cRenomear := IIF(ValType(cRenomear)=="N",Str(cRenomear),cRenomear) IncProc("Lendo arquivo texto para inclusao..." + Time() ) if (Upper(Right(Alltrim(cArquivo),4)) != ".CSV" ) MsgStop("Apenas arquivos com extensão CSV são aceitos!"+CRLF+"Verifique o arquivo informado!","Atenção") Return(U_AEST003()) EndIf if !File(cArquivo) MsgStop("O arquivo "+Alltrim(cArquivo)+" não existe, favor informar um arquivo existente!","Atenção") Return(U_AEST003()) EndIf nHdl := fOpen(cArquivo) If nHdl == -1 IF FERROR()== 516 ALERT("Feche a planilha que gerou o arquivo.") EndIF EndIf If nHdl == -1 MsgAlert("O arquivo de nome "+Alltrim(cArquivo)+" nao pode ser aberto! Verifique os parametros.","Atencao!") Return(U_AEST003()) Endif FSEEK(nHdl,0,0) nTamArq:=FSEEK(nHdl,0,2) FSEEK(nHdl,0,0) fClose(nHdl) FT_FUse(cArquivo) //abre o arquivo FT_FGOTOP() //posiciona na primeira linha do arquivo nTamLinha := Len(FT_FREADLN()) //Ve o tamanho da linha FT_FGOTOP() nLinhas := nTamArq/nTamLinha ProcRegua(nLinhas) aDadCab:={} aDadItens :={} nCont := 0 While !FT_FEOF() IncProc('Validando Linha: ' + Alltrim(Str(nCont)) ) clinha := FT_FREADLN() if !empty(cLinha) if nCont==0 //O usuario enviou o arquivo texto com o cabeçalho na primeira linha AADD(aDadCab,Separa(cLinha,";",.T.)) Else //O usuário enviou o arquivo texto com os itens começando da segunda linha em diante AADD(aDadItens,Separa(cLinha,";",.T.)) Endif endif FT_FSKIP() nCont++ EndDo FT_FUse() fClose(nHdl) cErro := "" if Len(aDadCab) == 0 .OR. Len(aDadItens) == 0 MsgInfo("Não há dados para serem importados!","ATENÇÃO") Return endif aCabecalho :={} aadd(aCabecalho, { "D3_FILIAL" , xFilial("SD3") , NIL}) //01-FILIAL aadd(aCabecalho, { "D3_TM" , aDadCab[1,1] , NIL}) //02-TM aadd(aCabecalho, { "D3_EMISSAO" , dDatabase , NIL}) //03-EMISSAO aadd(aCabecalho, { "D3_CC" , aDadCab[1,2] , NIL}) //04-CENTRO DE CUSTO For nI := 1 to len(aDadItens) nColunas := 0 For y := 1 to len(aDadItens[nI]) nColunas += 1 Next //guardei os dados do array em variaveis para facilitar a leitura do codigo cProduto := aDadItens[nI,1] cLocal := aDadItens[nI,2] nQtde := Valor(aDadItens[nI,3]) cEndereco:= aDadItens[nI,4] cSerie := iif(nColunas >=5,aDadItens[nI,5],"") //este campo não é obrigatório e por isso verifico se existe a coluna 5 IncProc("Lendo " + Alltrim(cProduto) + "..."+time()) dbSelectArea("SB1") SB1->(dbSetOrder(1)) SB1->(dbGoTop()) if SB1->(!dbSeek(xFilial("SB1")+cProduto)) cErro += Alltrim(cProduto)+CRLF IncProc("Produto "+Alltrim(cProduto)+" não existe..."+time()) Else IncProc("Validando " + Alltrim(cProduto) + "..."+time()) lMsErroAuto := .f. aAdd(aItens, { {"D3_COD" , cProduto , NIL},; //01-Produto {"D3_LOCAL" , cLocal , NIL},; //02-Local {"D3_QUANT" , nQtde , NIL},; //03-Quantidade {"D3_NUMSERI" , cSerie , NIL},; //04-Numero de Serie {"D3_LOCALIZ" , cEndereco , NIL}}) //05-Endereo Endif Endif Next nI if Len(aCabecalho) == 0 .OR. Len(aItens) == 0 MsgStop("Não há dados para serem importados!","ATENÇÃO") Return endif IncProc("Atualizando..."+time()) lMsErroAuto := .f. MSExecAuto({|X,Y,Z| MATA241(X,Y,Z)}, aCabecalho, aItens, 3) If lMsErroAuto MostraErro() DisarmTransaction() Else ConfirmSx8() if !Empty(cErro) MsgStop("Alguns produtos não puderam ser importados por não existirem na tabela padrão de produtos"+cErro,"Erro") else If(cRenomear=="1") fRename(cArquivo,StrTran(Lower(cArquivo),".csv",".processado")) Endif MsgInfo("Sucesso!","Atenção") Endif EndIf Return
Static Function AjustaSx1(cPerg) Local aParamBox := {} Local lRet := .F. aadd(aParamBox,{6,"Arquivo" ,Space(254),"@!","",".T.",80,.T.,"Arquivo .CSV |*.CSV","C:\LOCALDATA\",GETF_LOCALHARD+GETF_NETWORKDRIVE}) // MV_PAR01 aadd(aParamBox,{2,"Renomear",Space(1) ,{"1=Sim","2=Não"},80,".T.",.T.,".T."}) // MV_PAR02 If ParamBox(aParamBox,"Parametros",/*aRet*/,/*bOk*/,/*aButtons*/,.T.,,,,cPerg,.T.,.T.) lRet := .T. EndIf Return(lRet)