Salvar um vetor em arquivo .mem

Aqui você poderá oferecer suas Contribuições, Dicas e Tutoriais (Texto ou Vídeo) que sejam de interesse de todos.

Moderador: Moderadores

Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Salvar um vetor em arquivo .mem

Mensagem por Pablo César »

No fórum oficial da HMG, o colega polaco Marek, apresentou-nos uma solução radical para guardar vetores em arquivo MEM e eu gostaria também de compartilhar aqui nesta comunidade também. Passo a relatar:
Como você sabe, você não pode salvar variável de matriz em arquivo de mem. O nome da variável também é limitado a 10 caracteres (eu testei).
Primeiro, eu tentei criar muitas variáveis ​​para cada célula matriz. Mas, foi pouco bobo.

Então fiz de outra forma, declaro variável texto cTmp, por exemplo e ai configurei o seu valor para:

cTmp := "{|| aArrayToSave:=" + hb_valtoexp(aArrayToSave) + "}"

Ai esta variável do tipo texto pode ser gravada pelo comando:

Save all Like cTMP to MyMemFile

E para conseguir recuperar o meu vetor gravado no disco, preciso fazer deste modo:

Restore from MyMemFile Additive
Eval(&cTmp)
Aí fiz um teste com a ideia de salvar vários vetores, como tinha sido indicado também, porém eu consegui desta forma:

Código: Selecionar todos

#include <hmg.ch>

Function Main
Local aA1,aA2,aA3

If !File("MyMemFile.mem")
   aA1:={1,"Test1",CtoD("01/01/2013"),.T.}
   aA2:={2,"Test2",CtoD("02/01/2013"),.F.}
   aA3:={3,"Test3",CtoD("03/01/2013"),.T.}
   
   MsgInfo(hb_ValToExp(aA1), "Array aA1 Just assigned")
   MsgInfo(hb_ValToExp(aA2), "Array aA2 Just assigned")
   MsgInfo(hb_ValToExp(aA3), "Array aA3 Just assigned")

   Private cTmp1 := "{|| aA1:=" + hb_valtoexp(aA1) +"}"
   Private cTmp2 := "{|| aA2:=" + hb_valtoexp(aA2) +"}"
   Private cTmp3 := "{|| aA3:=" + hb_valtoexp(aA3) +"}"

   Save all Like cTMP* to MyMemFile
Endif

aA1:={}
aA2:={}
aA3:={}
Restore from MyMemFile Additive
aA1:=Eval(&cTmp1)
aA2:=Eval(&cTmp2)
aA3:=Eval(&cTmp3)

MsgInfo(hb_ValToExp(aA1), "Array aA1 recovered")
MsgInfo(hb_ValToExp(aA2), "Array aA2 recovered")
MsgInfo(hb_ValToExp(aA3), "Array aA3 recovered")
Return Nil
O código foi feito em HMG, mas pode ser utilizado em Harbour e adaptado em Clipper também. Espero que possa a vir ser útil e que tenham gostado !
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Salvar um vetor em arquivo .mem

Mensagem por Jairo Maia »

Olá Pablo,

Primeiro, parabéns ao colega Marek, e obrigado por compartilhar a idéia.

Tive uma situação que preferi ao invés de gravar num banco as mesas abertas (Bar resturante), deixár os dados em memória, mas prever uma queda de energia. Como trabalho com vetores, me deparei com o probelma de salvar em disco a cada alteração, para poder recuperar os cupons não fechados no caso de interrupção.

Lembrei imediatamente da contribuição do colega Marek, que você havia publicado, mas ficou estranho no meu caso, tanto para salvar como para recuperar, uma vez que a opção dele transforma cada elemento em Bloco depois volta para array.

Primeiro, tentei usar as funções ValToPrgExp() e PrgExpToVal(), mas não achei que lib elas estão. Então decidi usar as funções Hb_Serialize() e Hb_DeSerialize().

O exemplo está em MiniGui, mas pode ser compilado em modo console, bastando remover a inclusão do arquivo minigui.ch e trocar MsgInfo() por Hb_Alert():

Código: Selecionar todos

/*
   Salva Matriz em disco usando as funções:
   Hb_Serialize() e Hb_DeSerialize()

   Nota: Veja que propositalmente todas variáveis foram declaradas com tamanho
   maior que 10 caracteres, já que as funções Hb_MvSave() e Hb_MvRestore()
   salva variáveis com nomes longos, nao limitado a apenas 10 caracteres
*/

#include "minigui.ch"

