Página 1 de 1
SET INDEX está com erro?
Enviado: 14 Fev 2012 20:32
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
SET INDEX está com erro?
Enviado: 14 Fev 2012 20:40
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?
SET INDEX está com erro?
Enviado: 14 Fev 2012 21:33
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
SET INDEX está com erro?
Enviado: 15 Fev 2012 20:31
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.
SET INDEX está com erro?
Enviado: 15 Fev 2012 20:36
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")
SET INDEX está com erro?
Enviado: 15 Fev 2012 22:28
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
SET INDEX está com erro?
Enviado: 16 Fev 2012 14:29
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.
SET INDEX está com erro?
Enviado: 16 Fev 2012 14:54
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.
SET INDEX está com erro?
Enviado: 16 Fev 2012 15:02
por rochinha
Amiguinho,
Desculpe o lapso do velhinho aqui e obrigado pela correção.
SET INDEX está com erro?
Enviado: 16 Fev 2012 17:40
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.
SET INDEX está com erro?
Enviado: 16 Fev 2012 18:41
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.