Imprimi Página | Fechar janela

erro de importação CSV

Impresso de: Helpfacil - Portal do conhecimento
Nome do Forum: ADVPL
Descrição do Forum: Dúvidas sobre a programação em ADVPL
URL:http://www.helpfacil.com.br/display_topic_threads.asp?ForumID=1&TopicID=44430
Data da Impressão: sábado, 24 de fevereiro de 2024 at 16:36


Topico: erro de importação CSV

Postado por: CAIMCEZAR
Assunto: erro de importação CSV
Data Postagem: quinta-feira, 1 de fevereiro de 2024 at 20:19

Boa tarde,

estou montando um importador da tabela CW1. porém estou com problema no segundo registro. o código é o mesmo porém tem um sequencial para input do aItens. quando o código é o mesmo o sistema informa que não pode importar porque o registro já existe.

precisava que ele ignorasse a informação da chave duplicada para código e seguisse com o sequencial do CW1_SEQUEN. pois é um item daquele registro.

#include ‘protheus.ch‘
#include ‘parmtype.ch‘
#include ‘totvs.ch‘



/*Importador CW1 GRUPO DE RATEIOS
@type function
@version
@author Caio.Mario
@since 1/24/2024
@return variant, return_description
/*/



User Function impcw1()


    local   cFile       := ""
    local   nHandle     := 0
    local   cLinha      := ""
    local   lPrim       := .T.
    local   aCampos     := {}
    local   aDados      := {}   
    Local   nx
    //Local   aArea    := GetArea()

    Local   aDadosAuto := {}   
    Local   aItens      := {}   

    
    Private lMsHelpAuto := .F.
    Private lMsErroAuto := .F.


//Seleciona o arquivo Csv
    cFile := cGetFile( "Files TXT|*.txt", "Select txt File", 0, , .F., GETF_LOCALHARD, .T., .T.)

//Trava o arquivo
    nHandle := FT_FUSE(cFile)

    // Se houver erro de abertura abandona processamento
    If nHandle = -1
        Return
    Endif


    ProcRegua(FT_FLastRec())
//Posiciona na linha 1
    FT_FGoTop()
    // Enquanto não for final do arquivo continua lendo o mesmo.
    While !FT_FEOF()
       
        IncProc("Lendo arquivo CSV")
        // Le conteudo da linha posicionada.
        cLinha := FT_FREADLN()

        If lPrim
            aCampos := Separa(cLinha, ";",.T.)
               lPrim   := .F.
          Else
               AADD(aDados, Separa(cLinha, ";",.T.))
          EndIf
       
        // Proxima linha.
        FT_FSKIP()

    End

    // Libera arquivo.
    //FT_FUSE()    

           for nx := 1 to len(aDados)

               DBSelectArea("CW1")
               DBSetOrder(1)
               DBGoTop()

               if CW1->(dbseek(aDados[nx][1] + aDados[nx][6]))
               MsgAlert("Atencão!", "Registro já existe!")              
               lRet := .T.

               Return(lRet)

               Else

                      aDadosAuto:= {{‘CW1_CODIGO‘ , aDados[nx][1]                               , Nil},;    // Codigo da Filial
                                    {‘CW1_DESCRI‘ , aDados[nx][2]                               , Nil},;    // Descrição Grupo de Rateio              
                                    {‘CW1_TIPO‘    , aDados[nx][3]                               , Nil},;    // Tipo              
                                    {‘CW1_INDICE‘ , ""                                          , Nil},;    // indice   
                                    {‘CW1_ENTID‘   , aDados[nx][5]                               , Nil}}     // entidade
                        aAdd(aItens,{{‘CW1_SEQUEN‘ , aDados[nx][6]                               , Nil},;    // sequencia              
                                    {‘CW1_CONTA‘   , aDados[nx][7]                               , Nil},;    // Conta              
                                    {‘CW1_CCUSTO‘ , aDados[nx][8]                               , Nil},;    // Centro de Custo              
                                    {‘CW1_ITEM‘    , aDados[nx][9]                               , Nil},;    // Item Contabil                 
                                    {‘CW1_CLVL‘    , aDados[nx][10]                             , Nil},;    // Classe Valor              
                                    {‘CW1_PERCEN‘ , val(aDados[nx][11])                         , NIL},;    // Percentual
                                    {‘CW1_FATOR‘   , 0                                           , Nil},;    // Fator              
                                    {‘CW1_FORMUL‘ , aDados[nx][13]                             , Nil},;    // Formula              
                                    {‘CW1_STATUS‘ , aDados[nx][14]                             , Nil}})    // Status


                    MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aDadosAuto, aItens, 3)

                    aDadosAuto := {}
                    aItens := {}    

                    If lMsErroAuto
                     DisarmTransaction()
                        lRetorno := .F.
                        MostraErro()
                    Else
                        lRetorno := .T.
                        MsgAlert("Registro Incluido", "Aviso!")
                    EndIf
               Endif   

               Next


               FT_FUSE()    
                    

               //RestArea(aArea)
            Return


      



