SET INDEX está com erro?

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Senhores,

Me deparei com um problema hoje durante uma conversão de clipper para harbour vejam o código:

O problema acontece no "set index to temp" com harbour dá o seguinte erro:

Eu sintetizei o código para demonstrar o que acontece.

Error BASE/1003 Variável não existe: NANO
Called from ->ORDLISTADD(0)
Called from testedbf.prg->VERANO(26)
Called from testedbf.prg->MAIN(18)


Este erro não acontece em clipper.

Código: Selecionar todos

FUNCTION MAIN()
LOCAL nAno:=2012

   @10,00 SAY "Informe o ano: " GET nAno  PICTURE "9999"
   READ

   VerAno(nAno)
   
RETURN Nil

FUNCTION VerAno(nAno)
   USE TESTEDBF NEW EXCLUSIVE
   INDEX ON IF(Status = " " .AND. Year(Data)=nAno,"A","B") TO TEMP
   SET INDEX TO TEMP
RETURN Nil
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Continuando...

Se definir uma variável como private na função VerAno()
Não acontece o erro vejam:

Se declarar a variável como LOCAL acontece o erro:

Arquivo Log Erro...: Error BASE/1003 Variável não existe: NANOVER
Called from ->ORDLISTADD(0)
Called from testedbf.prg->VERANO(28)
Called from testedbf.prg->MAIN(18)

Código: Selecionar todos

FUNCTION VerAno(nAno)
PRIVATE nAnoVer:=nAno
   USE TESTEDBF NEW EXCLUSIVE
   INDEX ON IF(Status = " " .AND. Year(Data)=nAnoVer,"A","B") TO TEMP
   SET INDEX TO TEMP
RETURN Nil
Alguém já se deparou com isso?
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Continuando...

Declarando assim também não acontece o erro.

MEMVAR nAnoVer
nAnoVer:=nAno

REUMO:

LOCAL nAnoVer:=nAno - Acontece o Erro

PRIVATE nAnoVer:=nAno - Ok

MEMVAR nAnoVer - Ok
nAnoVer:=nAno
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
ricardo-barros
Usuário Nível 3
Usuário Nível 3
Mensagens: 104
Registrado em: 29 Out 2009 20:12
Localização: Fortaleza

SET INDEX está com erro?

Mensagem por ricardo-barros »

O erro acontece porque a expressão Year(Data)=nAno é passada para OrdListAdd() que atua na indexação.

Como nAno foi declarada com variável Local no Main ela só é visível lá. Qualquer que seja a variável que você vai usar na expressão Year(Data)=<var> elá terá que ser do tipo private para se tornar visível em OrdListAdd().

Sugiro que você declare nAno como private no Main. Assim a visibilidade se extenderá para todos os módulos seguintes. Eu testei e vi que funciona.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Olá Ricardo,

Então isso tava errado no clipper?
No clipper o nAno era o parametro da função e não dava erro. (clipper 5.2e)

Oops descobri algo curioso, ao invés de usar SET INDEX TO TEMP substitui por OrdListAdd( "TEMP" )

Assim não aconteceu o erro.

Vejam como ficou:

Código: Selecionar todos

FUNCTION VerAno(nAno)
//MEMVAR nAnoVer
//nAnoVer:=nAno
   //USE TESTEDBF NEW SHARED
   DbUseArea(.T.,"DBFNTX","TESTEDBF",,.T.) 
   INDEX ON IF(Status = " " .AND. Year(Data)=nAno,"A","B") TO TEMP
   //SET INDEX TO TEMP
   OrdListAdd( "TEMP" )
   Alert(TESTEDBF->(IndexKey()))
RETURN Nil
Ricardo, me parece que sua teoria não é 100% veja outro exemplo:
Declarei a variavel nAnoVer como local passei ela para o index, abri o indice com OrdListAdd() e não aconteceu o erro.
O problema me parece estar mesmo com o SET INDEX TO TEMP

Código: Selecionar todos

