Tamanho das variáveis nos .MEM

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

Moderador: Moderadores

Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Tamanho das variáveis nos .MEM

Mensagem por clodoaldomonteiro »

Olá amigos.

Tenho algumas variaveis que preciso guardar em um arquivo .mem, tipo DrvAutoHelp, que tem 11 caracteres, ms só que quando mando guardar no arquivo .mem com o comando SAVE, ele grava o nome da variável com no máximo 10 caracteres.

Tem como corrigir essa deficiência do xHarbour?
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por rochinha »

Amiguinho,

A muito tempo não uso arquivos .MEM e seus comandos de manipulação.

Tive a necessidade de gravar informações em arquivos que não .DBF e recorri a funções encontradas em meus livros embolorados.

A tempos faço uso delas e não tenho problema com tamanho dos conteúdos.

Funções:

Código: Selecionar todos

/*
 *
 * *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
 * Descricao: Funcoes para tratamento de arrays
 * *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
 *
 */
Function EK_SAVEARR(Arg1, Arg2, Arg3)        //Arg1=Array, Arg2=archivo, Arg3=doserror
   local Local1:= Fcreate(Arg2), Local2
   Arg3:= Ferror()
   If (Arg3 == 0)
      Local2:= _eksavesub(Arg1, Local1, @Arg3)
      Fclose(Local1)
      If (Local2 .AND. Ferror() != 0)
         Arg3:= Ferror()
         Local2:= .F.
      EndIf
    Else
      Local2:= .F.
   EndIf
   Return Local2

Static Function _EKSAVESUB(Arg1, Arg2, Arg3)
   local Local1, Local2, Local3
   private lret
   lret:= .T.
   Local1:= ValType(Arg1)
   Fwrite(Arg2, Local1, 1)
   If (Ferror() == 0)
     Do Case
      Case Local1 = "A"
         Local2:= Len(Arg1)
         Fwrite(Arg2, L2Bin(Local2), 4)
         If (Ferror() == 0)
           AeVal(Arg1, {|_1| lret:= _eksavesub(_1, Arg2)})
          Else
           lret:= .F.
         EndIf
      Case Local1 = "B"
         lret:= .F.
      Case Local1 = "C"
         Local2:= Len(Arg1)
         Fwrite(Arg2, L2Bin(Local2), 4)
         Fwrite(Arg2, Arg1)
      Case Local1 = "D"
         Local2:= 8
         Fwrite(Arg2, L2Bin(Local2), 4)
         Fwrite(Arg2, DToC(Arg1))
      Case Local1 = "L"
         Local2:= 1
         Fwrite(Arg2, L2Bin(Local2), 4)
         Fwrite(Arg2, iif(Arg1, "T", "F"))
      Case Local1 = "N"
         Local3:= Str(Arg1)
         Local2:= Len(Local3)
         Fwrite(Arg2, L2Bin(Local2), 4)
         Fwrite(Arg2, Local3)
     Endcase
    Else
      lret:= .F.
   Endif
   Arg3:= ferror()
   Return lret

Function EK_RESTARR(Arg1, Arg2)       // Arg1=Archivo, Arg2=doserror
   Local Local1:= Fopen(Arg1), Local2
   Arg2:= Ferror()
   If (Arg2 == 0)
      Local2:= _ekrestsub(Local1, @Arg2)
      FClose(Local1)
    Else
      Local2:= {}
   Endif
   Return Local2

Static Function _EKRESTSUB(Arg1, Arg2)
   local Local1:= " ", Local2, Local3, Local4, Local5, Local6
   Fread(Arg1, @Local1, 1)
   Local3:= Space(4)
   Fread(Arg1, @Local3, 4)
   Local2:= Bin2L(Local3)
   Arg2:= Ferror()
   If (Arg2 == 0)
      Do Case
         Case Local1 = "A"
            Local4:= {}
            For Local6 := 1 To Local2
               AAdd(Local4, _ekrestsub(Arg1))
            Next Local6
         Case Local1 = "C"
            Local4:= Space(Local2)
            Fread(Arg1, @Local4, Local2)
         Case Local1 = "D"
            Local5:= Space(8)
            Fread(Arg1, @Local5, 8)
            Local4:= CToD(Local5)
         Case Local1 = "L"
            Local5:= " "
            Fread(Arg1, @Local5, 1)
            Local4:= Local5 = "T"
         Case Local1 = "N"
            Local5:= Space(Local2)
            Fread(Arg1, @Local5, Local2)
            Local4:= Val(Local5)
      Endcase
         Arg2:= ferror()
   Endif
   Return Local4
Mesmo que o trecho abaixo pareça não tenha nada a ver com o tópico servirá de ajudar para saber como usar:

