Page 1 of 1

Ejemplos para aprender a usar HASH

Posted: Tue Sep 11, 2018 2:57 pm
by EBM
Hola compañeros, he estado viendo que los HASH se asimilan a los Arrays pero con grandes ventajas, pero no logro encontrar literatura sobre su uso y aplicación en Harbour y FW, donde puedo encontrar la forma de utilizarlos o un buen ejemplo de su aplicación?

Saludos!

Eduardo Borondón Muñiz

Re: Ejemplos para aprender a usar HASH

Posted: Tue Sep 11, 2018 7:03 pm
by cnavarro
Los ejemplos de la clase TLayout en samples puede ser un buen comienzo ( *lay*.prg )

Re: Ejemplos para aprender a usar HASH

Posted: Wed Sep 12, 2018 3:59 pm
by EBM
Mil Gracias Cristóbal, comienzo con eso

Saludos !!

Eduardo Borondón Muñiz

Re: Ejemplos para aprender a usar HASH

Posted: Wed Sep 12, 2018 8:39 pm
by FranciscoA
Mira este codigo, talvez te sea de ayuda.

Code: Select all

//----------------------------------------------------------------------------//
Function EditCata( oLbx, lAppend, oCatalogo )
local oDlg, lSave:=.f., oCkBox,lCkBox:=.f., oBmp,oFont
local nOldRec := oCatalogo:RecNo()
local oSay1,oSay2,oSay3,oSay4,oSay5,oSay6,oSay7,oSay8,oSay9,n
local hVars, oGets:= Array(7), cCodCta
local cCodiAnter,cCodigoCta,cNivelCta,cNombreCta,cUsuarioEdit
local oControl

DEFAULT lAppend := .f.

 if !cPermiso $ "T/M"
   MsgStop("Acceso denegado. Consulte con Administrador del Sistema.","Alto")
   Return nil
 endif

if !lAppend 
  if oCatalogo:LastRec() == 0
     MsgStop("No existe ningun registro.","Alto")
     return nil
  endif
