Indexar String + Valor como ?

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

Indexar String + Valor como ?

Mensagem por asimoes »

Pessoal,

Preciso criar um indice ou um vetor indexado com uma string + number

O vetor ou indice tem que estar ordenado pelo campo fonte( menor valor para o maior) + valor ( maior para o menor valor)

Por exemplo:

Código: Selecionar todos

100   900000.00
100    30000.00
100    20000.00
100    15000.00
100     5000.00
101  1010000.00 
101  1000000.00
101    15000.00
101    10000.00
101     5000.00

Código: Selecionar todos


       If ! (   cTabelaBloqGrupo )->( DbSeek("43730787000150") )
          aValor := {30000.00, 20000.00, 15000.00, 900000.00, 5000.00}
          For I:=1 TO 5
             (   cTabelaBloqGrupo )->( DbAppend() )
             (   cTabelaBloqGrupo )->CNPJ_CPF := "43730787000150"
             (   cTabelaBloqGrupo )->PROCESSO := StrZero(i,11) + "AA"
             (   cTabelaBloqGrupo )->PROCBLOQ := "00000000000000000001"
             (   cTabelaBloqGrupo )->OP       := StrZero(i,10)
             (   cTabelaBloqGrupo )->VALOR    := aValor[i]
             (   cTabelaBloqGrupo )->FONTE    := "100"
             (   cTabelaBloqGrupo )->( DbCommit(), DbUnlock() )
             nPos := Hb_aScan( aVetorBloqueioGrupo, {|a| a[1] = (   cTabelaBloqGrupo )->PROCESSO } )
             If nPos = 0
                aAdd( aVetorBloqueioGrupo, { (  cTabelaBloqGrupo  )->PROCESSO, ;
                                             (  cTabelaBloqGrupo  )->OP, ;
                                             (  cTabelaBloqGrupo  )->VALOR, ;
                                             (  cTabelaBloqGrupo  )->FONTE, ;
                                             " ", ;
                                             (  cTabelaBloqGrupo  )->CNPJ_CPF ;
                                           } )
             
             Endif
          Next
          aValor := {1000000.00,  15000.00, 10000.00, 5000.00, 1010000.00 }
          For I:=1 TO 5
             (  cTabelaBloqGrupo  )->( DbAppend() )
             (  cTabelaBloqGrupo  )->CNPJ_CPF := "43730787000150"
             (  cTabelaBloqGrupo  )->PROCESSO := StrZero(i,11) + "BB"
             (  cTabelaBloqGrupo  )->OP       := StrZero(i,10)
             (  cTabelaBloqGrupo  )->VALOR    := aValor[i]
             (  cTabelaBloqGrupo  )->FONTE    := "101"
             (  cTabelaBloqGrupo  )->( DbCommit(), DbUnlock() )
             nPos := Hb_aScan( aVetorBloqueioGrupo, {|a| a[1] = ( cTabelaBloqGrupo )->PROCESSO } )
             If nPos = 0
                aAdd( aVetorBloqueioGrupo, { (  cTabelaBloqGrupo  )->PROCESSO, ;
                                             (  cTabelaBloqGrupo  )->OP, ;
                                             (  cTabelaBloqGrupo  )->VALOR, ;
                                             (  cTabelaBloqGrupo  )->FONTE, ;
                                             " ", ;
                                             (  cTabelaBloqGrupo  )->CNPJ_CPF ;
                                           } )
             
             Endif             
          Next
  
       Endif

►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)
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

Indexar String + Valor como ?

Mensagem por rossine »

Olá Alexandre,

Não seria só usar o strzero() não ?

Exemplo:

Em ordem crescente seria:

Código: Selecionar todos

index on campo_string + strzero( campo_numerico, 10, 2 ) to _tmp


Em ordem decrescente seria:

Código: Selecionar todos

index on campo_string + descend(strzero( campo_numerico, 10, 2 )) to _tmp


Espero que seja isto o que você procura.
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Indexar String + Valor como ?

Mensagem por asimoes »

Rossine,

Tentei a sua dica mas não funcionou

INDEX ON Trim( CNPJ_CPF ) + FONTE + Descend( StrZero( VALOR, 10, 2 ) ) TAG IND_002 TEMPORARY ADDITIVE

A ordenação do campo fonte recurso ficou certo começando pelo número 100, mas a ordenação dos valores não, deveria iniciar do maior para o menor no mesma fonte 100 e sequencia
2018-12-11 18_49_57-Window.png
►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
Toledo
Administrador
Administrador
Mensagens: 3133
Registrado em: 22 Jul 2003 18:39
Localização: Araçatuba - SP
Contato:

Indexar String + Valor como ?

Mensagem por Toledo »