Código: Selecionar todos

Function ListaOpcoes( _array_, _controle_, _sarray_ )
   local oTBLDlg, oTBLLbx, cTBLDlg := _array_[1], lSave := .f.
   DEFINE DIALOG oTBLDlg RESOURCE "dlgTBLAux"
          REDEFINE LISTBOX oTBLLbx VAR cTBLDlg ITEMS _array_ ID 101 OF oTBLDlg 
                   oTBLLbx:bLdblClick := {|nRow,nCol|( lSave:=.t., oTBLDlg:end() )}
          REDEFINE BUTTON ID 5 OF oTBLDlg ACTION ( lSave:=.t., oTBLDlg:end() )
          REDEFINE BUTTON ID 4 OF oTBLDlg ACTION ( lSave:=.f., oTBLDlg:end() )
          REDEFINE BUTTON ID 3 OF oTBLDlg ACTION ( AddOpcoes( _array_, _sarray_ ), ;
                                                   oTBLLbx:Reset() , ;
                                                   oTBLLbx:SetItems(_array_) , ;
                                                   oTBLLbx:Refresh() )
          // MODIFICAR REDEFINE BUTTON ID 2 OF oTBLDlg ACTION fun()
          REDEFINE BUTTON ID 6 OF oTBLDlg ACTION ( nExcluir:=oTBLLbx:GetPos(), ;
                                                   iif( DelOpcoes( _array_, _sarray_, nExcluir ), ;
                                                        ( oTBLLbx:Reset() , ; // ( oTBLLbx:Del(nExcluir) , ;
                                                          oTBLLbx:SetItems(_array_) , ;
                                                          oTBLLbx:Refresh() ), .t. ) )
   ACTIVATE DIALOG oTBLDlg CENTERED VALID ( oTBLDlg := nil, .t.  )
   if lSave
      _controle_:cText(cTBLDlg+SPACE(80))
      _controle_:Refresh()
   endif
   return nil

Function AddOpcoes( _array_, _sarray_ )
   local lSave := .f., cArrData := SPACE(25)
   SET _3DLOOK ON
   DEFINE FONT fntHelv2     NAME "Helv"          SIZE  6, 6
   DEFINE DIALOG oDlg RESOURCE "dlgEstCTab" TITLE "Preferencia" FONT fntHelv2
          REDEFINE SAY oCtrl100 PROMPT "Preferencia" ID 100 OF oDlg
          REDEFINE GET oCtrl101 VAR cArrData PICTURE "@!" ID 101 OF oDlg
          REDEFINE BUTTON ID 1 OF oDlg ACTION ( lSave:=.t., oDlg:end() )
          REDEFINE BUTTON ID 2 OF oDlg ACTION ( lSave:=.f., oDlg:end() )
   ACTIVATE DIALOG oDlg CENTERED
   if lSave
      aLenArray:=len(_array_)
      ASize(_array_, aLenArray+1 )
      AIns(_array_, aLenArray+1 )
      _array_[aLenArray+1] := cArrData
      EK_SAVEARR( ASort(_array_), _sarray_ )
   endif
   return nil

Function DelOpcoes( _array_, _sarray_, _posicao_ )
   if MsgYesNo( 'Excluir '+_array_[_posicao_] )
      aLenArray:=len(_array_)
      ADel( _array_, _posicao_ )
      ASize(_array_, aLenArray-1 )
      EK_SAVEARR( _array_, _sarray_ )
      return .t.
   else
      return .f.
   endif
Como eu uso em meus sistemas?

Primeiro eu verifico se meu arquivo Array existe na pasta do sistema:

Código: Selecionar todos

...
public aHistos  := EK_RESTARR( "histos.arr" )
...
Em um de meus GETs, simulo combos e passo as variáveis:

Código: Selecionar todos

...
VALID ListaOpcoes( aHistos, oGet109, "histos.arr" )
...
Use o segundo parâmetro, se for o caso para passar a variável do GET e refrescar seu conteúdo.

Minha função ListaOpções se encarrega de mostrar em um browse, as informações salvas e alguns botões/funções me permitem incluir, excluir, etc.

Analise com cuidado o código e implemente em sua aplicação.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
alxsts
Colaborador
Colaborador
Mensagens: 3092
Registrado em: 12 Ago 2008 15:50
Localização: São Paulo-SP-Brasil

Re: Tamanho das variáveis nos .MEM

Mensagem por alxsts »

Olá!

Clodoaldo:
na inguagem Clipper, embora seja possível a declaração de nomes de variáveis, procedures e functions com mais de dez caracteres (o compilador não gera erro), apenas os dez caracteres iniciais são considerados. Assim, a variável declarada com o nome DrvAutoHelp consta na tabela de símbolos como DrvAutoHel. O limite para nomes de campos em um DBF é o mesmo.

