salvar array

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

Moderador: Moderadores

MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

salvar array

Mensagem por MARCELOG »

Olá pessoal,
em meus sistemas guardo informações num campo com formato xml.
Assim, uso a contribuição da xhb para trabalhar com o mesmo.
Entretanto, de acordo com informações do forum, a contrib xhb do harbour não será continuada/ atualizada, podendo, no futuro, determinar incompatibilidade.
Assim, estou antecipando soluções para adequar o sistema e não utilizar as contribuições da xhb.
Nesse contexto, pensei em armazenar no lugar do xml um array.
Assim, deparei-me com as funções não documentadas ctoa() e atoc().
Ao que parece, elas resolvem meu problema, pois o texto a ser armazenado não terá tamanho superior a 64k.
Todavia, elas fazem menção às funções CHAR() e VALUE(), que não conheço, gerando um erro na compilação.
Talvez alguém possa me ajudar indicando as correspondentesdo harbour, se existentes.
Seguem abaixo o conteúdo das funções e link para localização:

FUNCTION AToC( aArray )
LOCAL i, nLen := Len( aArray )
LOCAL cType, cElement, cArray := ""
FOR i := 1 TO nLen
cElement := Char( aArray[ i ] )
IF ( cType := ValType( aArray[ i ] ) ) == "A"
cArray += cElement
ELSE
cArray += Left( cType, 1) + I2Bin( Len( cElement ) ) + cElement
ENDIF
ENDFOR
RETURN "A" + I2Bin( Len( cArray ) ) + cArray

FUNCTION CToA( cArray )
LOCAL cType, nLen, aArray := {}
cArray := SubStr( cArray, 4 ) // strip off array and length
WHILE Len( cArray ) > 0
nLen := Bin2I( SubStr( cArray, 2, 2 ) )
IF ( cType := Left( cArray, 1 ) ) == "A"
AAdd( aArray, CToA( SubStr( cArray, 1, nLen + 3 ) ) )
ELSE
AAdd( aArray, Value( SubStr( cArray, 4, nLen ), cType ) )
ENDIF
cArray := SubStr( cArray, 4 + nLen )
END
RETURN aArray

https://www.google.com.br/url?sa=t&rct= ... mghBtoIztC

Atenciosamente.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
MARCELOG
Usuário Nível 4
Usuário Nível 4
Mensagens: 546
Registrado em: 15 Mar 2005 16:54
Localização: Divinópolis/MG

salvar array

Mensagem por MARCELOG »

Se o link falhar digite "ctoa atoc harbour" no google.

MarceloG
Água mole em pedra dura tanto bate que até espirra!
Avatar do usuário
JoséQuintas
Administrador
Administrador
Mensagens: 20267
Registrado em: 26 Fev 2007 11:59
Localização: São Paulo-SP

salvar array

Mensagem por JoséQuintas »

em meus sistemas guardo informações num campo com formato xml.
Assim, uso a contribuição da xhb para trabalhar com o mesmo.
Se os fontes são em PRG, é só copiar para seu aplicativo e pronto, mesmo que retirem, seu aplicativo vai ter.
E mesmo que retirem, ainda tem a opção de "devolver", então não porque complicar.
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
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

salvar array

Mensagem por Jairo Maia »

Olá Pessoal,

Não entendi direito qual é a idéia, mas quanto a salvar Array você pode usar as funções nativas do Harbour:

Código: Selecionar todos

cVar := Hb_Serialize( aVar )        // transforma um array em string
aVar := Hb_DeSerialize( cVar )      // transforma a string gerada pela função acima novamente em array
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)
rossine
Usuário Nível 3
Usuário Nível 3
Mensagens: 325
Registrado em: 06 Ago 2007 09:57
Localização: Divinópolis-MG

salvar array

Mensagem por rossine »

Olá,

Montei um exemplo para salvar/restaurar variáveis do tipo "Array" e "Hash"

Código: Selecionar todos

function main

local aMultiDimentional, aArray1, aArray2, h, cSerialized, cDocument, cIntermediateryFile

set date       to BRITISH
set epoch      to 2000
set century    ON

cls

aMultiDimentional := { 1, "A", date(), .T., NIL, { "A1", { "Aa1", "Aa2" } } }

? "Array original"
? hb_valtoexp( aMultiDimentional )

cDocument := hb_jsonEncode( aMultiDimentional, .T. )

cIntermediateryFile := "gravarr.txt"