Respostas:

Postado Por: ROBERTOMEN
Data Postagem: sexta-feira, 2 de fevereiro de 2024 at 07:58

BOM DIA

Vc vai precisar incluir na validacao do campo CW1_CODIGO a seguinte instrução

vai estar assim: ExistChav(‘CW1‘,,1) .And. FreeForUse(‘CW1‘,M->CW1_CODIGO)

deverá ficar assim:
ExistChav(‘CW1‘,,1) .And. FreeForUse(‘CW1‘,M->CW1_CODIGO) .and. ! isincallstack("U_IMPCW1")                                                                      


feito isto vc está dizendo para o execauto não validar o campo quando a chamada for feita pela sua função, feito isto, deverá salvar...


teste ai.

Abç




Postado Por: CAIMCEZAR
Data Postagem: sexta-feira, 2 de fevereiro de 2024 at 08:39

bom dia Roberto,

coloquei a chave porém seguiu a validação indicando erro.

ExistChav(‘CW1‘,,1) .And. FreeForUse(‘CW1‘,M->CW1_CODIGO) .and. ! isincallstack("U_IMPCW1")


AJUDA:EXISTCHAV
Variável já cadastrada.

Tabela CW1 02/02/2024 08:35:55
Cod. Grupo           - CW1_CODIGO   := 3
Descricao            - CW1_DESCRI   := SOMENTE 2
Tipo Grupo           - CW1_TIPO     := 1
Cod. Indice          - CW1_INDICE   :=
Entidade             - CW1_ENTID    := 3
--------------------------------------------------------------------------------
Tabela CW1 02/02/2024 08:35:55
Erro no Item   3
--------------------------------------------------------------------------------
Sequencial           - CW1_SEQUEN   := 002
Cod. Conta           - CW1_CONTA    :=
Cod C Custo          - CW1_CCUSTO   :=
Cod. Item            - CW1_ITEM     := 104010104
Cod Cl Valor        - CW1_CLVL     :=
Percen Ratei        - CW1_PERCEN   := 0.06
Fator Ind            - CW1_FATOR    := 0
Form. Fator          - CW1_FORMUL   :=
Status               - CW1_STATUS   := 1
Erro --> Inconsistencia na Linha de Itens



Postado Por: ROBERTOMEN
Data Postagem: sexta-feira, 2 de fevereiro de 2024 at 12:40

tente

!isincallstack("U_IMPCW1").and.ExistChav('CW1',,1).and.FreeForUse('CW1',M->CW1_CODIGO)



Postado Por: CAIMCEZAR
Data Postagem: sexta-feira, 2 de fevereiro de 2024 at 14:48

tentei novamente com essa nova validação. não consegui também. mudei na x3_valid dele. ainda indica a chave.



Postado Por: ROBERTOMEN
Data Postagem: sexta-feira, 2 de fevereiro de 2024 at 17:19


tente

iif(isincallstack("U_IMPCW1"),.t.,ExistChav(‘CW1‘,,1).and.FreeForUse(‘CW1‘,M->CW1_CODIGO))