Certamente o [x]Harbour seguiu este mesmo caminho.
[]´s
Alexandre Santos (AlxSts)
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por clodoaldomonteiro »

Pessoal!

Fiz o seguinte teste no xHarbour:

Código: Selecionar todos

   v1234567890:='clodoaldo'
   v12345678901:='monteiro'
   v1234567890123453456789:='de'
   ? v1234567890, v12345678901, v1234567890123453456789
   wait
   retu
O resultado foi:
clodoaldo monteiro de
Então, com certeza o harbour reconhece mais de 15 caracteres no nomes da variáveis.
Vejam que o radical das variáveis é o mesmo, mas ainda assim o harbour diferenciou elas.

Agora, se eu usar o comando:

Código: Selecionar todos

SAVE TO (MeuArquivoMem) ALL LIKE V*   // grava configuracoes,
Será gerado um arquivo .mem com três variáveis de nome: "v123456789", cada uma com seu conteúdo diferente.

Ai, quando recuperamos o arquivo .mem o xharbour traz uma única variável com o nome: "v123456789" e o conteúdo da última.

Em anexo está o arquivo .mem
Anexos
arquivo.zip
Teste de arquivo .mem com três variáveis com o mesmo nome.
(173 Bytes) Baixado 95 vezes
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por clodoaldomonteiro »

Encontrei o comando SAVE no arquivo STD.CH, que vem originalmente no clipper 5.3.

Código: Selecionar todos

#command SAVE ALL LIKE <skel> TO <(file)>                               ;
      => __MSave( <(file)>, <(skel)>, .t. )

#command SAVE TO <(file)> ALL LIKE <skel>                               ;
      => __MSave( <(file)>, <(skel)>, .t. )

#command SAVE ALL EXCEPT <skel> TO <(file)>                             ;
      => __MSave( <(file)>, <(skel)>, .f. )

#command SAVE TO <(file)> ALL EXCEPT <skel>                             ;
      => __MSave( <(file)>, <(skel)>, .f. )

#command SAVE [TO <(file)>] [ALL]                                       ;
      => __MSave( <(file)>, "*", .t. )


No xHarbour tá assim:

Código: Selecionar todos

#command SAVE TO <(f)> [<b:EXTENDED>]   ALL LIKE <(p)>     => __MVSave( <(f)>, <(p)>, .t. ,<.b.>)
#command SAVE ALL LIKE <(p)> TO <(f)>   [<b:EXTENDED>]   => __MVSave( <(f)>, <(p)>, .t. ,<.b.>)
#command SAVE ALL EXCEPT <(p)> TO <(f)> [<b:EXTENDED>]  => __MVSave( <(f)>, <(p)>, .f. ,<.b.>)
#command SAVE TO <(f)> [<b:EXTENDED>]  ALL EXCEPT <(p)>   => __MVSave( <(f)>, <(p)>, .f. ,<.b.>)
#command SAVE [TO <(f)>] [ALL]      [<b:EXTENDED>]    => __MVSave( <(f)>, "*", .t. ,<.b.>)
Vi que nesse arquivo tem vários comandos que usamos corriqueiramento quando estamos programando.

Vocês acham que teríamos como alterar esses comandos?
Pois vejam que o comando SAVE chama a FUNÇÂO __MSave(), mas onde posso editar ela?
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por sygecom »

Você encontra nos fontes do xHarbour, isso que você procura esta em:
\xHarbour\source\vm\memvars.c
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por clodoaldomonteiro »

Leonardo!

Eu não tenho essa pasta, mas pela lógica, depois de editar e midificar esse arquivo, teria que compilar novamente?
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Avatar do usuário
Maligno
Membro Master
Membro Master
Mensagens: 6398
Registrado em: 06 Jul 2004 01:40
Localização: Londrina/PR

Re: Tamanho das variáveis nos .MEM

Mensagem por Maligno »

Ao que parece pelos relatos das suas experiências com .MEM, imagino que os autores (conscientemente ou não) limitaram o tamanho dos símbolos em 10 caracteres. Com os fontes do [x]Harbour, você até pode modificar isso, mas terá de recompilar o [x]Harbour, para obter o "SEU" compilador. E isso terá de ser refeito todas as vezes em que trocar de versão, até que um dia alguém do time de desenvolvimento resolva acabar com essa limitação. Porque não tenta se comunicar com eles e requisitar essa modificação?

