Página 1 de 1

Hash com Harbour ?

Enviado: 14 Jan 2009 17:01
por Ale SB
Blz galera,

Olha eu tenho esta funçao aki q uso com xHb:

Código: Selecionar todos

local aVars 
//
aVars:=LoadDbf()
//
**********************
function LoadDbf()
**********************
LOCAL aVars  := {=>}
  LOCAL nField := FCount()
  LOCAL nX := 1
   FOR nX := 1 TO  nField
       aVars[FieldName(nX)] := FieldGet(nX)
   NEXT

Return aVars
Como poderia usar ela com Harbour ?
Pelo q eu fui informado o harbour nao aceita isto aki: LOCAL aVars := {=>}

Para xHb eu achei uma documentaçao e ate uns exemplos com hash, mas, para Harbour nao achei nada.

Alguem pode me dar uma Luz ?!

Valew ai galera.

@braços Ale

Re: Hash com Harbour ?

Enviado: 15 Jan 2009 20:02
por Eolo
Ale, o XH aceita, sim. Pra falar a verdade, nunca tinha visto isso e aí fui conferir: tem, sim. Olha um dos exemplos do help:

Código: Selecionar todos

// The example demonstrates how to create and populate hash values.

   PROCEDURE Main                      // literal hash
      LOCAL hHash := { "COM1" => 1, "COM2" => 2 }

      // object notation
      ? hHash:COM1                     // result: 1
* etc
Aliás, dá uma explicada aí como é que é esse treco?

Re: Hash com Harbour ?

Enviado: 16 Jan 2009 08:38
por Ale SB
Eolo, blzinha...

Eu sei q o xHb aceita trabalhar com Hash desta forma ai, mas, minha duvida eh como trabalhar com Hash com o Harbour.

o Harbour nao aceita trabalhar com Hash igual no xHB, comprende minha duvida agora.

Vc pediu para eu explicar como funfa o Hash, certo ?

Veja bem, nao sou a pessoa mais indicada para falar dela, ainda to tentanto entender melhor seu funcionamento, tb keria uma Luz de algum q conheça bem o assunto, o poko q sei peguei informaçoes na Hash.txt do xHb ( pasta Doc).

Mas pelo jeito trabalhar com Hash para substituir o Array convecional deixa o acesso ao array mais rapido, nao kero falar muito para nao falar besteira, ate pq toda documentaçao ta em Ingles e meu Ingles eh um poko fraco, ainda estou em busca de mais informaçoes...ok.

@braços Ale

Re: Hash com Harbour ?

Enviado: 17 Jan 2009 09:31
por Eolo
Cara, desculpe. Não li corretamente a sua pergunta (Harbour x xHarbour).


Bão, fui dar uma olhada e parece que o HASH é um negócio simples e até bacana.

É similar a uma matriz de 2 colunas. A diferença é que, numa matriz 'comum', vc pega os valores de acordo com a sua posição. Já no HASH, a matriz é 'indexada': vc pega os valores da coluna 2 de acordo com a 'chave' da coluna 1. Restrições: o HASH só pode ter 2 colunas e a coluna 1 tem que ser caracter, data ou numérico.

Matriz comum
mat:= {}
aadd(mat,"dois",2)
aadd(mat,"três",3)
aadd(mat,"um",1)
? mat[1,2] -> 2

HASH
mat:= {=>}
mat:dois := 2
mat:tres := 3
mat:um := 1
? mat:dois -> 2

Então, se vc não sabe a posição de um elemento:
a) na matriz comum vc precisa usar o ASCAN (com code block).
b) com o HASH, basta dar o nome. Ele faz o 'ascan' por vc.


No seu exemplo, me parece que, ao invés de fazer por exemplo ARQUIVO->CAMPO1 (acesso ao disco), você primeiro constrói a matriz HASH e depois faz a consulta via MATRIZ:CAMPO1 (memória), o que é mais rápido e pode fazer diferença no processamento em rede.

Mas será que é só essa a vantagem?

Re: Hash com Harbour ?

Enviado: 17 Jan 2009 09:55
por Eolo
(POST CORRIGIDO...)

Em tempo: eu guardo os valores dos campos em variáveis e, pra facilitar, montei a funçãozinha abaixo (que uso desde o Summer e me atende hoje no xHarbour).

Esta função faz algo parecido com o uso que vc fez do HASH: ela cria tantas variáveis quantos forem os campos do DBF aberto no momento (não importa qual), acrescentando um "V" no início dos nomes (sei que esta notação não está de acordo com o "tecnicamente recomendado", mas se for o caso é só alterar a função: pra campo DATA, acrescentar D; pra NUMÉRICO, N etc.).

Código: Selecionar todos

FUNCTION VAR
priv no,y,w,z
no=dbstruct()       // estrutura do DBF
for y=1 to len(no)
  z=no[y,1]         // nome do n-ésimo campo
  w="v"+z           // cria o nome da variável
  z=&z              // valor do n-ésimo campo
  &w=z              // joga o valor do campo na variável