O que deve estar atrapalhando é o Trim( CNPJ_CPF ). Faz um teste, retirando o Trim( CNPJ_CPF ) + e deixando apenas:

Código: Selecionar todos

INDEX ON FONTE + Descend( StrZero( VALOR, 10, 2 ) ) TAG IND_002 TEMPORARY ADDITIVE
Abraços,
Toledo - Clipper On Line
toledo@pctoledo.com.br
Harbour 3.2/MiniGui/HwGui
Faça uma doação para o fórum, clique neste link: http://www.pctoledo.com.br/doacao
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Indexar String + Valor como ?

Mensagem por asimoes »

Consegui desta forma, com 2 vetores
2018-12-11 19_18_32-Window.png
2018-12-11 19_18_32-Window.png (9.78 KiB) Exibido 1580 vezes

Código: Selecionar todos

   aVetor := {}
   
   aAdd( aVetor, {"100", StrZero(30000.00,   20, 2)})
   aAdd( aVetor, {"100", StrZero(20000.00,   20, 2)})
   aAdd( aVetor, {"100", StrZero(15000.00,   20, 2)})
   aAdd( aVetor, {"100", StrZero(900000.00,  20, 2)})
   aAdd( aVetor, {"100", StrZero(5000.20,    20, 2)})
   
   aAdd( aVetor, {"101", StrZero(1000000.00, 20, 2)})
   aAdd( aVetor, {"101", StrZero(15000.00,   20, 2)})
   aAdd( aVetor, {"101", StrZero(10000.00,   20, 2)})
   aAdd( aVetor, {"101", StrZero(5000.00,    20, 2)})
   aAdd( aVetor, {"101", StrZero(1010000.00, 20, 2)})
   
   aSort( aVetor ,,, {|x,y| y[1] + y[2] > x[1] + x[2] } )
   
   aVetor2 := {}
   
   For i:= 100 to 999
      For Each oElemento IN aVetor descend
         If oElemento[1] = StrZero(i, 3)
            aAdd( aVetor2, {oElemento[1], oElemento[2]})
         Endif
      Next
   Next
   
   cFonte := "100"
   For Each oElemento IN aVetor2 
      If oElemento[1] != cFonte //.OR. oElemento:__EnumIsFirst
         ?
      Endif
      ? oElemento[1], oElemento[2]
      cFonte :=  oElemento[1]
   Next
►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

Indexar String + Valor como ?

Mensagem por asimoes »

Toledo escreveu:O que deve estar atrapalhando é o Trim( CNPJ_CPF ). Faz um teste, retirando o Trim( CNPJ_CPF ) + e deixando apenas:
Toledo o trim é necessários porque esse campo CNPJ_CPF recebe os 2 tipos e é para o seek, se não não acha quando a busca for por cpf.

Não tem como fazer isso se não for usando 2 vetores como eu postei. por que o asort ou indice não ordena da forma que eu queria primeiro os 100 na ordem do maior valor pera o menor de depois o 101.

100 e 101, 102.... é a fonte de pagamento, o usuário pediu pra ordenar desata forma ele quer ver na ordem de fornte e maiores valores para o menor
►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)
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Indexar String + Valor como ?

Mensagem por alxsts »

Olá!
Toledo escreveu:O que deve estar atrapalhando é o Trim( CNPJ_CPF ). Faz um teste, retirando o Trim( CNPJ_CPF )
É isto mesmo. Os testes que fiz mostram que o Toledo tem razão. É sabido que em chaves de índice não se deve usar expressões que geram campos chave com tamanho variável.
asimoes escreveu:o trim é necessários porque esse campo CNPJ_CPF recebe os 2 tipos e é para o seek, se não não acha quando a busca for por cpf.
Veja no exemplo abaixo que isto não é verdade.
asimoes escreveu:Não tem como fazer isso se não for usando 2 vetores como eu postei
Veja no exemplo abaixo.

Código: Selecionar todos

