Ordem decrescente

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

Moderador: Moderadores

Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

É sério, até confirmei no Clipper 5.2 pra ver se era verdade.
Isto é novidade pra mim:

É mais eficiente do que usar a função Descend()

Código: Selecionar todos

INDEX ON Codigo TO temp DESCENDING
E isto:

Código: Selecionar todos

INDEX ON Descend( DateField ) TO temp
INDEX ON Codigo + Str( Descend( DateField ), 7 ) TO temp
Antes eu usava Descend( Dtos( DateField )) ), o que gera problemas ao usar codepage, e até criei CPDescend()
Descend() direto na data retorna um numérico, pra uso em ordem decrescente.
Clipper 5.2 NG:

Returns DESCEND() returns an inverted expression of the same data type as the <exp>, except for dates which return a numeric value. A DESCEND() of CHR(0) always returns CHR(0).

Notes . The preferred way to create a descending index is to use the DESCENDing clause of the INDEX command. Using DESCENDING is the same as specifying the DESCEND() function, but without the performance penalty during index updates. If you create a DESCENDING index, you won't need to use the DESCEND() function during a SEEK. DESCENDING is an attribute of the (.ntx) file, where it is stored and used for REINDEXing purposes.
Fica aí a dica, que pra mim é novidade, mesmo existindo há mais de 20 anos, no Clipper 5.2.
Não sei se pra mais alguém vai ser novidade.

Nota: Lógico, também vale no Harbour.
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
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Ordem decrescente

Mensagem por Itamar M. Lins Jr. »

Mesmo assim, ainda fica sem explicação para mim porque transformar via chr() ou seja usar internamente na função descend() a função chr() para números.
Então a função descend() com dtos() vai pegar o code page do pais... e fazer uma bagunça nessa situação.
Usando set date to "dd/mm/yyyy" com:

dtos( "04/05/2016") , dtos("09/03/2016"), se só tem números!!! para que transformar via chr() ? e ainda por cima usar code page nesta situação e desfazer o que o dtos() fez ? Agora depois da explicação do Elch eu entendi o problema, mas não sei porque usar isso para números(dígitos). Apesar das explicações do Przemek ainda vejo como um bug na indexação... a data não é salva de uma única forma, de uma forma padrão ? em hexadecimal, ou sei lá o quê...?

Dai a falha, nesta situação.

Código: Selecionar todos

REQUEST HB_LANG_PT, HB_CODEPAGE_PTISO
Function Main

SET( _SET_DATEFORMAT, "dd-mm-yyyy" )

dbcreate("test.dbf",{{"date","d",08,0}},,.T.)
append blank
field->date := ctod("09/03/2016")
append blank
field->date := ctod("04/05/2016")

index on descend(dtos(date)) to temp
? date, year(date), month(date), day(date) //Correct show 05/04/2016

use

HB_CDPSELECT([PTISO])
hb_langselect([PT])

use test
index on descend(dtos(date)) to temp
? date, year(date), month(date), day(date) //not correct show 03/09/2016

return nil
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

Código: Selecionar todos