Note um detalhe interessante: .MEM é algo meio fora de moda. Se até agora ainda existe essa limitação, pode ser porque ninguém dá bola pra .MEM. Talvez seja interessante começar a pensar em trocar a forma de armazenamento. Particularmente, eu prefiro INI para casos semelhantes.
[]'s
Maligno
---
Não respondo questões técnicas através de MP ou eMail. Não insista.
As dúvidas devem ser postadas no fórum. Desta forma, todos poderão
se beneficiar das respostas.

---
Se um dia precisar de uma transfusão de sangue você perceberá como
é importante a figura do doador. Procure o hemocentro de sua cidade e
se informe sobre a doação de sangue, plaquetas e medula óssea. Doe!
Avatar do usuário
asimoes
Colaborador
Colaborador
Mensagens: 4919
Registrado em: 26 Abr 2007 16:48
Localização: RIO DE JANEIRO-RJ

Re: Tamanho das variáveis nos .MEM

Mensagem por asimoes »

Senhores,

Por esta limitação dos arquivos .mem, o ideal é usar arquivos .ini
►Harbour 3.x | Minigui xx-x | HwGui◄
Pense nas possibilidades abstraia as dificuldades.
Não corrigir nossas falhas é o mesmo que cometer novos erros.
A imaginação é mais importante que o conhecimento. (Albert Einstein)
Avatar do usuário
rochinha
Administrador
Administrador
Mensagens: 4664
Registrado em: 18 Ago 2003 20:43
Localização: São Paulo - Brasil
Contato:

Re: Tamanho das variáveis nos .MEM

Mensagem por rochinha »

Amiguinho Clodoaldo,

Voce esta usando Clipper e quer adaptar as funções do xHarbour? será perda de tempo.

Os .CH do Clipper não são usados pelo xHarbour e voce não precisa adaptar os .CH padrão do xHarbour porque os mesmos já estão compatibilizados.

Utilize a idéia que passei e obterá bons resultados, ou utilize arquivos .INI como o Maligno frisou.

Realmente se o xHarbour é uma evolução do Clipper, se melhoraram o alcance de registros do .DBf e Arrays porque não melhoraram para os Arquivos .MEM? não sei.

Voce fez comparação de variáveis existentes em código e variáveis existentes dentro de um .MEM. Dentro do Código voce pode usar variáveis com tamanho maior, mas nem tanto.
OPS! LINK QUEBRADO? Veja ESTE TOPICO antes e caso não encontre ENVIE seu email com link do tópico para [url=mailto://fivolution@hotmail.com]fivolution@hotmail.com[/url]. Agradecido.

@braços : ? )

A justiça divina tarda mas não falha, enquanto que a justiça dos homens falha porque tarda.
Avatar do usuário
clodoaldomonteiro
Usuário Nível 4
Usuário Nível 4
Mensagens: 821
Registrado em: 30 Dez 2006 13:17
Localização: Teresina-PI
Contato:

Tamanho das variáveis nos .MEM

Mensagem por clodoaldomonteiro »

Depois de um tempinho, voltando aqui pra deixar uma função pra verificar a validade de um Arquivo MEM.
Cada variável salva tem um tamanho fixo de 10 caracteres, sendo que o 11. e 12. são respectivamente NUL e (ÃÌÎ)-uma das três letras.
- para as variáveis tipo String e Data os caracteres NUL e "Ã" indicam o término do nome da variável.
- para as variáveis tipo Número e Data os caracteres NUL e "Ì" indicam o término do nome da variável.
- para as variáveis tipo Lógico e Data os caracteres NUL e "Î" indicam o término do nome da variável.
- no final do arquivo, tem obrigatoriamente dois caracteres, NUL e SUB (valores em HexaDecimal 00 e 0A)
Sendo assim, dá pra com uma simples rotina de ler o arquivo e verificar os caracteres em suas devidas posições, confirmando se é um arquivo válido.

Código: Selecionar todos

Function cl_checaMEM( cFileName )
   Local mRetorno := .t., cTect

   cText := MemoRead( cFileName )

   If !( SubStr( cText, 12, 1) $ 'ÃÌÎ' )
      mRetorno := .f.
   Endif //

   If !(StrToHex(SubStr( cText, Len(cText), 1)) = '00' )
      mRetorno := .f.
   Endif
   
   If !(StrToHex(SubStr( cText, Len(cText)-1, 1)) = '0A')
      mRetorno := .f.
   Endif
   
   cText := NIL
   
   Return mRetorno
Forte abraço...
At. Clodoaldo Monteiro
Linguagens: Clipper / Harbour
Área de Atuação: Sistemas de gestão para Prefeituras Municipais
Fones: (86)3223-0653, 98859-0236
www.simplesinformatica.com.br
Responder