Postado Por: CAIMCEZAR
Data Postagem: segunda-feira, 5 de fevereiro de 2024 at 13:31

boa tarde.

meu fonte evoluiu para nao apresentar mais o erro. porém ele nao inclui o mesmo registro duas vezes. ainda não consegui entender porque.

quando o código é diferente ele deixa fazer a importação normal. quando é o mesmo código com CW1_SEQUEN diferente ele nao importa os próximos sequenciais. ele pula sem dar erro.

For nx := 1 to len(aDados)

       dbselectarea("CW1")
       DBSetOrder(1)

        If ! dbseek(xFilial("CW1")+aDados[nx][1]+aDados[nx][2]+aDados[nx][6])       
            MsgAlert("Já existe registro")
            loop
        Else

       
        aDadosAuto := {{‘CW1_CODIGO‘ , aDados[nx][1]                               , Nil},;    // Codigo da Filial
                      {‘CW1_DESCRI‘ , aDados[nx][2]                               , Nil},;    // Descrição Grupo de Rateio              
                      {‘CW1_TIPO‘    , aDados[nx][3]                               , Nil},;    // Tipo              
                      {‘CW1_INDICE‘ , ""                                          , Nil},;    // indice   
                      {‘CW1_ENTID‘   , aDados[nx][5]                               , Nil}}     // entidade
          aAdd(aItens,{{‘CW1_SEQUEN‘ , aDados[nx][6]                               , Nil},;    // sequencia              
                      {‘CW1_CONTA‘   , aDados[nx][7]                               , Nil},;    // Conta              
                      {‘CW1_CCUSTO‘ , aDados[nx][8]                               , Nil},;    // Centro de Custo              
                      {‘CW1_ITEM‘    , aDados[nx][9]                               , Nil},;    // Item Contabil                 
                      {‘CW1_CLVL‘    , aDados[nx][10]                             , Nil},;    // Classe Valor              
                      {‘CW1_PERCEN‘ , val(aDados[nx][11])                         , NIL},;    // Percentual
                      {‘CW1_FATOR‘   , 0                                           , Nil},;    // Fator              
                      {‘CW1_FORMUL‘ , aDados[nx][13]                             , Nil},;    // Formula              
                      {‘CW1_STATUS‘ , aDados[nx][14]                             , Nil}})    // Status


        //Executar a inclusão
        MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aDadosAuto, aItens, 3)


        // Lidar com erros
        If lMsErroAuto
            lRetorno := .F.
            MostraErro()
        Else
            lRetorno := .T.
            MsgAlert("Aviso", "Registros processados com sucesso!")
            EndIf
        Endif
    Next nx


Return



Postado Por: ROBERTOMEN
Data Postagem: segunda-feira, 5 de fevereiro de 2024 at 14:49

Boa Tarde.

Tente assim:



Local cCW1_CODIGO := aDados[nx][1]
Local cCW1_SEQUEN := aDados[nx][6]