Function Main()
   /*
     Aqui podem ser declaradas como Local, mas vamos declarar como
     Private para sofrer o efeito do comando Release, que não afeta
     variáveis declaradas Local
   */
   Private aPrimeiraMatriz := {}
   Private aSegundaMatriz := {}
   Private aMatrizMaster := {}

   /*
     Esta precisa ser Private ou Public, pois não é possível
     salvar variáveis Local, Static, Array ou Block
   */
   Private cMatrizSerializada

   /*
     Vamos montar uma primeira matriz bidimensional:
   */
   AaDd( aPrimeiraMatriz, { Date() + 1, "Campinas", 123.45 } )
   AaDd( aPrimeiraMatriz, { Date() + 2, "Paulinia", 123.46 } )
   AaDd( aPrimeiraMatriz, { Date() + 3, "Sao Paulo", 123.47 } )
   AaDd( aPrimeiraMatriz, { Date() + 4, "Rio de Janeiro", 123.48 } )

   /*
     Vamos montar uma segunda matriz bidimensional:
   */
   AaDd( aSegundaMatriz, { Date() + 5, "Andre", "Paulinia", 1994 } )
   AaDd( aSegundaMatriz, { Date() + 6, "Carolina", "Paulinia", 1996 } )
   AaDd( aSegundaMatriz, { Date() + 7, "Pedro", "Paulinia", 1998 } )
   AaDd( aSegundaMatriz, { Date() + 8, "Beatriz", "Paulinia", 2002 } )

   /*
     Para facilitar, vamos inserir as matrizes que queremos salvar
     em uma matriz Master:
   */
   AaDd( aMatrizMaster, { aPrimeiraMatriz, aSegundaMatriz } )

   /*
     Para poder salvar, vamos Serializar e colocar o resultado
     numa variável. O conteúdo retornado é tipo CARACTER:
   */
   cMatrizSerializada := Hb_Serialize( aMatrizMaster )

   /*
     Salva em arquivo. Se não for definida a extensão, será .hbv
   */
   Hb_MvSave( "MeuArray.Mem", "cMatrizSerializ*" )

   /*
     Vamos apagar todas as variáveis:
   */
   Release All

   /*
     Vamos provar que foram apagadas:
   */
   If Type( "aMatrizMaster" ) = "U"
    MsgInfo( [Variavel "aMatrizMaster" nao existe!], "Nenhuma variável em memória" )
   Endi

   /*
     Vamos restauar as variaveis salvas no disco:
   */
   Hb_MvRestore( "MeuArray.Mem", .T. )

   /*
     Vamos deserializar a variável caracter para que ela volte
     a ser uma Matriz (Array):
   */
   aMatrizMaster := Hb_DeSerialize( cMatrizSerializada )

   /*
     Vamos apagar a variável "cMatrizSerializada", desnecessaria agora:
   */
   Release cMatrizSerializada

   /*
     Vamos recompor nossas matrizes:
   */
   aPrimeiraMatriz := aMatrizMaster[ 1, 1 ]
   aSegundaMatriz := aMatrizMaster[ 1, 2 ]

   /*
     E vamos mostrar que foram restauradas:
   */
   MsgInfo( Padc( hb_ValToExp( aPrimeiraMatriz[ 1, 2 ] ), 50 ), "aPrimeiraMatriz [1,2]" )
   MsgInfo( Padc( hb_ValToExp( aSegundaMatriz[ 2, 3 ] ), 50 ), "aSegundaMatriz [2,3]" )

   MsgInfo( Padc( hb_ValToExp( aMatrizMaster[ 1, 1, 2 ] ), 50 ), "aMatrizMaster [1, 1, 2]" )
   MsgInfo( Padc( hb_ValToExp( aMatrizMaster[ 1, 1, 2, 3 ] ),50 ), "aMatrizMaster [1, 1, 2, 3]" )

Return
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Avatar do usuário
Pablo César
Usuário Nível 7
Usuário Nível 7
Mensagens: 5312
Registrado em: 31 Mai 2006 10:22
Localização: Curitiba - Paraná

Salvar um vetor em arquivo .mem

Mensagem por Pablo César »

Parabéns amigo Jairo ! Eu não testei ainda mas ficou muito interessante.
Seria bom postar o seu exemplo lá em http://hmgforum.com/viewtopic.php?p=25719#p25719 já que você também é usuário naquele fórum.

Obrigado Jairo por compartilhar ! Muito bom ! :)Pos
Um clip-abraço !

Pablo César Arrascaeta
Compartilhe suas dúvidas e soluções com todos os colegas aqui do fórum.
Evite enviar as dúvidas técnicas por MPs ou eMails, assim todos iremos beneficiar-nos.
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

Salvar um vetor em arquivo .mem

Mensagem por Jairo Maia »

Valeu Pablo. Feito!
Abraços, Jairo
Harbour / Clipper 5.2e - Blinker 7
(Não respondo dúvidas por MP ou E-mail. Por favor, não encaminhe via mensagem privada ou e-mail, dúvidas que podem ser compartilhadas com todos no fórum)
Responder