Página 1 de 1

Indexar String + Valor como ?

Enviado: 11 Dez 2018 16:47
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


Indexar String + Valor como ?

Enviado: 11 Dez 2018 17:28
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.

Indexar String + Valor como ?

Enviado: 11 Dez 2018 18:53
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

Indexar String + Valor como ?

Enviado: 11 Dez 2018 19:13
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,

Indexar String + Valor como ?

Enviado: 11 Dez 2018 19:20
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 1578 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

Indexar String + Valor como ?

Enviado: 11 Dez 2018 22:23
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

Indexar String + Valor como ?

Enviado: 12 Dez 2018 01:44
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
//------------------------------------------------------------------------------   

Indexar String + Valor como ?

Enviado: 12 Dez 2018 05:04
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

Indexar String + Valor como ?

Enviado: 12 Dez 2018 05:30
por asimoes
Pessoal,

Obrigado pela dica, era isso mesmo o trim( cnpj_cpf ), removi e fez conforme preciso.

Indexar String + Valor como ?

Enviado: 12 Dez 2018 10:39
por JoséQuintas
Pad() pra deixar o CNPJ de mesmo tamanho, e -valor pra deixar em ordem decrescente (ou 999999999999999-valor)