For nx := 1 to len(aDados)

       dbselectarea("CW1")
       DBSetOrder(1)

        If dbseek(xFilial("CW1")+cCW1_CODIGO + cCW1_SEQUEN // Se achou da a Msg
            MsgAlert("Já existe registro")
            loop
        Else                                             // Não Achou Inclui
            cCW1_SEQUEN := soma1(cCW1_SEQUEN)            // Soma 1 na Sequencia   
       
        aDadosAuto := {{'CW1_CODIGO' , aDados[nx][1]                               , Nil},;    // Codigo da Filial
                      {'CW1_DESCRI' , aDados[nx][2]                               , Nil},;    // Descrição Grupo de Rateio              
                      {'CW1_TIPO'    , aDados[nx][3]                               , Nil},;    // Tipo              
                      {'CW1_INDICE' , ""                                          , Nil},;    // indice   
                      {'CW1_ENTID'   , aDados[nx][5]                               , Nil}}     // entidade
          aAdd(aItens,{{'CW1_SEQUEN' , cCW1_SEQUEN                                , Nil},;    // sequencia              
                      {'CW1_CONTA'   , aDados[nx][7]                               , Nil},;    // Conta              
                      {'CW1_CCUSTO' , aDados[nx][8]                               , Nil},;    // Centro de Custo              
                      {'CW1_ITEM'    , aDados[nx][9]                               , Nil},;    // Item Contabil                 
                      {'CW1_CLVL'    , aDados[nx][10]                             , Nil},;    // Classe Valor              
                      {'CW1_PERCEN' , val(aDados[nx][11])                         , NIL},;    // Percentual
                      {'CW1_FATOR'   , 0                                           , Nil},;    // Fator              
                      {'CW1_FORMUL' , aDados[nx][13]                             , Nil},;    // Formula              
                      {'CW1_STATUS' , aDados[nx][14]                             , Nil}})    // Status


        //Executar a inclusão
        MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aDadosAuto, aItens, 3)


        // Lidar com erros
        If lMsErroAuto
            lRetorno := .F.
            MostraErro()
        Else
            lRetorno := .T.
            MsgAlert("Aviso", "Registros processados com sucesso!")
            EndIf
        Endif
    Next nx


Return



Postado Por: CAIMCEZAR
Data Postagem: terça-feira, 6 de fevereiro de 2024 at 08:27

nesse cenário ele tá somando um no sequencial.

na minha situação ele teria que ler o mesmo código e seguir com o sequencial do csv.

CW1_CODIGO;CW1_DESCRI;CW1_TIPO;CW1_INDICE;CW1_ENTID;CW1_SEQUEN;CW1_CONTA;CW1_CCUSTO;CW1_ITEM;CW1_CLVL;CW1_PERCEN;CW1_FATOR;CW1_FORMUL;CW1_STATUS
100101;testes;1;;3;001;;;104010104;;0.07;0;;1
100101;testes;1;;3;002;;;104010102;;0.06;0;;1

For nx := 1 to len(aDados)


cCW1_CODIGO := aDados[nx][1]
cCW1_SEQUEN := aDados[nx][6]

       dbselectarea("CW1")
       DBSetOrder(1)

        If dbseek(xFilial("CW1")+cCW1_CODIGO + cCW1_SEQUEN) // Se achou da a Msg
            MsgAlert("Já existe registro")
            loop
        Else                                             // Não Achou Inclui
            cCW1_SEQUEN := soma1(cCW1_SEQUEN)            // Soma 1 na Sequencia    
       
        aDadosAuto := {{‘CW1_CODIGO‘ , aDados[nx][1]                               , Nil},;    // Codigo da Filial
                      {‘CW1_DESCRI‘ , aDados[nx][2]                             , Nil},;    // Descrição Grupo de Rateio              
                      {‘CW1_TIPO‘    , aDados[nx][3]                               , Nil},;    // Tipo              
                      {‘CW1_INDICE‘ , ""                                          , Nil},;    // indice    
                      {‘CW1_ENTID‘   , aDados[nx][5]                               , Nil}}     // entidade
          aAdd(aItens,{{‘CW1_SEQUEN‘ , cCW1_SEQUEN                                 , Nil},;    // sequencia              
                      {‘CW1_CONTA‘   , aDados[nx][7]                               , Nil},;    // Conta              
                      {‘CW1_CCUSTO‘ , aDados[nx][8]                               , Nil},;    // Centro de Custo              
                      {‘CW1_ITEM‘    , aDados[nx][9]                               , Nil},;    // Item Contabil                  
                      {‘CW1_CLVL‘    , aDados[nx][10]                             , Nil},;    // Classe Valor              
                      {‘CW1_PERCEN‘ , val(aDados[nx][11])                         , NIL},;    // Percentual
                      {‘CW1_FATOR‘   , 0                                           , Nil},;    // Fator              
                      {‘CW1_FORMUL‘ , aDados[nx][13]                             , Nil},;    // Formula              
                      {‘CW1_STATUS‘ , aDados[nx][14]                             , Nil}})    // Status


        //Executar a inclusão
        MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aDadosAuto, aItens, 3)


        // Lidar com erros
        If lMsErroAuto
            lRetorno := .F.
            MostraErro()
        Else
            lRetorno := .T.
            MsgAlert("Aviso", "Registros processados com sucesso!")
            EndIf
        Endif
    Next nx


