PERGUNTAS E RESPOSTAS
 
Bem Vindo, Visitante  Todos os Fórums
  ADVPL
Enviar para a impressoraImprimir  Enviar e-mail para um amigoEnviar Para um Amigo
Precisa estar Logado

Subject Assunto:
Importação Arquivo CSV e Atualização Tabela
Versão:
12.1.17
Plataforma:
Microsoft
Complemento:
DB:
SQL Server
Complemento:
LinkedIn
Foto
Mensagem do Enviar e-mail Abrir o Perfil do usuário DANIELCOST DANIELCOST em 07/01/2021, 17:36 h
Local: MG  Registro: 18/06/2020  Postagens: 2
Boa tarde. Sou novo em ADVPL (mais ou menos), estou fazendo um fonte para pegar um arquivo CSV, ou TXT e atualizar o saldo da Tabela SB2 de duas filiais, mas não está funcionando, apesar de apresentar a mensagem que deu certo. Ele precisa ler o arquivo csv, somar o saldo do B2_QATU das duas filiais 09 e 29, guardar numa variável, comparar o valor do B2_COD do arquivo com o do banco de dados, se for igual, atualiza o saldo da filial 09 igual a do arquivo e depois atualiza o saldo da filial 29 com o valor da subtração entre o valor que guardei na variável no inicio e o novo valor da filial 09. Help! Eis o fonte:

Algumas linhas de código estão comentadas porque estava testando outros jeitos de fazer isso.

#include "totvs.ch"
#include "protheus.ch"
#include "TOPCONN.CH"

User Function fImpCsv()
Local cDiret               //GRAVA DIRETÓRIO
Local cLinha := ""          //QUEBRA POR PONTO E VIRGULA
Local lPrimlin   := .T. //IDENTIFICA PRIMEIRA LINHA (CABECALHO)
Local aCampos := {}      //GRAVA CAMPOS DO CABEÇALHO DO ARQUIVO
Local aDados := {}      //GRAVA DADOS DO ARQUIVO (VALORES)
Local i
Local j
Local vTemp := 0
Local vTempp := 0
Private aErro := {}

cDiret := cGetFile( ‘Arquito CSV|*.csv| Arquivo TXT|*.txt| Arquivo XML|*.xml‘,; //[ cMascara],
                         ‘Selecao de Arquivos‘,;                  //[ cTitulo],
                         0,;                                      //[ nMascpadrao],
                         ‘D:\TOTVS\‘,;                            //[ cDirinicial],
                         .F.,;                                    //[ lSalvar],
                         GETF_LOCALHARD + GETF_NETWORKDRIVE,;    //[ nOpcoes],
                         .T.)       

FT_FUSE(cDiret)
ProcRegua(FT_FLASTREC())
FT_FGOTOP()


While !FT_FEOF()

     IncProc("Lendo arquivo texto...")

     cLinha := FT_FREADLN()

     //If lPrimlin //SE PRIMEIRA LINHA FOR VERDADEIRO
          //aCampos := Separa(cLinha,";",.T.) //SEPARA OS CAMPOS POR PONTO E VIRGULA
          //lPrimlin := .F. //TRANSFORMA VARIAVEL EM FALSO
     //Else //SE PRIMEIRA LINHA FOR FALSO
          AADD(aDados,Separa(cLinha,";",.T.)) //SEPARA DADOS POR PONTO E VIRGULA E ADICIONA NO ARRAY
     //EndIf

     FT_FSKIP()
EndDo

