Página 1 de 1
Ajuda em indexação de dados
Enviado: 18 Ago 2014 10:29
por simoreira
Pessoal, bom dia.
Estou migrando o meu sistema para Harbour e seguindo muitas orientações do fórum. Compilei e rodei sem problemas, mas está acontecendo algo que não estou conseguindo resolver, pelo menos da maneira que penso estar certa.
Eu utilizava em meu sistema Clipper a indexação condicional para gerar na tela somente os dados que eu precisava, pois achava melhor assim do que gerar um filtro. Isso funcionava 100% no Clipper, mas no Harbour não tem funcionado, traz para a tela registros que não satisfazem a condição que eu coloquei na variável. Essa indexação á crucial para o sistema, pois mostro os dados para a edição com base nela, pego somente o que o o usuário pediu dentro de opções que ele informa antes.
Ainda uso o NTX, mas pretendo mudá-lo e desde já peço alguma dica sobre qual o melhor (CDX, talvez?). Segue abaixo o código que modifiquei para que alguém possa me ajudar a solucionar isso:
Código: Selecionar todos
/*******
* PROCEDURE pSafraNasc()
* obj: cria e apresenta os ventres prenhes para o nascimento
* psafranasc() psafranasc.prg
*******/
PROCEDURE pSafraNasc(pAval)
LOCAL lTodas, cCodigoFaz:=usuario->COD_FAZ, cCondInd:=vep->(ordfor(12)),;
cCondNasc, cCondFiltro:=""
if pAval==NIL; pAval:=False; endif
cCondRep:=left(upper(cCondInd), at(upper("ww=' '"),cCondInd)-1)
if !empty(cFazSaf).and.cFazSaf#"****"
if pAval
vep->(dbcreateindex(cCodigoFaz+"vp12",if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F"), {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.!empty(IAN+IAA+IAF)}))
else
vep->(dbcreateindex(cCodigoFaz+"vp12",if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F"), {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.left(COMREP,1)#'E'}))
endif
else
if pAval
vep->(dbcreateindex(cCodigoFaz+"vp12",if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F"), {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.!empty(IAN+IAA+IAF)}))
else
vep->(dbcreateindex(cCodigoFaz+"vp12",if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F"), {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.left(COMREP,1)#'E'}))
endif
endif
pIndRep(TRUE,cCondInd,TRUE)
vep->(dbsetorder(12) , dbgotop())
RETURN
Se tiverem outra sugestão sobre como gerar esse índice agradeço.
Também estou tendo dificuldade em encontrar documentação sobre as funções do Harbour. Tenho o arquivo "xHarbour Language Reference Guide.chm", que baixei quando tentei migrar com o xHarbour, mas não encontrei algo parecido para o Harbour. Existe alguma sugestão de documentação para eu ir buscando comando e funções Harbour para ir melhorando o meu sistema?
Abraços.
Sergio Moreira
Ajuda em indexação de dados
Enviado: 18 Ago 2014 10:51
por Jairo Maia
Olá simoreira,
Está parecendo que você não está carregando o índice após cria-lo, e os dados que está sendo apresentado são os dados do indice 12. Tem como você postar a função pIndRep()?
Ajuda em indexação de dados
Enviado: 18 Ago 2014 11:41
por simoreira
Bom dia, Jairo.
Segue a função pIndRep(). Ela somente fecha todos os arquivos da base "vep" para reabrí-los depois de gerado o índice.
Código: Selecionar todos
/******
* PROCEDURE pIndRep( lTodas, cCondIndice, lRep )
* Abre o arquivo VEP a partir da reprodu‡Æo
* pindrep.prg pindrep()
******/
PROCEDURE pIndRep( lTodas, cCondIndice, lRep, lDes )
local cCodEmp:=alltrim(usuario->COD_FAZ)
if lRep==NIL; lRep:=FALSE; endif
if lDes==NIL; lDes:=FALSE; endif
SETCURSOR(SC_NONE)
vep->(dbclearindex())
if !lTodas.and.lRep
vep->(dbcriaindice(cCodEmp+"VP14",if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F"),cCondIndice))
elseif !lTodas.and.lDes
vep->(dbcriaindice(cCodEmp+"VP14",if(cOrdIndex=="A","IAA+IAN+IAF","IAN+IAA+IAF"),cCondIndice))
endif
vep->(dbclearindex())
vep->( dbsetindex(cCodEmp+"VP1") )
vep->( dbsetindex(cCodEmp+"VP2") )
vep->( dbsetindex(cCodEmp+"VP3") )
vep->( dbsetindex(cCodEmp+"VP4") )
vep->( dbsetindex(cCodEmp+"VP5") )
vep->( dbsetindex(cCodEmp+"VP6") )
vep->( dbsetindex(cCodEmp+"VP7") )
vep->( dbsetindex(cCodEmp+"VP8") )
vep->( dbsetindex(cCodEmp+"VP9") )
vep->( dbsetindex(cCodEmp+"VP10") )
vep->( dbsetindex(cCodEmp+"VP11") )
if !lTodas
vep->(dbsetindex(cCodEmp+"VP14"))
else
vep->(dbsetindex(cCodEmp+"VP12"))
// vep->(dbreindex())
vep->(dbgotop(), dbskip(), dbgotop())
endif
vep->(dbsetindex(cCodEmp+"VP13"))
if lTodas
vep->(dbsetindex(cCodEmp+"VP14"))
endif
vep->(dbgotop())
RETURN
Obrigado e abraço!
Ajuda em indexação de dados
Enviado: 18 Ago 2014 14:22
por JoséQuintas
O normal seria:
INDEX ON chave TO arquivo FOR condicao
Aí tá chamando uma função sua, e não dá pra saber o que ela faz.
Ajuda em indexação de dados
Enviado: 18 Ago 2014 14:23
por Jairo Maia
Olá simoreira,
Particularmente em termos programáticos não vejo nada errado. Salvo se no Harbour o 3o. parâmetro na
dbcreateindex() não está funcionando (não estou afirmando). Tente alterar sua função
pSafraNasc() como abaixo e veja se funciona:
Código: Selecionar todos
PROCEDURE pSafraNasc(pAval)
LOCAL lTodas, cCodigoFaz:=usuario->COD_FAZ, cCondInd:=vep->(ordfor(12)),;
cCondNasc, cCondFiltro:="", cQualAlias
if pAval==NIL; pAval:=False; endif
cCondRep:=left(upper(cCondInd), at(upper("ww=' '"),cCondInd)-1)
cQualAlias := Alias()
Select( "vep" )
if !empty(cFazSaf).and.cFazSaf#"****"
cCampos := if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F")
if pAval
SET INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.!empty(IAN+IAA+IAF)}
else
SET INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.left(COMREP,1)#'E'}))
endif
else
cCampos := if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F")
if pAval
SET INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.!empty(IAN+IAA+IAF)}
else
SET INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR {|| ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.left(COMREP,1)#'E'}
endif
endif
pIndRep(TRUE,cCondInd,TRUE)
Select( cQualAlias )
vep->(dbsetorder(12) , dbgotop())
RETURN
Ajuda em indexação de dados
Enviado: 18 Ago 2014 14:31
por JoséQuintas
dbCreateIndex(), precisa ver a sintaxe correta para o Harbour, conforme a RDD
dbCriaIndice(), precisa ver o que a função faz
SET INDEX ON chave TO arquivo
Nunca vi essa sintaxe
FOR { || codigo }
Por acaso não deveria ser FOR Eval( { || codigo } )
ou
FOR codigo
Ajuda em indexação de dados
Enviado: 18 Ago 2014 14:34
por Jairo Maia
JoséQuintas escreveu:SET INDEX ON chave TO arquivo
Nunca vi essa sintaxe
Rs... Com certeza. Errei ao digitar. Tem que remover o
SET. O correto é mesmo
INDEX ON chave TO arquivo FOR condicao
Editado:
JoséQuintas escreveu:FOR { || codigo }
Por acaso não deveria ser FOR Eval( { || codigo } )
ou
FOR codigo
Está certo José. Como tem muitos erros na postagem da minha sugestão, estou repostando abaixo:
Código: Selecionar todos
PROCEDURE pSafraNasc(pAval)
LOCAL lTodas, cCodigoFaz:=usuario->COD_FAZ, cCondInd:=vep->(ordfor(12)),;
cCondNasc, cCondFiltro:="", cQualAlias
if pAval==NIL; pAval:=False; endif
cCondRep:=left(upper(cCondInd), at(upper("ww=' '"),cCondInd)-1)
cQualAlias := Alias()
Select( "vep" )
if !empty(cFazSaf).and.cFazSaf#"****"
cCampos := if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F")
if pAval
INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.!empty(IAN+IAA+IAF)
else
INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.AF==CFAZSAF.AND.DG=='P'.and.left(COMREP,1)#'E'
endif
else
cCampos := if(cOrdIndex=="A","I_MAE_A+I_MAE_N+I_MAE_F","I_MAE_N+I_MAE_A+I_MAE_F")
if pAval
INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.!empty(IAN+IAA+IAF)
else
INDEX ON ( &cCampos. ) TO cCodigoFaz+"vp12" FOR ((WW=' '.AND.SAFRA==CSAFRA).OR.(WW='*'.AND.SAFRAN==CSAFRA)).AND.DG=='P'.and.left(COMREP,1)#'E'
endif
endif
pIndRep(TRUE,cCondInd,TRUE)
Select( cQualAlias )
vep->(dbsetorder(12) , dbgotop())
RETURN
Ajuda em indexação de dados
Enviado: 18 Ago 2014 15:17
por simoreira
Prezados, vamos por partes.
José Quintas escreveu:
dbCreateIndex(), precisa ver a sintaxe correta para o Harbour, conforme a RDD
dbCriaIndice(), precisa ver o que a função faz
José, onde busco a informação sobre a sintaxe correta da dbCreateIndex() no Harbour?
A função dbCriaIndice() faz a mesma coisa que o INDE ON ... TO ... FOR ..., apenas a criei para não precisar selecionar a área diretamente toda a vez que for indexar. Veja:
Código: Selecionar todos
/*****
*
* FUNCTION dBCriaIndice(cArquivo, cChave, cCondicao)
* Cria uma arquivo de indice na area especificada
* dbcriaindice() dbcriaindice.prg
*
*****/
FUNCTION dBCriaIndice()
parameters cArquivo,; // Nome do arquivo de indice
cChave,; // Chave de indice
cCondFor // Condicao para FOR
if cCondFor#NIL
index on &cChave. to &cArquivo. for &cCondFor
else
index on &cChave. to &cArquivo.
endi
return NIL
Jairo, vou testar a forma que descreveste, mas já fiz isso através da função dbCriaIndice() e não havia dado certo. De repente, fazendo direto na procedure resolva.
Desde já agradeço pela ajuda.
Abraços.
Ajuda em indexação de dados
Enviado: 21 Ago 2014 16:18
por simoreira
Pessoal, boa tarde.
Infelizmente o problema não foi resolvido. Sigo tentando encontrar a saída e aceito sugestões.
Abraço
Ajuda em indexação de dados
Enviado: 21 Ago 2014 18:40
por Itamar M. Lins Jr.
Esses comandos são compatíveis com o clipper
Use o tradicional. Dai vc vai complicando p/ ver se funciona.
A sintaxe é a mesma do clipper.
Salvo comandos que comecem com a sintaxe "HB_" ai alguns já possuem algo mais.
NTX
index on cliente to ... for etc...
CDX
index on cliente tag ... for etc...
Isso é o feijão com arroz... existem n exemplos ai na internet, use o google.
Saudações,
Itamar M. Lins Jr.
Ajuda em indexação de dados
Enviado: 21 Ago 2014 18:53
por Itamar M. Lins Jr.
..Também estou tendo dificuldade em encontrar documentação sobre as funções do Harbour.
As funções e comandos do Harbour são os mesmos do clipper.
Agora a parte de desenho de telas existe uma miríade de opções.
A parte de DBF é a mesma coisa do clipper com alguns comandos a mais (registro do windows), já com SQL existe algumas opções que não existia na época do clipper.
Primeira parte, acredito que é resolver esse seu problema com indices.
Use os comandos que o clipper tem para saber se a ordem está ou não sendo respeitada. ORDNAME(), ORDNUMBER()...
This example retrieves the FOR condition from an order:
USE Customer NEW
INDEX ON Customer->Acct ;
TO Customer ;
FOR Customer->Acct > "AZZZZZ"
ORDFOR("Customer") // Returns: Customer->Acct > "AZZZZZ"
Saudações,
Itamar M. Lins Jr.
Ajuda em indexação de dados
Enviado: 22 Ago 2014 10:50
por Kapiaba
Código: Selecionar todos
USE Empresa NEW
DBCREATEINDEX( "Nome", "Nome", { || Nome })
Código: Selecionar todos
USE TESTS VIA "DBFNTX" NEW
ORDCREATE( "FNAME",, "Tests->fName" )
USE TESTS VIA "DBFCDX" NEW
ORDCREATE( , "lName", "tests->lName" )
Código: Selecionar todos
//
// $Id: testcdx.prg,v 1.2 2005/09/22 10:51:58 jonnymind Exp $
//
request DBFCDX
function Main()
local fh, size, data
local aStruct := { { "CHARACTER", "C", 25, 0 }, ;
{ "NUMERIC", "N", 8, 0 }, ;
{ "DOUBLE", "N", 8, 2 }, ;
{ "DATE", "D", 8, 0 }, ;
{ "MEMO", "M", 10, 0 }, ;
{ "LOGICAL", "L", 1, 0 } }
CLS
dbUseArea( .T., "DBFCDX", "test", "TESTDBF", .T., .F. )
dbCreate( "testcdx", aStruct, "DBFCDX", .T., "TESTCDX" )
? "RddName:", RddName()
// ? "Press any key to continue..."
// InKey( 0 )
Select( "TESTDBF" )
SET FILTER TO TESTDBF->SALARY > 140000
TESTDBF->( dbGoTop() )
fh := fopen( "test.jpg" )
FILESTATS( "test.jpg", 0, @size )
? size
inkey(0)
data := ""
fh := fopen( "test.jpg" )
fread( fh, @data, size )
? ferror()
fclose(fh)
while !TESTDBF->( Eof() )
TESTCDX->( dbAppend() )
TESTCDX->CHARACTER = TESTDBF->FIRST
TESTCDX->NUMERIC = TESTDBF->SALARY
TESTCDX->MEMO = data
? len( data )
Inkey(0)
TESTDBF->( dbSkip() )
end
? TESTCDX->( RecCount() )
TESTCDX->( dbGoTop() )
? TESTCDX->( Eof() )
while !TESTCDX->( Eof() )
? TESTCDX->( RecNo() ), TESTCDX->NUMERIC
fh = fcreate( "test1.jpg" )
fwrite( fh, TESTCDX->MEMO )
fclose( fh )
TESTCDX->( dbSkip() )
// ? "Press any key to continue..."
// InKey( 0 )
end
FErase( "testcdx.cdx" )
Select( "TESTCDX" )
OrdCreate( "testcdx", "Character", "CHARACTER", FIELD->CHARACTER, .F. )
return nil
abs,
Ajuda em indexação de dados
Enviado: 22 Ago 2014 17:33
por simoreira
Obrigado Itamar a Kapiaba pelas dicas. Vou fazer os testes e depois posto o resultado!
Abraços.
Sérgio Moreira