Str( Descend( Date() ) , 7 )
Descend( Dtos( Date() )
Descend() de uma string retorna outra string, seja letra ou número.
Dtos() retorna uma string com números, mas é string.
A tabela ASCII não é ordem alfabética, são caracteres que vão de 0 a 255.

Descend() de "20160626" vai retornar uma string onde cada caractere é convertido com o Ascii contrário, que não representa a ordem alfabética.

Código: Selecionar todos

PROCEDURE Main
   ? Asc( "0" )
   ? Asc( Descend( "0" ) )
   ? Descend( "0" )
   RETURN
test.png
test.png (4.33 KiB) Exibido 2343 vezes
O caractere vai depender da codepage, e aí está o problema em usar Descend( Dtos( Date() ) ), aliás, em qualquer string.
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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

Mais um:

Código: Selecionar todos

PROCEDURE Main
   ? Str( Descend( Date() ), 7 )
   ? Descend( Dtos( Date() ) )
   RETURN
teste.png
teste.png (2.74 KiB) Exibido 2341 vezes
Lembrando que hoje, Dtos() vai retornar "20160626"
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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

Só a última, que foi uma das novidades:

Código: Selecionar todos

INDEX ON Dtos( FieldDate ) TO lixo DESCENDING
Isso não converte nada. O índice usa a chave normal, o índice é criado em ordem decrescente.


Se fosse Descend( Val( Dtos( Date() ) ) ) acho que o resultado seria o que você pensou que fosse.
Não é isso?
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
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

Pela postagem do harbour-users acho que ainda não entendeu, ou quer uma solução melhor (eu também gostaria).

"RUA ANTONIO NUMERO 365"
"20160626"

Descend() não distingue se a string é composta somente de números, trata como uma string.
E pra manter compatibilidade com Clipper, Descend() não usa codepage.
O resultado é que com PTISO ou outra codepage, Descend() não serve pra indexar string, principalmente se tiver números, porque o Ascii inverso é exatamente a área de caracteres que mais é afetada pela codepage.

O inverso de "A" não é "Z", e nem de "0" é "9".

O inverso de Letra é Chr( 256 - Asc( Letra ) ). o que resulta num caractere diferente, conforme a codepage.

Descend() funciona sem problemas em qualquer codepage quando o argumento é numérico ou data, porque retorna numérico.

Ok em:

Código: Selecionar todos

INDEX ON Descend( numero )
INDEX ON Descend( Data )
INDEX ON StrCodigo + Str( Descend( Data ), 7 ) + Str( Descend( Numero ), 16, 2 )
Obrigatoriamente codepage US pra funcionar em:

Código: Selecionar todos

INDEX ON Descend( Str( numero, 10 ) )
INDEX ON Descend( Dtos( Data ) )
INDEX ON Descend( Texto )
INDEX ON StrCodigo + Descend( Dtos( Data ) ) + Str( Descend( Numero ), 16, 2 )
O Clipper é assim, a diferença é que sempre usamos a codepage default no Clipper.
No Harbour... como Descend() é compatível com Clipper.... ficou sem codepage.

E só pra reforçar: INDEX ON ... DESCENDING não converte nada, apenas o NTX/CDX fica na sequência invertida, e a chave usada pra indexar continua sendo a mesma de sempre, por isso sem problemas com codepage.

O problema em Descend(Dtos()) não tem a ver com SET DATE, é diferença de codepage no valor inverso.

O que eu fiz nesta função CPDescend() foi encontrar o caractere que em ordem alfabética corresponde ao contrário do caractere original também em ordem alfabética. Pra isso crio uma lista em ordem crescente, e outra em ordem decrescente, e troco uma pela outra.

Código: Selecionar todos

FUNCTION CPDescend( cText )
   LOCAL cResult, acAscii := {}, nCont
   STATIC cFrom, cTo
   IF cFrom == NIL .OR. cTo == NIL
      FOR nCont = 1 TO 255
         Aadd( acAscii, Chr( nCont ) )
      NEXT
      ASort( acAscii )
      cFrom := cTo := ""
      FOR nCont = 1 TO 255
         cFrom += acAscii[ nCont ]
         cTo   += acAscii[ 256 - nCont ]
      NEXT
   ENDIF
   cResult := hb_StrReplace( cText, cFrom, cTo )
   RETURN cResult
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
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7929
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Ordem decrescente

Mensagem por Itamar M. Lins Jr. »

O caractere vai depender da codepage, e aí está o problema em usar Descend( Dtos( Date() ) ), aliás, em qualquer string.
Pois é, penso que isso foi um problema para entender, pelo menos a explicação para string´s deveria ser melhor...

Ordem descendente de "1234" deve ser "4321" de "ABCD", "DCBA"... A tabela ASCII padrão é a 437 e no Brasil usamos 850, veja lá que os números estão na mesma ordem.
Descendente é descendente tanto faz ser aqui ou no Japão.
Agora para acentos, Ã é muito diferente de A... a história muda... entretanto, contudo, todavia... depois de reler o que vc escreveu eu aprendi mais um pouco, agora sei que para strings "descend()" usa a tabela ASCII que conforme foi explicado é o contrário lá na tabela...

Código: Selecionar todos

? descend(123) //retorna -123
? descend(ctod("26/06/16")) //retorna 2807125
? descend(ctod("26/06/2016")) //retorna 5231808 ou seja 7 dígitos.
Já que descend() de string retorna o campo contrário da tabela ASCII.
Deveria eles então corrigirem o nome da função de descend() para asciiDescend(), acho que faria menos confusão.
<exp> is any valid expression of character, date, logical, or
numeric type. Memo type is treated in the same way as character type.
Ai está a confusão! de usarmos sem necessidade dtos() com descend() se for usar descend() com campo data não precisa de dtos().
Mas a maneira como o Elch ensinou faz mais sentido para mim.

Código: Selecionar todos

INDEX ON dtos(date) TO temp DESCENDing
Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

Ordem decrescente

Mensagem por JoséQuintas »

Na época o Clipper não dependia de codepage.
Olhando a tabela ASCII PTISO dá pra entender melhor.
Ela seria em ordem alfabética, se não fossem os caracteres PTISO, são eles que bagunçam a ordem. (letras acentuadas)
tabelaascii.png
A questão é simples:
Descend() tem que ficar compatível com Clipper, então podemos considerar que não existe mais Descend( string ).
Dtos( date() ) retorna string, e faz parte disso.

Saídas:
- cláusula DESCENDING
- Descend( Date() ) direto no campo date, sem converter pra Dtos(), se for o caso converter o RESULTADO pra string Str( Descend( Date() ), 7 )

Devo eliminar minha CPDescend().
Ainda vou confirmar se em algum lugar ela vai fazer falta. Nesse caso poderíamos justificar uma hb_Descend().
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