Return



Postado Por: ROBERTOMEN
Data Postagem: terça-feira, 6 de fevereiro de 2024 at 09:51

Entendi, então tente apenas corrigir o seu dbseek pois a chave 1 da CW1 é
filial + codigo + sequencia e não filial + descrição + codigo + sequencia


For nx := 1 to len(aDados)

       dbselectarea("CW1")
       DBSetOrder(1)

        If ! dbseek(xFilial("CW1")+aDados[nx][1]+aDados[nx][6]) // Aqui !!!     
            MsgAlert("Já existe registro")
            loop
        Else

       
        aDadosAuto := {{'CW1_CODIGO' , aDados[nx][1]                               , Nil},;    // Codigo da Filial
                      {'CW1_DESCRI' , aDados[nx][2]                               , Nil},;    // Descrição Grupo de Rateio              
                      {'CW1_TIPO'    , aDados[nx][3]                               , Nil},;    // Tipo              
                      {'CW1_INDICE' , ""                                          , Nil},;    // indice   
                      {'CW1_ENTID'   , aDados[nx][5]                               , Nil}}     // entidade
          aAdd(aItens,{{'CW1_SEQUEN' , aDados[nx][6]                               , Nil},;    // sequencia              
                      {'CW1_CONTA'   , aDados[nx][7]                               , Nil},;    // Conta              
                      {'CW1_CCUSTO' , aDados[nx][8]                               , Nil},;    // Centro de Custo              
                      {'CW1_ITEM'    , aDados[nx][9]                               , Nil},;    // Item Contabil                 
                      {'CW1_CLVL'    , aDados[nx][10]                             , Nil},;    // Classe Valor              
                      {'CW1_PERCEN' , val(aDados[nx][11])                         , NIL},;    // Percentual
                      {'CW1_FATOR'   , 0                                           , Nil},;    // Fator              
                      {'CW1_FORMUL' , aDados[nx][13]                             , Nil},;    // Formula              
                      {'CW1_STATUS' , aDados[nx][14]                             , Nil}})    // Status


        //Executar a inclusão
        MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aDadosAuto, aItens, 3)


        // Lidar com erros
        If lMsErroAuto
            lRetorno := .F.
            MostraErro()
        Else
            lRetorno := .T.
            MsgAlert("Aviso", "Registros processados com sucesso!")
            EndIf
        Endif
    Next nx



Postado Por: CAIMCEZAR
Data Postagem: terça-feira, 6 de fevereiro de 2024 at 10:03

Então. mas

        If ! dbseek(xFilial("CW1")+aDados[nx][1]+aDados[nx][6]) // Aqui !!!     

aDados[nx][1] é codigo
aDados[nx]6 é sequencial






Postado Por: EMERSON.EN
Data Postagem: terça-feira, 6 de fevereiro de 2024 at 16:26

o procedimento que você está tentando executar não vai funcionar.

observe que, apesar de não tem uma tabela mestre e outra detalhe, o cadastro de grupos de rateio se comporta como mestre/detalhe, visto que você precisa enviar cabeçalho e itens.

logo, se o código do grupo já existe na CW1 e será necessário acrescentar um item de rateio, isso não será uma inclusão, será uma alteração do grupo para adição de um item.

solução: para inclusão de grupo você precisa enviar todos os itens simultaneamente.

problema: a rotina CTBA276 não prevê alteração por ExecAuto (para incluir um item no grupo, por exemplo).

sugiro alterar a importação para tratar todos os itens simultaneamente.
daí você avalia quais grupos precisam ser cadastrados e quais precisam ser alterados. as alterações precisam ser efetuadas ‘manualmente‘.