? ""
? "Gravando Array em arquivo"
? ""

hb_memoWrit( cIntermediateryFile, cDocument )

aMultiDimentional := hb_jsonDecode( hb_memoRead( cIntermediateryFile ) )

? "Retornando array gravada no arquivo. Tipo=" + valtype(aMultiDimentional)
? hb_valtoexp( aMultiDimentional )

? ""
? "------------------------------------------"
? ""

aArray1 := { 1, 2, 3 }
aArray2 := { "A", "B", "C" }

h       := { "aArray1" => aArray1, "aArray2" => aArray2 }

? "Hash original"
? hb_valtoexp( h )

cSerialized := hb_Serialize( h )

? ""
? "Gravando Hash em arquivo"
? ""

hb_memoWrit( "gravhash.txt", cSerialized )

h := hb_Deserialize( hb_memoRead( "gravahash.txt" ) )

if hb_isHash( h )
   ? "Retornando Hash gravado arquivo. tipo=" + valtype(h)
   ? hb_valtoexp(h)
else
   ? "Erro no retorno da variavel"
endif

return NIL

T+
Rossine.

Harbour 3.4, MingW / Msvc, QT, Qt5xhb, GtQtc, DbfCdx, MySql/MariaDB.
Avatar do usuário
JAIR RANGEL
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 19 Jul 2005 16:01
Localização: RIO DE JANEIRO
Contato:

salvar array

Mensagem por JAIR RANGEL »

Boa tarde!

Estou testando o banco de dados Postgresql.
Então criei, via programa, uma tabela e inseri um registro. Até ai tudo bem.
No entanto, ao ler este registro, utilizo uma função que o retorno vem dentro de um Array(): aTable:=pgSelectQuery(oServer,cQuery)
Em seguida uso a função HB_Serialize(aTable[1]) para converter o Tipo do dado, que vem como "A" Array para "C" String...

Após exibir a variável já convertida, o conteúdo exibido aparece uns caracteres estranhos a esquerda da String. A informação é convertida para o tipo de dado "C", mas esses caracteres a esquerda da String não tem significado algum.... ao menos é o que vejo.

Quando uso a função de conversão ATOC(), os caracteres de controle a esquerda da String ficam da seguinte forma: "A 24C 19LEGNA TECH SISTEMAS"
Essa parte "A 24C 19" não entendo de onde vem...

Obs: Se eu exibir a informação sem fazer a conversão, o conteúdo da var fica normal: "LEGNA TECH SISTEMAS" - Mas, não posso usar a var, pois ao carregar para um campo no Form, ocorre erro, pois o tipo de dado não é "C" String, e sim "A" Array.

Vocês, nobres colegas de ofício, teriam uma ideia do que pode estar ocorrendo?

Desde já, um muito obrigado e forte abraço!
MINIGUI + HARBOUR + BRMAKE + CDX
CLIPPER 5.2E + VISUALLIB 2 + BLINKER
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

salvar array

Mensagem por Jairo Maia »

Olá Jair,

Use Hb_ValToStr(). Exemplo:

Código: Selecionar todos

Function Main()

 Local aArray, xVar1, xVar2
 
 Clear Screen
 
 aArray := { "LEGNA TECH SISTEMAS 1", "LEGNA TECH SISTEMAS 2" }  // unidimensional
 
 ? Hb_ValToStr( aArray[1] )  // retorna: LEGNA TECH SISTEMAS 1
 ? Hb_ValToStr( aArray[2] )  // retorna: LEGNA TECH SISTEMAS 2

 aArray := { { "LEGNA TECH SISTEMAS 3", "LEGNA TECH SISTEMAS 4" } }  // bidimensional
 
 ?
 ? Hb_ValToStr( aArray[1,1] )  // retorna: LEGNA TECH SISTEMAS 3
 ? Hb_ValToStr( aArray[1,2] )  // retorna: LEGNA TECH SISTEMAS 4
 
 //Por outro lado, é o mesmo que fazer:
 xVar1 := aArray[1,1]
 xVar2 := aArray[1,2]
 ?
 ? xVar1  // retorna: LEGNA TECH SISTEMAS 3
 ? xVar2  // retorna: LEGNA TECH SISTEMAS 4

Return Nil
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
JAIR RANGEL
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 19 Jul 2005 16:01
Localização: RIO DE JANEIRO
Contato:

salvar array

Mensagem por JAIR RANGEL »