endif

 hVars:= HASH()
 If lAppend
     hVars["CODIANTERIOR"]  := Space(Len(oCatalogo:Codicont))
     hVars["NOMBREANTER"]   := Space(Len(oCatalogo:Nombre))
     hVars["CODI"]          := Space(Len(oCatalogo:Codicont))
     hVars["CUENTA"]        := NIV1
     hVars["SCUENTA1"]      := NIV2
     hVars["SCUENTA2"]      := NIV3
     hVars["SCUENTA3"]      := NIV4
     hVars["SCUENTA4"]      := NIV5
     hVars["NIVEL"]         := Space(Len(oCatalogo:nv))
     hVars["NOMBRE"]         := Space(Len(oCatalogo:nombre))
     *hVars["SALDOI"]        := 0
     *hVars["SALDOANT"]      := 0
     *hVars["MOVDEBE"]       := 0
     *hVars["MOVHABER"]      := 0
     *hVars["SALDOACT"]      := 0
 Else
     hVars["CODIANTERIOR"]  := oCatalogo:Codicont
     hVars["NOMBREANTER"]   := oCatalogo:Nombre
     hVars["CODI"]          := oCatalogo:Codicont
     hVars["CUENTA"]        := Substr(oCatalogo:Codicont,1,len(NIV1))
     hVars["SCUENTA1"]      := Substr(oCatalogo:Codicont,1+len(NIV1),len(NIV2))
     hVars["SCUENTA2"]      := Substr(oCatalogo:Codicont,1+LEN(NIV1)+LEN(NIV2),len(NIV3))
     hVars["SCUENTA3"]      := Substr(oCatalogo:Codicont,1+LEN(NIV1)+LEN(NIV2)+LEN(NIV3),len(NIV4))
     hVars["SCUENTA4"]      := Substr(oCatalogo:Codicont,1+LEN(NIV1)+LEN(NIV2)+LEN(NIV3)+LEN(NIV4),len(NIV5))
     hVars["NIVEL"]         := if(empty(oCatalogo:nv),"N",oCatalogo:nv)
     hVars["NOMBRE"]        := oCatalogo:nombre
     *hVars["SALDOI"]       := oCatalogo:saldoi
     *hVars["SALDOANT"]     := oCatalogo:saldoant
     *hVars["MOVDEBE"]      := oCatalogo:movdebe
     *hVars["MOVHABER"]     := oCatalogo:movhaber
     *hVars["SALDOACT"]     := oCatalogo:saldoact
 Endif


  DEFINE FONT oFont NAME "MS SANS SERIF" SIZE 0,-09 
  DEFINE DIALOG oDlg RESOURCE "CATALOGOEDIT" ;
         TITLE If( lAppend, " Agregar nuevo registro al Catalogo", " Modificar Catalogo de Cuentas" ) ;
         FONT oFont ;
         TRANSPARENT

  For n:=101 to 108   //Los says
    REDEFINE SAY ID n OF oDlg
  Next

   REDEFINE CHECKBOX oCkBox VAR lCkBox ID 110 OF oDlg ON CHANGE if(lCkBox=.t.,MsgInfo("Utilice con cuidado. Puede descuadrar Estados Financieros"),)
   oCkBox:lTransparent := .t.

   REDEFINE GET oGets[1] VAR hVars["CUENTA"]    ID 201 OF oDlg PICTURE "@!"
   REDEFINE GET oGets[2] VAR hVars["SCUENTA1"]  ID 202 OF oDlg PICTURE "@!" VALID campolleno(hVars["SCUENTA1"],NIV2)
   REDEFINE GET oGets[3] VAR hVars["SCUENTA2"]  ID 203 OF oDlg PICTURE "@!" VALID campolleno(hVars["SCUENTA2"],NIV3)
   REDEFINE GET oGets[4] VAR hVars["SCUENTA3"]  ID 204 OF oDlg PICTURE "@!" VALID campolleno(hVars["SCUENTA3"],NIV4)

   REDEFINE GET oGets[5] VAR hVars["SCUENTA4"]  ID 205 OF oDlg PICTURE "@!" VALID campolleno(hVars["SCUENTA4"],NIV5) ;
                 .AND. CATAERROR(hVars["CODIANTERIOR"], hVars["CUENTA"]+hVars["SCUENTA1"]+hVars["SCUENTA2"]+hVars["SCUENTA3"]+hVars["SCUENTA4"], oLbx, lAppend, oGets[1], oGets[5], oCatalogo)

   REDEFINE GET oGets[6] VAR hVars["NIVEL"]     ID 206 OF oDlg PICTURE "@!" Valid NivelAuxi(hVars["NIVEL"])
   REDEFINE GET oGets[7] VAR hVars["NOMBRE"]    ID 207 OF oDlg PICTURE "@!"

   REDEFINE BITMAP oBmp RESOURCE "CONFIG64" ID 400 OF oDLG ; oBmp:lTransparent:=.t.

   REDEFINE BUTTONBMP ID 312 OF oDlg BITMAP "ACEPTAR" TEXTRIGHT ACTION ( IF(CATAERROR(hVars["CODIANTERIOR"], hVars["CUENTA"]+hVars["SCUENTA1"]+hVars["SCUENTA2"]+hVars["SCUENTA3"]+hVars["SCUENTA4"], oLbx, lAppend, oGets[1], oGets[5], oCatalogo),(lSave := .t. , oDlg:End()), lSave:=.f.) )
   REDEFINE BUTTONBMP ID 313 OF oDlg BITMAP "CANCELAR" TEXTRIGHT ACTION oDlg:End() CANCEL

   ACTIVATE DIALOG oDlg CENTERED 
 
   IF lSave .and. !empty( hVars["CUENTA"] )

      cCodiAnter := hVars["CODIANTERIOR"]
      cCodigoCta := hVars["CUENTA"]+hVars["SCUENTA1"]+hVars["SCUENTA2"]+hVars["SCUENTA3"]+hVars["SCUENTA4"]
      cNivelCta  := if(upper(hVars["NIVEL"]) = "N"," ","S")
      cNombreCta := hVars["NOMBRE"]
      cUsuarioEdit:=Substr(cNombUser,1,22)+" "+dtoc(date())+" "+time() //usuario que edita
 
      If lAppend
         oServer:Query( "INSERT INTO catalogo (codicont,nv,nombre,usuario) VALUES ('"+cCodigoCta+"','"+cNivelCta+"','"+cNombreCta+"','"+cUsuarioEdit+"')" )
      Else   
         oServer:Query( "UPDATE catalogo SET codicont = '"+cCodigoCta+"', nv = '"+cNivelCta+"', nombre = '"+cNombreCta+"', modificado = '"+cUsuarioEdit+"' WHERE Codicont = '"+cCodiAnter+"'  ORDER BY codicont LIMIT 1")
      Endif

      if oServer:lError
         MsgStop(oServer:Error)
      endif

     //Sin esto no refresca bien (no se coloca en registro recien ingresado)     
      *If lAppend
         oCatalogo:GoTop()
         oCatalogo:Refresh()
         oCatalogo:Locate("Codicont",cCodigoCta,,)
      *Endif

     if oLbx != NIL    //bandera desde grabar():ExisteCta()
        oCatalogo:Refresh()
        oLbx:Refresh()
     endif

     if alltrim(cCodigoCta)<>alltrim(cCodiAnter  )
        oControl:=oServer:Query("SELECT * FROM control ;")
        if substr(cCodigoCta,1,1)=Substr(alltrim(oControl:Ingr),1,1);
           .or. substr(cCodigoCta,1,1)==Substr(alltrim(oControl:Cost),1,1);
           .or. substr(cCodigoCta,1,1)==Substr(alltrim(oControl:Egre),1,1)
           MsgInfo("La codificacion introducida es de Resultado."+CRLF+;
                   "Revise si debe incluirse en Estado de Resultado definido por el usuario.","ADVERTENCIA")
        endif
        oControl:End()
     endif

     IF !lAppend  //ES MODIF
        if hVars["NOMBRE"] <> hVars["NOMBREANTER"]
           Proceso(alltrim(cNombUser)+ " modif nombre a Cta "+hVars["CODI"]+" de "+alltrim(hVars["NOMBREANTER"])+" a "+hVars["NOMBRE"])
        endif 
        if cCodigoCta<>cCodiAnter
           Proceso(alltrim(cNombUser)+ " modif Codigo a Cta "+ cCodiAnter +" a "+ cCodigoCta )
        endif 
     ENDIF

   ELSE  //Si no se salva el registro...
      oCatalogo:GoTo(nOldRec)
      oCatalogo:Refresh()
   ENDIF

   oFont:End()
   oLbx:SetFocus()
