|
Bem Vindo, Visitante
|
Todos os Fórums
ADVPL
|
Imprimir
Enviar Para um Amigo Precisa estar Logado
|
|
|
Assunto: |
erro de importação CSV |
|
Versão: |
12.1.2210 |
|
Plataforma: |
Microsoft |
Complemento: |
|
|
DB: |
SQL Server |
Complemento: |
|
|
|
|
|
Mensagem do
CAIMCEZAR
em 01/02/2024, 20:19 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
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
|
|
|
Mensagem do
ROBERTOMEN
em 02/02/2024, 07:58 h
Local: PR Registro: 04/07/2017 Postagens: 544 |
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ç
|
|
|
Mensagem do
CAIMCEZAR
em 02/02/2024, 08:39 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
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 |
|
|
Mensagem do
ROBERTOMEN
em 02/02/2024, 12:40 h
Local: PR Registro: 04/07/2017 Postagens: 544 |
tente
!isincallstack("U_IMPCW1").and.ExistChav('CW1',,1).and.FreeForUse('CW1',M->CW1_CODIGO) |
|
|
Mensagem do
CAIMCEZAR
em 02/02/2024, 14:48 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
tentei novamente com essa nova validação. não consegui também. mudei na x3_valid dele. ainda indica a chave. |
|
|
Mensagem do
ROBERTOMEN
em 02/02/2024, 17:19 h
Local: PR Registro: 04/07/2017 Postagens: 544 |
tente
iif(isincallstack("U_IMPCW1"),.t.,ExistChav(‘CW1‘,,1).and.FreeForUse(‘CW1‘,M->CW1_CODIGO)) |
|
|
Mensagem do
CAIMCEZAR
em 05/02/2024, 13:31 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
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 |
|
|
Mensagem do
ROBERTOMEN
em 05/02/2024, 14:49 h
Local: PR Registro: 04/07/2017 Postagens: 544 |
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 |
|
|
Mensagem do
CAIMCEZAR
em 06/02/2024, 08:27 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
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 |
|
|
Mensagem do
ROBERTOMEN
em 06/02/2024, 09:51 h
Local: PR Registro: 04/07/2017 Postagens: 544 |
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 |
|
|
Mensagem do
CAIMCEZAR
em 06/02/2024, 10:03 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
Então. mas
If ! dbseek(xFilial("CW1")+aDados[nx][1]+aDados[nx][6]) // Aqui !!!
aDados[nx][1] é codigo
aDados[nx]6 é sequencial
|
|
|
Mensagem do
EMERSON.EN
em 06/02/2024, 16:26 h
Local: SP Registro: 20/08/2010 Postagens: 681 |
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
|
|
|
Mensagem do
CAIMCEZAR
em 07/02/2024, 11:03 h
Local: RJ Registro: 05/12/2017 Postagens: 17 |
Show Emerson,
Sua ideia funcionou melhor que a minha. consegui importar a maioria seguindo o sequencial do CSV.
muito obrigado pelo apoio de todos. |
|
Para postar no Fórum você precisa efetuar o seu login ou se registrar
|
|