Begin Transaction
     ProcRegua(Len(aDados))
     For i:=1 to Len(aDados)

          IncProc("Importando Registros...")

          dbSelectArea("SB2")
          cQuery     := " SELECT B2_FILIAL, B2_COD, B2_LOCAL, B2_QATU "
          cQuery     += " FROM " + RetSqlName("SB2") + " B2 "
          cQuery     += " WHERE B2_FILIAL IN (‘09‘) "
          cQuery     += " AND (B2_COD = ‘" + AllTrim(aDados[i,1]) + "‘) "
          cQuery     += " AND B2.D_E_L_E_T_ = ‘ ‘ "
          cQuery := ChangeQuery(cQuery)
          DbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), "B2F1", .F., .T.)
          
          dbSelectArea("SB2")
          cQuery     := " SELECT B2_FILIAL, B2_COD, B2_LOCAL, B2_QATU "
          cQuery     += " FROM " + RetSqlName("SB2") + " B2 "
          cQuery     += " WHERE B2_FILIAL IN (‘29‘) "
          cQuery     += " AND (B2_COD = ‘" + AllTrim(aDados[i,1]) + "‘) "
          cQuery     += " AND B2.D_E_L_E_T_ = ‘ ‘ "
          cQuery := ChangeQuery(cQuery)
          DbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), "B2F2", .F., .T.)
          
          DbSelectArea("B2F1")
          DbSelectArea("B2F2")
          
          vTemp := 0
          vTemp := B2F1->B2_QATU + B2F2->B2_QATU //ARMAZENA SOMA DA FILIAL 09 e 29
          
          dbSelectArea("SB2")
          dbSetOrder(1)
          
          dbGoTop()
          
          If dbSeek("09"+aDados[i,1]+"01")
               Reclock("SB2",.F.)
               
               //For j:=1 to Len(aCampos)
                    //cCampo := "SB2->" + aCampos[j,2] //B2->B2_QATU
                    //&cCampo := aDados[i,2] //SB2->B2_QATU := 4
                    
                    B2F1->B2_QATU := aDados[i,2] //ATUALIZA QUANTIDADE DA FILIAL 09
                    
                    vTempp := 0
                    vTempp := vTemp - B2F1->B2_QATU //ARMAZENA VALOR DA SUBTRACAO DA VARIAVEL vTemp E DO NOVO VALOR DO CAMPO B2_QATU DA FILIAL 09
                    
                    B2F2->B2_QATU := vTempp // ATUALIZA QUANTIDADE DA FILIAL 29
                    
               //Next j
               
               SB2->(MsUnlock())
          EndIf
          
DbSelectArea("B2F1")
DbCloseArea()
DbSelectArea("B2F2")
DbCloseArea()

     Next i
     
End Transaction

ApMsgInfo("Atualização concluída com sucesso!","Sucesso!")

Return

Foto
Mensagem do Enviar e-mail Abrir o Perfil do usuário LABAMBAMOG LABAMBAMOG em 20/08/2021, 09:36 h
Local: SP  Registro: 29/08/2008  Postagens: 22
Cara, atualizar tabelas "por fora" nunca é boa ideia, mais cedo ou mais tarde você terá diferenças e terá que criar um sistema paralelo para acerta-las (se é que isso já não esteja acontecendo), mas vamos lá.

Seu código não funciona devido a erros de conceito, vou citar o principal deles.
Você mistura a área padrão do SB2 (Reclock("SB2",.F.)) com a atualização de um alias temporário (B2F1->B2_QATU := aDados[i,2])).
Considerando que as linhas acima da Begin Transaction estejam corretas e que o almoxarifado (B2_LOCAL) não importa pra vc...