Olá, Jairo!

Após utilizar a hb_ValTOStr(), o tipo da xVar realmente muda para "C" String
No entanto, ao exibir a xVar, o valor fica em branco, ou seja, parece que a conversão não acontece...

Quando faço xVar:=Array[1] --> O Valor fica normal, exatamente como gravado, mas o tipo da xVar continua como "A" Array, onde acontece o problema ao carregar a xVar no Form.

Ou seja, este exemplo não está funcionando aqui:

Código: Selecionar todos

//Por outro lado, é o mesmo que fazer:
19	 xVar1 := aArray[1,1]
20	 xVar2 := aArray[1,2]
21	 ?
22	 ? xVar1  // retorna: LEGNA TECH SISTEMAS 3
23	 ? xVar2  // retorna: LEGNA TECH SISTEMAS 4
Parece que alguma coisa está bloqueando essa conversão do tipo "A" Array para "C" String.

Segue o trecho do código onde faço a leitura do registro e trato o Array retornado:

Código: Selecionar todos

cQuery := "SELECT x_texto FROM letr1x WHERE x_cod='NOMEMP';"  // Carrega Nome Empresa
aQuery := pgSelectQuery(oServer, cQuery)

//xNomEmp:=ALLTRIM(HB_Serialize(aQuery[1])) // Transform um Array() em String
//xNomEmp:=aQuery[1]
//xNomEmp:=ALLTRIM(ATOC(xNomEmp))           // Transform um Array() em String


xNomEmp:=aQuery[1]
MSGINFO(xNomEmp)                            // Exibe a Variável
MSGINFO( VALTYPE(xNomEmp) )                 // Exibe o Tipo da Variável


xNomEmp:=HB_VALTOSTR(aQuery[1])                // Transform um Array() em String

MSGINFO( VALTYPE(xNomEmp) )                 // Exibe o Tipo da Variável

MSGINFO(xNomEmp)                            // Exibe a Variável
MINIGUI + HARBOUR + BRMAKE + CDX
CLIPPER 5.2E + VISUALLIB 2 + BLINKER
Avatar do usuário
Jairo Maia
Moderador
Moderador
Mensagens: 2785
Registrado em: 16 Ago 2010 13:46
Localização: Campinas-SP

salvar array

Mensagem por Jairo Maia »

Olá Jair,

Se você fizer xNomEmp:=aQuery[1] ela continuará sendo tipo "A" porque a matriz aQuery é bidimensional, ou seja, você pegou o elemento 1 da matriz, e agora é um elemento unidimensional.

Teste:

Código: Selecionar todos

xNomEmp:=aQuery[1]

? ValType( xNomEmp )  // retorna "A"...

For x=1 To Len( xNomEmp )
 ? ValType( xNomEmp[x] )  // retorna o tipo de dado do elemento...
 ? xNomEmp[x]
Next
Veja que a matriz tem mais elementos, apenas segregou o elemento 1. Se nome da empresa está na posição 3 por exemplo, então basta fazer:

Código: Selecionar todos

xNomEmp := aQuery[3]
 ? ValType( xNomEmp )  // retorna "C", pois tem o nome da empresa...
Ou pegar esse contúdo direto na primeira etapa, quando ainda a matriz é multidimensional. Exemplo:

Código: Selecionar todos

xNomEmp:=aQuery[1,3]
 ? ValType( xNomEmp )  // retorna "C", pois pegou direto o elemento que tem o nome da empresa...
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
JAIR RANGEL
Usuário Nível 3
Usuário Nível 3
Mensagens: 178
Registrado em: 19 Jul 2005 16:01
Localização: RIO DE JANEIRO
Contato:

salvar array

Mensagem por JAIR RANGEL »

Olá, Jairo!

Enfim, consegui enxergar o que estava na frente dos meus olhos e não via.

Como o retorno da Query é apenas um campo, eu coloquei na cabeça que poderia acessar o Array desse jeito:
xNomEmp:=aTable[1]
Mero engano! Mesmo que o Array retorne com um campo apenas, ele ainda é um Array multidimensional. Então, o acesso deve ser sempre assim:
xNomEmp:=aTable[1,1]

Problema resolvido!
Vamos em frente!

Obrigado pela atenção de todos!

:xau
MINIGUI + HARBOUR + BRMAKE + CDX
CLIPPER 5.2E + VISUALLIB 2 + BLINKER
Responder