First Chapter: Structured Data Types
This is the first of a series of articles that describe the various features of GeneXus, in particular version 9.0, and other topics such as configuration and implementation in different production environments. By GxOpen Task Force(*)
The purpose of these articles is to help both those who
are new in the use of the tool and those who have used it for quite a while but
do not have enough time to test the new functionalities and at the same time
eliminate the various obstacles you are faced with when using the tool or when
taking your projects to different production environments.
Through this
effort we seek to receive comments and suggestions of topics of interest for the
community in order to gain understanding of the powerful GeneXus
tool.
Today's article provides a simple, clear and concise explanation of
Structured Data Types (SDT). In the first part, the basic operation of SDTs is
shown and in the second part, there is a detailed description of the work with
SDT collections.
What is SDT?
SDT is the definition
of a customized structure. When you need to use this structure in a GeneXus
object, you may define a variable with the required SDT type. This means the SDT
resides in the memory.
SDTs operate like objects in other
languages.
If, for example, you were in C#, the SDT definition would be
the "Class", while when using it you would be working with the class instance.
It is worth mentioning that the most
significant difference between SDTs and objects is that SDTs do not have their
own functionality. It is not possible to define methods, among other more subtle
differences.
Let's say we have the "PCliAdd" process with the following
code:
Rules:
parm( in:CliNom, in:CliApe, in:CliDir, in:CliTel,
in:CliCiu, in:CliPais, in:CliCP);
Source:
new
CliId =
PGetNumber.Udp("CLI")
endnew
From any customer addition process you
would call the previous process as follows:
PCliAdd.Call( "Aldo", "Rmido", "18 de Julio 1830", "4136260",
"Montevideo", "Uruguay", 11200)
With an SDT, it would be solved in the
following way:
&Cliente.CliNom = "Aldo"
&Cliente.CliApe =
"Rmido"
&Cliente.CliDir = "18 de Julio 1830"
&Cliente.CliTel =
"4136260"
&Cliente.CliCiu = "Montevideo"
&Cliente.CliPais =
"Uruguay"
&Cliente.CliCP =
11200
PCliAdd.Call(sdtCliente)
Accordingly, the procedure "PCliAdd"
would change as follows:
Rules:
parm(
in:&Cliente);
Source:
new
CliId =
PGetNumber.Udp("CLI")
CliNom = &Cliente.CliNom
CliApe =
&Cliente.CliApe
Elidir = &Cliente.CliDir
CliTel =
&Cliente.CliTel
CliCiu = &Cliente.CliCiu
CliPais =
&Cliente.CliPais
CliCP = &Cliente.CliCP
endnew
As you see
with the SDT the call to the "PCliAdd" procedure is highly simplified and you
can view the information of the parameters you are loading, and therefore the
call is not as confusing as the previous one.
Likewise, when you need
new parameters in your process, you do not need to modify the "parm" rule;
instead, you modify the SDT instead. This is an added value because it allows
managing "optional parameters".
With this example, we intend to show its
use in processes with large quantity of parameters, which sometimes confuse the
code.
Creating your first
SDT
Creating an SDT is very simple, and to continue with the
previous examples, we will use the example of the "sdtCliente".
1) Go to
"Object/New Object" menu option.
2) Select "Structured Data Type" and
write "sdtCliente" in the name. You may also write a description if you
want.

3) At this point, you create the attributes as if you were in a
transaction. You may add a new field by pressing enter and indicating your data
type.
Of course, you may also base those attributes on
domains defined in your KB.
E.g.: CliNom - Character(32).

To speed up the insertion of attributes in the SDT, you have
the option of selecting attributes directly ("Insert Atributes...") from the
"contextual menu" of the SDT (right button) or copying the structure directly
from a transaction ("Copy structure from...").
Implementing your
SDT
In order to use the SDT you have previously created, you
must create an "sdtCliente" type variable in a GeneXus functional object
(Transaction, Procedure, Report, etc.).
To access the SDT attributes you
must use the ".". A very clear example of this is presented in the first part of
our article.
For example, if you define the variable "&Cliente" of
the "sdtCliente" type and you want to access the name attribute you will do it
as follows:
&Cliente.CliNom =
"Jose"
msg(&Cliente.CliNom)
Import and Export to XML
A very
interesting SDT feature is the possibility of exporting them from and importing
them to XML format.
You may see an example of their use in the web
environment. Let's say you have a security SDT with the following
structure:
sdtSession
+UsrLogin - Character(20)
+UsrHorIni -
DateTime
Using SDT toXML function, you may save the result in a cookie
and when you need to perform a security check, you may obtain the SDT again from
the cookie using the XML function.
Example:
Login
procedure
Variables:
&Session of the type
"sdtSession".
&Error of the type "Numeric(5)".
Rules:
parm(
in:&UsrLogin, in:&UsrPass);
Source
Error =
SetCookie(SESSION, &Session.ToXml())
Procedure to obtain the
SDT of the web user
Variables:
&Session of the type
"sdtSession".
&Error of the type "Numeric(5)".
Rules:
parm(
out:&UsrLogin);
Source
// Save the SDT XML in the "SESSION"
cookie
&Session.FromXml(getCookie("SESSION))
Here, we are showing
a very simple use of the functions for handling XML with SDT but there are
several uses for them, either to import/export data from our systems or to work
with small auxiliary databases in this format.
Interesting
Links
SDTonForm - http://wiki.gxtechnical.com/wiki/tiki-index.php?page=SDTonForm
GxOpen Task Force (*)
For those of you who do not know us,
GxOpen Task Force is a group of people dedicated to the GeneXus community. Among
other activities we are responsible for maintaining the
e-mail: info@gxopen.com
GxOpen TaskForce
We believe in GeneXus