exemplo:

     nTamCod := len(CW1->CW1_CODIGO)
     nTamSeq := len(CW1->CW1_SEQUEN)
     aGrupos := {}

     CW1->(dbSetOrder(1)) // CW1_FILIAL, CW1_CODIGO, CW1_SEQUEN

     // monta os grupos com seus itens (rateios)
     // aGrupos[n][1] - cabeçalho
     // aGrupos[n][2] - itens
     // aGrupos[n][3] - inclui?
     For nx := 1 to len(aDados)
          cCW1Codigo := left(padr(aDados[nx][1],nTamCod),nTamCod)

          iGrupo := aScan(aGrupos, {|x| x[1][1][2] == cCW1Codigo})
          if iGrupo = 0 // não encontrou o grupo no array
               // adiciona o grupo
               aAdd(aGrupos, {{;
                    {‘CW1_CODIGO‘, cCW1Codigo, nil},/*Codigo da Filial*/;
                    {‘CW1_DESCRI‘, aDados[nx][2], nil},/*Descrição Grupo de Rateio*/;
                    {‘CW1_TIPO‘, aDados[nx][3], nil},/*Tipo*/;
                    {‘CW1_INDICE‘, ‘‘, nil},/*indice*/;
                    {‘CW1_ENTID‘, aDados[nx][5], nil}/*entidade*/},;
                    {},/*itens do rateio*/;
                    !CW1->(dbseek(xFilial()+cCW1Codigo))/*inclui?*/;
               })
               iGrupo := len(aGrupos)
          endif
          // adiciona o item (rateio) ao grupo
          aAdd(aGrupos[iGrupo][2], {;
               {‘CW1_SEQUEN‘, left(padr(aDados[nx][6],nTamSeq),nTamSeq), nil},/*sequencia*/;
               {‘CW1_CONTA‘, aDados[nx][7], nil},/*Conta*/;
               {‘CW1_CCUSTO‘, aDados[nx][8], nil},/*Centro de Custo*/;
               {‘CW1_ITEM‘, aDados[nx][9], nil},/*Item Contabil*/;
               {‘CW1_CLVL‘, aDados[nx][10], nil},/*Classe Valor*/;
               {‘CW1_PERCEN‘, val(aDados[nx][11]), nil},/*Percentual*/;
               {‘CW1_FATOR‘, 0, nil},/*Fator*/;
               {‘CW1_FORMUL‘, aDados[nx][13], nil},/*Formula*/;
               {‘CW1_STATUS‘, aDados[nx][14], nil}/*Status*/;
          })
     Next nX

     // inclui os grupos que ainda NÃO EXISTEM no sistema
     For nx := 1 to len(aGrupos)

          if aGrupos[nX][3] // se inclusão

               lMsErroAuto := .F.

               MSExecAuto({|X, Y, Z| CTBA276(X, Y, Z)}, aGrupos[nX][1], aGrupos[nX][2], 3)
               if lMsErroAuto
                    MostraErro()
               endif

          endif

     Next nx

     // altera os grupos que JÁ existem no sistema
     For nx := 1 to len(aGrupos)
          if !aGrupos[nX][3] // se NÃO é inclusão
               aCabGrp := aGrupos[nX][1]
               aItensGrp := aGrupos[nX][2]

               cCW1Codigo := aCabGrp[1][2]
               cCW1Tipo := aCabGrp[3][2]
               cCW1Entid := aCabGrp[5][2]

               // aqui você manipula os registros do grupo de rateio [transaction, Reclock() / MSUnlock()]


               // depois de alterar o grupo, faça a amarração do rateio (função padrão)
               CW1->(dbseek(xFilial()+cCW1Codigo))
               CTB276Amarra(xFilial("CW1"), xFilial("CW2"), cCW1Codigo, cCW1Tipo, cCW1Entid, .F.)
          endif
     Next nx






Postado Por: CAIMCEZAR
Data Postagem: quarta-feira, 7 de fevereiro de 2024 at 11:03

Show Emerson,

Sua ideia funcionou melhor que a minha. consegui importar a maioria seguindo o sequencial do CSV.

muito obrigado pelo apoio de todos.




Imprimir Página | Fechar Janela