Ajuda em indexação de dados

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

Moderador: Moderadores

simoreira
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 20 Ago 2004 16:21

Ajuda em indexação de dados

Mensagem 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
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Ajuda em indexação de dados

Mensagem 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()?
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
simoreira
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 20 Ago 2004 16:21

Ajuda em indexação de dados

Mensagem 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!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ajuda em indexação de dados

Mensagem 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.
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Ajuda em indexação de dados

Mensagem 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
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ajuda em indexação de dados

Mensagem 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
José M. C. Quintas
Harbour 3.2, mingw, gtwvg mt, fivewin 25.04, multithread, dbfcdx, MySQL, ADOClass, PDFClass, SefazClass, (hwgui mt), (hmg3), (hmg extended), (oohg), PNotepad, ASP, stored procedure, stored function, Linux (Flagship/harbour 3.2)
"The world is full of kings and queens, who blind our eyes and steal our dreams Its Heaven and Hell"

https://github.com/JoseQuintas/
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Ajuda em indexação de dados

Mensagem 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
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
simoreira
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 20 Ago 2004 16:21

Ajuda em indexação de dados

Mensagem 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.
simoreira
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 20 Ago 2004 16:21

Ajuda em indexação de dados

Mensagem por simoreira »

Pessoal, boa tarde.

Infelizmente o problema não foi resolvido. Sigo tentando encontrar a saída e aceito sugestões.

Abraço
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Ajuda em indexação de dados

Mensagem 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.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Ajuda em indexação de dados

Mensagem 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.
Saudações,
Itamar M. Lins Jr.
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Ajuda em indexação de dados

Mensagem 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,
simoreira
Usuário Nível 1
Usuário Nível 1
Mensagens: 40
Registrado em: 20 Ago 2004 16:21

Ajuda em indexação de dados

Mensagem por simoreira »

Obrigado Itamar a Kapiaba pelas dicas. Vou fazer os testes e depois posto o resultado!

Abraços.

Sérgio Moreira
Responder