Begin Transaction
     ProcRegua(Len(aDados))
     For i := 1 to Len(aDados)
          IncProc("Importando Registros...")

          If Select("B2F1") > 0
               B2F1->(dbCloseArea())
          Endif
          
          cQuery     := " SELECT SUM(B2_QATU) SOMA "
          cQuery     += " FROM " + RetSqlName("SB2")
          cQuery     += " WHERE B2_FILIAL IN (‘09‘,‘29‘) "
          cQuery     += " AND B2_COD = ‘" + AllTrim(aDados[i,1]) + "‘"
          cQuery     += " AND R_E_C_D_E_L_ = 0 "
          cQuery := ChangeQuery(cQuery)
          DbUseArea(.T., "TOPCONN", TCGenQry(,,cQuery), "B2F1", .F., .T.)

          vTempp := B2F1->SOMA
          B2F1->(dbCloseArea())
          
          cQuery := "UPDATE SB2 SET B2_QATU = " + StrTran(cValToChar(aDados[i,2]),",",".")          //Veja se há necessidade dessa conversão pq não sei o que ocorre na sua função Separa...
          cQuery += "     FROM "+RetSqlName("SB2") +" SB2 "
          cQuery += "     WHERE B2_FILIAL = ‘09‘ "
          cQuery += " AND B2_COD = ‘" + AllTrim(aDados[i,1]) + "‘"
          TCSQLExec(cQuery)

          B2F1->(dbCloseArea())
          
          cQuery := "UPDATE SB2 SET B2_QATU = " + StrTran(cValToChar(vTempp-aDados[i,2]),",",".")
          cQuery += "     FROM "+RetSqlName("SB2") +" SB2 "
          cQuery += "     WHERE B2_FILIAL = ‘29‘ "
          cQuery += " AND B2_COD = ‘" + AllTrim(aDados[i,1]) + "‘"
          TCSQLExec(cQuery)

          B2F1->(dbCloseArea())
     Next i
     
End Transaction

Acho que é isso, t+


Foto
Mensagem do Enviar e-mail Abrir o Perfil do usuário LABAMBAMOG LABAMBAMOG em 20/08/2021, 09:41 h
Local: SP  Registro: 29/08/2008  Postagens: 22
Esses dois últimos B2F1->(dbCloseArea()) vc pode apagar pq a TCSQLExec não os utiliza. Fui copiando e não vi, desculpe-me.
T+

Foto
Mensagem do Enviar e-mail Abrir o Perfil do usuário CARNEIRO CARNEIRO em 20/08/2021, 09:47 h
Local: SP  Registro: 16/09/2005  Postagens: 456
Atualizar a SB2 direto no banco é uma das piores coisas que se pode fazer no Protheus. Vai bagunçar todo o kardex do produto. Você só deve alterar o saldo de produto através de movimentos. Se o produto que você está ajustando estiver envolvido em um processo produtivo, pode até dar problema com o fisco por causa do bloco K.

Cesar Arneiro
C.A. ERP Consulting
Fone: (12) 99744-4546
Email: cesar@caerpconsulting.com.br

Foto
Mensagem do Enviar e-mail Abrir o Perfil do usuário LGPADRAO LGPADRAO em 20/08/2021, 14:51 h
Local: MG  Registro: 14/06/2021  Postagens: 3
Daniel, saudações!

Meu amigo venho apenas reafirmar o que os colegas citaram em algumas respostas e vou te explicar o principal motivo.

A tabela SB2 é dinâmica e acompanha cada movimentação realizada com produtos no sistema, fazer esses cálculos que você disse até resolve momentaneamente, mas ao rodar a rotina de saldo atual esse valor será atualizado novamente.

Esse campo está nas principais rotinas do módulo e nas rotinas dos livros fiscais por exemplo, pois quando falamos de estoque não podemos esquecer do bloco K.

Essa não é uma boa prática e acredito que você precise buscar uma solução que faça interação com os movimentos do processo e não com o resultado final. São os movimentos que geram seu saldo, de repente está faltando um olhar diferente para essa situação pois uma personalização nesse ponto do sistema não é viável as chances de piorar a situação são maiores do que as de solução.

Para postar no Fórum você precisa efetuar o seu login ou se registrar

 Mudar para Fórum

 

 

 
 
   
Pagina Principal Shopping PROTHEUS Tire suas duvidas Vagas Microsiga em todo Brasil Aprofunde seus conhecimentos Noticias Online Fale Conosco Pagina Principal