Sugestão para atualizar campo memo no Protheus de um arquivo txt
Algumas pessoas estavam me perguntando como atualizar o campo memo no Protheus já que este trabalha com a tabela SYP (Descrição dos campos memos)?
Tabelas como a do cadastro de produto é uma das tabelas que usam campos mesmo, no caso tem os campos “Descrição LI”, “Descrição em inglês” e “Descrição em português”.
O processo de atualização é bem simples, vamos exemplificar usando o cadastro padrão de produtos (SB1).
Irei definir um layout do arquivo texto, irei pedir ao meu usuário que crie um arquivo texto contendo as seguintes colunas:
Código do produto; código da tabela SYP, descrição.
O código do produto deverá ser o mesmo existente na tabela de produtos
O código da tabela SYP, deverá ser o mesmo conteúdo existente no campo correspondente ao campo memo, irei trabalhar com os campos B1_DESC_GI e B1_VM_GI (Descrição da LI), este campo tem o seguinte inicializador padrão:
E_MSMM(SB1->B1_DESC_GI,48)
A cada 48 caracteres do meu texto, ou a cada quebra de linha será uma linha na minha tabela SYP.
E teremos também no meu layout a descrição que quero incluir, pode ser uma coluna só onde você fará a quebra dos 48 caracteres ou peça ao usuário para criar várias colunas que corresponda à quantidade de linha na tabela SYP.
1 2 3 4 |
Produto;Número LI;Desc1;Desc2;Desc3;Desc4 3915008;069418;PARADA DE EMERGENCIA FANT.; texto segunda linha; texto terceira linha; texto quarta linha com xxxxxxxxxxxxxxxxxxxxxxxx 3729745;069725;BARRA INFERIOR DEPEN F201 MAQ; texto segunda linha; texto terceira linha; texto quarta linha com xxxxxxxxxxxxxxxxxxxxxxxx 3729740;069726;BARRA INFERIOR DEPENADEIRA F20; texto segunda linha; texto terceira linha; texto quarta linha com xxxxxxxxxxxxxxxxxxxxxxxx |
A codificação abaixo é apenas uma sugestão, se tiverem outras sugestões fiquem a vontade para compartilhar.
Vamos ao que interessa:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#INCLUDE "PROTHEUS.CH" #INCLUDE "TOPCONN.CH" User Function MCOM009() Local cTitulo := "Ajustar descrição da LI do cadastro de Produtos" Local nOpcao := 0 Local aButtons := {} Local aSays := {} Private cArea := GetArea() Private cPerg := Padr("MCOM009",10) Private oProcess ajustaSx1(cPerg) pergunte(cPerg, .F.) AADD(aSays,OemToAnsi("Ajustar descrição da LI do cadastro de 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.,{|| pergunte(cPerg,.T.) } } ) FormBatch( cTitulo, aSays, aButtons,,200,530 ) if nOpcao = 1 oProcess := MsNewProcess():New( { || MCOM009I(MV_PAR01) } , cTitulo , "Aguarde..." , .F. ) oProcess:Activate() endif RestArea(cArea) Return |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
Static Function MCOM009I(cArquivo) Local cLinha := "" Local cTexto := "" Local nI := 0 Local nHdl Local nTamArq Local nTamLinha Local nLinhas Local aDados := {} Local nCont Local cLinhas Local cAviso := "" Local aStrutSC1 := {} Local nItem := 0 Local nTotal := 0 Local lPrim := .T. Local nPrim := 1 Local alin := {} Local cErro := "" Local cProduto := "" Local cChave := "" Local cDesc1 := "" Local cDesc2 := "" Local cDesc3 := "" Local cDesc4 := "" Local aDescYP := {} Local cTipo := "" Local nColunas := 0 Local nDesc1, nDesc2, nDesc3, nDesc4 := 0 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 EndIf if !File(cArquivo) MsgStop("O arquivo "+Alltrim(cArquivo)+" não existe, favor informar um arquivo existente!","Atenção") Return EndIf nHdl := fOpen(cArquivo) If nHdl == -1 IF FERROR()== 516 ALERT("Feche a planilha que gerou o arquivo.") EndIF EndIf //+---------------------------------------------------------------------+ //| Verifica se foi possível abrir o arquivo | //+---------------------------------------------------------------------+ If nHdl == -1 MsgAlert("O arquivo de nome "+Alltrim(cArquivo)+" nao pode ser aberto! Verifique os parametros.","Atencao!") Return Endif //+---------------------------------------------------------------------+ //| Posiciona no Inicio do Arquivo | //+---------------------------------------------------------------------+ FSEEK(nHdl,0,0) //+---------------------------------------------------------------------+ //| Traz o Tamanho do Arquivo TXT | //+---------------------------------------------------------------------+ nTamArq:=FSEEK(nHdl,0,2) //+---------------------------------------------------------------------+ //| Posicona novamemte no Inicio | //+---------------------------------------------------------------------+ FSEEK(nHdl,0,0) //+---------------------------------------------------------------------+ //| Fecha o Arquivo | //+---------------------------------------------------------------------+ 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() //+---------------------------------------------------------------------+ //| Verifica quantas linhas tem o arquivo | //+---------------------------------------------------------------------+ nLinhas := nTamArq/nTamLinha oProcess:SetRegua1(nLinhas) aDados:={} nCont := 0 While !FT_FEOF()// .and. ncont < 16 oProcess:IncRegua1('Validando Linha: ' + Alltrim(Str(nCont))) clinha := FT_FREADLN() if !empty(cLinha) AADD(aDados,Separa(cLinha,";",.T.)) //Armazena no array aDados todas as linhas do TXT endif FT_FSKIP() nCont++ EndDo FT_FUse() fClose(nHdl) aStrutSC1 := dbStruct() oProcess:SetRegua1(len(aDados)) cErro := "" dbSelectArea("SB1") SB1->(dbSetOrder(1)) For nI := 1 to len(aDados) aColunas := {} cProduto := aDados[nI,1] cChave := iif( !Empty(aDados[nI,2]) , aDados[nI,2] , fUltimo() ) cTipo := iif( !Empty(aDados[nI,2]) , "A" , "N" ) nColunas := 0 For y := 1 to len(aDados[nI]) nColunas += 1 Next cDesc1 := iif(nColunas>=3, aDados[nI,3], "") If Empty(cDesc1) MsgStop("É obrigatório ter pelo menos a primeira descrição!") Return Endif cDesc2 := iif(nColunas>=4, aDados[nI,4], "") cDesc3 := iif(nColunas>=5, aDados[nI,5], "") cDesc4 := iif(nColunas>=6, aDados[nI,6], "") SB1->(dbGoTop()) if SB1->(!dbSeek(xFilial("SB1")+cProduto)) cErro += Alltrim(cProduto)+CRLF oProcess:IncRegua1("Produto "+Alltrim(cProduto)+" não existe...") Else oProcess:IncRegua1("Atualizando produto " + Alltrim(cProduto)) //Verifica se a chave existe, se existir deve excluir todos os registros que contem a chave dbSelectArea("SYP") SYP->(DbSetOrder(1)) SYP->(DbGoTop()) If(SYP->(DbSeek(xFilial("SYP") + cChave, .T.))) oProcess:SetRegua2( SYP->(RecCount()) ) While SYP->(!Eof()) ; .And. ( Alltrim(SYP->YP_CHAVE) == Alltrim(cChave)) ; .And. ( Alltrim(SYP->YP_CAMPO) == "B1_DESC_GI") ; .And. ( SYP->YP_FILIAL == xFilial("SYP")) oProcess:IncRegua2("Excluindo sequencia " + SYP->YP_SEQ + "...") RecLock("SYP",.F.) SYP->(dbDelete()) SYP->(MsUnlock()) SYP->(DbSkip()) End While Endif SYP->(DbCloseArea()) //Inserir os registros na tabela SYP aDescYP := {} if !Empty(cDesc1) aadd(aDescYP,{cChave,cDesc1}) Endif if !Empty(cDesc2) aadd(aDescYP,{cChave,cDesc2}) Endif if !Empty(cDesc3) aadd(aDescYP,{cChave,cDesc3}) Endif if !Empty(cDesc4) aadd(aDescYP,{cChave,cDesc4}) Endif oProcess:SetRegua2( len(aDescYP) * 2) dbSelectArea("SYP") For i := 1 to len(aDescYP) Begin Transaction RecLock("SYP",.T.) SYP->YP_FILIAL := xFilial("SYP") SYP->YP_CHAVE := aDescYP[i,1] SYP->YP_SEQ := StrZero(i,3) SYP->YP_TEXTO := aDescYP[i,2] SYP->YP_CAMPO := "B1_DESC_GI" SYP->(MsUnlock()) DbCommit() oProcess:IncRegua2("Incluindo Descrição LI - Registro " + StrZero(nI,4) + "...") End Transaction Next if cTipo=="N" RecLock("SB1",.F.) SB1->B1_DESC_GI := cChave SB1->(MsUnlock()) Endif Endif Sleep(100) dbSelectArea("SB1") Next nI if !Empty(cErro) Aviso("ATENÇÃO", "Alguns produtos não puderam ser importados por não existirem na tabela padrão de produtos."+CRLF+cErro,{"OK"},3) Endif if(mv_par02==1) fRename(Upper(Alltrim(cArquivo)),Upper(Alltrim(cArquivo))+".processado") Endif oProcess:IncRegua1("Atualização finalizada...") oProcess:IncRegua2("") Return |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
Static Function fUltimo() local cUltimo := "" Local cQuery := "" cQuery := " SELECT MAX(YP_CHAVE) ULTIMO " cQuery += " FROM " + RetSqlName("SYP") cQuery += " WHERE YP_FILIAL = '"+XFILIAL("SYP")+"' " cQuery += " AND D_E_L_E_T_ = ' ' " If ( SELECT("TMPSYP") ) > 0 dbSelectArea("TMPSYP") TMPSYP->(dbCloseArea()) EndIf TCQUERY cQuery NEW ALIAS "TMPSYP" IF TMPSYP->(!Eof()) cUltimo := StrZero(Val(TMPSYP->ULTIMO)+1,6) Endif TMPSYP->(dbCloseArea()) Return(cUltimo) |
1 2 3 4 |
static function ajustaSx1(cPerg) PutSx1(cPerg, "01", "Arquivo ?","","", "mv_ch1", "C",99, 0, 0, "G", "","DIR","","","mv_par01","","","","","","","","","","","","","","","","",{"Informe o arquivo para importar,","obrigatóriamente deve ser .CSV","",""},{"","","",""},{"","",""},"") PutSx1(cPerg, "02", "Renomear?","","", "mv_ch2", "N", 1, 0, 2, "C", "", "","","","mv_par02","Sim","Si","Yes","","Nao","No","No") Return |