next
Eu rodo a função acima na entrada da rotina de edição do DBF e aí trabalho com as variáveis. Na saída, eu reseto as variáveis com o seguinte:

Código: Selecionar todos

FUNCTION VAR2
priv no,y,w
no=dbstruct()        // estrutura do DBF
for y=1 to len(no)
  w="v"+no[y,1]     // nome da variável
  rele &w              // limpa a variável da memória
next

Re: Hash com Harbour ?

Enviado: 18 Jan 2009 14:02
por sygecom
Interesante tbm. não conhecia, vou dar uma pesquisada tmb. sobre isso.

Hash com Harbour ?

Enviado: 22 Nov 2017 13:07
por pauloa1
Problemas na busca ou estou fazendo algo errado:

Quero localizar [PROCEVENTONFE002] no arquivo.
E não acha, apenas se eu colocar o [PROCEVENTONFE001].

aRet_acbr := Hb_ReadIni("c:\teste\sainfe000006.txt")
IF HHasKey( aRet_Acbr,"PROCEVENTONFE001" )

// retorna .t.
IF HHasKey( aRet_Acbr,"PROCEVENTONFE002" )
// retorna .f.

O segundo evento da carta de correção da nfe, não tem jeito dele achar.

Se for final 001 localiza e for final 002 não.

Paulo

Hash com Harbour ?

Enviado: 22 Nov 2017 23:57
por JoséQuintas

Código: Selecionar todos


PROCEDURE Test

   LOCAL aRet

   SetMode(24,80)
   CLS

   aRet := hb_ReadIni( "sainfe.txt" )
   ? HHasKey( aRet, "PROCEVENTONFE001" )
   ? HHasKey( aRet, "PROCEVENTONFE002" )
   Inkey(0)

Retornou .T. nos dois

Hash com Harbour ?

Enviado: 23 Nov 2017 08:39
por pauloa1
Olá José! Muito obrigado por testar!

Você fez o teste com o arquivo que anexei?

Vou ver o que estou fazendo de errado.

Paulo

Hash com Harbour ?

Enviado: 25 Jul 2021 19:44
por vcatafesta
Olá pessoal,

Minha contribuição de hash em classe.

Código: Selecionar todos

#include "hbclass.ch"

CLASS THash
	EXPORTED:
		DATA xNil   INIT nil
		DATA Hash   INIT {=>}

	public:
		METHOD new CONSTRUCTOR
		DESTRUCTOR Destroy()
		METHOD Create()
      METHOD Value(xHash, xValue) SETGET
      METHOD Execute(xValue, nRow, nCol)
      METHOD Position(nPosition)
      MESSAGE SetValue method value
      MESSAGE GetValue method value
      MESSAGE add method value
ENDCLASS

METHOD New()
	::Hash := ::Create()
	return self

METHOD Destroy()
   self := nil
   return self

METHOD Create()
	LOCAL aHash := {=>}
   HSetAutoAdd( aHash, .T.)
	HSetCaseMatch( aHash, .F. )                 // desabilita o case-sensitive
	return aHash

METHOD value(xHash, xValue)
   if pcount() == 2
      ::Hash[xHash] := xValue
   endif
   return ::Hash[xHash]

METHOD execute(xValue, nRow, nCol)
   LOCAL bBlock := ::Hash[xValue]
   if pcount() == 1
      if HB_ISBLOCK( bBlock )
         eval( bBlock)
         return self
      endif
   endif
   if pCount() = 2
      hb_default(@nRow, 2)
      if HB_ISBLOCK( bBlock[nRow])
         eval( bBlock[nRow])
         return self
      endif
   endif
   if pCount() > 2
      hb_default(@nRow, 2)
      hb_default(@nCol, 1)
      if HB_ISBLOCK( bBlock[nRow, nCol])
         eval( bBlock[nRow, nCol])
         return self
      endif
   endif
   return self

METHOD position(nPosition, nPos)
   if pcount() == 1
      return hb_hPairAt( ::Hash, nPosition )
   endif
   hb_default(@nPos, 1)
   return hb_hPairAt(::Hash, nPosition)[nPos]

def THashNew()
	return( THash():New())
endef
Codigo para testes:

Código: Selecionar todos

function main
   LOCAL oh := THashNEw()
   oh:setvalue("COM1", {||Funcao2()})
   oh:setvalue("COM2", 'COM2')
   oh:add("COM3", 'COM3')
   altd()
   oh:execute('COM1')
   ? oh:getvalue('COM2')
   ? oh:getvalue('COM3')
   oh:setvalue("MULTI", {{||Funcao2()}, 1.01})

   oh:execute('MULTI',1)
   ? oh:getvalue('MULTI')[2]

   oh:SetValue(6.01, {"Layout Janela",        {||Funcao3() }})
   ? menu := oh:position(5)[1]
   ? oh:execute(6.01, 2)
   inkey(0)

function funcao2()
   alert("OK")
   return nil

function funcao3()
   alert("FUNCAO 3")
   return nil