FUNCTION VerAno(nAno)
//MEMVAR nAnoVer
LOCAL nAnoVer:=nAno
   DbUseArea(.T.,"DBFNTX","TESTEDBF",,.T.) 
   INDEX ON IF(Status = " " .AND. Year(Data)=nAnoVer,"A","B") TO TEMP
   //SET INDEX TO TEMP
   OrdListAdd( "TEMP" )
   Alert(TESTEDBF->(IndexKey()))
RETURN Nil
Completando:

Com DbSetIndex() também não acontece o erro.
DBSETINDEX("TEMP.NTX")
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Continuando,

Resolvi o meu problema usando macro:

Código: Selecionar todos

FUNCTION VerAno(nAno)

   PRIVATE nAnoVer:=nAno, cAno
  
   DbUseArea(.T.,"DBFNTX","TESTEDBF",,.F.) 
  
   cAno:=StrZero(nAno,4)
   
   INDEX ON IF(Status = " " .AND. Year(Data)=&cAno.,"A","B") TO TEMP
   
   SET INDEX TO TEMP.NTX //ADDITIVE
   //DBSETINDEX("TEMP.NTX")
   //OrdListAdd( "TEMP" )
   Alert(TESTEDBF->(IndexKey()))

RETURN Nil
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SET INDEX está com erro?

Mensagem por rochinha »

Amiguinho,

No Clipper provavelmente ao compilar voce indicava /M para automatizar a declaração de variáveis.

Já no Harbour se isto não aconteceu voce obteve os problemas citados.

Se voce tem variáveis com mesmos nomes de campos de suas tabelas, em Harbour, torne-as em memória, se não voce pode balear uma tabela.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

SET INDEX está com erro?

Mensagem por alxsts »

Olá!

Muito estranhas as situações mostradas neste tópico... Seria alguma falha do compilador?

E a solução encontrada... Sempre evitei usar variáveis publicas, privadas e macros.

Rochinha: a chave /M (compile module only) do compilador Clipper indica a compilação apenas do prg indicado, sem compilar os módulos chamados pelo que está sendo compilado. Essa que você mencionou é a /A que assume como memvar (m->) todas as variáveis public e private não declaradas.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SET INDEX está com erro?

Mensagem por rochinha »

Amiguinho,

Desculpe o lapso do velhinho aqui e obrigado pela correção.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

SET INDEX está com erro?

Mensagem por asimoes »

Rochinha,

A variável em questão é um parâmetro da função VerAno() e no caso não é campo de tabela.

FUNCTION VerAno(nAno)
DbUseArea(.T.,"DBFNTX","TESTEDBF",,.F.)
cAno:=StrZero(nAno,4) <-- parâmetro de função
INDEX ON IF(Status = " " .AND. Year(Data)=&cAno.,"A","B") TO TEMP

A chamada original era assim:

INDEX ON IF(Status = " " .AND. Year(Data)=nAno.,"A","B") TO TEMP

No clipper não acontece o erro no set index.
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

SET INDEX está com erro?

Mensagem por rochinha »

Amiguinho,

Ao compilar a sua chamada ao harbour esta acrescida do parametro /v?

Funciona como o /A que assume variáveis como de memória.

Agora é lógico que o harbour pode dar prioridade para nomes se os mesmo forem campos de tabelas e ai ocorre algum erro.

Adote como regra se referenciar a campos em tabelas e variaveis da seguinte forma:

tabela->campo

Exemplo:

clientes->nome
clientes->endereco

e variáveis colocando um diferenciador para que visualmente voce descubra o seu tipo só de olhar para a mesma:

cVariavel - para variavel com conteúdo caracter
nVariavel - para variavel com conteúdo numérico
dVariavel - para variavel com conteúdo data
lVariavel - para variavel com conteúdo lógico
mVariavel - para variavel com conteúdo memo

Com certeza acho que voce já se utiliza destes métodos, mas saiba que migrar do Clipper para Harbour não é só pegar o código e compilar.

O ganho que voce terá migrando com Harbour é de tamanho enorme. E problemas na mesma proporção.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Responder