Primeiro capítulo: Structured Data Types (II)
Na primeira entrega deste artigo se apresentou os Structured Data Types (SDT) e sua criação. Nesta segunda parte será detalhado o seu funcionamento e o manejo de coleções com SDT. Por GxOpen Task Force(*)
Funcionamento de um SDT
Antes de
come
Quando nos nossos programas declaramos uma variável, reservamos um lugar na memória e ao designá-la, o conteúdo desta é copiado para outro lugar na memória correspondente a outra variável ou estrutura.
Exemplo:
Variáveis:
&a do tipo "Numeric(5)".
&b do tipo "Numeric(5)".
Source:
&a = 1
&b = &a
&a = 2
msg(str(&a))
msg(str(&b))
A execução deste pequeno código, nos ativará uma mensagem com o valor 2 e outro com o valor 1. É muito simples, mas já verão que é bastante diferente trabalhar com SDT.
Observemos o seguinte exemplo utilizando o SDT "sdtCliente" definido no capítulo anterior e detalhado no final deste:
Variáveis:
&Cli1 do tipo "sdtCliente".
&Cli2 do tipo "sdtCliente".
Source:
&Cli1.CliNom = "Daniel"
&Cli2 = &Cli1
&Cli1.CliNom = "Marcelo"
msg(&Cli1.CliNom)
msg(&Cli2.CliNom)
Observe que é um exemplo muito parecido ao anterior, mas com a diferença de que este ativará nas duas mensagens "Marcelo".
Neste momento estará se perguntando: "Como é que funciona?"
Já mencionamos que quando são designadas variáveis se copia o conteúdo da memória de um lugar para outro, mas quando designamos um SDT a outro, estamos designando uma referência ou ponteiro.
Na seguinte imagem vemos que quando definimos as duas variáveis (&Cli1 y &Cli2), é criada em algum lugar da memória uma estrutura com toda a informação do SDT e -> variável lhe é designada o endereço de memória para dita estrutura.

Ao designar a variável &Cli1 a &Cli2, estamos designando a &Cli2 o endereço para a estrutura de &Cli1. Vejamos graficamente:

Daqui é que quando se designa um valor a um atributo de &Cli1, também se estará designando a &Cli2, já que é uma referência -> mesma estrutura.
Isto nos altera um pouco a forma de pensar em quanto ->s variáveis normais.
Mas: como posso copiar só o conteúdo de um SDT para outro sem designar-lhe o mesmo endereço?
Com o método "Clone()". O método clone cria outra estrutura na memória igual e com os mesmos dados do SDT que se está copiando. Vejamos um exemplo:
&Cli2 = &Cli1.Clone()
Desta maneira estamos trabalhado com estruturas diferentes e quando se designe um valor a um atributo de &Cli1, não nos afetará o conteúdo do SDT &Cli2.
Manejo de Coleções de SDT
Com o que foi dito anteriormente estamos prontos para começar a trabalhar com coleções de SDT.
Podemos realizar isto de duas maneiras:
1- Marcamos o nosso SDT que é uma coleção e definimos um nome para seus itens.

2- Criamos um novo SDT, Ex.: "Clientes" e na coluna DataType selecionamos "sdtCliente". Assim é como os WSDL Inspector obtêm as estruturas para trabalhar com um determinado WebService.

Por ser a Nro. 1 a maneira mais comum de trabalhar com coleções de SDT, realizaremos os seguintes exemplos baseando-nos naquela. Desta maneira o SDT coleção é "sdtCliente" e cada item seria "sdtCliente.Cliente".
Acrescentar objetos em uma coleção.
No seguinte exemplo carregaremos a informação da tabela de clientes em uma coleção.
Ex.:
Variáveis:
&Cliente do tipo "sdtCliente.Cliente".
&Clientes do tipo "sdtCliente".
Source:
for each
&Cliente.CliNom = CliNom
&Cliente.CliSob = "Rmido"
&Cliente.CliEnd = "18 de Julio 1830"
Clientes.Add( &Cliente.Clone() )
endfor
Observe que estamos utilizando o método "Clone()" para acrescentar a mesma referência cada vez que se acrescenta um elemento na coleção já que sempre estaríamos trabalhando com o mesmo elemento.
O código anterior, também pode ser implementado da seguinte maneira, sem usar o método "Clone()".
for each
&Cliente = new sdtCliente.Cliente()
&Cliente.CliNom = CliNom
&Cliente.CliSob = "Rmido"
&Cliente.CliEnd = "18 de Julio 1830"
Clientes.Add( &Cliente )
endfor
Neste exemplo, observamos o uso do operador "new", o qual cria uma nova estrutura na memória e se designa um novo ponteiro para o SDT para não trabalhar com o mesmo que acrescentamos na coleção.
Percorrer uma coleção e obter um SDT
Nas seguintes linhas veremos os diferentes métodos para percorrer uma coleção e obter os SDT que contêm. A seguinte é a forma mais simples de percorrer o conteúdo de uma coleção de SDT.
Variáveis:
&Cliente do tipo "sdtCliente.Cliente".
&Clientes do tipo "sdtCliente".
Source:
Cliente in &Clientes
msg(&Cliente.CliNom)
endfor
Como podem observar o SDT &Cliente é carregado automaticamente em cada iteração e rapidamente podemos trabalhar com o SDT "&Cliente".
A outra maneira é um pouco mais tradicional:
Variáveis:
&i do tipo "Numeric(5)"
&Cliente do tipo "sdtCliente.Cliente".
&Clientes do tipo "sdtCliente".
Source:
i = 1 to &Clientes.Count
&Cliente = &Clientes.Item(&i)
msg(&Cliente.CliNom)
endfor
Esta é a forma clássica de realizar o caminho e obter um SDT. Está implícito que se pode utilizar qualquer outra estrutura de iteração ou obter diretamente um SDT pelo índice si existem elementos na coleção utilizando a propriedade "Count".
Remover SDT de uma coleção.
O seguinte código mostra como remover um elemento de uma coleção de SDT.
Variáveis:
&i do tipo "Numeric(5)"
&Clientes do tipo "sdtCliente".
Source:
Clientes.Count 0
&Clientes.Remove(1)
endif
No exemplo, se checa se existem elementos no SDT. Se existirem elementos, remove-se o primeiro da coleção.
Resumindo, os SDT são para o desenvolvedor GeneXus uma poderosa ferramenta orientada para diminuir o código como a maioria das melhoras nas sucessivas versões. Nestes exemplos vimos um mínimo das possibilidades, mas com estes objetos, poderemos desde exportar nossos dados a XML, até utilizar pequenas bases de dados locais nos nossos sistemas manejando coleções e XML.
Do grupo GxOpen TaskForce, esperamos que estes artigos sejam de utilidade para o leitor e esperamos que nos enviem seus comentários e proponham futuros temas para expor.
GxOpen TaskForce
e-mail: info@gxopen.com