ExplicaçãoEsse erro acontece quando a função "TcSetField" recebeu um tamanho maior que suporta. - Customização nos fontes
- Customização no dicionário (gatilho/estrutura da tabela/campo)
Tópicos de Análise (com tickets de exemplo) Deck of Cards |
---|
startHidden | false |
---|
effectDuration | 0.5 |
---|
id | Custo Médio |
---|
effectType | horizontal |
---|
loopCards | true |
---|
| Card |
---|
default | true |
---|
id | #19278994 |
---|
label | #19278994 |
---|
| Erro Expandir |
---|
| Para ver o erro completo, abra o ticket: https://totvssuporte.zendesk.com/agent/tickets/19278994 Bloco de código |
---|
firstline | 1 |
---|
title | Trecho |
---|
linenumbers | true |
---|
| THREAD ERROR ([7388], Leandro Henrique, DESKTOP-FRPSSCH) 07/02/2024 17:16:29
: WARNING - TCSetField - Invalid field len: 20 on {|X| IF(X[2] <> "C", TCSETFIELD(CCURSOR3,X[1],X[2],X[3],X[4]),NIL)}(MATA461.PRX) 01/12/2023 15:19:53 line : 1119 |
|
Tópicos de Análise Expandir |
---|
title | 1 - Visualizar validações |
---|
| : WARNING - TCSetField - Invalid field len: 20 on {|X| IF(X[2] <> "C", TCSETFIELD(CCURSOR3,X[1],X[2],X[3],X[4]),NIL)}(MATA461.PRX) 01/12/2023 15:19:53 line : 1119 Ou seja: - Função a ser analisada: TCSetField
- Suposto Erro: Invalid field len: 20
- Trecho: {|X| IF(X[2] <> "C", TCSETFIELD(CCURSOR3, X[1], X[2], X[3], X[4]), NIL)}
|
Expandir |
---|
title | 2 - Estudar a função |
---|
| Função 1 a ser estudada:
A documentação do TCSetField está aqui: TCSetField
Sintaxe: TCSetField( < cAlias >, < cField >, < cType >, [ nSize ], [ nPrecision ] ) - nSize especifica a quantidade total de dígitos de um campo "N", e seu valor deve estar entre 1 e 18. Caso o valor não esteja nesse intervalo, será apresentada a mensagem de erro fatal: "WARNING - TCSetField - Invalid field len: nSize".
Linha no fonte: - aEval(SC9->(dbStruct()), {|x| If(x[2] <> "C", TcSetField(cCursor3,x[1],x[2],x[3],x[4]),Nil)})
A linha está validando, se a posição x[2] não for Caractere, pode-se utilizar a função TCSetField() pois ela não espera Caractere no elemento "nSize". - O x[3] é o elemento nSize na função TCSetField na linha do fonte.
Função 2 a ser estudada:
Tudo está dentro da função aEval: AEVal
Sintaxe: AEval( < aArray >, < bBlock >, [ nStart ], [ nCount ] ) - aArray = Indica o array que será lido.
- bBlock = Indica o bloco de código que será executado para cada elemento encontrado.
aArray = SC9->(dbStruct()) bBlock = {|x| If(x[2] <> "C", TcSetField(cCursor3,x[1],x[2],x[3],x[4]),Nil)}
Função 3 a ser estudada:
É utilizado a função dbStruct(): DBStruct como primeira posição da função aEval.
Retorno: - aRet - Retorna um array com a estrutura dos campos. Cada elemento é um subarray contendo nome, tipo, tamanho e decimais.
- Essa função é utilizada para recuperar a estrutura da tabela corrente. Esse mesmo array é usado para criar a tabela, por exemplo através da função DBCreate.
É retornado um array bidimensional onde cada linha corresponde a um campo da estrutura e cada coluna a seguinte informação: Posição | Tipo | Tamanho | Descrição |
---|
1 | C | 10 bytes | Contém o nome do campo da tabela. | 2 | C | 1 byte | Contém o tipo do campo da tabela. Pode ser: "C" (Caractere), "N" (Numérico), "L" (Lógico), "D" (Data) ou "M" (Memo). | 3 | N | - | Contém o tamanho do campo. | 4 | N | - | Contém a quantidade de casas decimais que o campo pode armazenar, desde que o campo seja do tipo "N". Para os demais tipos, esta informação retorna sempre com 0 (zero). |
A informação retornada na terceira coluna do array, correspondendo ao tamanho do campo, está condicionada ao tipo do campo. Tipo | Descrição |
---|
C | O tamanho retornado corresponde ao tamanho de string máxima que pode ser armazenado na coluna. | D | É retornado sempre 8 bytes. | L | É retornado sempre 1 byte. | M | É retornado sempre 10 bytes. Observação: É importante lembrar que, este valor é retornado por compatibilidade e não corresponde a capacidade real de armazenamento da coluna. O tamanho máximo de armazenamento de uma coluna do tipo "M" está condicionada ao driver RDD utilizado. | N | Juntamente com o valor retornado na quarta posição, quantidade de decimais, informa a capacidade de armazenamento de valores numéricos no campo. |
Conclusão:- 0 O erro está que o campo recebeu um valor que não está no intervalo de 1 e 18.
- 1 Está tudo sendo lido e executado dentro da função eVal que executa comandos para um bloco de código.
- 2 A primeira posição está o Array lido com a função DbStruct(), posição 3: Contém o tamanho do campo.
- 3 A segunda posição está sendo executado dentro do bloco de código a partir do conteúdo do Array lido, a função TCSetField().
- 4 A função TCSetField() não está aceitando o parâmetro passado, pego pela posição 3 na função DbStruct()
É necessário saber qual campo nessa posição e de qual tabela eventualmente pode estar sendo atribuido. |
Expandir |
---|
title | 3 - Procurar o valor e tabela possível com o erro |
---|
| Voltando um pouco mais acima no fonte. Na linha acima há o trecho: - dbUseArea(.T.,"TOPCONN",TcGenQry(,,cQrySC9),cCursor3,.F.,.T.)
Documentação da função dbUseArea: DBUseArea
Sintaxe: DBUseArea( [ lNewArea ], [ cDriver ], < cFile >, < cAlias >, [ lShared ], [ lReadOnly ] )
A posição 3 da função pega a tabela a ser aberta. A posição 4 da função pega o nome dado ao ALIAS da tabela para ser interpretado pelo AdvPL.
Conclusão:- Algum campo da tabela SC9 possui o X3_PICTURE ou o X3_TAMANHO maior que 18 ou menor que 1. (Sendo esse campo com erro do Tipo (X3_TIPO) "N" ou "D").
|
Resultado pós análise/interação-
|
|
|