Noticias

Primer capítulo: Structured Data Types (II)

En la primera entrega de este artículo se presentó a los Structured Data Types (SDT) y su creación. En esta segunda parte se detalla su funcionamiento y el manejo de colecciones con SDT. Por GxOpen Task Force(*)

Funcionamiento de un SDT
Antes de comenzar con el tema principal de este segundo capítulo, explicaremos como trabajan los SDT. Para los que han trabajado con objetos les va a ser muy sencillo entender el concepto, pero aún así nos esforzamos en dar una explicación que sea clara para todos.

Cuando en nuestros programas declaramos una variable, reservamos un lugar en memoria y al asignarla, se copia el contenido de está a otro lugar en memoria correspondiente a otra variable o estructura.

Ejemplo:

Variables:
&a del tipo "Numeric(5)".
&b del tipo "Numeric(5)".

Source:
&a = 1
&b = &a
&a = 2
msg(str(&a))
msg(str(&b))

La ejecución de este pequeño código, nos desplegará una mensaje con el valor 2 y otro con el valor 1. Es muy simple pero ya verán que es bastante más diferente trabajar con SDT.

Observemos el siguiente ejemplo utilizando el SDT "sdtCliente" definido en el capitulo anterior y detallado al final de este:

Variables:
&Cli1 del tipo "sdtCliente".
&Cli2 del tipo "sdtCliente".

Source:
&Cli1.CliNom = "Daniel"
&Cli2 = &Cli1
&Cli1.CliNom = "Marcelo"
msg(&Cli1.CliNom)
msg(&Cli2.CliNom)

Obsérvese que es un ejemplo muy parecido al anterior pero con la diferencia que este desplegara en los dos mensajes "Marcelo".

En este momento se estará preguntando "¿cómo es que funciona?".

Ya mencionamos que cuando se asignan variables, se copia el contenido de la memoria de un lugar a otro pero cuando asignamos un SDT a otro, estamos asignando una referencia o puntero.

En la siguiente imagen, vemos que cuando definimos las dos variables (&Cli1 y &Cli2), se crea en algún lugar de la memoria una estructura con toda la información del SDT, y a la variable se le asigna la dirección de memoria a dicha estructura.

Al asignar la variable &Cli1 a &Cli2, estamos asignado a &Cli2 la dirección a la estructura de &Cli1. Veámoslo con gráficamente:

De aquí es que cuando se le asigna un valor a un atributo de &Cli1, también se estará asignando a &Cli2 ya que es una referencia a la misma estructura.

Esto nos cambia un poco la forma de pensar en cuanto a las variables normales.

Pero ¿cómo puedo copiar sólo el contenido de un SDT a otro sin asignarle la misma dirección?:

Con el método "Clone()". El método clone crea otro estructura en memoria igual y con los mismos datos al SDT que se está copiando. Veamos un ejemplo:

&Cli2 = &Cli1.Clone()

De esta manera, estamos trabajando con estructuras diferentes y cuando se asigne un valor a un atributo de &Cli1, no nos afectará el contenido del SDT &Cli2.

Manejo de Colecciones de SDT

Con lo dicho anteriormente estamos listos para comenzar a trabajar con colecciones de SDT.

Esto lo podemos realizar de dos maneras:

1-  Le marcamos a nuestro SDT que es una colección y definimos un nombre para sus ítems.

2- Creamos un nuevo SDT, Ej.: "Clientes" y en la columna DataType seleccionamos "sdtCliente". Así es como los WSDL Inspector obtiene las estructuras para trabajar con un determinado WebService.

Por ser la Nro.1 la manera más común de trabajar con colecciones de SDT, realizaremos los siguientes ejemplos basándonos en aquella. De esta manera el SDT colección es "sdtCliente" y cada item sería "sdtCliente.Cliente".

Agregar objetos a una colección

En el siguiente ejemplo cargaremos la información de la tabla de clientes en una colección.

Ej.:

Variables:
&Cliente del tipo "sdtCliente.Cliente".
&Clientes del tipo "sdtCliente".

Source:
for each
&Cliente.CliNom = CliNom
&Cliente.CliApe = "Rmido"
&Cliente.CliDir = "18 de Julio 1830"
&
&Clientes.Add( &Cliente.Clone() )
endfor

Obsérvese que estamos utilizando el método "Clone()" para no agregar la misma referencia cada vez que se agrega un elemento en la colección ya que siempre estaríamos trabajando con el mismo elemento.

El código anterior, también se puede implementar de la siguiente manera sin usar el método "Clone()".

for each
&Cliente = new sdtCliente.Cliente()
&Cliente.CliNom = CliNom
&Cliente.CliApe = "Rmido"
&Cliente.CliDir = "18 de Julio 1830"
&
&Clientes.Add( &Cliente )
endfor

En este ejemplo, observamos el uso del operador "new", el cual crea una nueva estructura en memoria y se asigna un nuevo puntero al SDT para no trabajar con el mismo que agregamos a la colección.

Recorrer una colección y obtener un SDT

En las siguientes líneas veremos los diferentes métodos para recorrer una colección y obtener los SDT que contiene. La siguiente es la forma más sencilla de recorrer el contenido de una colección de SDT.

Variables:

&Cliente del tipo "sdtCliente.Cliente".

&Clientes del tipo "sdtCliente".

Source:
& // Código para agregar los clientes al SDT

for &Cliente in &Clientes
msg(&Cliente.CliNom)
endfor

Como observarán el SDT &Cliente se carga automáticamente en cada iteración y rápidamente podemos trabajar con el SDT "&Cliente".

La otra manera es un poco más tradicional:

Variables:
&i del tipo "Numeric(5)"
&Cliente del tipo "sdtCliente.Cliente".
&Clientes del tipo "sdtCliente".

Source:
& // Código para agregar los clientes al SDT

for &i = 1 to &Clientes.Count
&Cliente = &Clientes.Item(&i)
msg(&Cliente.CliNom)
endfor

Esta es la forma clásica de realizar la recorrida y obtener un SDT. Está implícito que se puede utilizar cualquier otra estructura de iteración ú obtener directamente un SDT por el índice si hay elementos en la colección utilizando la propiedad "Count".

Remover SDT de una colección
El siguiente código muestra como remover un elemento de una colección de SDT.

Variables:
&i del tipo "Numeric(5)"
&Clientes del tipo "sdtCliente".

Source:
& // Código para agregar los clientes al SDT

if &Clientes.Count > 0
&Clientes.Remove(1)
endif

En el ejemplo, se chequea si hay elementos en el SDT. Si hay elementos, se remueve el primero de la colección.

En síntesis, los SDT son para el desarrollador GeneXus, una muy poderosa herramienta orientada a disminuir código como la mayoría de las mejoras en las sucesivas versiones. En estos ejemplos vimos un mínimo de las posibilidades, pero con estos objetos, podremos desde exportar nuestros datos a XML, hasta utilizar en nuestros sistemas pequeñas bases de datos locales manejando colecciones y XML.

Desde el grupo GxOpen TaskForce, esperamos que estos artículos  sean de utilidad para el lector y esperamos nos envíen sus comentarios y propongan futuros temas a exponer.

GxOpen TaskForce 
e-mail: info@gxopen.com