RETURN NIL
 
Saludos.

Re: Ejemplos para aprender a usar HASH

Posted: Wed Sep 26, 2018 9:02 pm
by EBM
Mil gracias Francisco, muy claro el ejemplo.

Saludos!

Eduardo Borondón Muñiz

Re: Ejemplos para aprender a usar HASH

Posted: Tue Oct 02, 2018 11:48 am
by MarioG
Hola;
Si no es tarde; este es el ejemplo vino en alguna distribución de Harbour o xHarblour; ya no recuerdo

Code: Select all

*****************************************************
* Hash Grammar test
*
* Giancarlo Niccolai (C) 2003
*
* This is a test that demonstrates how to use hashes
*
* $Id: hash.prg,v 1.9 2003/12/13 19:27:00 ronpinkas Exp $
*

PROCEDURE Main()
   LOCAL hHash, hTemp
   LOCAL nSum, nLevel, eError
   LOCAL xKey, xValue, hDest

   SET DATE TO ITALIAN
   CLEAR SCREEN

   @0,0 SAY "*** Hash test ***"
   ? "Giancarlo Niccolai"
   ?

   * Creation by PP command:
   * Equivalent to Hash( K1, V1, ... KN, VN )

   hHash := Hash()
   HSetPartition( hHash, 2, 2 )


   /* Insertion by API */
   hHash["Kval"] = 'StrKey 0'
   hHash[ 8 ] = 'Num Key 0'
   HSet( hHash, 4,  "Numeric key 1" )
   HSet( hHash, 2,  "Numeric key 2" )
   HSet( hHash, "Str8", "String key 1" )
   HSet( hHash, "Str1", "String key 2" )
   HSet( hHash, CToD("1/1/2003"), "Date key 1" )
   HSet( hHash, CToD("30/11/2002") , "Date key 2" )

   ? "Standard API compliance test:"
   ? "Hash type:", ValType( hHash )
   ? "Hash length:", Len( hHash )
   ? "Hash value:", ValToPrg( hHash )
   ? "Empty hash value:", ValToPrg( { => } )
   ? "String representation (should be nothing):", {=>}
   ? "Equality of hashes (Success for .T. , .F.): ", hHash == hHash, hHash == {=>}
   HGetPartition(hHash, @nSum, @nLevel )
   ? "Hash partitioned as: ", nSum, nLevel

   ? "Plus operator: ", ValToPrg( { 1=>1, 'a'=>2} + { 3=>3, 'b'=>4 } )
   hHash += { 5=> "numkey 3" }
   ? "Plusequal operator (success if Len(hHash) == 9: ", Len(hHash), ",(", hHash[5], ")"
   hTemp := {'a'=>1, 1=>2, 'c'=>3}
   ? "Minus hash - hash operator: ", ValToPrg( hTemp - { 1=>2, 'c'=>3} )
   ? "Minus hash - array operator: ", ValToPrg( hTemp - { 1, 'a'} )
   ? "Minus hash - item operator: ", ValToPrg( hTemp - 'a' )
   ? "Hash is now: ", ValToPrg( hHash )
   ? "operator kval IN hash", ('Str1' IN hHash)
   ? "operator {=>} IN hash", ({ "Str8" => "String key 1" } IN hHash)
   ? "Turning autoadd off (currently:", HGetAutoAdd( hHash ), ")"
   HSetAutoAdd( hHash, .F. )
   TRY
      hHash[ 'a very new key' ] := 'a value'
      ? "Failure (new key inserted)"
   CATCH eError
      ? "Success: ", eError:description
   END
   HSetAutoAdd( hHash, .T. )

   ? "Press a Key to continue"
   ?
   Inkey(0)

   ? "VM compliance test:"
   ? "Numeric key value hHash[4]:", hHash[4]
   ? "Date key value hHash[CToD('1/1/2003')]:", hHash[CToD('1/1/2003')]
   ? "String key value hHash['Kval']:", hHash['Kval']
   ? "Assign eval hHash['Kval'] := 100", (hHash['Kval'] := 100)
   ? "Assign eval result hHash['Kval']", hHash['Kval']
   M->iPos := 2
   ? "Memvar test hHash[ m->iPos ]: ", hHash[ m->iPos ]
   m->hMem := hHash
   ? "Memvar assign m->hMem := hHash, ValType( m->hMem ): ", ValType( m->hMem )
   TRY
      ? "Wrong index test: hHash[Array()]: Failed", hHash[Array()]
   CATCH eError
      ? "Wrong index test: hHash[Array()]: Passed (", eError:description, ")"
   END
   HSetCaseMatch( hHash, .F. )
   ? "Hash gramar ':' existing key insensitive:", hHash:kval
   HSetCaseMatch( hHash, .Y. )
   ? "Hash gramar ':' adding key:", ( hHash:ColonKey := 'Colon value' )
   ? "Hash gramar ':' retreiving key:", hHash:ColonKey
   ? "Hash grammar ':' classname:", hHash:ClassName
   ? "Hash grammar ':' keys:", ValToPrg( hHash:Keys )
   ? "Hash grammar ':' values:", ValToPrg( hHash:Values )

   ? "Press a Key to continue"
   ?
   Inkey(0)

   ? "HASH api test:"
   ? "HGetPos existing key:", HGetPos( hHash, 2 )
   ? "HGetPos unexisting key:", HGetPos( hHash, 1000 )
   ? "HDel key Str1: (should be ok) "
      HDel( hHash, "Str1" )
   ? "HGetKeys: ", ValToPrg( hGetKeys( hHash ) )
   ? "HGetValues: ", ValToPrg( hGetValues( hHash ) )
   ? "HGetKeyAt 3d pos: ", HGetKeyAt( hHash, 3 )
   ? "HGetValueAt 3d pos: ", HGetValueAt( hHash, 3 )
   ? "HGetPairAt 4th pos (as array):", ValToPrg( HGetPairAt( hHash, 4 ) )
   HGetPairAt( hHash, 4, @xKey, @xValue )
   ? "HGetPairAt 4th pos (as byref):", xKey, xValue
   ? "HDelAt 4th position:"
      HDelAt( hHash, 4 )
   ? "Setting 4th value to 'A newer value'"
      HSetValueAt( hHash, 4, 'A newer value' )
   ? "Hash is now: ", ValToPrg( hHash )
   ? "Press a Key to continue"
   ?
   Inkey(0)

   ? "HASH Case insensitive test:"
   HSetCaseMatch( hHash, .F. )
   hHash[ 'a' ] := 100
   TRY
      HSetCaseMatch( hHash, .T. )
      ? "Sensitivity test failed: ", hHash[ 'A' ]
   CATCH eError
      ? "Sensitivity test Passed (", eError:description,  ")"
   END

   HSetCaseMatch( hHash, .F. )
   TRY
      ? "Insensitivity test passed: ", hHash[ 'A' ]
   CATCH eError
      ? "Insensitivity test Failed (", eError:description,  ")"
   END

   TRY
      hHash['A'] := 50
      ? "Insensitive assignment (success if 50): ", hHash[ 'a' ]
   CATCH eError
      ? "Insensitivity assignment Failed (", eError:description,  ")"
   END
   ? "Press a Key to continue"
   ?
   Inkey(0)


   ? "HGetPos existing key:", HGetPos( hHash, 2 )
   ? "HGetPos unexisting key:", HGetPos( hHash, 1000 )
   ? "HDel key Str1: (should be ok) "
      HDel( hHash, "Str8" )
   ? "HGetKeys: ", ValToPrg( hGetKeys( hHash ) )
   ? "HGetValues: ", ValToPrg( hGetValues( hHash ) )
   ? "HGetKeyAt 3d pos: ", HGetKeyAt( hHash, 3 )
   ? "HGetValueAt 3d pos: ", HGetValueAt( hHash, 3 )
   ? "HGetPairAt 4th pos (as array):", ValToPrg( HGetPairAt( hHash, 4 ) )
   HGetPairAt( hHash, 4, @xKey, @xValue )
   ? "HGetPairAt 4th pos (as byref):", xKey, xValue
   ? "HDelAt 4th position:"
      HDelAt( hHash, 4 )
   ? "Setting 4th value to 'A newer value'"
      HSetValueAt( hHash, 4, 'A newer value' )
   ? "Hash is now: ", ValToPrg( hHash )
   ? "Press a Key to continue"
   ?
   Inkey(0)


   ? "HASH Secondary API test:"
   ? "Scanning for value 'A newer value': ", HScan( hHash, 'A newer value' )
   ? "Scanning for value 'A newer value' using CB: ",;
       HScan( hHash, {| cKey, cVal| HB_ISSTRING(cVal) .and. cVal == 'A newer value'} )

   nSum := 0
   HEval( hHash, { | cKey, cVal|;
       IIF (HB_ISNUMERIC(cKey), nSum += cKey, )} )

   ? "Eval summing up all the numeric keys :", nSum
   ? "Clone of the hash:", ValToPrg(HClone( hHash ))
   hDest := { 'A'=> 1, 'b'=>2 }
   ? "Merging hash with { 'a'=> 1, 'b'=>2 }:"
   ? "Result: ", ValToPrg(HCopy( hHash, hDest ))

   hDest := { 'B'=> 1, 'A'=>2 }
   ? "Merging limited with a codeblock (Only numeric values): "
   ? "Result: ", ValToPrg( HMerge( hDest, hHash, { |cKey, nVal| HB_IsNumeric( nVal ) } ) )
   * The last "2" means XOR
   ? "Doing a xor merge with the original one (first 4 elements): "
   ? "Result: ",  ValToPrg( HCopy( hHash, hDest, , , 2 ) )

   ? "Doing an AND merge with { 'A'=>0, 'B'=>1 } "
   ? "Result: ",  ValToPrg( HMerge( hDest, {'A'=>0, 'B'=>1 }, 1) )

   ? "Press a Key to continue"
   ?
   Inkey(0)
 

Re: Ejemplos para aprender a usar HASH

Posted: Tue Oct 02, 2018 3:02 pm
by EBM
Muchisimas gracias Mario

Excelente ejemplo, muy completo y en muy buen momento.

Gracias de nuevo

Eduardo Borondón Muñiz

Re: Ejemplos para aprender a usar HASH

Posted: Thu Oct 31, 2019 9:08 pm
by vilian
Hi guys,

Is possible to use hash arrays as a multidimensional array? something like this:

? aHash[ 'A',1]
? aHash[ 'A',2]

Re: Ejemplos para aprender a usar HASH

Posted: Thu Oct 31, 2019 10:49 pm
by cnavarro
Dear Vilian
Yes, same as arrays

Code: Select all

    //In this case aItems is a array of Hash and aItems[ x ] is a Hash
    if hb_hHaskey( aItems[ x ][ "end" ], "timeZone" )
       cTime   := aItems[ x ][ "end" ][ "timeZone" ]
    endif
 

Re: Ejemplos para aprender a usar HASH

Posted: Fri Nov 01, 2019 6:06 pm
by vilian
Thank you ;)