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