Function Main()

   FIELD CNPJ_CPF
   FIELD FONT
   FIELD VALOR

   REQUEST DESCEND
   REQUEST DBFCDX
   RDDSetDefault( "DBFCDX" )

   If ! File( "tbTest.dbf" )
      Setup()
   Endif
   
   ClS

   USE tbTest SHARED NEW

   hb_Alert( { "Primeiro Browse, sem indice", "Tecle algo..." } )

   Browse()

   // com esta linha abaixo, a ordenação fica errada
   //INDEX ON Trim( CNPJ_CPF ) + FONTE + Descend( StrZero( VALOR, 10, 2 ) ) TAG IND_002
   //-----------------------------------------------------------------------------------

   // com esta linha abaixo, a ordenação fica correta
   INDEX ON CNPJ_CPF + FONTE + Descend( StrZero( VALOR, 10, 2 ) ) TAG IND_002

   DbSetIndex( "tbTest")

   hb_Alert( { "Segundo Browse, com indice", "Tecle algo..." } )

   Browse()

   // Nenhum problema ao buscar um CPF na coluna CNPJ_CPF.
   // É só completar o CPF com espaços à direita, ajustando para o tamanho da coluna
   If tbTest->( dbSeek( PadR( "23538132089", 14 ) ) )
      hb_Alert( { "CPF encontrado: 23538132089", "Tecle algo..." } )
   Else
      hb_Alert( { "CPF NÃO encontrado: 23538132089", "Tecle algo..." } )   
   Endif

   // Busca por um lançamento qualquer existente. Sucesso...
   // Note que no SEEK é preciso invocar a função Descend
   If tbTest->( dbSeek( PadR( "43730787000150", 14 ) + ;
                              "100" + ;
                              Descend( StrZero( 5000.00, 10, 2 ) ) ) )
      hb_Alert( { "Lancamento encontrado:",  "PadR( '43730787000150', 14 ) " + ;
                  "100 + Descend( StrZero( 5000.00, 10, 2 ) ) )", "Tecle algo..." } )
   Else
      hb_Alert( { "Lancamento NAO encontrado:",  "PadR( '43730787000150', 14 ) " + ;
                  "100 + Descend( StrZero( 5000.00, 10, 2 ) ) )", "Tecle algo..." } )
   Endif
   
   tbTest->( DbCloseArea() )

   RETURN NIL
//------------------------------------------------------------------------------

 STATIC Function Setup()

   LOCAL aArray, e, i, aValor

   aArray := {}

   AAdd( aArray, { "CNPJ_CPF",  "C",  14, 0 } )
   AAdd( aArray, { "PROCESSO",  "C",  13, 0 } )
   AAdd( aArray, { "PROCBLOQ",  "C",  10, 0 } )
   AAdd( aArray, { "OP",        "C",  10, 0 } )   
   AAdd( aArray, { "VALOR",     "N",  10, 2 } )
   AAdd( aArray, { "FONTE",     "C",   3, 0 } )

   DBCREATE("tbTest", aArray, "DBFCDX" )

   USE tbTest EXCLUSIVE NEW

   aValor := {1000000.00,  15000.00, 10000.00, 5000.00, 1010000.00 }

   For I:=1 TO 5
      tbTest->( DbAppend() )
      tbTest->CNPJ_CPF := "79705909000103"
      tbTest->PROCESSO := StrZero(i,11) + "BB"
      tbTest->OP   := StrZero(i,10)
      tbTest->VALOR  := aValor[i]
      tbTest->FONTE  := "101"
      tbTest->( DbCommit(), DbUnlock() )
   Next

   aValor := {30000.00, 20000.00, 15000.00, 900000.00, 5000.00}                

   For I:=1 TO 5
      tbTest->( DbAppend() )
      tbTest->CNPJ_CPF := "43730787000150"
      tbTest->PROCESSO := StrZero(i,11) + "AA"
      tbTest->PROCBLOQ := "00000000000000000001"
      tbTest->OP   := StrZero(i,10)
      tbTest->VALOR  := aValor[i]
      tbTest->FONTE  := "100"
      tbTest->( DbCommit(), DbUnlock() )
   Next

   aValor := {570.20, 201.82, 15021.00, 900000.00, 5000.00}                
   
   For I:=1 TO 5
      tbTest->( DbAppend() )
      tbTest->CNPJ_CPF := "23538132089"
      tbTest->PROCESSO := StrZero(i,11) + "AA"
      tbTest->PROCBLOQ := "00000000000000000001"
      tbTest->OP   := StrZero(i,10)
      tbTest->VALOR  := aValor[i]
      tbTest->FONTE  := "900"
      tbTest->( DbCommit(), DbUnlock() )
   Next

   tbTest->( DbCloseArea() )
   aArray := NIL

   RETURN NIL
//------------------------------------------------------------------------------   
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Indexar String + Valor como ?

Mensagem por asimoes »

alxsts escreveu:É isto mesmo. Os testes que fiz mostram que o Toledo tem razão. É sabido que em chaves de índice não se deve usar expressões que geram campos chave com tamanho variável.
Ok, os testes que você fez, o índice ficou na ordem que eu preciso?
Ex.
100 100.00
100. 90.00
100 80.00
101 100.00
101 90.00
101 80.00
►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

Indexar String + Valor como ?

Mensagem por asimoes »

Pessoal,

Obrigado pela dica, era isso mesmo o trim( cnpj_cpf ), removi e fez conforme preciso.
►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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Indexar String + Valor como ?

Mensagem por JoséQuintas »

Pad() pra deixar o CNPJ de mesmo tamanho, e -valor pra deixar em ordem decrescente (ou 999999999999999-valor)
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/
Responder