Sie sind auf Seite 1von 409

Introduo Terica

Ferramentas e Metodologias

Nossa tarefa como profissionais de informtica consiste em desenvolver e manter aplicaes para apoiar ao usurio na sua atividade. Para realizar esta tarefa existem diferentes ferramentas e metodologias. GeneXus uma ferramenta para o desenvolvimento de aplicaes sobre bases de dados. Seu objetivo permitir a implantao de aplicaes no menor tempo e com a melhor qualidade possvel. Em linhas gerais, o desenvolvimento de uma aplicao implica tarefas de anlise, desenho e implementao. A maneira do GeneXus alcanar o objetivo anterior liberar as pessoas das tarefas automatizveis (como o desenho da base de dados), permitindo assim se concentrar nas tarefas realmente difceis e no automatizveis (como compreender os problemas do usurio). GeneXus emprega uma metodologia que tem um enfoque muito diferente das metodologias mais utilizadas. Aprender a utilizar GeneXus adequadamente vai alm de conhecer uma nova linguagem: o mais importante aprender sua metodologia.

Modelo da realidade
A partir das vises dos usurios

Satisfaz
MODELO DA REALIDADE

Engenharia Reversa

BASE DE DADOS

PROGRAMAS

VISES DE USURIOS

O primeiro problema enfrentado no desenvolvimento de aplicaes a obteno do conhecimento da realidade. Ningum dentro da empresa conhece os requerimentos e o alcance da aplicao para desenvolver toda a aplicao. Ento, como fazer para obter o conhecimento da realidade de uma forma suficientemente objetiva e detalhada ao mesmo tempo, que nos permita construir um modelo corporativo? Este conhecimento se encontra em cada uma das vises dos usurios. Cada usurio conhece bem os objetos que trabalha cotidianamente, a informao que ele gerencia, as regras que devem ser seguidas, os clculos que devem ser realizados. O ponto de partida da metodologia GeneXus : descrever as vises dos usurios para modelar o sistema; e a partir da definio da realidade do modelo, o GeneXus constri o suporte computacional - base de dados e programas - de forma totalmente automtica.

Desenvolvimento com GeneXus

REALIDADE
DESCRIO DE OBJETOS

Utilizando GeneXus, a tarefa bsica do analista a descrio da realidade. Somente o homem pode desenvolver esta tarefa, j que s ele pode entender o problema do usurio. O analista GeneXus trabalha em alto nvel, em vez de realizar tarefas de baixo nvel como: desenhar arquivos, normalizar, desenhar programas, programar, buscar e eliminar os erros dos programas. Para comear o desenvolvimento de uma aplicao com GeneXus, primeiramente deve ser criado um novo projeto ou base de conhecimento. Uma vez criada uma nova base de conhecimento (em ingls : knowledge base; abreviado: KB), o seguinte passo descrever as vises dos usurios. Para isso, os objetos da realidade (prestando ateno aos substantivos que os usurios mencionam em suas descries, como por exemplo: clientes, produtos, faturas) e passar a defini-los mediante objetos GeneXus. Com a definio destes objetos, o GeneXus pode extrair o conhecimento, desenhar a base de dados e os programas da aplicao em forma totalmente automtica.

Desenvolvimento com GeneXus

REALIDADE
DESCRIO DE OBJETOS

BASE DE CONHECIMENTO

Utilizando GeneXus, a tarefa bsica do analista a descrio da realidade. Somente o homem pode desenvolver esta tarefa, j que s ele pode entender o problema do usurio. O analista GeneXus trabalha em alto nvel, em vez de realizar tarefas de baixo nvel como: desenhar arquivos, normalizar, desenhar programas, programar, buscar e eliminar os erros dos programas. Para comear o desenvolvimento de uma aplicao com GeneXus, primeiramente deve ser criado um novo projeto ou base de conhecimento. Uma vez criada uma nova base de conhecimento (em ingls : knowledge base; abreviado: KB), o passo seguinte descrever as vises dos usurios. Para isso, os objetos da realidade (prestando ateno aos substantivos que os usurios mencionam em suas descries, como por exemplo: clientes, produtos, faturas) e passar a defini-los mediante objetos GeneXus. Com a definio destes objetos, o GeneXus pode extrair o conhecimento, desenhar a base de dados e os programas da aplicao em forma totalmente automtica.

Desenvolvimento com GeneXus


REALIDADE

DESCRIO DE OBJETOS

BASE DE DADOS

BASE DE CONHECIMENTO

PROGRAMAS

A partir dos objetos definidos na base de conhecimento, GeneXus gera automaticamente tanto os programas de criao/reorganizao da base de dados como os programas da aplicao. Depois, se um objeto da realidade muda, so identificadas as novas ou diferentes caractersticas acerca do mesmo, ou encontrando objetos ainda no modelados. O analista GeneXus deve refletir sobre as mudanas correspondentes nos objetos GeneXus e a ferramenta se encarrega automaticamente de realizar as modificaes necessrias tanto na base de dados como nos programas associados. A metodologia GeneXus uma metodologia incremental, pois, parte da base da construo de um sistema mediante realizaes sucessivas. Em cada momento, o analista GeneXus define o conhecimento que tem e assim que passa a ter mais conhecimento (ou simplesmente um conhecimento diferente), reflete na base de conhecimento, e o GeneXus se ocupa de fazer automaticamente todas as adaptaes na base de dados e nos programas. Se GeneXus no for capaz de realizar automaticamente as modificaes na base de dados e nos programas, conforme sejam realizadas as mudanas que assim o requerem, o desenvolvimento incremental seria invivel

Alguns objetos GeneXus

Transaes
(Trns)

Procedimentos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

e tem mais, que veremos...

Uma vez criada uma nova base de conhecimento, o passo seguinte consiste em comear a descrever os objetos da realidade mediante objetos GeneXus. Os objetos GeneXus mais importantes so: Transaes Permite definir os objetos da realidade que o usurio manipula (ex: clientes, produtos, fornecedores, faturas, etc.). So os primeiros objetos definidos, j que atravs das transaes, GeneXus infere o desenho da base de dados. Alm de ter por objetivo a definio da realidade e a conseqente criao da base de dados normalizada, cada transao tem associada uma janela para ambiente windows e outro para ambiente Web, para permitir ao usurio inserir, eliminar e modificar de forma interativa a base de dados. O analista GeneXus decidir se trabalha em ambiente windows, Web, ou ambos, e GeneXus gera os programas para isso. Procedimentos Permitem recuperar informao da base de dados, e ser mostrada na tela, em um arquivo ou impressa em papel. So as tpicas listagens ou relatrios. Alm disso, permitem atualizar informao da base de dados. Data Providers Permitem carregar e devolver dados hierrquicos para troca de informao entre objetos da mesma aplicao ou de outras aplicaes. Web Panels Permite ao usurio realizar interativamente consultas na base de dados, atravs de uma janela. Exemplo: uma web panel permite ao usurio ingressar uma faixa de caracteres, e mostra todos os clientes cujos nomes se encontram dentro dessafaixa. So objetos muito flexveis que podem ser usados para mltiplos usos. No permitem a atualizao da base de dados, somente consult-los.

Processo de desenvolvimento de uma aplicao com GeneXus


Transaes
(Trns)

Procedimentos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base de Conhecimento Base de Conhecimento

Base de Dados

Os primeiros objetos definidos so as transaes, j que a partir delas que o GeneXus extrai o conhecimento necessrio para desenhar o modelo de dados normalizado (em 3. forma normal). Depois vo se definindo os demais objetos que correspondam

Criao da Base de Dados


Transaes
(Trns)

Procedimentos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base de Conhecimento Base de Conhecimento

Base de Dados

Programas Criao BD

GeneXus gera automaticamente os programas necessrios para criar a base de dados e os executa. Desta forma a base de dados criada pelo GeneXus de forma automtica.

Gerao dos Programas da aplicao


Transaes
(Trns)

Procedimentos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base de Conhecimento Base de Conhecimento

Base de Dados

Programas de Aplicao
(Trns, Procs, Wbps, etc)

Depois, GeneXus gera programas de aplicao para interagir com a base de dados previamente criada.

10

Resultado final na Etapa de Desenvolvimento


Transaes
(Trns)

Procedimentos
(Procs)

Data Providers
(DP)

Web Panels
(Wbps)

Base de Conhecimento Base de Conhecimento

Base de Dados

Programas de Aplicao
(Trns, Procs, Wbps, etc.)

Uma vez criada a base de dados e gerados os programas, contamos com uma aplicao pronta para executar.

11

As vises dos usurios mudam


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Base de Conhecimento Base de Conhecimento

Base de Dados

Nova Nova Base Base de de Dados Dados

Programas de Aplicao
(Trns, Procs, Wbps, DPs)

Durante o ciclo de vida da aplicao, vai surgir repetidamente necessidade de serem feitas modificaes na base de conhecimento, seja porque as vises dos usurios mudaram, ou porque devem ser feitas correes, ou acrescentar novos conhecimentos. As modificaes realizadas na base de conhecimento sero analisadas pelo GeneXus para avaliar a necessidade de efetuar mudanas na base de dados (por exemplo: modificao/criao de tabelas/ndices), ou no. Em caso de detectar mudanas para efetuar na base dados, o GeneXus vai detalhar os mesmos num relatrio de anlise de impacto (IAR: Impact Analisis Report), um relatrio que explica todas as mudanas sobre tabelas, ndices, dados, etc. que precisam ser realizados que refletem a nova realidade. Mesmo assim, no relatrio de anlise de impacto, se informam os eventuais problemas que as mudanas em questes podem ocasionar como ter inconsistncias ou redundncias.

12

Anlise de Impacto Automtico


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Anlise de impacto

Base de Conhecimento Base de Conhecimento

Base de Dados

Nova Nova Base Base de de Dados Dados

Programas de Aplicao
(Trns, Procs, Wbps, DPs)

Algumas vezes a nova base de dados coincide com a anterior. Outras vezes isto no ocorre, e a base de dados sofre alguma modificao para representar a nova realidade. O analista deve estudar o relatrio de anlise de impacto e resolver se deseja realizar efetivamente as mudanas na base de dados, ou renunciar a base de dados e deixar como estava, ou fazer outras alteraes.

13

Gerao de Programas de Reorganizao da Base de Dados


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Programas de Reorganiz.

Base de Conhecimento Base de Conhecimento

Base de Dados

Nova Nova Base Base de de Dados Dados

Programas de Aplicao
(Trns, Procs, Wbps, DPs)

Se o analista opta por aplicar as mudanas propostas, dizemos que optou por reorganizar a base de dados. Utilizamos este termo para definir a ao de aplicar mudanas fsicas sobre a base de dados. GeneXus gera os programas que implementam as modificaes sobre as estruturas fsicas da base de dados, e mediante sua execuo nos brindar com uma nova verso da base de dados com as mudanas efetuadas.

14

Anlise automtica do impacto das mudanas sobre os programas


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Base de Conhecimento Base de Conhecimento

Anlise de Impacto sobre os programas

Nova Base de Dados

Novos Programas de Aplicao


(Trns, Procs, Wbps, DPs)

Visto que se quer reorganizar a base de dados ou no, considerando as novas definies introduzidas, GeneXus estuda o impacto das alteraes sobre os programas atuais.

15

Gerao automtica de novos programas


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Base de Conhecimento Base de Conhecimento

Gerao de programas

Nova Base de Dados

Novos Programas de Aplicao


(Trns, Procs, Wbps, etc.)

Por ltimo, GeneXus prossegue com a gerao/regerao dos programas de aplicao necessrios, obtendo assim uma nova verso da aplicao.

16

Nova realidade, com as mudanas na aplicao


Novas Transaes Novos Procedimentos Novos Data Providers Novos Web Panels

Base de Conhecimento Base de Conhecimento

Nova Base de Dados

Novos Programas de Aplicao

Assim novamente teremos uma aplicao pronta para executar, com as mudanas aplicadas.

17

Environments
O Lugar onde se armazena a informao para gerar a aplicao em certa plataforma de execuo se chama Environment.
Environments:
Implementation #1
C# & SQL Server
C# Application SQL

Implementation #2 GeneXus Project


C# & MySQL
C# Application MySQL

Implementation #3
Java & MySQL
Java Application MySQL

Knowledge Base

O uso de vrios Environments implementaes da mesma aplicao.

permite

diferentes

18

Environments
Quando se cria uma base de conhecimento (KB), GeneXus pede ao usurio que selecione o Environment que vai trabalhar:

Com estes dados, se cria automaticamente um Environment.

Para criar uma base de conhecimento, selecionar na barra do menu do GeneXus, o item File / New Knowledge Base. Em seguida vai aparecer um dilogo como o que segue:

Dever ser indicado; Nome da Knowledge Base: em nosso caso ser BillingSystem. Diretrio onde ser criada. O Environment por default: veja que so mostradas linguagens de programao. GeneXus os utilizar para criar os programas associados a base de dados. As opes oferecidas so: C# Environment, Java Environment e Ruby Environment. Language: Idioma em que vai aparecer os botes, mensagens, etc. No momento de criar a KB se comea a definir o ambiente de implementao (Environment) cujas definies sero depois completadas no momento de executar a aplicao (nome da base de dados, servidor, forma de conexo, etc).

19

Environments
Para ver o Environment criado, selecionamos a janela de Preferences do Knowledge Base Navigator:

Default Environment

20

Environments
Para ter implementaes em diferentes plataformas, criamos vrios Environments.

21

Environments
Vemos os Environments criados:
Environments:

C# & SQL Server

GeneXus Project
Java & MySQL

Knowledge Base

O environment ativo indicado em negro e tem o icone de Play.

22

Metodologia Incremental
Construir uma aplicao mediante aproximaes sucessivas.

DEFINIO INICIAL

A construo automtica da base de dados e programas permite ao GeneXus aplicar esta metodologia de desenvolvimento, conhecida como metodologia incremental. Como explicado anteriormente, este processo realizado mediante aproximaes sucessivas.

23

Metodologia Incremental
Aplicar um desenvolvimento incremental, diferentes verses da aplicao. pode gerenciar

Verso para prototipao

Verso para colocar em produo

Referente a verses (do que se trata, como realizar, etc.) voltaremos no final. No momento suficiente saber que ao criar a base de conhecimento, os programas que estaremos executando, programas reais, sero uma verso da aplicao, de teste. Uma vez que resolvermos que essa verso est pronta para ser colocada em produo, basta fazer outra verso da aplicao, e pronto!.

24

Vantagens da Prototipao
Permite ver resultados no incio Permite seguir os requerimentos do usurio Detecta os erros no incio O usurio se compromete com o desenvolvimento Sistemas de melhor qualidade

Toda comunicao susceptvel a erros: O usurio esquece certos detalhes O analista no toma nota de alguns elementos O usurio se equivoca em algumas situaes O analista interpreta mal algumas explicaes do usurio Como a implementao dos sistemas habitualmente uma tarefa que consome bastante tempo. E muitos destes problemas somente so detectados nos testes finais do sistema, o custo em tempo e dinheiro em solucion-los muito grande. Sabendo que a realidade no permanece esttica, por isto no razovel pensar que as especificaes no vo mudar at que o sistema seja implementado. A conseqncia de manter as especificaes, que se acaba implementando uma soluo relativamente insatisfatria. O impacto destes problemas diminui muito se for possvel testar cada especificao, imediatamente, e saber qual a repercusso de cada alterao sobre o resto do sistema. Uma primeira aproximao de resoluo deste problema, oferecida por diversos sistemas, a possibilidade de mostrar ao usurio formatos de janelas, relatrios, etc. animados por menus. Isto permite ajudar o usurio a ter uma idia de como o sistema ser construdo, porm no final, sempre aparecem surpresas. Uma situao bastante diferente seria colocar a disposio do usurio, para sua execuo imediata, uma aplicao funcionalmente equivalente desenhada, at nos mnimos detalhes. Isto o que faz o GeneXus: um prottipo GeneXus uma aplicao pronta, funcionalmente equivalente a aplicao de produo. Assim a aplicao pode ser totalmente provada antes de colocar em produo, e durante estes testes, o usurio afinal pode trabalhar com os dados reais, testando de uma forma natural no somente os formatos de telas, relatrios, etc., mas tambm suas frmulas, regras do negcio, estruturas de dados, etc. e trabalhar com seus dados reais. Isto somente possvel graas a construo automtica que o GeneXus realiza do suporte computacional (base de dados e programas).

25

Objeto Transao

A anlise de toda aplicao GeneXus comea com o desenho das transaes.

As transaes permitem definir os objetos da realidade.

Para identificar quais so as transaes que precisam ser criadas, se recomenda prestar ateno aos substantivos que o usurio menciona quando escreve a realidade.

Alm de ter por objetivo a definio da realidade a conseqente criao da base de dados normalizada, as transaes, igual como os demais objetos GeneXus, provocam a gerao de programas. Os programas oriundos das transaes tm o objetivo de permitir inserir, eliminar e modificar de forma interativa nas tabelas que tenham implicaes, controlando estes programas e a integridade referencial dos dados.

26

Transaes
Generalidades Definio Objeto a partir do qual GeneXus criar de forma automtica a base de dados na 3 forma normal
Descrevem as vises dos usurios.

Contem toda a informao necessria referente os dados da aplicao e de como os usurios acessam o sistema para sua manipulao (inserir, modificar e eliminar). Elementos que as compem:

Alguns elementos das transaes, que sero vistos: Estrutura: Permite definir os atributos (campos) que compem a transao e a reao entre elas. A partir deles, o GeneXus conclui o desenho da base de dados: tabelas, chaves, ndices, etc. Web Form: Cada transao contm um Form (tela) Web mediante o qual se realiza inseres, eliminaes e alteraes no ambiente Web. Regras: As regras permitem definir o comportamento particular das transaes. Por exemplo, permitem definir valores por default para os atributos, definir validaes sobre os dados, etc. Eventos: As transaes suportam a programao orientada a eventos. Este tipo de programao permite definir cdigo ocioso, que se ativa em resposta a certas aes provocadas pelo usurio ou pelo sistema. Variveis: Permite a definio de variveis que so locais a Transao. Propriedades: Permitem definir certos detalhes referentes ao comportamento da transao. Documentao: Permite a incluso de texto tcnico, para ser utilizado como documentao do sistema. Ajuda: Permite a incluso de texto de ajuda, para ser consultado pelos usurios em tempo de execuo da transao. Category e Work With: Patterns (padres) que podem ser aplicados a Transao com a finalidade de implementar de forma automtica certa funcionalidade. Alguns destes elementos tambm esto associados a outros tipos de objetos GeneXus.

27

Transaes
Estrutura
Exemplo: Precisa registrar informao de fornecedores.

Definir a transao Supplier, com estrutura: { SupplierId* SupplierName SupplierAddress SupplierPhone } Identificador de fornecedor Nome de fornecedor Endereo de fornecedor Telefone de fornecedor

A estrutura de uma transao permite definir que atributos integram a mesma e como esto relacionados. Por exemplo, se numa aplicao necessrio registrar informao de fornecedores, ter que ser definido uma transao, a qual podemos dar o nome Supplier e sua estrutura pode ser a seguinte: {SupplierId* SupplierName SupplierAddress SupplierPhone } Esta lista de nomes (um dos quais est sucedido do smbolo asterisco) corresponde aos atributos dos fornecedores que interessam ser mantidos. Ento, criamos uma transao de nome Supplier cuja estrutura composta dos atributos SupplierId*, SupplierName, SupplierAddress e SupplierPhone. Isto significa que cada fornecedor identificado por um cdigo SupplierId (o qual fica determinado pelo asterisco aps o atributo), ter um nome SupplierName, um endereo SupplierAddress e um telefone SupplierPhone. Para cada atributo definido na estrutura, deveremos indicar coisas como seu tipo de dados, descrio e alguns outros detalhes mais que veremos.
_____________________________________________________________________________
1

O asterisco corresponde a uma notao terica que utilizamos para indicar que o atributo identificador. Como veremos, esse asterisco em GeneXus aparece representado por um cone de chave e o usurio pode configur-lo mediante um menu contextual que oferece esta possibilidade.

28

Transaes
Estrutura
Estrutura em GeneXus:

Atributos Chave Na pgina anterior foi explicado que o asterisco aps o atributo SupplierId indica que o mesmo o identificador na transao. Toda transao deve ter pelo menos um identificador, isto , um atributo ou conjunto de atributos que definam a unicidade da informao. No exemplo no vo existir dois fornecedores com o mesmo valor de SupplierId. Em definitivo se trata do conceito de chave primria, e para fazer a escolha dos atributos que a compem, devemos levar em considerao os requisitos da realidade do objeto. Nos casos em que no se pode determinar um identificador, deve-se optar por criar um atributo artificial (no existente na realidade), e que seu valor seja atribudo internamente, por exemplo, na forma correlativa. Como pode ser observado no editor de transaes GeneXus, um cone de chave representa o asterisco que usamos como notao terica. Atributo descriptor O cone com uma lupa representa o atributo que melhor descreve a transao. Em outras palavras seriam os atributos que tem maior carga semntica na transao. Por default o primeiro atributo na estrutura da transao que seja do tipo de dados character, se define como atributo descriptor. possvel definir outro atributo como descriptor utilizando o menu pop-up correspondente, assim como no definir nenhum.

29

Transaes
Estrutura
Exemplo: Precisa registrar informao referente a fatura de venda.
Invoice { InvoiceId* InvoiceDate CustomerId CustomerName

Identificador de fatura Data de fatura Identificador de cliente Nome de cliente

Detail { ProductId* Identificador de produto ProductDescription Descrio de produto ProductPrice Preo de produto InvoiceDetailQuantity Quantidade de produto levada da linha InvoiceDetailAmount Valor da linha de fatura } InvoiceAmount Valor total da fatura }

Nveis de uma transao A transao Invoice consta de dois nveis: o primeiro nvel fica implcito, no necessitando de um jogo de chaves; e o segundo nvel corresponde ao conjunto de atributos que ficam definidos entre chaves . O fato de definir um segundo nvel significa que existem vrias instncias do mesmo, para cada instancia do nvel anterior. No exemplo, um cabealho da fatura e seus vrios produtos. Cada nvel de uma transao define um grupo de atributos que devem operar em conjunto, ou seja, se insere, elimina ou se altere conjuntamente na base de dados. Chamamos de transao plana a uma transao de um nvel s. Assim, podemos dizer que a transao Supplier a transao plana. A diferena da transao Invoice que contm dois nveis. comum falarmos de cabealho para o primeiro nvel e de linhas para o segundo. Para cada nvel da transao, deve ser indicado quais atributos atuam como identificador. O identificador de cada nvel pode ser composto somente de um atributo, como o caso das transaes que vimos at agora, ou pode ser composto por vrios atributos. Na transao Invoice o atributo InvoiceId o identificador do primeiro nvel, e o atributo ProductId + o atributo dos nveis superiores o identificador do segundo nvel. Este ltimo significa que para um nmero de fatura dado, no repetido o valor do atributo ProductId em distintas linhas. Uma transao pode conter vrios nveis paralelos, assim como aninhados. ____________________________________________________________________________
1 O asterisco uma notao terica representando que o atributo que o antecede identificador na transao, o jogo de chaves tambm utilizado como notao terica, para representar que os atributos contidos formam parte de um nvel aninhado, e que tem uma representao visual em GeneXus distinta, mas indica o mesmo.

30

Transaes
Estrutura
Estrutura em GeneXus

Em GeneXus fica visualmente claro o nvel correspondente as linhas da fatura. A cada nvel de uma transao se deve atribuir um nome, tipo1 e descrio (exceto ao primeiro nvel, que recebe como nome o da transao). Nveis paralelos e aninhados Uma transao pode ter vrios nveis aninhados, assim como nveis paralelos. Por exemplo, no caso hipottico que uma fatura pode ter vrios pagamentos, poderamos definir dois tipos de estrutura, dependendo do que se quer representar:
Invoice { InvoiceId* InvoiceDate CustomerId CustomerName InvoiceAmount Detail {ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount} Payment {InvoicePaymentDate* InvoicePaymentAmount} } Invoice { InvoiceId* InvoiceDate CustomerId CustomerName InvoiceAmount Detail {ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount Payment {InvoicePaymentDate* InvoicePaymentAmount}} }

Na estrutura da esquerda definido uma fatura que tem muitos produtos e muitos pagamentos, mas no tem relao direta entre os produtos e os pagamentos (a no ser pelo fato de pertencerem mesma fatura). Na estrutura da direita so registrados os pagamentos por produto comprado. fcil compreender que o segundo e o terceiro nvel da transao da esquerda so paralelos. Ambos esto aninhados ao primeiro nvel, mas entre eles, so paralelos. Na estrutura da direita, so todos os nveis aninhados.
________________________________________________________________________________________
1

Como veremos depois, o tipo que se define para um nvel de uma transao, ser utilizada para trabalhar com business components, conceito relacionada as transaes.

31

Transaes
Definio do modelo de dados: estruturas das transaes Transao
Supplier { SupplierId* SupplierName SupplierAddress SupplierPhone }

Transao
Invoice { InvoiceId* InvoiceDate CustomerId CustomerName Detail { ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount } InvoiceAmount }

Tabela INVOICE
InvoiceId* InvoiceDate CustomerId CustomerName InvoiceAmount

Tabela INVOICEDETAIL
InvoiceId* ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount

Tabela SUPPLIER
SupplierId* SupplierName SupplierAddress SupplierPhone

GeneXus utiliza a estrutura das transaes para capturar o conhecimento necessrio para definir automaticamente qual o modelo de dados que ser criado. Para poder realizar a normalizao da base de dados ser realizada numa 3 forma normal, GeneXus deve extrair as dependncias funcionais existentes entre os atributos definidos na base de conhecimento. Na base de conhecimento de nosso exemplo, temos definido na transao Supplier e de sua estrutura GeneXus extramos as seguintes dependncias funcionais: SupplierId {SupplierName, SupplierAddress, SupplierPhone}

Dadas estas dependncias funcionais, GeneXus determina que deve criar uma tabela que ter por default o mesmo da transao (SUPPLIER)1, e que estar conforme nem mais nem menos que pelos quatro atributos anteriores, sendo SupplierId a chave primria da mesma:

SUPPLIER

SupplierId

SupplierName

SupplierAddress

SupplierPhone

Diremos que a transao Supplier tem a tabela associada SUPPLIER quando inserir, modificar ou eliminar pela transao, assim estaro armazenando, modificando ou eliminando fisicamente na tabela associada. _____________________________________________________________________
1

Na documentao, para distinguir o nome de uma tabela do nome de uma transao escreveremos o nome da tabela em maisculo.

32

A partir da estrutura da transao Invoice, GeneXus determina que deve criar duas tabelas: Tabela INVOICE, correspondente ao primeiro nvel da transao:

Chave primria: InvoiceId

INVOICE

InvoiceId

CustomerId

CustomerName

InvoiceDate

InvoiceAmount

Tabela INVOICEDETAIL correspondente ao segundo nvel da transao:

INVOICEDETAIL

InvoiceId

ProductId

ProductDescription InvoiceDetailAmount

ProductPrice

InvoiceDetailQuantity

Chave primria: {InvoiceId, ProductId} Chave estrangeira: InvoiceId j que as dependncias funcionais so: InvoiceId {CustomerId, CustomerName, InvoiceDate, InvoiceAmount} {InvoiceId, ProductId} {ProductDescription, ProductPrice, InvoiceDetailQuantity, InvoiceDetailAmount} Observe que a chave primria da tabela INVOICEDETAIL a concatenao do identificador do primeiro nvel, InvoiceId, com o identificador do segundo nvel, ProductId. A regra geral: a chave primria da tabela correspondente a um nvel n de uma transao se obtm em concatenar os identificadores dos n-1 nveis anteriores aninhados, com o identificador desse nvel. GeneXus atribuiu um nome pr-determinado s tabelas que cria. A tabela associada ao primeiro nvel de uma transao atribui o mesmo nome que o da transao; e as tabelas dos nveis subordinados so atribudas a concatenao dos nomes dos nveis. Por isso que a tabela associada ao segundo nvel da transao Invoice recebe o nome de INVOICEDETAIL, sendo que o nome do primeiro nvel o da transao INVOICE, e o segundo nvel DETAIL. Os nomes das tabelas podem ser modificados pelo analista GeneXus quando o desejar.

33

Transaes
Estrutura
Ao definir as novas transaes:

Customer { CustomerId* CustomerName CustomerAddress CustomerGender }

Sexo do cliente

Product { ProductId* ProductDescription ProductPrice ProductStock }

Depois de ter modelado a transao Invoice, damos conta que existem informaes de clientes e produtos que interessante manter independente das faturas. Isto , os clientes e os produtos so dois objetos de realidades independentes das faturas, para isso necessrio criar duas novas transaes "Customer" e "Product" detalhadas acima. Dependncias funcionais Com estas novas transaes definidas, aparecem novas dependncias funcionais: CustomerId {CustomerName, CustomerAddress, CustomerGender, CustomerStatus} ProductId {ProductDescription, ProductPrice, ProductStock} Que conduzem diretamente a criao de duas novas tabelas:

CUSTOMER

CustomerId

CustomerName

CustomerAddress

CustomerGender

Chave primria: CustomerId E:


PRODUCT ProductId ProductDescription ProductPrice ProductStock

Chave primria: ProductId

34

Transaes
Normalizao: alteraes nas tabelas
Tabela INVOICE
InvoiceId* InvoiceDate CustomerId CustomerName InvoiceAmount

Tabela CUSTOMER
CustomerId* CustomerName CustomerAddress CustomerGender

Tabela SUPPLIER
SupplierId* SupplierName SupplierAddress SupplierPhone

Tabela INVOICEDETAIL
InvoiceId* ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount

Tabela PRODUCT
ProductId* ProductDescription ProductPrice ProductStock

O conjunto total de dependncias funcionais existentes requer algumas modificaes nas tabelas INVOICE e INVOICEDETAIL desenhadas previamente para que o desenho da base de dados permanea na 3 forma normal1. Se representarmos sobre as tabelas CUSTOMER e INVOICE as dependncias funcionais encontradas para os seus atributos:

Podemos ver claramente que INVOICE viola a 3 forma normal (existe uma dependncia funcional transitiva): InvoiceId CustomerId CustomerId CustomerName InvoiceId CustomerName por tanto GeneXus normaliza, tirando o atributo CustomerName da tabela INVOICE: Agora CustomerName somente estar na tabela CUSTOMER.

_______________________________________________________________________________
1

Para mais informao sobre as formas normais (3 forma normal, etc.) recomendamos a leitura do documento Fundamentos de bases de dados relacionais, que est includo no captulo Anexos do curso GeneXus no presencial. Do contrrio, pode pedir ao docente.

35

Agora veremos as dependncias funcionais encontradas nas tabelas PRODUCT e INVOICEDETAIL: podemos perceber claramente que a tabela INVOICEDETAIL est violando a 3 forma normal (existem atributos que dependem de forma parcial da chave primria): ProductId {InvoiceId, ProductId} ProductDescription ProductDescription ProductId {InvoiceId, ProductId} ProductPrice ProductPrice

Portanto GeneXus normaliza, tirando os atributos ProductDescription e ProductPrice da tabela INVOICEDETAIL: ProductDescription e ProductPrice somente ficaro na tabela PRODUCT.

36

Transaes
Relaes: estabelecidas pelos nomes de atributos Conceitos iguais devem ter o mesmo nome
Invoice { InvoiceId* CustomerId CustomerName ... } Customer { CustomerId* CustomerName } Invoice { InvoiceId* InvoiceCustomerId ... } Customer { CustomerId* CustomerName }

Conceitos diferentes NO devem ter o mesmo nome


Invoice { InvoiceId* Date CustomerId CustomerName ... }

incorreto

VendorInvoice { VendorInvoiceId* Date SupplierId* SupplierName ... }

Conceitos iguais devem ter o mesmo nome e conceitos diferentes devem ter nomes diferentes. O GeneXus estabelece as relaes atravs dos nomes dos atributos, de modo que, quando encontra atributos com o mesmo nome em diferentes transaes, entende que trata-se do mesmo conceito, e mediante este conhecimento que pode normalizar. No exemplo que estamos utilizando, quando o GeneXus encontra o atributo de nome CustomerId tanto na transao "Customer" como na transao "Invoice", analisa que: o atributo tem o mesmo nome em ambas transaes, assim possuem o mesmo conceito. Na transao "Customer" CustomerId est marcado como identificador, o qual significa que chave primria na tabela fsica CUSTOMER; ento na tabela fsica INVOICE ser chave estrangeira. O atributo CustomerName, por sua parte, tambm se encontra tanto na transao "Customer" como na transao Invoice, mas a diferena de CustomerId, no est marcado como identificador em nenhuma transao do modelo; com isso, o GeneXus entende que trata-se de um atributo secundrio. As dependncias funcionais indicam que o CustomerName o determina CustomerId: InvoiceId CustomerId CustomerId CustomerName assim que o GeneXus incluir a CustomerName na tabela fsica CUSTOMER (e no na tabela fsica INVOICE). Atributos primrios e secundrios Um atributo se qualifica como primrio quando o mesmo identificador em alguma transao do modelo. No exemplo que estamos vendo, CustomerId um atributo primrio, j que identificador na transao "Customer". CustomerName, na verdade um atributo secundrio j que no identificador em nenhuma transao do modelo.

37

Atributos Armazenados e Inferidos Ao definir as transaes "Customer" e "Product", inclumos nelas certos atributos que no eliminados da transao Invoice. Os atributos CustomerId e ProductId, sero includos nas transaes "Customer" e "Product" respectivamente, e ao serem marcados como identificadores das mesmas, passaro a serem atributos primrios. O atributo CustomerName, por sua vez, se agregou na transao "Customer"; e os atributos ProductDescription e ProductPrice na transao "Product". Estes so atributos secundrios. Todos os atributos antes mencionados esto em mais de uma transao: partindo do princpio que continuam na transao Invoice tal como foi definido no princpio, e foram includos nas transaes "Customer" e "Product" respectivamente, porque notamos a necessidade de criar estes objetos. Posteriormente, apresentamos 3 estruturas das transaes em questo, para poder visualizlas juntas:
Invoice { InvoiceId* InvoiceDate CustomerId CustomerName Detail { ProductId* ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount } InvoiceAmount } Customer { CustomerId* CustomerName CustomerAddress CustomerGender }

Provavelmente voc est se perguntando qual a razo dos atributos secundrios CustomerName, ProductDescription e ProductPrice continuam na estrutura da transao "Invoice". A explicao a seguinte: as estruturas das transaes, no so equivalentes s estruturas de tabelas fsicas. Nas estruturas das transaes podem ser includos atributos que no estaro nas tabelas fsicas associadas s mesmas, j que na hora de reorganizar a base de dados, o GeneXus analisa o conjunto total de dependncias funcionais existentes na base de conhecimento, e cria - ou modifica, segundo o caso - as tabelas fsicas, deixando-as na 3 forma normal. Agora, com que finalidade temos deixado os atributos secundrios CustomerName, ProductDescription e ProductPrice na estrutura da transao Invoice? Foram deixados para poder inclu-los em algum dos elementos do objeto da transao, por exemplo, nos forms (GUI-Windows e/ou Web) associados a transao Invoice, e assim poder visualizar os valores destes atributos em tempo de execuo. Ditos atributos, como temos explicado, no ficam armazenados na tabela INVOICE, nem na tabela INVOICEDETAIL; por exemplo, em tempo de execuo quando o usurio ingressa atravs de algum dos forms (GUI-Windows e/ou Web) um valor de CustomerId (atributo que armazenar na tabela INVOICE sendo chave estrangeira), a continuao mostrar CustomerName correspondente. Dizemos que o atributo CustomerName um atributo inferido na transao "Invoice", j que seu valor no est armazenado em nenhuma das tabelas associadas a mesma, mas sim que se infere isto , se obtm - da tabela CUSTOMER, dado o valor do atributo CustomerId. Analogamente, os atributos ProductDescription e ProductPrice tambm so inferidos na transao Invoice, j que no se encontram armazenados nas tabelas associadas mesma, mas sim que seus valores se inferem na tabela PRODUCT, para serem mostrados na tela.
38

Product { ProductId* ProductDescription ProductPrice ProductStock }

Transaes
Estrutura conveniente usar padres para os nomes dos atributos.

Facilitam a tarefa de dar nome. Facilitam a tarefa de integrao de bases de conhecimento. Facilitam a leitura do cdigo gerado.

39

Transaes
Estrutura Nome de atributos: Nomenclatura GIK Componente de Entidade + Categoria [+ Qualificador + Complemento]
Entity Component Cliente Cliente Cliente Cliente Fatura Fatura FaturaDetalhe FaturaCompra Category Id Nome Data Data Id Data Quantidade Id Vencimento Inicial Final Qualifier

e em ingls:
Entity Component Customer Customer Customer Customer Invoice Invoice InvoiceDetail VendorInvoice Due Start End Qualifier Category Id Name Date Date Id Date Amount id

A ARTech definiu um padro para a nomenclatura de atributos: o GeneXus Incremental Knowledge Base (GIK) que utilizado pela comunidade de usurios GeneXus. Nesta nomenclatura, o nome de um atributo se forma com 4 componentes (alguns opcionais, assinalados entre parnteses retos): Componente de Entidade + Categoria [+ Qualificador + Complemento] 1 Posteriormente descrevemos em que consiste cada componente: Componente de Entidade (ou Objeto): uma Entidade um ator (ex: Customer), o objeto evento (ex: VendorInvoice, Fatura de Venda) que intervm em uma dada aplicao, representado por uma transao GeneXus. Um Componente de Entidade representa qualquer nvel subordinado ou paralelo que defina a entidade. Exemplo: A fatura tem os seguintes componentes, Invoice (cabealho), InvoiceLine (linhas da fatura). Se sugere um tamanho de 10 caracteres para representar o componente da Entidade. Categoria: a Categoria semntica do atributo que define o rol que o mesmo assume dentro do objeto e dentro do ambiente da aplicao. Sugere que no ultrapasse os 10 caracteres. Exemplos: Id (identificador), Code (cdigo), Name (nome), Date (data), Description (descrio), Price (preo), Stock (estoque).
_____________________________________________________________________________
1

Para pases que utilizem lnguas nas quais os adjetivos so colocados depois do substantivo. Em ingls ao contrrio, por isso a categoria (ou substantivo) vai no final. 2 Ou um conjunto de Transaes paralelas e/ou subordinadas, que falaremos mais adiante.

40

Qualificador: qualquer adjetivo ou advrbio, entorno de 10 caracteres, diferenciao conceitual ao nome do atributo para que o torne nico. Em geral refere ao texto que qualifica a categoria: Data de Vencimento. Exemplos: Start (inicial), End (final), Due (vencimento)

que agregue

Complemento: Texto livre at completar a quantidade de caracteres significativos (30) para o nome. No slide se mostram alguns exemplos de nomes de atributos. Nota 1: As letras maisculas permitem estabelecer fronteiras entre os componentes que formam os nomes dos atributos. Nota 2: Para cada componente se podem utilizar a quantidade de caracteres desejada, ainda se sugere utilizar 10 e que o nome completo no seja superior a 30.

41

Demo
Uma vez criada a base de conhecimento: criao das primeiras transaes

Uma vez criada a base de conhecimento, a mesma ficar aberta para comear a criar as transaes. A criao de objetos, se realiza pressionando Ctrl+N. Os objetos criados ficaro ou na pasta Objects que se pode ver no Folder View da janela KB Navigator. Se desejar que o objeto ao ser criado fique guardado em outra pasta, se deve posicionar em dita pasta e depois fazer click com o boto direito do mouse. No menu escolher New, Object. Tambm poder ser indicado a pasta no quadro de criao de um objeto como se v na imagem. mostrado um dilogo onde se deve escolher o tipo de objeto que se deseja criar (neste caso o tipo de objeto: transao), dar um nome ao objeto que se est criando (por exemplo: Customer), uma descrio longa, e a pasta na qual guardar o objeto:

Uma vez criada a transao, a mesma ficar aberta para que se defina sua estrutura.

42

Transaes
Definio de atributos F4

Para definir um atributo, simplesmente deve-se digitar no primeiro campo de uma linha (ou ramo) da estrutura, o nome do atributo que se deseja criar. Mediante a tecla de tabulao pode-se passar aos seguintes campos para indicar o tipo de dados do atributo, assim como sua descrio, e no caso que o mesmo venha a ser uma frmula (conceito que veremos em breve), como calcul-la. Com a tecla Enter pode-se passar a seguinte linha, para definir outro atributo. Uma vez definidos os atributos na estrutura da transao, somente restar guardar/salvar as mudanas. Caso necessite modificar o nome de um atributo, seu tipo de dados, descrio, nulabilidade, ou frmula, bastar dar um duplo clique sobre o campo desejado, e o mesmo habilitado e pode ser editado. Aps as alteraes as mudanas precisam ser salvas novamente. Para indicar que um ou mais atributos so identificadores na transao, deve-se selecion-los e pressionar CTRL+K; aparecero com um smbolo de chaves. Para definir o incio de outro nvel na transao, deve-se digitar CTRL+L, e automaticamente se produz uma endentao e o usurio dever dar um nome a esse nvel, assim, como definir o nome de seu tipo de dado e uma descrio para o nvel. Para indicar que um atributo de um dos nveis da transao ser o atributo descriptor, deve-se selecionlo e clicar CTRL +D. GeneXus conta com menus pop-up, que so menus que se abrem quando o usurio est posicionado em determinado contexto e fazendo click com boto direito do mouse. Por exemplo, ao clicar com o boto direito do mouse sobre um atributo da estrutura, abre-se um menu pop-up sobre o atributo selecionado, que oferece varias utilidades, como por exemplo indicar que o atributo chave (opo Toggle key), tira-lo da estrutura, pass-lo a um seguinte nvel de animao, etc. Cada atributo contm propriedades. Algumas delas (as fundamentais e obrigatrias) so as que se oferecem diretamente na estrutura para seu ingresso inline. Para acessar o dilogo que permite configurar todas as propriedades de um atributo, deve-se selecionar o item Properties do menu contextual, ou pressionando a tecla F4. Na figura alteramos a propriedade Autonumber que como veremos oportunamente, permite autonumerar atributos chave primria.
_______________________________________________________________________________________
1 2

Veremos sua utilidade enquanto estudarmos os business components. Tambm chamados contextuais visto que variam segundo o contexto.

43

Name: o nome do atributo. Utilizado para identific-lo. Description: A Descrio ou mais propriamente Nome extenso uma definio ampliada do atributo. O atributo deve ser bem identificvel com essa descrio, com independncia do contexto, e principalmente deve ser entendvel pelo usurio final. Deve ser um identificador global do atributo, isto , no se deve atribuir dois atributos na base de conhecimento com a mesma descrio, j que ser atravs desta descrio que o usurio final poder selecionar atributos para definir suas prprias consultas na base de dados, com o GXQuery, executando relatrios dinmicos (tema bastante simples, mas que no ser abordado neste curso). Relacionadas a esta propriedade, esto s propriedades Title, Column Title e Contextual Title. As 2 primeiras por default tem o mesmo valor especificado no Description, podendo ser modificado. Title: A descrio aqui inserida colocada por default ao lado do atributo, cada vez que se utilize em sadas planas como, por exemplo: no primeiro nvel dos forms das transaes (veremos em breve os forms). Column Title: A descrio aqui inserida por default como o ttulo do atributo, cada vez que for includo na coluna de um grid. (no caso de uma transao somente se trata de um atributo inferido, como por exemplo o atributo ProductDescription na transao Invoice)1. Contextual Title: Quando o atributo pertence ao segundo nvel de uma transao, e no inferido (exemplo InvoiceDetailQuantity em Invoice), o nome da coluna do grid da transao pega desta propriedade. Observe que por default se pega da propriedade Description, mas tirando o nome da transao, pois assume o contexto. Type Definition Based on: Permite associar um domnio ao atributo. Ao atribuir um domnio a um atributo, certas propriedades do atributo so desabilitadas (como por exemplo, Data Type e Length) tomando os valores do domnio. Em caso do atributo no pertencer a um domnio, o programador deixar o valor [none] nesta propriedade, e as propriedades correspondentes ao tipo de dados do atributo estaro habilitadas para serem ingressadas. Data Type: Permite indicar o tipo de dados do atributo, onde escolhido um dos tipos de dados suportados pelo GeneXus. Dependendo do tipo de dados selecionados, haver certas propriedades, ou outras, para configurar. Length: Permite indicar o tamanho do atributo. Se na propriedade Data Type indica que o atributo numrico, ento, dever ser considerado que o tamanho inclui as posies decimais, o ponto decimal o sinal. Esta propriedade estar desabilitada quando o tipo de dados escolhido requer estabelecer um tamanho (por exemplo, quando trata do tipo de dados Date). Decimals: Se a propriedade Data Type indica que o atributo numrico, esta propriedade oferecida, para especificar a quantidade de decimais. O valor 0 neste campo, indica que trata um inteiro.

de

Signed: Se na propriedade Data Type se indica que o atributo numrico, esta propriedade oferecida, para indicar se tem sinal ou no. O valor por default False, o que indica que no sero representados valores negativos. Validation Value Range: Permite indicar uma faixa de valores vlidos para o atributo. Por exemplo: 1:20 30: - significa que os valores vlidos so entre 1 e 20; e 30 ou maior. 1234 - significa que os valores vlidos so 1, 2, 3 o 4. 'S' 'N' - significa que os valores vlidos so 'S' ou 'N'.

Picture: Permite indicar o formato de edio para a entrada e sada do atributo. Dependendo do tipo de dados do atributo, determinadas propriedades abaixo desta classe so disponibilizadas. O GeneXus fornece um nmero maior de propriedades dos atributos que as j mencionadas; dependendo do valor que se escolhe para determinada propriedade, so disponibilizadas certas propriedades relacionadas ou outras. recomendvel a leitura de todas as outras propriedades e no somente estas, acessando o Help do GeneXus.
________________________________________________________________________________________
1 O atributo tambm pode estar num objeto objeto Web Panel. Nesse caso, de aparecer como coluna, sempre ser oferecido por default para o nome da mesma o de sua propriedade Column Title. 2 Os domnios sero abordados mais adiante no curso, mas em resumo, o objetivo dos domnios realizar definies de dados genricos. Por exemplo: pode-se definir um domnio de nome Price e tipo de dados Numeric(10,2) e depois associar este domnio para todos os atributos que armazenam preos. Tem a vantagem que se depois desejar modificlo por exemplo para Numeric(12,2), tem que modificar somente a definio do domnio e automaticamente todos os atributos baseados nesse domnio herdam essa mudana.

44

Control Info Um atributo pode associar um tipo de controle. Os possveis tipos de controles: - Edit - Radio Button - Check Box - Combo Box - List Box - Dynamic Combo Box - Dynamic List Box A associao de certo tipo de controle de um atributo, serve para especificar o tipo de controle por default que ser usado pelo atributo, cada vez que seja incluso em um form. Quando um atributo definido com um tipo de dados bsico, o tipo de controle associado a ele o Edit, podendo ser alterado pelo programador para qualquer um dos outros tipos. Em geral GeneXus escolhe o tipo de controle para um atributo dependendo de seu tipo de dados. Se um domnio enumerado, como veremos, escolher Radio Button ou Combo Box, dependendo da quantidade de valores de domnio. No grupo Control Info do dilogo de edio das propriedades de um atributo, onde o programador pode mudar o tipo de controle associado ao atributo; e dependendo do tipo de controle escolhido, uma informao distinta pode ser solicitada. Logo, cada vez que um atributo agregado em um form, apresentar automaticamente com o tipo de controle que tenha associado. Nota No caso de associar ao atributo o tipo Edit, poder especificar que disfarce seus valores, mostrando os de outro atributo (propriedade InputType), e incluso que sugira os valores possveis ao usurio, a medida que este v digitando (propriedade Suggest), entre outras, como veremos depois, quando estudarmos Descries ao invs de cdigos. Tambm se pode escolher a cor da fonte da letra que se deseja associar por default ao atributo, assim como a cor de fundo, de modo que cada vez que se agregue o atributo em um form, se apresente automaticamente com as cores que ele tenha associado (ver grupo Appearance).

45

Transaes
Atributos: Tipos de Dados Numeric, Character, Date, Boolean VarChar
- Equivalente a Character, exceto na forma que armazenada no BD. - Propriedades Maximum Length e Avarage Length associadas.

Long Varchar
- Permite armazenar textos longos, comentrios, etc. (memo).

DateTime
- Permite armazenar uma combinao de data e hora.

Blob
- Permite armazenar qualquer tipo de informao: texto, imagens, vdeos, planilhas, etc., na base de dados.

Numeric: Permite armazenar dados numricos. Quando se seleciona este tipo de dados se deve indicar a quantidade total de dgitos do nmero, a quantidade de posies decimais, e se permite sinal ou no. Exemplo: Se definimos que o tipo de dados do atributo InvoiceAmount numrico de tamanho 10, com decimais 2, e sem sinal, estamos especificando que representar nmeros com at 7 dgitos na parte inteira e 2 decimais (7 dgitos na parte inteira + ponto + 2 dgitos para os decimais = 10 dgitos). Character: Permite armazenar qualquer tipo de texto (caracteres e dgitos). Para este tipo de dados, deve ser indicado o tamanho. Exemplo: O atributo CustomerName que utilizamos para armazenar o nome de um cliente, de tipo Character e sabemos que nunca um nome ter mais de 20 caracteres, podemos fixar o tamanho: 20. Date: Permite armazenar uma data. Exemplo: O atributo InvoiceDate que utilizamos para armazenar a data de uma fatura, ser deste tipo de dados. O formato a utilizar para as data (dia-ms-ano, ms-dia-ano), se configura em forma genrica para todo o modelo dentro de um tipo especial de objeto, o objeto Language correspondente a linguagem que vai ser gerado o modelo. O objeto language existe para poder ter uma mesma aplicao traduzida em qualquer linguagem. A escolha de apresentar o ano com 2 dgitos ou 4, se configura com a propriedade Picture de cada atributo. Boolean: permite que um atributo ou varivel assuma os valores lgicos: True, False.

46

VarChar: Permite armazenar texto de tamanho varivel. Sua funo, em contraposio ao Character, otimizar o armazenamento na base de dados. Quando se seleciona o tipo de dados Varchar no dilogo de definio do atributo se acrescentam as 2 seguintes propriedades: Maximum Length e Avarage Length. A primeira para indicar o tamanho mximo de caracteres que podero armazenar, enquanto que a segunda para indicar o tamanho mdio de caracteres que se vai armazenar pelo geral. Exemplo: Quando se define um atributo do tipo Character e tamanho 60, se inserimos um dado que ocupa 25 caracteres, a capacidade restante de armazenamento do atributo (35 caracteres), se completa com brancos. O tipo de dados Varchar, aperfeioa o armazenamento da seguinte forma: se definir Avarage Length (por exemplo: 25), e Maximum Length (por exemplo: 60); ento, se o dado tem tamanho menor ou igual que 25, fica armazenado no campo (se completa brancos), exceto nos casos em que o dado seja de tamanho maior que 25, quando ficam armazenados os primeiros 25 caracteres no campo, e o resto em um rea de overflow. Em contrapartida a vantagem de otimizao do armazenamento, para os casos que se utilize a rea de overflow, ser necessrio realizar um acesso adicional tanto para a leitura como para a gravao do dado. O tipo de dados Varchar equivalente ao tipo Character em todos os sentidos, exceto na forma em que armazena os caracteres na base de dados. Podem ser aplicadas todas as funes e operadores existentes para o tipo de dados Character. Se o DBMS no suporta este tipo de dados, se criar o atributo do tipo Character. Long Varchar: Permite definir um atributo memo; isto , normalmente utilizado para armazenar textos grandes, comentrios, etc. Ao selecionar este tipo de dados deve-se indicar um tamanho mximo de caracteres. Existem duas funes para manipular este tipo de dados: GXMLines e GXGetMLi. GXMLines retorna a quantidade de linhas que tem um atributo Long Varchar, tendo como parmetro o nome do atributo, e a quantidade de caracteres que se deseja considerar por linha. Exemplo: &cantlin = GXMLines( AtribMemo, 40 ). O GXGetMLi por sua vez, extrai uma linha do atributo Long Varchar (para depois imprimi-la, por exemplo), tendo como parmetro o nome do atributo, o nmero da linha desejado, e a quantidade de caracteres que deseja considerar por linha. Exemplo: &txt = GXGetMLi( AtribMemo, 1, 40 ). Geralmente estas 2 funes so usadas combinadas, j que primeiro consulta a quantidade de linhas que tem certo atributo Long Varchar, indicando a quantidade desejada de caracteres por linha, e depois prossegue extraindo o contedo das linhas, utilizando um loop at chegar ltima linha, e desta forma eles so impressos, por exemplo. DateTime: Permite armazenar uma combinao de data e hora. A propriedade Picture deste tipo de dados, permite escolher o que desejamos mostrar sobre a data, e o que desejamos mostrar sobre a hora. Referente a data podemos escolher entre: no mud-la, mud-la e apresentar o ano com 2 dgitos, mud-la e apresentar o ano com 4 dgitos. Referente a hora podemos escolher entre: mudar somente 2 dgitos para a hora (no administrando minutos nem segundos), mudar 2 dgitos para a hora e 2 dgitos para os minutos (no administrando segundos), mudar 2 dgitos para a hora, 2 dgitos para os minutos e 2 dgitos para os segundos. Os valores antes mencionados no afetam a forma de armazenar o tipo de dados, caso no seja especificado a forma de aceitar ou mostrar seu contedo. Nota: Em caso de no alterar a data, s a hora, o valor da data que ficar no campo ser o mnimo suportado pelo DBMS, e ser reconhecido pelo GeneXus como data vazia ou nula. No que se diz respeito hora, os valores no aceitados (minutos e/ou segundos) sero armazenados com valor zero. Blob: As aplicaes requerem cada vez mais manter e trabalhar com este tipo de informao. O tipo de dados Blob permite armazenar esta diversidade de informao na prpria base de dados, aproveitando assim os diferentes mecanismos de integridade e controle fornecido pelos DBMSs. Este tipo de dados somente pode ser utilizado quando se tem um DBMS. Para aprofundar o conhecimento nesse tipo de dados entrar no Help GeneXus.

47

Transaes
Definio de variveis
Em todo objeto GeneXus possvel definir variveis. As variveis so visveis somente dentro do objeto; isto , so locais. Editor similar ao da estrutura das transaes:

possvel definir variveis do tipo coleo (qualquer tipo de dados).

Para definir variveis em determinado objeto, deve selecionar o seletor Variveis, como se mostra na figura. Este seletor mostra variveis definidas por default (Standard variveis, como por exemplo a varivel Today que contem a data do sistema) para o objeto, e permite definir variveis novas atravs de um editor similar ao das transaes. Tambm se pode ir a opo Insert do menubar e escolher Variables. No quadro de dilogo que se mostra para selecionar New Varivel.

Este dilogo solicita o nome da varivel, sua descrio, tipo de dados e tamanho, o domnio, de forma anloga quando se define um atributo. A propriedade Dimensions permite indicar se a varivel ser escalar ou se tratar de um vetor (1 dimenso) o matriz (2 dimenses). O valor que oferece por default esta propriedade escalar.

48

Based On Oferece uma forma rpida de definir uma varivel. Quando se seleciona, se mostra um dilogo que mostra todos os atributos definidos na base de conhecimento; em dito dilogo, simplesmente se deve selecionar um atributo, e em seguida se defini automaticamente uma varivel com o mesmo nome e a mesma definio que o atributo. Vale declarar que se podem selecionar vrios atributos, criando nesse caso uma varivel para cada atributo selecionado, com suas mesmas caractersticas. Por outra lado, possvel definir variveis dentro do editor de cdigo de cada objeto (source, eventos, etc.), fazendo uso do menu contextual (boto direito) depois de escrever o nome da varivel. Isto , ao escrever &nomeDeVariavel (ex: &x) e pressionar boto direito do mouse. No menu contextual depois escolher Add Varivel. Variveis coleo possvel definir variveis coleo sobre qualquer tipo de dados oferecido por GeneXus. Para isso basta clicar na correspondente casinha no editor de variveis, ou indicar o valor True na propriedade Collection associada as variveis. Para percorrer depois os itens colecionados em dita varivel, se deve utilizar a estrutura de controle For in. Por exemplo, temos definido a varivel &myNumbers de tipo Numeric(4.0) Para percorrer os valores armazenados se dever criar uma nova varivel de tipo Numeric (4.0). Criamos ento a varivel &OneNumber, e declaramos: For &OneNumber in &myNumbers ---------Endfor

49

Transaes
Domnios
Objetivo: Realizar definies genricas. Quando os domnios devem ser utilizados? Atributos e/ou variveis com a mesma definio. Exemplo: Atributos ProductPrice InvoiceDetailAmount
Preo do produto Valor total da linha

Domnios

comum ter numa base de conhecimento, atributos que compartilhem definies similares, mas que no tenham nenhuma relao. Por exemplo, comum definir todos os nomes, como atributos do tipo character e tamanho 20; ou todos os valores, como atributos do tipo numrico e tamanho 10.2. O objetivo dos domnios permitir realizar definies genricas. Como exemplo, o atributo InvoiceDetailAmount do tipo numrico e tamanho 10.2, assim como o atributo ProductPrice que do mesmo tipo e tamanho, na mesma base de conhecimento. Desse modo, podemos definir um domnio de nome Price, que seja do tipo numrico com tamanho 10.2, e a cada um dos atributos mencionados atribuir o domnio valores Price. A vantagem de faz-lo assim, que se no futuro surgir a necessidade de mudar a definio dos atributos que representam valores, a mudana realizada uma nica vez (no domnio Price), propagando-se este automaticamente aos atributos InvoiceDetailAmount e ProductPrice.

50

Transaes
Domnios
Domnios enumerados: manter o estado do cliente: Active, On Hold,

Closed

dominio Status

Atributo CustomerStatus de domnio Status


Se trabalha com os nomes ao invs de trabalhar com os valores: CustomerStatus = Status.Active

Existe a possibilidade de trabalhar com domnios enumerados (aqueles que representam valores finitos e particulares). Nas linguagens de programao so bem conhecidos. O caso tpico de uso para os dias da semana, quando se precisa que uma varivel tenha um dos seguintes valores: Segunda-feira, Tera-feira, Quarta-feira, Quinta-feira, Sexta-feira, Sbado, Domingo. Em nosso caso, vamos adicionar estrutura da transao Customer um atributo que representa o estado do cliente no sistema num determinado momento. Pode estar active, on hold ou closed. Uma forma de represent-lo definindo um domnio Status, que corresponde ao tipo de dados Character(1) mas para o qual explicitamente dizemos que no queremos que possa ter todos os valores desse tipo de dados, mas apenas 3: A, H e C, e dizemos tambm que queremos trabalhar dando nomes a estes 3 valores e trabalhar com seus nomes. Assim, ao A associamos o nome Active, ao H OnHold e ao C Closed. Associando ao atributo CustomerStatus o domnio Status (observar que, devido terminao do nome do atributo, ao inserir o atributo na estrutura depois de ter definido o domnio isto automaticamente sugerido pelo GeneXus) no atributo da tabela internamente ser salvo um dos 3 valores: A, H ou C, porm, no teremos de lembrar esses valores, mas sim seus cdigos: Active, OnHold e Closed. J tnhamos outro atributo com domnio enumerado: CustomerGender. Nesse caso, possua apenas 2 valores: Female e Male. Observar como o Control Info oferece para o ControlType um Combo Box ao invs de um Edit. Isto far sentido quando vermos o Form de uma transao um pouco mais adiante.

51

Transaes
Domnios

Assim como o domnio pode ser associado a um atributo (e a outro domnio), da mesma forma pode ser associado a uma varivel. Um mesmo domnio pode ser referido tanto a atributos como a variveis, j que o objetivo exatamente o mesmo. Como definir um domnio? Existem vrios caminhos: 1) Opo Domains do Folder View: Mediante um editor similar ao das variveis, pode ser definido um novo domnio. 2) Visto que na tela de configurao das propriedades de um atributo onde se atribui a um atributo um domnio existente, em dita tela, se oferece um boto para criar um domnio novo. Idem com o dilogo de definio de variveis. 3) Na estrutura da transao possvel definir um novo domnio no campo de definio do tipo de dados de um atributo, simplesmente escrevendo sobre essa mesma linha, o nome do domnio, e atribuindo o tipo de dados. Por exemplo, digitando Price = Numeric(10.2) sobre a coluna Type do atributo que se est definindo, fica tambm definido o domnio de nome Price, com o tipo de dados Numeric(10.2).

52

Transaes
Web Form

Cada transao tem um Web Form.

Por default criado ao gravar a estrutura da transao, podendo ser modificado pelo programador.

Para cada transao, GeneXus cria um form web, que ser a interface com o usurio. criado por default por GeneXus ao momento de gravar a estrutura da transao, e contem todos os atributos includos na mesma, com suas respectivas descries, alm de alguns botes. Se bem criado por default, possvel modific-lo para deix-lo mais vistoso, mudar por exemplo controles de tipo edit a outros tipos de controles, agregar e/ou tirar botes, etc.

53

Transaes
Web Form da transao Invoice
Control Error Viewer

GRID

No exemplo que se mostra o form Web correspondente a transao Invoice. Atravs deste form o usurio final poder ingressar, modificar e eliminar faturas na aplicao Web. O controle Error Viewer se utiliza para poder colocar e programar no lugar onde queremos que as mensagens gerais sejam mostradas ao usurio final de uma transao Web. Poderemos especificar entre outras coisas o lugar onde queremos que este controle esteja dentro do form, seu tipo de letra, cor, etc..
Observe que o segundo nvel da transao aparece no form como um control grid.

54

Transaes
Web Form da transao Customer

Domnios bsicos controles Edit Domnios enumerados controles Combo Box

55

Transaes
Paletas de ferramentas para o desenho de Forms

Inserir controles: Opo View do Menubar \ Other Tool Windows \ Toolbox

Cortar, copiar e colocar controles:

Podemos definir um controle como uma rea da interface com o usurio, que tem uma forma e um comportamento determinado. Existem diferentes controles: - Texto: Permite colocar texto fixo - Atributo/Varivel: Permite colocar atributos ou variveis. - Linha horizontal - Error Viewer - Tabela: Inserir tabelas no form - Grid: Permite definir grids de dados. - Boto: Permite incluir botes nos forms. - Bitmap: Permite definir bitmaps estticos, etc. Paleta de ferramentas para inserir controles: Quando se est editando um form, se encontra disponvel uma paleta de ferramentas (Toolbox) que oferece os controles possveis de inserir no mesmo. Simplesmente se deve selecionar o controle e arrast-lo sobre o form.

56

Transaes
Controles em Web Form
Cada controle do Web form pode ter associada uma classe, de um objeto theme (tema) determinado que est associado ao objeto. Ao criar uma KB, se cria por default o tema GeneXus X e todos os objetos criados tero este tema associado. Isto permite que o desenho da interface seja independente da programao. Cada tema vai ter muitas classes definidas para cada tipo de controle. O analista somente associa um tema ao objeto, e uma classe a cada controle do form e no precisa se preocupar com o desenho dos mesmos. O controle herda o desenho da classe do tema associado.

Para separar os aspectos de desenho grfico de um site web, dos aspectos de programao propriamente dito, existe um tipo de objeto chamado Theme (Tema em portugus). O objetivo desta separao paralelizar o desenvolvimento de um site Web, permitindo ao programador aproximar-se das tarefas de programao, e apoiar-se em um design grfico para que defina as questes de desenho. Desta maneira o design grfico configurar o tema escolhido pelo programador, e o programador somente dever aplic-lo aos objetos de sua base de conhecimento. Um objeto tema conter um conjunto de classes, para cada tipo de controle dos que podem aparecer no form Web de um objeto GeneXus. Por exemplo, ter vrias classes para o controle boto, algumas para o controle atributo, uma classe para o controle Error Viewer, etc. Quando se cria uma base de conhecimento, automaticamente aparecer dentro do Folder View da pasta Customazation com objetos Theme pr-definidos que podero ser importados na KB. Por default se importa o de nome Genexus X. Este tema contem um conjunto de classes associadas aos diferentes controles existentes. Os objetos com form Web que vo sendo criados tero por default associado este Theme, e cada controle que aparea em seus forms ter associado uma classe desse tema, para este controle.

57

Transaes
Controles em Web Form

Deste modo, quando o analista cria a transao "Customer e informa sua estrutura, ao grav-la pode ver que o Form Web ter automaticamente o aspecto mostrado na tela acima esquerda. Quem deu o formato a todos os controles se no foi o analista exatamente? Pois bem, todas as transaes tero associado por default o tema GeneXus X e todos os controle colocados no form, tero classes deste tema associadas. Se sobre o Text Bloxk (controle de texto) mostrado acima (Name), se editam suas propriedades (F4), pode-se observar a propriedade Class, que tem configurada a classe TextBlock. Esta propriedade pode ser mudada pelo analista. Ao clicar o combo box poderemos ver uma lista de classes possveis para esse controle (so as que figuram no tema associado). A direita mudamos a classe para uma de nome Title e no form podemos ver a repercusso no desenho do TextBlock. No entraremos em detalhe neste tema no presente curso.

58

Demo
Como executar a aplicao?
Opo Build \ Run Developer Menu, ou pressionar a tecla F5. F5: Dispara automaticamente todas as aes necessrias para executar a aplicao Se BD no existe, se cria automaticamente
(sempre e quando usurio e password tenham permisso de DBCreator)

Lembremos que no momento de criao da KB, se indicou o gerador por default a ser utilizado. Agora deve completar a informao necessria para terminar de definir o ambiente de implementao. Database name: Nome da base de dados que estar associada a aplicao. Server name: Nome do servidor da base de dados que a administra. Use trusted connection: Yes (dever indicar o usurio e contra-senha vlido no DBMS) No Consideraes: Se a base de dados no existir, GeneXus a criar, sempre e quando o usurio e contrasenha configurados na janela de dilogo tenham permisso de DBCreator no DBMS.

59

Processo de Build
O processo de Build inclui todas as tarefas necessrias para a execuo da aplicao: Verificao de alteraes na BD, Reorganizao (se for necessrio), Especificao, Gerao e Compilao. No inclui a execuo.
KB
DBASE IMPACT ANALYSIS REORGANIZATION

SPECIFICATION

GENERATION

Aplicao pronta para executar

COMPILATION

APPLICATION

O processo de Build executado em background, permitindo realizar outras tarefas enquanto o mesmo estiver correndo, por exemplo continuar com o desenvolvimento.

Cada vez que se executa a aplicao (F5), GeneXus realiza uma comparao entre as definies atuais de todos os objetos e as definies da ltima execuo. Esta comparao que o GeneXus faz, se chama anlise de impacto. Este nome auto-descritivo: GeneXus analisa o impacto causado pelas novas definies, e o resultado da anlise de impacto um relatrio de anlise de impacto (IAR: Impact Analisis Report) que informa ao programador quais alteraes fsicas ou estruturais precisam ser realizadas na base de dados associada. Se por exemplo se criou uma nova transao, isto provocar (tal como o objetivo das transaes) que se criam as tabelas correspondentes na base de dados (ver pgina seguinte).

60

IAR e Reorganizao
Create se estiver tudo OK sero construdos os programas no Environment e vai executar...

No exemplo, criar as 2 transaes Customer e Invoice e dar F5, aparece o relatrio de anlise de impacto que pode se ver, onde so listados entre outras coisas, a estrutura que ter cada tabela que ser criada, com seus atributos, tipo de dados, os ndices que sero criados sobre as tabelas, as chaves estrangeiras (observar que o relatrio da tabela INVOICE diz que se referenciar a tabela CUSTOMER (isto acontece pelo atributo CustomerId da transao Invoice que se chama igual que o atributo CustomerId de CUSTOMER, constituindo portanto uma chave estrangeira a dita tabela). Se o programador est de acordo com os alteraes estruturais informadas no relatrio de anlise de impacto, poder prosseguir, passando a reorganizar a base de dados. O trmino reorganizar refere a efetuar alteraes fsicas na base de dados. Se na alterao o programador encontra algo informado no relatrio de anlise de impacto no era o que pretendia obter, poder no efetuar a reorganizao, e as redefinies convenientes so criadas. Quando se decide efetuar uma reorganizao GeneXus gera programas (na linguagem escolhida quando se criou a KB) que implementam as modificaes a serem realizadas na base de dados. A execuo destes programas tem como resultado a obteno de uma nova verso da base de dados com as alteraes efetuadas. O seguinte passo ser obter os programas da aplicao associados aos objetos GeneXus. Para isso GeneXus dever especificar, gerar e compilar os programas da aplicao. Especificar um objeto significa que GeneXus analisar tudo o que foi definido em cada um dos elementos que o compem: estrutura, forms, ou outros elementos segundo corresponda. GeneXus verificar a sintaxe das definies, a validez do definido, e como resultado da especificao mostrar ao usurio uma listagem de navegao, na qual informar a lgica interpretado, e se tem alguma advertncia ou erro. Gerar um objeto, significa que GeneXus escrever linhas de cdigo que implementem a programao do mesmo, na linguagem escolhida. Compilar os programas significa que o cdigo escrito (gerado) seja convertido a linguagem de mquina (binrio) para que possam ser executados.
61

Execuo

62

Opo Build da barra do menu de GeneXus

Opes do item Build: Build All e Rebuild All: Estas opes so utilizadas quando no se est seguro do impacto das alteraes e se quer ter atualizadas as ltimas definies. A opo Build All realiza todas as aes que estejam pendentes, enquanto que Rebuild All fora todas elas. As aes so: - Salvar todos os objetos que no estejam salvos. - Reorganizar a base de dados, se for necessrio. - Especificar somente os objetos que foram modificados (se selecionou Build All), ou forar a especificao de todos (selecionou Rebuild All). - Gerar os objetos - Compilar os objetos definidos Main - Compilar o Developer Menu Build / Rebuild Developer Menu: Similar as opes anteriores mas aplicadas somente ao Developer Menu. No o executa. Run Developer Menu: Executa todas as aes que estejam pendentes e executa o Developer Menu. - Salva todos os objetos que no estejam salvos. - Reorganiz-la a base de dados, se for necessrio. - Especifica somente os objetos que foram modificados. - Gera os objetos. - Compila e executa o Developer Menu.

63

Build / Rebuild / Run options: Opes aplicadas a objetos definidos como Main. Disparam as seguintes aes: - Salvam os objetos que no estejam salvos. - Reorganizao a base de dados, se for necessrio. - So especificados somente os objetos que sofrerem alteraes (se selecionou Build), ou se fora a especificao de todos os objetos pertencentes a rvore de chamadas do objeto Main (quando selecionado Rebuild). - Gerao - Compilao do objeto Main - Execuo do objeto Main (quando selecionado a opo Run) Build / Run with this only options: Build e execuo do objeto definido como Startup. Por default o objeto Startup o Developer Menu. - Salvam todos objetos que no estejam salvos. - Reorganizao a base de dados, se for necessrio. - Especificam somente o objeto selecionado. - Geram somente o objeto selecionado. - Compilam o objeto Startup - Se executa o objeto Startup (se selecionou Run). Set As Startup Object: O objeto indicado passar a ser o objeto Startup da aplicao, ou seja o objeto que finalmente se executa quando se pressione a tecla F5. Por default o objeto Startup o Developer Menu. Create Database Tables: Cria novamente as tabelas. Se perdem os dados que podero estar armazenados previamente. Impact Database Tables: Se realiza um impacto sobre as tabelas da base de dados.

64

Transaes
Modos em tempo de execuo
Os diferentes modos podem ocorrer ao executar uma transao, dependendo da operao que se realize: Modo Insert: Indica que se est efetuando uma insero Modo Update: Indica que se est efetuando uma atualizao Modo Delete: Indica que se est efetuando uma eliminao Modo Display: Indica que se est efetuando uma consulta

Dependendo do ambiente de gerao, existem algumas diferenas referentes operacionalidade das transaes em tempo de execuo. Diante da plataforma, cada vez que se realize uma operao de insero, atualizao, eliminao, ou consulta da base de dados atravs de uma transao, existem um modo associado.

65

Transaes
Em tempo de execuo

&GxRemove: Varivel do sistema para eliminar linhas.

Para agregar uma nova linha

Sempre vai mostrar um nmero de linhas vazias fixas para ser ingressadas pelo usurio (valor configurvel pelo analista a nvel do grid, em sua propriedade Rows). Por default so mostradas 5 linhas vazias. Se o usurio ingressou as 5 linhas e necessita ingressar mais, bastar pressionar New Row, ou simplesmente pressionar Enter e uma nova linha agregada. Para poder eliminar linhas em execuo, GeneXus incorpora automaticamente no grid do form Web uma primeira coluna com uma varivel do sistema de nome &GxRemove, em forma de check box. Para visualizar este check box, se deve pressionar o boto direito do mouse sobre a linha a ser eliminada. Depois deve pressionar o boto Confirm.

66

Transaes
Master Pages
As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em somente um objeto e reutiliz-lo em qualquer outro objeto sem ter que programar.

Criadas automaticamente automaticamente com a KB

Ter um look&feel consistente hoje em dia um dever de toda aplicao Web. Criar e manter cada pgina de uma aplicao Web assegurando a consistncia com o resto do site toma grande tempo de programao. Ao criar uma base de conhecimento GeneXus X cria tambm dois objetos de tipo Master Page: AppMasterPage: Para a aplicao. PromptMasterPage: Para os prompts. As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em um objeto somente e reutiliz-lo em qualquer outro objeto sem ter que programar. Isto significa que a modificao de alguma parte do layout ou do comportamento comum to fcil como modificar em um nico objeto e pronto! Em uma mesma base de conhecimento podem ser definidas quantas Master Pages como se deseje. Quando estudarmos o objeto Web Panel compreenderemos que uma Master Page ser em particular uma Web Panel categorizado como Master Page com todo o Layout e comportamento comum a todas as pginas do site, dentro deste objeto se deixa um espao para carregar em cada oportunidade a pgina que corresponda (o contedo varivel do site). Isso se faz no controle presente no form de nome Content Placeholder.

67

Transaes
Master Pages
Propriedade Master Page

As pginas web que implementam o contedo varivel, se associam a Master Page, de maneira que cada vez que sejam executadas, carreguem com esse contexto (o da Master Page).

68

Demo
Agregar a transao Product que no foi definida e ver como ficam os cones em Invoice

O que acontece ao fazer F5?

Observe como depois de criar a transao Product GeneXus normaliza e indica graficamente na estrutura da transao Invoice que os atributos, antes prprios da tabela INVOICEDETAIL, agora sero inferidos, atravs da nova chave estrangeira ProductId. A chave primria da tabela INVOICEDETAIL continua sendo composta: {InvoiceId, ProductId}, mas alm disso, o atributo ProductId sozinho, ser uma FK na tabela PRODUCT, a partir da qual se inferem os atributos ProductDescription e ProductPrice. Depois do F5, naturalmente ser informado a necessidade de reorganizar a base de dados, criando a tabela PRODUCT e modificando a tabela INVOICEDETAIL da maneira que indicamos nos pargrafos anteriores. O que acontece com os registros j existentes na tabela INVOICEDETAIL, para os que possuiam valores de ProductDescription e ProductPrice? Como ser visto quando executar, o programa de reorganizao agrega uma rotina para criar os registros de produtos na tabela PRODUCT com essa informao pr-existente. O que acontecer se existia o mesmo produto em vrias linhas de diferentes faturas?

69

INTEGRIDADE REFERENCIAL

70

Integridade Referencial
Diagramas

COUNTRY
1

CountryId* CountryName

CUSTOMER
N

CustomerId* CustomerName CountryId

O conceito de integridade referencial um conceito que se refere s bases de dados relacionais. Se refere que deve fazer a consistncia entre os dados das diferentes tabelas de uma base de dados relacional. As tabelas de uma base de dados relacional esto relacionadas por atributos que tem em comum. Estas relaes implicam que os dados das tabelas no sejam independentes, ou seja, ao inserir, modificar ou eliminar registros de uma tabela tem que ser levado em considerao os dados das outras tabelas para que sempre se conserve a consistncia da informao na base de dados. Se temos um modelo de dados relacional com as tabelas: COUNTRY (CountryId, CountryName) Chave Primria: CountryId CUSTOMER (CustomerId, CustomerName, CountryId) Chave Primria: CustomerId Chave Estrangeira: CountryId (COUNTRY) CustomerAddress, CustomerGender,

O fato do atributo CountryId est na tabela CUSTOMER ser uma chave estrangeira com respeito a tabela COUNTRY, estabelece uma relao entre ambas as tabelas. A relao entre elas pode ser representada com o diagrama mostrado. No Diagrama de Bachman, a seta simplesmente representa a existncia de uma instancia da tabela mostrada, para cada instancia da outra (para cada cliente existe um e somente um pas). A seta dupla representa a ocorrncia de vrias instncias da tabela apontada, para cada instancia de outra tabela (para cada pas, existem muitos clientes). Dizemos que a relao entre a tabela COUNTRY e a tabela CUSTOMER 1 de N (1 a muitos). Reciprocamente, a relao entre CUSTOMER e COUNTRY N de 1 (muitos a 1).
71

Integridade Referencial
Diagramas COUNTRY
1 N
Tem que verificar existncia do COUNTRY referenciado.

CUSTOMER

Na transao Customer: se inserir um novo registro, ou se modificar o CountryId de um registro

COUNTRY
1 N

Na transao Country: se quer eliminar um registro

CUSTOMER

Tem que verificar se no existe nenhum CUSTOMER que o referencie.

Na terminologia GeneXus, dizemos que existe uma relao de subordinao entre ambas as tabelas. Dizemos que: COUNTRY est superordinada a CUSTOMER CUSTOMER est subordinada a COUNTRY Significando que: Quando se cria ou modifica um registro na tabela subordinada (CUSTOMER), deve existir o registro relacionado na tabela superordinada (COUNTRY). Quando se elimina um registro na tabela superordinada (COUNTRY), no devem existir registros relacionados na tabela subordinada (CUSTOMER). Devido a esta relao entre as tabelas, a informao contida nelas no independente, e necessrio realizar controles para que os dados sejam consistentes. A estes controles se chama de Integridade Referencial e basicamente so os seguintes: Quando se insere ou modifica um registro na tabela CUSTOMER, o valor ingressado no atributo que chave estrangeira (CountryId), deve existir como valor de chave primria de um registro na tabela COUNTRY. Quando se elimina um registro na tabela COUNTRY, no devem existir registros na tabela CUSTOMER cujos valores da chave estrangeira (CountryId), sejam iguais ao valor da chave primria do registro que se deseja eliminar. GeneXus gera os programas associados as transaes, incluindo no cdigo gerado estes controles de Integridade Referencial. Por esta razo, se o usurio final insere (ou modifica) um cliente atravs da transao "Customer", validado automaticamente que o valor ingressado no cdigo de pas CountryId, exista como chave primria de um registro na tabela COUNTRY. Em caso de falhar este controle de integridade referencial, uma mensagem mostrada ao usurio indicando que no se encontrou esse pas.

72

Integridade Referencial
ndices

Os ndices so vias de acesso eficientes as tabelas. GeneXus cria automaticamente alguns deles, e outros devero ser criados pelo programador quando este assim o determine, baseando-se em critrios de otimizao. Existem quatro tipos de ndices em GeneXus: Primrios Estrangeiros De usurio Temporrios De todos eles, os nicos que no so criados automaticamente por GeneXus so os de usurio. Enquanto aos tipos de ndices que so criados por GeneXus, a diferena que existe entre eles o momento em que so criados e o tempo durante o qual se mantm. - Os ndices primrios e estrangeiros so criados no momento de criar ou reorganizar as tabelas que compem a base de dados, e depois so mantidos automaticamente por GeneXus. - Os ndices temporrios, por sua vez, so criados ao executar as aplicaes, para acessar a tabelas ordenadas por algum atributo ou conjunto de atributos para ele/eles que no existe um ndice de usurio criado; estes se criam em tempo de execuo das aplicaes, so utilizados e depois so eliminados. NDICES PRIMRIOS E ESTRANGEIROS GeneXus cria para cada tabela um ndice por sua chave primria (ndice primrio), e um ndice por cada chave estrangeira que a tabela tenha (ndices estrangeiros). Por que criar ndices primrios e estrangeiros para as tabelas no incio de forma automtica, sendo que depois devem ser mantidos? Sejam as tabelas COUNTRY e CUSTOMER, que vimos um par de pginas atrs, criadas em nosso modelo de dados a partir das estruturas das transaes "Country" e "Customer. Existe entre estas tabelas uma relao 1-N, que ocorre pelo fato de que o atributo CountryId na tabela CUSTOMER uma chave estrangeira com respeito a tabela COUNTRY.

73

Integridade Referencial
ndices primrios e estrangeiros
CountryId* CountryName
PK

ICountry

ICustomer CustomerId* CustomerName ... FK ICustomer1 CountryId

PK

CountryId CountryName 1 2 3 Uruguay United States China

CustomerId 4 1 3 2

CustomerName Ann Silver John Smith Mary Jones Jessica Deep

CountryId 1 1 1 2

Se na transao Country queremos eliminar United States:

O programa deve buscar sobre CUSTOMER se existe registro com CountryId = 2 para que essa busca seja eficiente: ndice estrangeiro (ICustomer1)

Por existir esta relao, o GeneXus inclui nos programas associados s transaes "Country" e "Customer", os controles de integridade referencial pertinentes. Estes controles so: Se o usurio final insere ou modifica um cliente atravs da transao "Customer", ser validado automaticamente assim que o valor ingressado na chave estrangeira CountryId exista como chave primria de um registro na tabela COUNTRY. Caso o controle de integridade referencial falhe indicado ao usurio que no foi encontrado este pas. Para controlar isto, deve-se buscar na tabela COUNTRY a existncia de um registro que tenha esse valor de CountryId como chave primria; devemos consultar a tabela COUNTRY, buscando pela chave primria, sendo que, a busca pode ser otimizada se existir um ndice pela chave primria em dita tabela. Se o usurio final tentar eliminar um pas atravs da transao "Country" validado automaticamente que no existam clientes no pas atribudo com chave estrangeira; em caso de encontrar um registro na tabela CUSTOMER, cujo valor de chave estrangeira CountryId seja o que se deseja eliminar, ser indicado ao usurio que no possvel eliminar o pas (j que do contrrio ficariam dados inconsistentes na base de dados). Para controlar isto, devemos consultar a tabela CUSTOMER, buscando pela chave estrangeira CountryId. Esta busca ser otimizada se existir um ndice por CountryId na mesma. Controle de unicidade de chave primria Outro controle que o GeneXus tambm inclui nos programas associados s transaes a unicidade da Chave Primria; isto , em nenhuma tabela podero existir dois registros com o mesmo valor na Chave Primria. Para controlar isto, quando o usurio final tentar inserir um registro, validado automaticamente que o valor ingressado para a Chave Primria, no exista como Chave Primria de outro registro na tabela. Para fazer esta busca com eficincia, devemos utilizar o ndice primrio da tabela. Concluindo, o GeneXus ao criar cada tabela da base de dados, cria tambm seu ndice primrio, e um ndice estrangeiro por cada Chave Estrangeira que a tabela contenha. A criao destes ndices permite realizar os controles de integridade referencial e de unicidade de chave primria acessando as tabelas de forma eficiente.

74

Integridade Referencial
ndices de Usurio
O analista os cria sobre uma tabela. Deve ser categorizado conforme for aceito valores repetidos (duplicate) ou no (unique).

Se na realidade modelada, dois clientes podem ter o mesmo nome:

CustomerId 1 2 3

CustomerName Ann Ann Mary

CountryId 1 2 1

NDICES DE USURIO Estes ndices devem ser definidos explicitamente pelo analista. No so definidos automaticamente. Dividem-se em duplicate e unique: Um ndice de usurio duplicate definido para atributos de uma tabela que possam ter vrios registros com o mesmo valor nos mesmo (isto , se define para atributos que no so uma chave candidata). Este tipo de ndices se define fundamentalmente para acessar os dados ordenados por determinados atributos de forma eficiente. Por exemplo, supondo que o nome do cliente no chave na tabela de CUSTOMER (seus valores podem se repetir) poderemos definir um ndice de usurio duplicate para o atributo CustomerName, sendo muito til para realizar consultas e relatrios que necessitem que sejam ordenados por nome. Um ndice de usurio unique utilizado para especificar que um conjunto de atributos chave candidata em uma tabela (diferente da chave primria). Esta a forma de representar chaves candidatas no modelo de dados. Com isso conseguimos que o GeneXus incorpore automaticamente o controle de unicidade correspondente nas transaes associadas. Por exemplo, se o nome do cliente no pode ser repetido, a forma de represent-lo e fazer com que o GeneXus o controle automaticamente definindo na tabela CUSTOMER um ndice de usurio unique pelo atributo CustomerName.

75

Integridade Referencial
ndices de Usurio
Se o nome no pode ser repetido ( portanto um atributo chave da tabela)
CustomerId 1 2 3 CustomerName John Smith Ann Jones Richard Land CountryId 1 2 1

A forma de definir chaves candidatas no modelo de dados atravs de ndices unique. GeneXus passar a incorporar controles nas transaes, utilizando o ndice, para no permitir a insero de registros duplicados. Ao tentar ingressar um novo cliente com nome Ann Jones a transao dar um erro de registro duplicado.

ndices unique (chaves candidatas) Em uma tabela da base de dados podem existir vrios conjuntos de atributos cujos valores sejam nicos na realidade. Dizemos que cada um desses conjuntos uma chave da tabela. Depois, o analista escolhe uma das chaves como a chave primria. GeneXus identifica a chave primria da tabela de acordo com os atributos que foram qualificados pelo analista com o smbolo da chave. Vamos supor que na realidade alm de poder identificar um cliente por seu cdigo ou possa ser identificado por sua carteira de identidade. Neste caso tanto o atributo CustomerId como o atributo CustomerSSN (armazena o Nro da Carteira de Identidade) seriam chaves da tabela CUSTOMER. Ao indicar que CustomerId o identificador da transao, o GeneXus cria automaticamente um ndice primrio para dito atributo e controla a unicidade dos valores ingressados para o mesmo. O que acontecer com a carteira de identidade do cliente? Ao ser este atributo chave, queremos que o GeneXus garanta da mesma forma, no permitindo que seja inserido um registro, j existindo outro com o mesmo valor da carteira de identidade (CustomerSSN). Para poder fazer este controle de forma eficiente, o GeneXus deveria ter um ndice para cada atributo chave. A forma de definir em GeneXus que um atributo ou um conjunto de atributos Chave alternativa ou candidata e que para tanto deve-se checar sua unicidade, definindo um ndice de usurio composto por esse atributo ou conjunto de atributos, e o qualificando como unique ao invs de duplicate, que o valor por default de um ndice de usurio. A partir da, GeneXus inclui na lgica da transao esse controle de unicidade utilizando esse ndice definido pelo usurio. Em resumo, as transaes GeneXus realizam automaticamente os seguintes controles: . Integridade referencial . Unicidade de chave (tanto primria como candidatas)
76

Integridade Referencial
ndices Temporrios
So criados automaticamente, sob certas condies, quando so necessrios, e so eliminados quando termina a execuo do objeto que os criou. Se deseja acessar os dados ordenados por determinados atributos, mas no se deseja criar um ndice permanente para ele: GeneXus cria um ndice temporrio. Em algumas plataformas, as consultas para as quais se quer obter o resultado ordenado por determinados atributos, e no existe o ndice de usurio, so resolvidos pelo DBMS correspondente sem a criao de ndices temporrios. O usurio pode resolver deixar de utilizar um ndice temporrio, criando um ndice de usurio.

NDICES TEMPORRIOS Quando se deseja acessar os dados ordenados por determinados atributos, mas no se deseja criar um ndice permanente para ele (por exemplo, porque se trata de uma consulta que se realiza com pouca freqncia), ento, dependendo da plataforma, um ndice temporrio criado.

77

Integridade Referencial
Gerncia de nulos

Para cada atributo no inferido, e que no seja o identificador na estrutura de uma transao, possvel definir para a tabela associada se vai ser nulo ou no

A permisso ou no do valor <NULL> na base de dados muito importante no modelo relacional. Permitir o valor null para um atributo dado, significa que pode em certas circunstncias, ser ignorado visto que valor no especificado. Por outro lado, o atributo no permitindo valor null, um valor vlido deve sempre ser atribudo a ele. A propriedade Nulls (apresentada como coluna no editor de estrutura de transaes), permite configurar para cada atributo se admite ou no valor null na tabela associada. Os atributos que podem ser configurados desta forma, so aqueles armazenados nas tabelas associadas na transao (isto , no inferidos) sempre e quando no forem atributos primrios nestas tabelas (j que por definio as chaves primrias no suportam valor null). Resumindo: o objetivo desta propriedade definir qual valor vai ser armazenado na base de dados quando no for digitado nada no campo (o valor <NULL> ou o valor empty).

78

Integridade Referencial
Gerncia de nulos
A propriedade Nulls aceita os seguintes valores: - No: Valor por default. O atributo na tabela associada, no permitir valor null - Yes: o atributo na tabela associada, admitir valor null

Atributos que fazem parte da chave primria no suportam valor null (propriedade Nulls = No, sempre) Atributos da chave estrangeira aceitam nulo e isto repercute nos controles de integridade referencial.

Os valores possveis de serem configurados para essa propriedade Nulls so: No: significa que o atributo no permite o valor null na tabela associada (valor por default) Yes: significa que o atributo permite o valor null na tabela associada. A definio de nulls utilizada por GeneXus no momento de criar/reorganizar as tabelas da base de dados, j que o suporte ou no suporte de nulabilidade dos atributos em sua tabela, se define a nvel da base de dados. Ou seja que modificar o valor da propriedade Nulls para um atributo vai implicar em executar uma reorganizao (para redefinir a nvel da base de dados o suporte de nulabilidade do atributo em sua tabela).

79

Integridade Referencial
Gerncia de nulos
Repercusso em controles de integridade referencial

CountryId* CountryName

CountryId* CityId* CityName

FK composta

CustomerId* CustomerName CountryId CityId

1) CountryId e CityId com propriedade Nulls=No As checagens de IR mostradas acima so realizadas 2) CityId com propriedade Nulls=Yes Um controle de IR em CUSTOMER agreagado nulo CityId, realiza checagem contra COUNTRY. se deixar

Repercusso em controles de integridade referencial A definio de nulls para atributos que formam uma chave estrangeira diz ao GeneXus quo forte a referncia a outra tabela. Se nenhuns dos atributos que compem uma chave estrangeira permitem valores nulos (caso 1), trata-se de uma referncia forte (tambm conhecida como not null reference), j que estabelecido que a FK dever sempre apontar a um registro existente da tabela referenciada. Outro caso, se uma chave estrangeira que tenha pelo menos um atributo que suporte nulos (caso 2), se estabelece uma referncia fraca (tambm conhecida como null reference), j que se algum dos atributos que formam parte da chave estrangeira so nulls, ento a referncia no ser checada. Quando uma chave estrangeira composta e os nulos so permitidos para alguns de seus atributos, podem aparecer novas referencias (no checadas caso possua referncias fortes) se os atributos restantes compem tambm uma chave estrangeira. Um exemplo o apresentado acima, onde se o usurio deixar nulo o valor de CityId para um cliente, se realizar a checagem de IR contra COUNTRY, para assegurar que o pas ingressado esteja correto.

80

Integridade Referencial
Gerncia de nulos
Diferena entre valor empty e null para atributos: empty: um valor (0 para Numeric, para Character, etc.) null: se permitido, no um valor. Significa que o valor deve ser considerado como: no especificado no disponvel no atribudo desconhecido

Mtodos segundo se o atributo permite null ou empty: IsEmpty IsNull SetEmpty SetNull

Mtodos para trabalhar com nulos e vazios IsEmpty, IsNull: devolvem true quando o atributo contem respectivamente.

valor empty ou null

SetEmpty, SetNull: configuram no atributo o valor empty ou null, respectivamente. Exemplos: * error(You must specify a name) if CustomerName.IsEmpty(); * msg(Warning: You didnt specify a Country) if ContryId.IsNull();

81

TABELA BASE E TABELA ESTENDIDA

82

Os critrios de normalizao do desenho da base de dados servem para minimizar a possibilidade de inconsistncia dos dados. Uma base de dados desenhada desta maneira tem uma srie de vantagens importantes (tanto assim que atualmente a normalizao de dados um padro de desenho), mas que deve ser considerado tambm alguns inconvenientes. O inconveniente mais notrio que os dados se encontram dispersos em muitas tabelas, e muitas vezes quando se quer realizar consultas mais ou menos complexas base de dados, devemos consultar uma quantidade importante de tabelas. Assim, por exemplo, se o seguinte Diagrama representa nosso modelo de dados:

para listar as faturas seria necessrio consultar as tabelas: INVOICE e INVOICEDETAIL (linhas de faturas), CUSTOMER, COUNTRY e PRODUCT. Para simplificar esta tarefa GeneXus utiliza o conceito de tabela estendida. Chamamos tabela base a qualquer tabela da base de dados na qual estamos posicionados em determinado momento; e dada certa tabela base, sua tabela estendida alcanar todos os atributos da prpria tabela base, mas todos os atributos das tabelas que tenham informao relacionada unicamente com a tabela base (relao N-1 desde a tabela base, direta e indiretamente).

83

Tabela Base e Tabela Estendida


INVOICE
InvoiceId* InvoiceDate CustomerId

CUSTOMER
CustomerId* CustomerName CountryId

COUNTRY
CountryId* CountryName

INVOICEDETAIL
InvoiceId* ProductId* InvoiceLineQuantity InvoiceLineAmount

PRODUCT
ProductId* ProductDescription ProductPrice ProductStock

Utilizando o diagrama fcil determinar qual a tabela estendida correspondente a uma tabela base qualquer: Partindo da tabela base, devem-se seguir as relaes N-1 (devem-se seguir as setas que tem ponta dupla partindo da tabela base e ponta simples no outro extremo). Todas as tabelas as quais se pode chegar seguindo as setas que representam relaes N-1 da tabela base, formaram parte de sua tabela estendida. O seguinte quadro mostra a tabela estendida correspondente a cada uma das tabelas de nosso modelo de dados:

84

Regras
So utilizadas para definir o comportamento das transaes. Algumas regras: Default Atribuio Msg Error Noaccept Add Subtract Serial Update Podem incluir: atributos, variveis, constantes e funes. So LOCAIS a transao. Programao DECLARATIVA.

No objeto transao as regras cumprem um rol muito importante, j que permitem programar seu comportamento (por exemplo: atribuir valores por default, definir controles sobre os dados, etc.). So escritas de forma declarativa, ou seja, a ordem em que se escreve no significa a ordem de execuo. Podem envolver os atributos definidos na estrutura da transao, assim como as variveis definidas dentro do objeto, constantes e funes. Somente so vlidas dentro da transao na qual esto definidas, ou seja, so locais.

___________________________________________________________________________
1 Todas as regras das transaes podem utilizar atributos das tabelas base associadas a transao; e a maior parte delas pode tambm utilizar atributos das tabelas estendidas de ditas tabelas base. Para um atributo poder ser referenciado em regra, o mesmo deve estar includo na estrutura da transao (seja que pertena a alguma das tabelas base associadas da transao ou as suas tabelas estendidas).

85

Algumas regras vlidas para transao so: Default OBJETIVO: Permite atribuir um valor por default para um atributo ou varivel; o valor por default inicialiaza o atributo ou a varivel quando est sendo realizada uma insero atravs da transao (modo Insert), mas o usurio final pode alterar esse valor se no for o desejado. SINTAXE: Default( att | &var, exp ); ONDE: att: um atributo que pertence a alguma das tabelas base associadas na transao. var: o nome de uma varivel. exp: uma expresso que pode envolver constantes, funes, variveis ou outros atributos. FUNCIONALIDADE: Esta regra atribui o valor da expresso exp como valor por default do atributo att ou varivel var, quando a transao executada em modo Insert. Esta regra no vlida para atributos que formam parte da chave primria de algum dos nveis da transao, porque disparada logo que a chave informada (j que somente nesse momento o modo conhecido e esta regra disparada somente em modo Insert EXEMPLOS: Default( InvoiceDate, &today ); /* Regra definida na transao Invoice */

Quando uma Invoice nova inserida, se sugere o valor de InvoiceDate o valor contido na varivel do sistema &today. Default( InvoiceDate, Today()); /* Regra definida na transao Invoice */

Anloga a anterior, a diferena que ao invs de utilizar a varivel do sistema today, se utiliza a funo Today que devolve a data correspondente ao dia. Default( InvoiceLineAmount, ProductPrice*InvoiceLineQuantity); /* Regra definida na transao Invoice */ Quando uma linha da fatura inserida, se sugere que o atributo InvoiceLineAmount (valor da linha) receba o valor resultante da expresso ProductPrice*InvoiceLineQuantity (preo do produto vezes a quantidade levada do mesmo). Nota: O tipo de dados da expresso deve coincidir com o tipo de dados do atributo ou varivel. Regra de atribuio OBJETIVO: Permite atribuir a um atributo ou a uma varivel, o valor de uma expresso. SINTAXE: att | &var = exp [if cond] [on evento / momento de disparo]; ONDE: att: um atributo que pertence alguma das tabelas base associadas a transao, ou a suas estendidas (deve estar declarado na estrutura). var: o nome de uma varivel. exp: uma expresso que pode envolver constantes, funes, variveis ou outros atributos, e deve ser do mesmo tipo que att ou var. cond: uma expresso booleana (pode conter os operadores lgicos and, or, not) evento/momento de disparo: um dos eventos predefinidos do GeneXus disponveis para regras de transaes, que permitem definir o momento especfico de execuo de uma regra. FUNCIONALIDADE: Uma regra deste tipo permite atribuir ao atributo ou varivel que fica a esquerda, o valor resultante da expresso. Como se pode ver, a condio opcional; se ela no for definida, a atribuio realizada sempre. A atribuio a um atributo, implica sua atualizao no registro que corresponda. A atribuio a um atributo, implica em sua atualizao no registro que corresponda. As regras de atribuio podem ser definidas aos atributos de alguma das tabelas bases associadas a transao, incluso de suas estendidas. Isto significa que os atributos inferidos podem ser atualizados em uma transao (sendo necessrio os declarar na estrutura).
86

EXEMPLO: InvoiceLineAmount = ProductPrice * InvoiceLineQuantity; /* Regra definida na transao Invoice */ Se o valor de cada linha de uma fatura calculado sempre multiplicando o preo do produto vezes a quantidade levada do mesmo, podemos utilizar esta regra de atribuio para que o usurio no precise realizar o clculo. Error OBJETIVO: Permite mostrar uma mensagem de erro se a condio seja satisfeita. Serve para definir os controles que os dados devem cumprir. SINTAXE: Error( msg | &var | character expresion, msgId ) if cond [on evento/momento de disparo]; ONDE: msg: uma string com uma mensagem de error a mostrar var: o nome de uma varivel de tipo caractere, que contm uma string com uma mensagem de erro a mostrar character expression: uma expresso cujo tipo resultante, caractere e que ser mostrada msgId: uma string (sem espaos em branco nem aspas) que ser utilizado somente se a transao definida tambm como business component1. cond: tipo booleana (que pode conter os operadores lgicos and, or, not) evento/momento de disparo: um dos eventos pr-definidos do GeneXus disponveis para regras de transaes, que permitem definir o momento especfico da execuo de uma regra. FUNCIONALIDADE: Esta regra mostra a mensagem do parmetro msg, var ou expresso caractere, se a condio cond avaliada resulta como verdadeira. A mensagem de erro aparece em uma tela pop-up quando o ambiente de trabalho Windows e no controle Error Viewer e/ou um quadro texto quando o ambiente de trabalho Web, detendo qualquer atualizao na base de dados. Quando a transao executado como business component (estudaremos este tema mais adiante), ao disparar o error, gera um entrada no SDT messages, com identificador msgId. EXEMPLOS: Error(Informe o Nome do Cliente) if CustomerName.isEmpty(); /*Regra definida na transao Customer*/ Se avalia a condio CustomerName.isEmpty(), e se for satisfeita, mostra a mensagem Informe o Nome do Cliente na tela. No permite continuar at que o usurio ingresse um nome no campo CustomerName ou abandone a transao (nesse caso no realizada nenhuma atualizao na base de dados). Error(Fatura no pode ser eliminada) if Delete; /* Regra definida em a transao Invoice */ Necessita proibir a eliminao de faturas. Com esta regra, se o usurio tentar realizar uma eliminao, a condio dar True e se dispara a regra, evitando a eliminao.

Msg

OBJETIVO: Permite mostrar uma mensagem de advertncia se a condio for satisfeita SINTAXE: Msg( msg | &var | character expresion, msgId) if cond [on evento/momento de disparo]; ONDE: msg, var, character expresion, msgId, cond, evento/momento de disparo: so os mesmos que para a regra error. Observar que a sintaxe exatamente a mesma. FUNCIONALIDADE: Esta regra se utiliza para apresentar mensagens de advertncia ao usurio. Mostra a mensagem do primeiro parmetro, se a condio satisfeita, analogamente a regra Error; mas a diferena desta ltima, permite continuar com a execuo se a condio segue sendo satisfeita. Do mesmo modo, se a transao business component1, se disparar a regra gera entrada no SDT messages. As mensagens de advertncia so mostradas no Error Viewer.
__________________________________________________________________________________________ 1 Este tema ser visto mais adiante no curso.

87

EXEMPLO: Msg( Nome do Cliente no foi informado ) if CustomerName.isEmpty(); /*Regra definida na transao "Customer*/ Se avalia a condio CustomerName.isEmpty(), e se esta se satisfaz mostra-se a mensagem Nome do Cliente no foi informado. A diferena que ocorre com a regra Error, que aqui permitido continuar a execuo, pois no se trata de um erro e sim de uma advertncia. Noaccept OBJETIVO: Permite indicar que o atributo no aceite valores por parte do usurio (ser somente de sada). SINTAXE: Noaccept(att) [if cond] [on evento/momento de disparo]; ONDE: att: um atributo pertencente a alguma(s) da(s) tabela(s) base(s) associada(s) transao cond: uma expresso booleana (pode conter os operadores lgicos and, or, not) Evento/momento de disparo: um dos eventos predefinidos pelo GeneXus disponveis para regras de transaes, que permitem definir o momento especfico de execuo de uma regra. FUNCIONALIDADE: em uma transao, todos os atributos que pertencem as tabelas base associadas a transao, por default so aceitos. Se quisermos que um atributo destas caractersticas no seja aceito, ento contamos com a regra Noaccept. EXEMPLO: Noaccept( InvoiceDate) if Update; /* Regra definida na transao Invoice */ Se est modificando uma fatura (modo Update), no permitido que seja modificada sua data. Subtract OBJETIVO: Subtrai o valor de um atributo ao valor de outro atributo, se satisfaz a condio especificada. SINTAXE: subtract(att1, att2) [if cond]; ONDE: att1, att2: so atributos pertencentes a alguma das tabelas base associadas transao, ou a suas tabelas estendidas (e devem estar declarados na estrutura). cond: uma expresso booleana (que pode conter os operadores lgicos and, or, not). FUNCIONALIDADE: A subtrao realizada levando em considerao o modo que se esteja trabalhando na transao (Insert, Update ou Delete). Em modo: - Insert: subtrai o valor do atributo att2, o valor do atributo att1 - Delete: soma a valor de att2, o valor do atributo att1 - Update: subtrai o valor do atributo att2, a diferena entre o valor novo e o velho do att1 EXEMPLO: Na transao Invoice, cada vez que se ingressa uma linha com um produto que se est comprando, se deve diminuir o stock do mesmo, segundo a quantidade levada. Isto poderia ser feito de forma simples com a seguinte regra de atribuio: ProductStock = ProductStock InvoiceLineQuantity; Se prestarmos ateno, todavia, vemos que esta regra no nos serve, pois no est condicionada a um modo particular, razo pelo qual ser disparada tanto quando estiver inserindo uma nova linha na fatura, como quando se est eliminando ou modificando uma j existente. Nestes ltimos dois casos incorreto disparar a regra.

88

De fato, quando eliminada uma linha existente, a operao contrria deve ser realizada, ou seja, devolver ao estoque o que havia sido quitado quando se inseriu a linha. O correto ento, tendo em conta todos os casos possveis seria ter 3 regras: ProductStock =ProductStock - InvoiceLineQuantity if Insert; ProductStock =ProductStock + InvoiceLineQuantity if Delete; ProductStock=ProductStock + old(InvoiceLineQuantity) InvoiceLineQuantity if Update; Aqui estamos utilizando a funo old, que devolve o valor armazenado do atributo ( o valor antes de modificlo). Para evitar fazer tudo GeneXus fornece a regra subtract que se encarrega de fazer a atribuio correta de acordo ao modo. Ento podemos substituir as 3 atribuies anteriores, por: subtract( InvoiceLineQuantity, ProductStock); Esta regra tem a inteligncia para, dependendo do modo, subtrair ou somar, Add OBJETIVO: Soma o valor de um atributo ao valor de outro atributo, se a condio especificada for satisfeita. SINTAXE: add( att1, att2) [if cond]; ONDE: att1, att2 : so os atributos pertencentes a alguma das tabelas base associadas a transao, ou a suas estendidas (e devem estar declarados na estrutura). cond: uma expresso booleana. FUNCIONALIDADE: a adio realizada considerando o modo da transao (Insert, Update ou Delete). Modo: - Insert: soma ao valor do atributo att2, o valor do atributo att1 - Delete: subtrai ao valor de att2, o valor do atributo att1 - Update: soma ao valor do atributo att2, a diferena entre o valor novo e o velho de att1 EXEMPLO: Definimos na transao "Customer", um atributo de nome CustomerTotalPurchases, para registrar o valor total de compras efetuadas pelo mesmo. O comportamento desejado que cada vez que for criado uma fatura para um cliente, seja somado o total da fatura (InvoiceTotal) ao total de compras efetuadas pelo cliente (CustomerTotalPurchases). Como vimos na regra subtract, no devemos esquecer que na transao Invoice podemos tambm eliminar e modificar Invoice, e no somente cri-las; para tanto importante ter em conta o modo de trabalho na transao (Insert, Update, Delete). O GeneXus nos libera de termos que considerar os modos, tendo que escrever as seguintes 3 regras de atribuio na transao Invoice : CustomerTotalPurchases = CustomerTotalPurchases + InvoiceTotal if Insert; CustomerTotalPurchases = CustomerTotalPurchases InvoiceTotal if Delete; CustomerTotalPurchases = CustomerTotalPurchases old(InvoiceTotal) + InvoiceTotal if Update; Ao invs disso o GeneXus nos brinda com a regra add, que encarrega de somar ou diminuir, dependendo do modo.

89

Se agregarmos na transao "Customer o atributo CustomerTotalPurchases (total de compras do cliente): CustomerId* CustomerName CustomerAddress CustomerGender ... CustomerTotalPurchases E na transao Invoice inferimos o atributo CustomerTotalPurchases estendida -, podemos definir a regra: add(InvoiceTotal, CustomerTotalPurchases); E conseguimos o comportamento desejado, que : se insere uma fatura (Insert): soma ao valor do atributo CustomerTotalPurchases, o valor do atributo InvoiceTotal se elimina uma fatura (Delete): subtrai ao valor do atributo CustomerTotalPurchases, o valor do atributo InvoiceTotal se modifica uma fatura (Update): soma ao valor do atributo CustomerTotalPurchases, a diferena entre o valor novo e o velho de InvoiceTotal que pertence a tabela

Serial

OBJETIVO: Permite serializar (auto-numerar) atributos numricos. SINTAXE: Serial( att1, att2, step); ONDE: att1 : um atributo pertencente a alguma das tabelas base associadas transao (isto ,no inferido), que deseja serializar (depende de estar declarado na estrutura). att2 : deve pertencer a uma tabela diretamente superordinada do atributo att1. step: o passo ou incremento da serializao FUNCIONALIDADE: o propsito desta regra atribuir um nmero correlativo att1 cada vez que inserido um registro na tabela que pertence att1. Toma-se o valor de att2 att2 contm o ltimo nmero utilizado na auto-numerao), incrementa-se o valor do parmetro step, e o valor resultante atribudo tanto ao atributo att1 do novo registro, como ao atributo att2 para conservar o ltimo nmero atribudo. Quando um registro inserido por meio de uma transao na qual foi definida a regra: Serial (att1, att2, step), se acesse ao att2 (haver um s valor deste atributo relacionado, pois pertence a uma tabela diretamente superordinada), soma-se o valor step, e se atribui o valor obtido tanto a att1 do registro que vai inserir, como a att2 pertencente a uma tabela diretamente superordinada com respeito tabela que contem a att1. Desenha a transao "Invoice" contendo um Nmero de linha de Invoice (atributo InvoiceLineId) como identificador nico do segundo nvel. A estrutura da transao seria: INVOICE { InvoiceId* CustomerId CustomerName InvoiceDate InvoiceLastLineId { INVOICEDETAIL InvoiceLineId* ProductId ProductDescription

90

Neste desenho o atributo ProductId unicamente.

no o identificador nico do nvel, e sim a chave estrangeira

Cada linha tem um nmero de linha que identificada de forma nica, possvel ingressar o mesmo produto em distintas linhas. Pode ser til atribuir por meio do sistema, nmeros correlativos ao campo InvoiceLineId, definindo a regra: Serial (InvoiceLineId, InvoiceLastLineId, 1); O primeiro parmetro da regra serial define qual o atributo a ser numerado automaticamente, no segundo parmetro deve ser indicado um atributo cuja funo guardar o ltimo valor atribudo at o momento, e por ltimo o terceiro parmetro para indicar o incremento (neste caso se incrementa de um em um). O segundo parmetro (no exemplo InvoiceLastLineId) deve pertencer a uma tabela diretamente superordinada tabela que contm o atributo que se deseja numerar automaticamente (InvoiceLineId). A regra serial o requer assim. No exemplo, pode ser observado que InvoiceLastLineId encontra-se na tabela de chave InvoiceId*, a qual diretamente superordinada tabela que contm o atributo numerar (InvoiceLineId). Isto , cada fatura ter no cabealho, um atributo que armazena o ltimo nmero de linha atribudo at o momento (InvoiceLastLineId). A regra serial est implementada de forma que necessita deste atributo (para fixar o ltimo nmero utilizado, som-lo ou incremento, e atribuir o prximo nmero da nova linha). Considerao: A regra serial til na hora de auto-numerar (serializar) linhas, no em cabealhos (por exemplo, nmeros de faturas, nmeros de clientes, etc.). Para utiliz-la precisa definir um atributo em uma tabela diretamente superordinada; isto resulta que se desejarmos auto-numerar linhas devemos incluir este atributo no nvel da estrutura imediatamente superior ao do atributo a serializar.

91

Contamos com uma soluo muito mais simples para autonumerar cabealhos: quando uma tabela tem uma chave simples ( formada por somente um atributo) e o tipo de dados numrico, pode numerar-se automaticamente utilizando a funcionalidade que fornecem os administradores de base de dados para isto. A forma de indic-lo em GeneXus configurando a propriedade Autonumber do atributo chave:

Se na propriedade Autonumber de um atributo numrico chave, selecionar o valor True, significa que ser realizada a numerao automtica do mesmo. Sero agregadas as seguintes propriedades no dilogo: Start: Mediante esta propriedade se configura a partir de qual nmero comea a numerao automtica. Step: Mediante esta propriedade possvel configurar o incremento do campo (entre dois registros). For replication: Esta propriedade somente vlida para o motor de base de dados SQL Server; o valor Yes indica a este que no deve aplicar a propriedade em caso de que a tabela seja receptora de replicao (mas que deve manter os nmeros vindos da replicao). Para maiores detalhes desta propriedade, recomendamos acessar ao Help de GeneXus.

92

Update
OBJETIVO: Possibilita atualizar no form de uma transao (Win/Web) atributos da tabela estendida (inferidos). SINTAXE: Update( att1[, atti ]); ONDE: atti: um atributo pertencente a tabela estendida de alguma das tabelas bases associadas a transao. FUNCIONALIDADE: Em uma transao, todos os atributos que pertencem as tabelas associadas a transao, por default so aceitos e os que pertencem a tabela estendida, no pertencem a base, so inferidos, e portanto no aceitos. Mas se queremos que estes atributos inferidos sejam aceitos, para que o usurio possa modificar a partir do form seu valor, ento temos a regra Update. EXEMPLO:

InvoiceId* InvoiceDate CustomerId CustomerName

CustomerId* CustomerName

update(CustomerName);

93

Regras
Conceitos importantes

Em qual nvel de uma transao so executadas as regras definidas na mesma?

Como condicionar regras para que sejam executadas em determinados modos?

Em qual nvel de uma transao so executadas as regras definidas na mesma? Na maioria das vezes no necessrio agregar explicitamente na definio das regras o nvel da transao no qual se deseja que sejam disparadas, j que os atributos envolvidos nas regras guiam GeneXus ao nvel correspondente para execut-las. Por exemplo, se uma regra referencia unicamente a atributos do primeiro nvel da transao na qual se encontra definida (seja na prpria regra ou na condio de disparo), GeneXus entende que a mesma estar associada ao primeiro nvel da transao. Analogamente, se uma regra referencia somente atributos do segundo nvel da transao na qual est definida (seja na prpria regra ou na condio de disparo), GeneXus entende que a mesma estar associada ao segundo nvel da transao. No caso que uma regra referencie atributos de vrios nveis, GeneXus entende que a regra est associada ao ltimo dos nveis dos atributos envolvidos, j que ser no ltimo nvel que ter os valores de todos os atributos implicados. Em seguida apresentaremos exemplos concretos: 1) Se define a seguinte regra na transao Invoice: Default(InvoiceDate, &today); como o nico atributo que se menciona na regra InvoiceDate, e um atributo do primeiro nvel da transao, GeneXus determina que se trata de uma regra associada ao primeiro nvel. 2) Se definir a seguinte regra na transao Invoice: subtract( InvoiceLineQuantity, ProductStock ); como os dois atributos mencionados na mesma se encontram no segundo nvel da transao, GeneXus determina que se trata de uma regra associada ao segundo nvel.

94

3) Se definir a seguinte regra na transao Invoice:

InvoiceLineDiscount= InvoiceLineAmount * CustomerDiscountPercentage/100; sendo InvoiceLineDiscount (desconto correspondente a uma linha) um atributo pertencente ao segundo nvel da transao Invoice e CustomerDiscountPercentage (porcentagem de desconto ortogado a um cliente) um atributo declarado no primeiro nvel da transao Invoice, GeneXus determina que se trata de uma regra associada ao segundo nvel da transao. Quando nos referimos que uma regra est associada a determinado nvel, significa que a mesma se executa para cada instancia com a qual se trabalhe atravs desse nvel (se cumprir com a condio de disparo da regra). No caso do primeiro exemplo visto, a regra Default(InvoiceDate, &today) uma regra associada ao primeiro nvel da transao Invoice. Isto significa que ao executar todo cabealho de fatura inserido atravs do primeiro nvel da transao Invoice (a regra Default tem a particularidade de se disparar unicamente quando o modo de execuo Insert). No caso do segundo exemplo visto, a regra subtract(InvoiceLineQuantity, ProductStock) uma regra associada ao segundo nvel da transao Invoice. Isto significa que executando toda linha da fatura que se insira, atualize ou elimine atravs do segundo nvel da transao Invoice. No caso do terceiro exemplo, a regra: InvoiceLineDiscount = InvoiceLineAmount * CustomerDiscountPercentage/100 uma regra associada ao segundo nvel da transao Invoice. De modo que esta regra se executa para toda linha da fatura que se insira, atualize ou elimine atravs do segundo nvel da transao Invoice. Concluindo, para cada fatura com a qual se trabalhe atravs da transao Invoice: - para o cabealho: so executadas as regras associadas ao primeiro nvel - para cada uma das linhas: so executadas as regras associadas ao segundo nvel importante saber que como norma geral GeneXus sempre determina que uma regra seja disparada no primeiro momento possvel, isto , naquele momento que tenha todos os dados necessrios. E somente em alguns casos que assim o requeiram, a mesma regra voltar a ser disparada mais adiante. Qual nvel de disparo por default associado uma regra que no referencia atributos? Quando no tem atributos envolvidos numa regra, o nvel associado por default a regra ser o primeiro. Por exemplo, a seguinte regra definida na transao Invoice: Error(Faturas no podem ser eliminadas) if Delete; no tem atributos envolvidos, portanto, o nvel associado por default a regra ser o primeiro. Quando tem que especificar explicitamente o nvel de disparo de uma regra? Existe uma clusula opcional de nome Level que permite modificar o nvel por default de disparo de uma regra, alterando-o por um nvel posterior. Isto , se por exemplo uma regra se executa por default para o primeiro nvel de uma transao e se deseja que se execute para o segundo, se dever agregar a regra ou componente Level seguido de um atributo ou conjunto de atributos do segundo nvel. Isto far que a regra se execute para cada uma das instancias correspondentes as linhas, e no para a instancia correspondente ao cabealho como era o comportamento por default. Por exemplo, se definimos a seguinte regra na transao Invoice: msg(A data da fatura maior que a data atual) if InvoiceDate > &Today; por default esta regra est associada ao primeiro nvel da transao, j que o nico atributo referenciado na regra se encontra no primeiro nvel da transao. Se por algum motivo desejamos que a regra se execute para cada uma das instancias correspondentes as linhas em vez de executar-se para a instancia correspondente ao cabealho, teremos que agregar na definio da regra, a clusula Level seguida de um ou vrios atributos do segundo nvel: msg(A data da fatura maior que a data atual) if InvoiceDate>&Today Level InvoiceLineAmount;

95

Agregar a clusula Level a uma regra somente faz sentido se a continuao da mesma so mencionados atributos que so de algum nvel posterior aos nveis dos atributos implicados na definio da regra em si. No seguinte exemplo, o fato de ter agregado a clusula Level a regra no agrega mais informao visto que o atributo que j tem essa informao na definio da prpria regra: msg(A data da fatura maior que a data atual) if InvoiceDate > &Today Level CustomerId; fcil compreender que o atributo InvoiceDate j guia GeneXus que se trata de uma regra associada ao primeiro nvel, assim que o especificado pela clusula Level no exemplo no contribui mais informao e portanto desnecessrio. Por ltimo, no exemplo que segue: InvoiceLineDiscount= InvoiceLineAmount * CustomerDiscountPercentage/100 Level InvoiceDate; se incluiu a clusula Level na definio da regra, como o atributo que segue a clusula de um nvel superior ao nvel dos atributos referenciados na regra, a clusula Level definida no contribuiu com informao til neste caso. Isto , no possvel que possuindo atributos envolvidos de um segundo nvel em uma regra, a mesma se execute no primeiro nvel, j que no primeiro nvel no tem informao do ou dos nveis inferiores (alm de que tem N instancias para os nveis inferiores). De modo que a regra seguir estando associada ao segundo nvel da transao Invoice, no contribuindo com informao til da clusula Level neste exemplo. Concluindo, a clusula Level somente faz sentido que seja agregada para modificar o nvel por default de disparo de uma regra, a um nvel posterior. Como condicionar regras para que se executem em determinados modos? GeneXus fornece as seguintes funes booleanas para poder inclu-las na condio de disparo das regras com o objetivo de limit-las que se executem pontualmente em alguns dos modos possveis:

Insert Update Delete

Exemplos de uso (todas as regras correspondem a transao Invoice) 1) Noaccept( InvoiceDate ) if Update; Se est modificando uma fatura (modo Update), no se permite que sua data seja modificada. Se a regra foi definida sem condio de disparo que temos explicitado, o atributo InvoiceDate fica desabilitado em todos os modos de execuo. 2) Error( Faturas no podem ser eliminadas ) if Delete; Se tentar eliminar uma fatura, se dispara o error impedindo a eliminao. Como no tem atributos envolvidos na regra, por default o nvel associado a regra ser o primeiro. 3) Error( Linhas da Faturas no podem ser eliminadas ) if Delete Level InvoiceLineQuantity; Se tenta eliminar uma linha de uma fatura, se dispara o error impedindo a eliminao. Observar que se tem explcito na regra a clusula Level seguida de um atributo do segundo nvel da transao Invoice, para indicar que se deseja que a mesma esteja associada ao segundo nvel da transao.

96

Frmulas

97

Frmulas
Objetivos e Definio

Definir frmulas possibilita compartilhar conhecimento e obter cdigo gerado otimizado

Quando o valor de um atributo ou varivel pode ser calculado a partir de outros atributos, constantes e/ou funes, pode ser definida como uma frmula

Contamos com 2 formas de definir frmulas: - Globais: A nvel da Base de Conhecimento - Locais: Entre certo cdigo
Veremos este conceito mais adiante com mais conhecimento GeneXus

Veremos este conceito em primeiro lugar

Quando definirmos uma frmula, GeneXus pode combinar a consulta / clculo associada a frmula com a consulta na qual a frmula est presente e assim gerar sentenas otimizadas.

98

Frmulas
Globais

Frmula Global = atributo onde o analista GeneXus atribui um clculo associado Somente atributos podem ser definidos como frmulas globais, variveis no podem Como a realizada a definio?

Acessando o editor de frmulas a partir da estrutura da transao

99

Frmulas
Globais

Dizemos que: atributos frmulas globais = atributos virtuais

Significando que:
- No so criados como atributos fsicos - Para cada objeto que referencie um atributo frmula global, GeneXus incluir em seu programa gerado o cdigo necessrio para realizar o clculo e mostr-lo em tempo de execuo

Tabela base / Tabela associada a um atributo frmula global:


- Tabela na qual o atributo seria armazenado se no fosse frmula

Como explicamos neste slide, os atributos definidos como frmula global, no so criados como campos fsico em tabelas, dizemos que so atributos virtuais. Todavia, dizemos que tem uma tabela associada ou tabela base, para conhecer o contexto na qual foi definida, e contar com esse contexto do momento de disparar o clculo correspondente onde for referenciado.

100

Frmulas
Classificao

Horizontais: Uma ou vrias expresses aritmticas


Aggregate: Sum, Count, Average, Max, Min, Find Compostas: Conjunto de expresses Horizontais e/ou Aggregate
TODAS PERMITEM INCLUIR CONDIO DE DISPARO PODE SER GLOBAIS E LOCAIS

Importante:

- Quando definirmos frmulas no GeneXus no indicamos a classificao


- A classificao externa ao GeneXus e sua finalidade agrupar frmulas por:
Tipo de clculo oferecido Atributos que podem ser envolvidos na sua definio

101

Frmulas
Classificao

Exemplo de Frmula Horizontal (Global) :


Customer { CustomerId* CustomerName CustomerTotalPurchases CustomerTotalPayments CustomerBalance }

CustomerTotalPurchases CustomerTotalPayments
DEIXA DE PERTENCER FISICAMENTE A TABELA

TABELA CUSTOMER CustomerId* CustomerName CustomerTotalPurchases CustomerTotalPayments

Na definio de um atributo como frmula horizontal, possvel envolver atributos pertencentes a tabela associada ao atributo que a frmula est sendo definida e a sua tabela estendida. No exemplo, ao definir que o atributo CustomerBalance frmula, o mesmo deixar de existir como campo fsico da tabela CUSTOMER. Diremos a partir desse momento CustomerBalance um atributo virtual e que sua tabela base ou associada ser CUSTOMER, j que se fosse armazenar dito atributo novamente (seja porque o analista definiu que deixa de ser frmula ou que frmula redundante) seria criado como atributo fsico na tabela CUSTOMER. O tipo de clculo desta frmula definida horizontal, j que consiste em uma expresso aritmtica; portanto os atributos que podem ser referenciado na definio desta frmula so os pertencentes a tabela CUSTOMER (tanto os armazenados como frmulas) e sua tabela estendida.

102

Frmulas
Classificao

Exemplo II de Frmula Horizontal (Global) :


Invoice { InvoiceId* CustomerId CustomerName InvoiceDate Detail { InvoiceDetailId* ProductId ProductDescription ProductPrice InvoiceDetailQuantity InvoiceDetailAmount } } ProductPrice*InvoiceDetailQuantity if InvoiceDetailQuantity<=100; ProductPrice*InvoiceDetailQuantity*0.9 otherwise;

Neste exemplo o atributo InvoiceDetailAmount foi definido como frmula global tambm. Isto , utilizando o editor de frmulas, foi associado um clculo a este atributo e o mesmo passar a ser um atributo virtual. A tabela associada ao atributo InvoiceDetailAmount ser INVOICEDETAIL, caso dito atributo for armazenado novamente, ser criado em dita tabela fsica. Como podemos observar a frmula definida cai na classificao de horizontal, j que consiste em 2 expresses aritmticas condicionais. Os atributos envolvidos na definio da frmula pertencem a tabela INVOICEDETAIL ou a sua tabela estendida.

103

Frmulas
Classificao

Exemplos de Frmulas Aggregate (Globais) :


Invoice { InvoiceId* CustomerId CustomerName InvoiceDate InvoiceDetail Count(InvoiceDetailQuantity) InvoiceAmount Sum(InvoiceDetailAmount) Detail { InvoiceDetailId* ProductId ProductDescription ProductPrice Em ambos os clculos somente intervm os registros que InvoiceDetailQuantity cumprirem: InvoiceDetailAmount INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId } }

No exemplo os atributos InvoiceDetail e InvoiceAmount foram definidos como frmulas globais, j que utilizando o editor de frmulas foi definido uma frmula para cada um destes atributos (os passando a ser atributos virtuais). Visto que as frmulas definidas so Count e Sum respectivamente, em ambos casos se trata de frmulas Aggregate. A tabela associada a ambos atributos frmula INVOICE, j que caso estes atributos estivesses armazenados, seriam criados em dita tabela fsica. As frmulas Aggregate no possuem somente uma tabela base associada (como todas as frmulas), mas tambm envolvem uma tabela a ser navegada. A tabela a ser navegada numa frmula Aggregate, a tabela que ser navegada para realizar o clculo. GeneXus inferi qual a tabela a ser navegada por uma frmula Aggregate, pelos atributos envolvidos na definio da frmula. Em nosso exemplo, a tabela a ser navegada em ambas frmulas Aggregate INVOICEDETAIL, j que tanto na definio de Sum como Count, temos referenciado a um nico atributo associado a INVOICEDETAIL. Quando definirmos uma frmula Aggregate, j temos conhecimento de qual tabela pretendemos navegar para efetuar o clculo. Os atributos que poderemos referenciar na definio de uma frmula Aggregate devero pertencer a tabela a ser navegada e sua tabela estendida + a tabela associada ao atributo que est sendo definido como frmula e sua tabela estendida. De envolver numa frmula Aggregate atributos que no pertenam a este contexto mencionado, um error ser mostrado na listagem de navegao correspondente. Por ltimo, havendo atributos em comum (com o mesmo nome) nas tabelas envolvidas na definio de uma frmula, GeneXus aplicar essa relao (isto , um filtro automtico por igualdade pelos atributos com o mesmo nome). Isto o que acontece neste 2 exemplos, que GeneXus conta e soma as linhas relacionadas a seus cabealhos (ao somar e contar, aplica automaticamente o filtro INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId ).

104

Sintaxe completa de Sum, Count, Average: Sum | Count | Average(Expresso, [Condio Explcita, Valor por Default]) [if Condio Disparo]; Nos 2 exemplos de frmulas Sum e Count que vimos, somente definimos o parmetro obrigatrio, a expresso a ser somada o contada (que num caso consistiu num atributo armazenado e no outro caso num atributo frmula). Tambm dita expresso poderia envolver constantes e/ou funes. Vimos que GeneXus determina condies de filtro implcitas ao realizar ao soma, conta ou mdia/ Tambm poderamos ter definido condies de filtro explcitas e no caso de faz-las, GeneXus levar ambas em considerao: implcitas + explcitas. De forma opcional possvel definir um valor por default a ser retornado quando no so encontrados registros para contar, somar, ou mdia. Da mesma forma que todas as frmulas, estas tambm permitem incluir condio de disparo. Por ltimo, vale mencionar uma exceo e em particular nas frmulas Count, o primeiro parmetro deve corresponder a um atributo e no a uma expresso. Pode referenciar qualquer atributo da tabela na qual se quer contar registros (que cumpram com condies explcitas e/ou implcitas).

105

Frmulas
Classificao

Exemplos de Frmulas Aggregate (Globais) :


Invoice Product { { InvoiceId* ProductId* CustomerId ProductDescription CustomerName PriceList InvoiceDate { InvoiceDetail Count(InvoiceDetailQuantity) ProductPriceListDate* InvoiceAmount Sum(InvoiceDetailAmount) ProductPriceListPrice Detail } { } InvoiceDetailId* ProductId ProductDescription InvoiceDetailQuantity Max(ProductPriceListDate, InvoiceDetailProductPrice ProductPriceListDate<=InvoiceDate, InvoiceDetailAmount 0, ProductPriceListPrice) } } InvoiceDetailProductPrice*InvoiceDetailQuantity

Modificamos o desenho das transaes para que ao invs de representar que cada produto possui um preo nico, representamos que cada produto tem uma lista de preos de acordo com uma data de alterao dos mesmos. Ao efetuar esta mudana, o atributo ProductPriceListPrice no poder estar presente no segundo nvel da transao Invoice. Por que? Porque o novo desenho estar representando que um produto no vai ter um preo nico, mas sim muitos: um para cada data da alterao do preo do mesmo. Portanto um produto numa linha de uma fatura, teremos que buscar o preo vigente do mesmo, considerando a data da fatura. Lembre que os atributos que podem ser inferidos em determinado nvel de uma transao, so os que pertencem a tabela estendida da tabela base associada ao nvel em questo. Neste exemplo, a tabela estendida da tabela INVOICEDETAIL, no inclui a tabela PRODUCTPRICELIST (naquela que o atributo esteja ProductPriceListPrice):

portanto no nvel Detail da transao Invoice (associado a tabela INVOICEDETAIL) no possvel inferir o atributo ProductPriceListPrice (armazenado na tabela PRODUCTPRICELIST).

106

O que ocorre se deixarmos o atributo ProductPriceListPrice no nvel Detail transao Invoice? Como no pode ser inferido, ento GeneXus no ter outra opo que armazen-lo na tabela INVOICEDETAIL e este atributo secundrio j estar em outra tabela (PRODUCTPRICELIST). Como resultado um modelo de dados no normalizado, e mostrar o error ao querer reorganizar a base de dados. E como fazemos para mostrar em cada linha da factura, o preo vigente do produto da mesma? De todos os preos correspondentes ao produto de una linha, qual queremos recuperar? Evidentemente, de todos os preos que tenham data menor ou igual a data da fatura, queremos aquele que tenha data maior. Procedemos ento a criar no nvel Detail da transao Invoice, um novo atributo de nome InvoiceDetailProductPrice, ao qual o definiremos como frmula global e portanto ser um atributo virtual. A dito atributo vamos associar a frmula Max:

Condies que devem cumprir os registros para ser considerados

Valor de retorno se no encontrar nenhum registro que cumpra con las condies

Max(ProductPriceListDate, ProductPriceListDate<= InvoiceDate, 0, ProductPriceListPrice)

Atributo a maximixar entre os registros que cumpram as condies

Para o registro encontrado, se retorna este atributo

GeneXus infere a tabela a ser navegada pelo ltimo parmetro da frmula (o atributo de retorno). Como j se foi explicado, os atributos que poderemos referenciar na definio de uma frmula Aggregate devero pertencer a tabela a ser navegada e sua tabela estendida + a tabela associada ao atributo definido como frmula e sua tabela estendida. Envolvendo atributos que no pertenam neste contexto mencionado, um error mostrado na listagem de navega correspondente. GeneXus considera o momento de efetuar a busca a condio explcita de filtro + as condies implcitas detectadas. A frmula Min totalmente anloga a Max, com uma nica diferena de que ao encontrar um conjunto de registros que cumpram com as condies, ser selecionado aquele registro que tenha valor mnimo para o atributo indicado no primeiro parmetro e retorne o valor de retorno indicado no ltimo parmetro. A frmula Find por sua vez, tambm permite buscar um registro que cumpra com certas condies, contudo se ter mais de 1 registro que cumpra com elas, a frmula devolver o atributo de retorno correspondente ao primeiro registro encontrado (sem maximizar nem minimizar um valor no conjunto de registros que cumpram com as condies). A sintaxe Find : Find (Expresso de retorno, [Condio explcita], [Valor por default) [if Condio de disparo] Observar que a expresso de retorno neste caso se escreve no primeiro parmetro da frmula.

107

Frmulas
Classificao

Exemplo de Frmula Composta (Global):

Customer { CustomerId* CustomerName CustomerTotalPurchases CustomerTotalPayments CustomerBalance CustomerAverage }

Sum(InvoiceAmount) / Count(InvoiceAmount)

108

Comunicao entre objetos

109

Comunicao entre objetos

Data Provider

Procedimento

Web Panel

Transao

Procedimento PDF

Os objetos GeneXus podem comunicar-se entre eles ou com outros programas externos. Um objeto GeneXus pode chamar ou ser chamado por qualquer outro objeto, trocando informaes atravs de parmetros. Veremos em seguida como chamar desde um objeto a outro, e como especificar os parmetros (no objeto chamador e no chamado) para a troca da informao. O esquema apresentado acima ilustra as possveis interaes entre objetos GeneXus para uma aplicao Web. Observe que a flecha simples entre Web Panel e Procedimento PDF (assim como entre Transao e Procedimento PDF) indica que uma web panel poder chamar um Procedimento PDF mas um Procedimento PDF no poder chamar uma web panel (ou transao Web).

110

Comunicao entre objetos


2 possibilidades:
1) PgmName.Call(par , , par ) 1 N
Parm(par1 , , parN);
/*Chamada a PgmName*/ /*Declarao de parmetros no objeto chamado*/

Pode omitir-se

2)

att|&var = PgmName.Udp(par1, , parN) /* Chamada a PgmName*/ Parm(par1, , parN , parsada);


/*Declarao de parmetros no objeto chamado*/

CALL - Permite chamar a um objeto GeneXus ou a um programa externo, podendo passar parmetros ou no. UDP (User Defined Procedure) Permite chamar a um objeto GeneXus ou programa externo tanto passando parmetros ou no, e com a particularidade de que o programa chamado retornar necessariamente ao menos um valor ao programa que chamou. Em ambientes Web, um objeto com interface uma vez chamado no devolve o controle ao chamador, porque a UDP utiliza unicamente para chamar Procedimentos e Data Providers (devido que estes cumprem com a condio de executar e devolver o controle ao chamador). Uma chamada (seja com CALL ou UDP) pode ser utilizado em distintas partes do objeto chamador, dependendo se o mesmo uma transao, wep panel, procedimento, etc. A UDP pode utilizar-se tambm na definio de um atributo formula. Quer dizer que se define que certo atributo uma formula e que a definio da mesma consiste no chamada a um procedimento utilizando UDP. Quando na sintaxe da chamada se escreve o nome do objeto chamado e nenhum mtodo de chamada, se assume que se est chamando com udp, e pode ser omitida e escrever diretamente: att|&var = PgmName( par1, ..., parN) PARM Quando um objeto chamado desde outro com parmetros, deve ter declarada a lista de parmetros que recebe. Esta declarao se realiza mediante a regra: PARM. A continuao daremos mais detalhes sobre o uso de CALL, UDP e PARM.

111

Comunicao entre objetos


2 possibilidades Exemplos:
1) A partir da transao Invoice chamamos um procedimento PDF para imprimir a fatura: ListInvoice.Call(InvoiceId)
E nas regras do procedimento ListInvoice:
Parm(InvoiceId)

2) Ex:

&discount = GetDiscount.udp(ProductId,CustomerId)

Na proc GetDiscount

Parm(ProductId,CustomerId , &disc);

Aqui mostramos um exemplo do uso do CALL para realizar uma chamada e outro exemplo do uso do UDP. Dependendo de qual objeto for o chamador, estas chamadas podero escrever-se em uma seo ou outra do mesmo, mas independentemente disso, aqui mostraremos que CALL permite chamar um objeto com estilo de chamada a um programa, enquanto que UDP uma chamada a um objeto com estilo de chamada em uma funo. No primeiro exemplo esta se utilizando CALL para chamar um procedimento pdf (objeto ListInvoice) passando um parmetro (InvoiceId). No procedimento chamado se declarou o parmetro que recebe (em sua seo de regras, mediante a regra parm). No segundo exemplo utilizado UDP para chamar um procedimento (objeto GetDiscount) passando dois parmetros (ProductId, CustomerId). Agora observemos na sintaxe da chamada ao procedimento, que o mesmo retornar um valor (na varivel &disc). Por este motivo no procedimento solicitado so declarados trs parmetros utilizando a regra parm: os dois parmetros recebidos + o parmetro de retorno no ltimo lugar. Podemos ver ento que quando se utiliza CALL para chamar um objeto enviando-lhe Nparmetros, se devem declarar os N parmetros (posicionais e do mesmo tipo de dados que os enviados) no objeto solicitado mediante a regra parm. Por outro lado quando se utiliza UDP para chamar um objeto enviando N parmetros (exceto que seja o caso particular de um Data Provider, caso que veremos mais adiante): na regra parm do objeto chamado se devem declarar N + 1 o ltimo parmetro declarado na regra parm do objeto chamado corresponde ao que se encontra no comeo de tudo na chamada, dizer, ao que recebe o valor retornado. em algum lugar do objeto chamado dever ser atribudo valor ao parmetro de retorno.

112

Declarar o que na regra parm: varivel ou atributo?


Varivel: Pode ser utilizada livremente, na lgica do objeto chamado: como condio de filtro por =, >, >=, <, <=, LIKE, etc. para alguma operao aritmtica. como flag (bandeira). etc. Atributo: Automaticamente o mesmo atuar como filtro por igualdade no objeto, no sendo possvel modificar o valor recebido.

Ao definir uma Chamada a um objeto (seja utilizando CALL ou UDP), se tivermos que enviar dados por parmetro ao objeto chamado, precisamos determinar se enviaremos atributos e/ou variveis: se um dado a ser enviado por parmetro, se encontra no objeto que o chamou, em um atributo, ter que enviar o mesmo; e se estiver numa varivel, ter que enviar a varivel. Todavia, ao declarar a lista de parmetros no objeto chamado, o programador GeneXus dever decidir para cada parmetro, se o declara como um atributo ou uma varivel, independentemente de como tenha sido enviado. Qual a diferena entre declarar o parmetro como varivel ou como atributo na regra parm do objeto chamado? Se for declarar como uma varivel, poder utilizar livremente a mesma lgica do objeto chamado: pode utiliz-la como condio de filtro por igualdade, por maior, maior ou igual, menor, menor ou igual, LIKE, etc.; poder utilizar para alguma operao aritmtica, como bandeira (flag), ou para o que se queira. Se for declarar um atributo, automaticamente o mesmo atuar como filtro por igualdade no objeto, no sendo possvel modificar o valor recebido. Quando cheguemos etapa do curso na qual podemos chamar a procedimentos pdf para listagem, passando parmetros, assim como a outros objetos, poderemos terminar de compreender melhor este tema.

113

Definio de tipo de passagem de parmetros (in, out, inout)


Para cada parmetro declarado na regra parm, possvel definir que o mesmo seja:
de entrada (in) de sada (out) de entrada-sada (inout)

Exemplo: parm( out:&par1, in:&par2, &par3, inout:&par4); Vantagens:


Melhor especificao da semntica das interfaces. Independncia da linguagem de gerao. Otimizar a passagem de parmetros das aplicaes de acordo com a arquitetura implementada (vantagem que contrasta com a anterior).

Como pode-se perceber claramente na sintaxe do exemplo o primeiro parmetro definido de sada, o segundo parmetro de entrada, e o quarto parmetro de entrada-sada. Quando no for especificado, como o caso do terceiro parmetro do exemplo, depender do seguinte: se o objeto foi chamado com CALL, o parmetro, ser de entrada-sada. se o objeto foi chamado com UDP, e se trata do ltimo parmetro, ser de sada; e se for outro parmetro diferente do ltimo, depender da linguagem de operao. Declarar explicitamente como se quer que cada parmetro opere, possui as seguintes vantagens: 1. Melhor especificao da semntica das interfaces; ou seja, o GeneXus e o programador quando trabalham com um objeto, fica claro: - se o mesmo chegar com valor e depois da execuo do objeto chamado, devolvido ao objeto que o chamou o valor que tenha ficado (inout). - se o mesmo chegar com valor e depois da execuo do objeto chamado, no devolve ao objeto que o chamou o valor que tenha ficado (in). - se o mesmo no chegar com valor e depois da execuo do objeto que o chamado, se devolve ao objeto que o chamou o valor que tenha ficado (out). 2. Independncia da linguagem de gerao; isto , se define explicitamente como deseja que cada parmetro opere, ao gerar as aplicaes utilizando diferentes linguagens de gerao no muda o comportamento dos parmetros baseados ao comportamento por default da linguagem de gerao correspondente. 3. Otimizar a passagem de parmetros de acordo com a arquitetura gerada (sendo uma vantagem que contrasta com a anterior); isto se refere que para a maioria das linguagens mais eficiente passar os parmetros por referncia (inout) que por valor (in / out); mas em Java, por exemplo, os parmetros somente podem ser passados por valor, para poder obter esta funcionalidade de passlos por referncia necessrio que exista converses de parmetros, que pode redundar em um overhead importante; por outro lado, quando se trata de aplicaes distribudas (por exemplo Java com RMI ou HTTP), a utilizao de parmetros de tipo out tm a vantagem de que no necessrio enviar parmetro na chamada, diferente de definir os parmetros inout (tem que passar todos parmetros); isto tem como conseqncia que sero enviados mais bytes do que os necessrios, o que inconveniente especialmente nos casos como Internet.

114

Comunicao entre objetos Web


Mais possibilidades para definir chamadas Funo Link

1)

control.Link = PgmName.Link([,par1 , parN]) Ex: imagem.Link = Customer.Link()


Os parmetros so opcionais e no caso de existirem, so declarados com a regra parm

2)

control.Link = Link(URL) Ex: imagem.Link = Link(http://www.artech.com.uy)

A funo Link se associa propriedade link de um controle dentro de qualquer evento de uma transao ou web panel, tendo como resultado que ao fazer click sobre dito controle se realiza a chamada ao objeto URL referenciada no Link. PgmName (o objeto chamado) poder ser uma web panel, transao, ou procedimento PDF1.

____________________________________________________________________
1

tambm um procedimento HTTP, mas no aprofundaremos sobre este conceito neste curso

115

Comunicao entre objetos Web


Mais possibilidades para definir chamadas Comando Link

1)

PgmName.Link([,par1 , parN]) Ex: Customer.Link(CustomerId)

2)

Link(URL) Ex: Link(http://www.google.com)

O comando Link pode ser utilizado dentro de qualquer evento de uma transao ou web panel Quando se execute o evento, ao chegar a sentena com o comando Link, se redirecionar em forma automtica URL especificada. No caso de utilizar-se o comando Link como no exemplo 1, chamando um PgmName (sendo PgmName uma web panel, transao ou procedimento PDF), ser equivalente utilizao do Call. Opcionalmente se poder passar parmetros ao objeto chamado, devendo declarar-se os mesmos no objeto chamado, com a regra parm.

___________________________________________________________________
1

tambm um procedimento HTTP, mas no aprofundaremos sobre este conceito neste curso

116

Ordem de execuo de regras e frmulas

Ordem de execuo de regras e frmulas


Transao "Invoice"
InvoiceId* InvoiceDate CustomerId CustomerTotalPurchases CategoryDiscount InvoiceDiscount = InvoiceSubTotal *CategoryDiscount InvoiceShippingCharge = Max( ShippingDate, ShippingDate <=InvoiceDate,,ShippingCharge) InvoiceSubTotal = SUM( InvoiceDetailAmount ) InvoiceTotal = InvoiceSubTotal InvoiceDiscount + InvoiceShippingCharge {ProductId* ProductPrice ProductStock InvoiceDetailQuantity InvoiceDetailAmount} = InvoiceDetailQuantity * ProductPrice

Customer
CustomerId* CustomerName CategoryId CustomerTotalPurchases

Category
CategoryId* CategoryDiscount

Shipping
ShippingDate* ShippingCharge

Product
ProductId* ProductPrice ProducStock

Regras:

Add( InvoiceTotal, CustomerTotalPurchases); Error( Insufficient Stock ) if ProductStock<0; Subtract( InvoiceDetailQuantity, ProductStock);

A forma de programar o comportamento das transaes definindo regras, escritas de forma declarativa. Quando temos clculos para efetuar, podemos optar pela alternativa de definir atributos frmulas. Em nenhum momento, o programador GeneXus especifica a seqncia de execuo das regras e frmulas definidas em uma transao. Quando for gerar, o GeneXus determina as dependncias existentes entre as regras e frmulas definidas. Vamos supor que estamos definindo uma aplicao para uma empresa que vende determinados produtos, e que conta com um servio de entrega a domiclio que leva a mercadoria a seus clientes. E definimos entre outras, as seguintes 5 transaes: Customer (para registrar os clientes da empresa) Category (as que pertencem cada cliente) Shipping (envios: guarda um histrico de custos de envio) Invoice (faturas emitidas aos clientes) Product (produtos que so vendidos pela empresa) Ressaltamos a estrutura da transao Invoice, com seus atributos frmulas e suas regras declaradas. Em que ordens sero disparadas as regras e frmulas da transao Invoice?

rvore de avaliao
R. Add(InvoiceTotal, CustomerTotalPurchases); F. InvoiceTotal = InvoiceSubTotal - InvoiceDiscount + InvoiceShippingCharge F. InvoiceDiscount = InvoiceSubTotal*CategoryDiscount F. InvoiceShippingCharge = MAX( ShippingDate, ShippingDate <= InvoiceDate,,ShippingCharge) F. InvoiceSubTotal = SUM( InvoiceDetailAmount ) F. InvoiceDetailAmount = InvoiceDetailQuantity *ProductPrice R. Subtract(InvoiceDetailQuantity, ProductStock) ; R. Error( Insuffcient Stock) if ProductStock < 0 ;

CustomerTotalPurchases

InvoiceTotal

InvoiceDiscount InvoiceShippingCharge
error (Insufficient Stock )

InvoiceSubTotal

ShippingDate

InvoiceDate

ShippingCharge ProductStock InvoiceDetailAmount CategoryDiscount

InvoiceDetailQuantity

ProductPrice

No momento de gerar o programa associado na transao Invoice, o GeneXus determinar as dependncias existentes entre as regras e frmulas definidas; e construir logicamente uma rvore de dependncias (ou rvore de avaliao) que determinar a seqncia de avaliao. Podemos imaginar que a rvore executada de baixo para cima, cada vez que alteramos algum valor de um atributo, se executam todas as regras e frmulas que dependem desse atributo (e que na rvore se encontram para cima). Por exemplo, alterando a quantidade de uma linha de uma fatura (InvoiceDetailQuantity), como este atributo interfere na frmula que calcula o valor da linha (InvoiceDetailAmount), esta frmula ser disparada novamente. Para alterar o valor de uma linha, a frmula disparada novamente correspondendo ao subtotal da fatura (InvoiceSubTotal) e como conseqncia, tambm dever ser recalculada a frmula correspondente ao desconto (InvoiceDiscount), j que depende do subtotal. Dever ser disparada novamente a frmula correspondente ao total da fatura (InvoiceTotal) j que depende tanto do valor de InvoiceSubTotal como do valor de InvoiceDiscount. Por ltimo, por alterar o total, tambm ser disparada a regra Add(InvoiceTotal, CustomerTotalPurchases). Alm de serem disparadas todas as frmulas e regras envolvidas na parte direita da rvore desde o atributo InvoiceDetailQuantity, tambm so disparadas as frmulas e regras envolvidas na parte esquerda. Ou seja, ao alterar o valor do atributo InvoiceDetailQuantity, ser disparada novamente tambm a regra Subtract(InvoiceDetailQuantity, ProductStock); e em conseqncia, por modificar esta regra o valor do atributo ProductStock verifica a necessidade de disparar a regra Error(Insufficient Stock) if ProductStock < 0; Concluindo, as regras e frmulas que se definem numa transao esto inter-relacionadas e GeneXus determina as dependncias entre elas assim como sua ordem de avaliao. Observemos as 2 ltimas regras definidas: Subtract(InvoiceDetailQuantity, ProductStock); Error(Insufficient Stock) if ProductStock < 0;

Estas regras esto inter-relacionadas porque envolvem o atributo ProductStock. Agora, enquanto que a segunda somente consulta seu valor, a primeira o atualiza. Ento, a regra que atualiza o atributo ser a que vai disparar o primeiro, e em seguida dispara a que o consulta. Toda regra que atualize o valor de um atributo, ser disparada antes que uma regra que o consulte (isto pode ser observado claramente na rvore). Por este motivo que a regra Error consulta se o atributo ProductStock ficou com valor negativo; porque como sabemos que a subtrao ser realizada primeiro,. Na programao clssica primeiro consulta-se o estoque, a subtrao realizada quando ele for suficiente. Por isso quem est aprendendo GeneXus pode intuitivamente escrever a regra: Error(Insufficient Stock) if InvoiceDetailQuantity > ProductStock. Esta sintaxe correta, no correta sua lgica, j que como temos explicado, na rvore de avaliao determinada pelo GeneXus primeiro disparada a regra Subtract e depois a regra Error; portanto temos que definir que se dispare a mensagem de error se o estoque ficou o stock com valor negativo, j que ser executado a subtrao no momento de consultar o valor de ProductStock. Assim que a regra deve definir : Error(Insufficient Stock) if ProductStock < 0; E no: Error('Insufficient Stock') if InvoiceDetailQuantity > ProductStock; Quando se dispara uma regra Error, se detm qualquer atualizao da base de dados e desarma a rvore de avaliao, ficando no estado anterior ao se produzir o erro. Seguindo o exemplo que estamos vendo, se ao disparar a regra Subtract o stock que ficar negativo, se dispararia a regra Error. Como conseqncia ao se disparar a regra Error, o Subtract que foi executado desfeito, assim como todas as demais regras e frmulas que tenham executado (reclculo dos atributos InvoiceDetailAmount, InvoiceSubTotal, ...., CustomerTotalPurchases).

Alteraes da ordem de disparo das regras


Error Total Calculado Total Ingressado

SupplierId* InvoiceId* ... InvoiceEntTotal Entered Total InvoiceDetailAmount { ProductId* InvoiceDetailQuantity InvoiceDetailPrice InvoiceDetailAmount = InvoiceDetailPrice * InvoiceDetailQuantity} ... InvoiceCalcTotal = SUM(InvoiceDetailAmount) Calculated Total

Error(The calculated total doesnt match with the entered total') if (InvoiceEntTotal<>InvoiceCalcTotal) On AfterLevel Level ProductId;

Na maioria dos casos a ordem de execuo das regras definida pelo GeneXus a partir de nossas especificaes o desejado. Porm em alguns casos podemos querer alterar o momento de disparo de uma Regra. Exemplo: Definimos uma transao para registrar as faturas que recebemos de nossos fornecedores. O identificador do primeiro nvel composto pelo cdigo do fornecedor e o nmero de fatura, j que o nmero de fatura no nos serve como identificador nico, porque fornecedores distintos podem repetir o mesmo nmero de fatura. Para cada fatura de um fornecedor que inserimos, nos interessa controlar que o total que venha escrito na fatura (e que ser digitado no atributo InvoiceEntTotal) seja correto. Para fazer este controle, definimos o atributo InvoiceCalcTotal como frmula vertical SUM(InvoiceDetailAmount), e agregamos uma regra Error que ser disparada se no coincidir os valores dos atributos InvoiceEntTotal e InvoiceCalcTotal: Error(The calculated total doesnt match with the entered total') if InvoiceCalcTotal <> InvoiceEntTotal; Se construirmos a rvore de avaliao correspondente as frmulas e regra que definimos nesta transao:

vemos que as dependncias indicam que cada vez que so inseridos, modificados ou eliminados valores dos atributos InvoiceDetailAmount e InvoiceDetailQuantity nas linhas, recalcula-se o valor do atributo InvoiceDetailAmount correspondente; em conseqncia, recalculamos o valor do atributo frmula InvoiceCalcTotal que temos definido para ter o total calculado da fatura; e como o atributo frmula InvoiceCalcTotal est envolvido na condio de disparo da regra Error, cumpre a dita condio de disparo e dispara a regra Error(The calculated total doesnt match with the entered total) if InvoiceCalcTotal <> InvoiceEntTotal; Agora, prestamos ateno a condio de disparo InvoiceCalcTotal<>InvoiceEntTotal vai ser cumprida repetidamente na medida em que o operador vai inserindo as linhas, porque para cada linha que inserida, calcula-se o valor do atributo frmula InvoiceDetailAmount da linha, e como consequncia recalculado o valor do atributo frmula InvoiceCalcTotal. Mas o valor calculado do atributo InvoiceCalcTotal no coincidir com o valor inserido no atributo InvoiceEntTotal at que no tenham ingressado todas as linhas da fatura; ento, dispara-se a regra Error(The calculated total doesnt match with the entered total) if InvoiceCalcTotal <> InvoiceEntTotal;. Conclumos ento que neste caso, no nos serve o determinado na rvore de avaliao, j que no queremos que seja analisada a condio de disparo da regra Error cada vez que o operador insira, altere ou elimine as linhas, e sim necessitamos que seja analisada quando o usurio tenha terminado trabalhar com todas as linhas da fatura. GeneXus oferece eventos ou momentos de disparo nas transaes, que ocorrem antes ou depois de determinada ao, como a gravao do cabealho, ou de uma linha. As regras das transaes podem serem condicionadas de tal maneira que sejam disparadas no momento especfico que ocorre algum desses eventos de disparo. Seguindo o exemplo visto, existe um evento de disparo que ocorre assim que entramos num nvel e samos do mesmo. A sintaxe deste evento de disparo : AfterLevel Level Atributo, devendo Atributo um atributo pertencente ao nvel interagido e que se abandona. De modo que a regra Error de nosso exemplo, agregaramos este evento de disparo, e ficaria definida da seguinte forma: Error(The calculated total doesnt match with the entered total) if InvoiceCalcTotal<>InvoiceEntTotal On AfterLevel ProductId; Agregando este evento de disparo a regra controlamos o que se deseja no momento adequado. Alm deste evento de disparo, existem outros que veremos em seguida.

Eventos de disparo
A maioria das regras nas transaes permitem agregar um evento ou momento de disparo. Ao agregar um evento ou momento de disparo a uma regra, estaremos especificando que a regra deve ser executada nesse determinado momento. Eventos de disparo:
BeforeValidate AfterValidate BeforeInsert, BeforeUpdate, BeforeDelete AfterInsert, AfterUpdate, AfterDelete AfterLevel BeforeComplete AfterComplete

No momento da confirmao da transao, ocorre uma srie de aes que necessrio para poder programar corretamente o comportamento das regras. Para uma transao de dois nveis, poderamos enumer-las como segue: validao dos dados do cabealho gravao fsica do cabealho (seja insero, modificao ou eliminao) validao dos dados da primeira linha gravao fsica dos dados da primeira linha validao dos dados da segunda linha gravao fsica dos dados da segunda linha validao dos dados da n-sima linha gravao fsica dos dados da n-sima linha commit A ao de validao dos dados do cabealho ocorre aps todos serem validados e cada um dos campos informados no cabealho. Observar que neste ponto j foi disparado todas as regras que correspondiam aos atributos do cabealho e que no tinham evento de disparo associado (exemplo: Default(InvoiceDate, &today)). Imediatamente depois ser gravado o registro correspondente ao cabealho. Anlogo o caso das linhas: a validao dos dados de uma linha ocorre aps todos serem validados e cada um dos dados da linha, e tambm aps terem sido disparadas todas as regras correspondentes segundo a rvore de avaliao (exemplo: subtract( InvoiceDetailQuantity, ProductStock)). Imediatamente depois desta ao de validao, ser gravado fisicamente o registro correspondente linha. Cada transao, ao terminar de trabalhar com um cabealho e suas linhas, realiza um commit ( automtico). Ser colocado no cdigo gerado por GeneXus, exceto se o analista especifique o contrrio, como veremos mais adiante. Isto , se os dados de duas faturas distintas forem ingressados utilizando a transao Invoice, aps serem ingressados os dados da primeira, os registros sero comitados, e depois ser ingressado o segundo, ao qual seus registros sero comitados. Os eventos de disparo de regras permitem condicionar o disparo de uma regra da transao para que se execute antes ou depois de alguma das aes que acabamos de enumerar. Veremos quando ocorre cada evento de disparo.

Evento de disparo: BeforeValidate Este evento de disparo ocorre um pouco antes da informao da instancia que se trabalhe (cabealho ou linha) seja validada (ou confirmada). Isto , ocorrer antes da ao de validao do cabealho ou validao da linha, correspondente. Observar que aqui tambm havero disparadas todas as regras segundo a rvore de avaliao que no estejam condicionadas com nenhum evBeforeento de disparo. Eventos de disparo: AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete O evento de disparo AfterValidate permite definir que uma regra seja executada imediatamente antes de que gravemos fisicamente cada instancia do nvel ao qual est associada a regra, na tabela fsica correspondente e depois de ter validado os dados desta instancia. Em outras palavras, agregando o evento de disparo AfterValidate a uma regra, a mesma executar, para cada instancia do nvel ao qual esteja associada a regra, imediatamente antes de que a instancia seja gravada fisicamente (seja quando insere, altere ou elimine) como registro na tabela fsica associada ao nvel. EXEMPLOS 1.Tem vezes que no contamos com a possibilidade de utilizar a Propriedade Autonumber para numerar de forma automtica e correlativa os atributos que so chave primria simples. Tal funcionalidade prevista pelos administradores de base de dados (DBMSs) e o GeneXus a aproveita e permite us-la; nos casos em que no trabalhamos com um administrador de base de dados, no temos a possibilidade de selecionar esta facilidade. Nesses casos que no contamos com a possibilidade de utilizar a Propriedade Autonumber e necessitamos numerar de forma automtica e correlativa certos atributos, devemos resolver ns mesmos na programao. Para faz-lo somente definindo uma transao contendo ao menos dois atributos, um para armazenar um literal e outro para armazenar o ltimo nmero atribudo automaticamente ao atributo descrito pelo literal1; a transao vai fazer com que seja criada uma tabela, e temos que definir um procedimento que consulte essa tabela, obtenha o ltimo nmero atribudo para o atributo a ser numerado, some um e devolva o prximo nmero, alm de atualiz-lo na tabela. Para chamar ao procedimento de numerao automtica se deve definir nas transaes que o requerem a seguinte regra: CustomerId = PGetNumber.udp( CUSTOMER ) if Insert on AfterValidate; Neste caso se est querendo serializar o atributo CustomerId da transao Customer Do mesmo modo, se queremos serializar o identificador de faturas, escreveramos na transao Invoice com a seguinte regra: InvoiceId = PGetNumber.udp( INVOICE ) if Insert on AfterValidate; Desta forma definimos que se efetuam numeraes automticas nas transaes unicamente quando se realizem inseres (pela condio de disparo: if Insert) e imediatamente antes do registro ser gravado fisicamente cada instancia a ser inserida (pelo evento de disparo: on AfterValidate) atravs do primeiro nvel da transao (porque nas duas regras de chamadas que foram mostradas, tem somente um atributo envolvido que pertence ao primeiro nvel das transaes Customer e Invoice respectivamente). O motivo pelo qual agregamos o evento de disparo on AfterValidate a estas regras para chamar o procedimento de numerao automtica imediatamente antes de que seja inserido o registro na base de dados e depois da validao, tentando desta forma ter o maior grau de segurana possvel ao nmero atribudo que ser utilizado (e no perder nmeros). Caso a regra fosse disparada sem ter condio, e no caso de faltar alguma validao dos dados do cabealho. A resposta simples: um nmero seria perdido. Ou seja, se o nmero da fatura anterior for 5 e o usurio quer informar a seguinte fatura, a regra de atribuio com udp chama o procedimento de numerao que seria disparado assim que ingressar na transao com modo insert, porque o primeiro atributo do cabealho utilizado. O procedimento devolveria o nmero 6, e se ao validar os dados do cabealho encontrar algum error que no permita continuar com o processo, abandonar a transao, por exemplo, esse nmero 6 seria perdido e a prxima fatura, que deveria ter o nmero 6 no o ter, e sim o nmero 7.

________________________________________________________________________________________
1

Quando vimos a regra serial falamos este tema de numerao de cabealho, com a transao "Number que era a que tinha o literal: NumberCode e o ltimo nmero atribudo a transao correspondente a esse literal: NumberLast

Existem 3 eventos de disparo que ocorrem no mesmo momento que o AfterValidate, mas j possuem o modo de forma intrnseca. So eles: BeforeInsert, BeforeUpdate e BeforeDelete. equivalente escrever a regra apresentada como: InvoiceId = PGetNumber.udp( 'INVOICE' ) on BeforeInsert; Observar que aqui redundante condicionar a regra a If Insert. Portanto, as seguintes equivalncias so vlidas: on BeforeInsert on BeforeUpdate on BeforeDelete If Insert on AfterValidate If Update on AfterValidate If Delete on AfterValidate

Se tivermos um esquema das aes que rodeiam o disparo do evento, ficam claros os dois sinnimos escolhidos para este evento (AfterValidate e BeforeInsert para modo insert) VALIDAO DOS DADOS AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRAVAO DO REGISTRO (insert, update, delete segundo corresponda) 2) Se definirmos uma regra em que inclumos tambm o evento de disparo on AfterValidate, ou on BeforeInsert, BeforeDelete, BeforeUdate, mas a diferena dos exemplos recm vistos, referenciado na regra pelo menos um atributo do segundo nvel da transao na qual est definindo a regra, a mesma estar associada ao segundo nvel1. Portanto, a regra executar imediatamente antes que seja gravada fisicamente cada instancia correspondente ao segundo nvel da transao. Eventos de disparo: AfterInsert, AfterUpdate, AfterDelete Assim como existe um evento de disparo que permite definir que determinadas regras sejam executadas imediatamente antes que seja produzida a gravao fsica de cada instancia de um nvel (AfterValidate, BeforeInsert, BeforeUpdate e BeforeDelete), tambm existem eventos de disparo para definir que certas regras sejam executadas imediatamente depois de que sejam inseridas, modificadas ou eliminadas fisicamente instancias de um nvel. Estes eventos so AfterInsert, AfterUpdate e AfterDelete. O evento de disparo AfterInsert permite definir que uma regra execute imediatamente depois de que seja inserida fisicamente cada instancia do nvel ao qual est associada a regra; o AfterUpdate depois de atualizar fisicamente a instancia, e o AfterDelete depois de eliminar. EXEMPLOS Vamos supor que na transao Customer queremos chamar um relatrio que realize a impresso dos dados de cada cliente com o qual trabalhamos por meio da transao. Em que momento devemos realizar as chamadas ao relatrio a partir da transao? Caso 1: RPrintCustomer.call( CustomerId ) on AfterValidate; No adequado agregar-lhe este evento de disparo a regra de chamadas ao relatrio, porque o mesmo seria chamado imediatamente antes da gravao fsica de cada cliente. Em conseqncia, o relatrio no encontraria o cliente com seus dados na tabela CUSTOMER (caso estivesse inserindo um cliente por meio da transao), ou o encontraria com seus dados desatualizados (caso estivesse modificando um cliente por meio da transao). Se na alterao estivesse eliminando um cliente por meio da transao, o relatrio encontraria os dados do cliente na tabela CUSTOMER e os listaria justamente antes da atualizao fsica (eliminao). Caso desejarmos emitir uma lista com os dados de cada cliente que forem eliminados, seria adequado definir a seguinte regra: RPrintCustomer.call( CustomerId ) on BeforeDelete; ou equivalente: RPrintCustomer.call( CustomerId ) if delete on AfterValidate; tempo

________________________________________________________________________________________________
1

Existe outra forma de provocar que uma regra que contem atributos de um nvel determinado, se dispare no nvel seguinte, por meio de clusula Level que foi mencionado quando vimos conceitos importantes sobre as regras de transaes.

para restringir o disparo da regra unicamente quando estamos eliminando um cliente, porque o nico caso em que seria correto utilizar o evento de disparo AfterValidate (j que justamente necessitamos emitir o relatrio antes da eliminao). Caso 2: RPrintCustomer.Call( CustomerId ) on AfterInsert; O evento de disparo AfterInsert ocorre imediatamente depois de que inserimos fisicamente cada instancia associada a certo nvel da transao (neste caso, como o nico atributo envolvido na regra CustomerId, trata-se de uma regra associada ao primeiro e nico nvel da transao Customer). Como indica claramente pelo seu nome, o evento de disparo AfterInsert somente ocorre ao inserir uma nova instancia (precisamente aps ser inserida como registro fsico). Utilizando ele quando se agrega o evento de disparo on AfterInsert a uma regra, no necessrio agregar-lhe a condio de disparo if insert. correto agregar este evento de disparo a regra de chamadas ao relatrio, j que o relatrio seria chamado imediatamente depois de que fosse inserido fisicamente cada cliente. Assim que o relatrio encontrar o cliente com seus dados na tabela CUSTOMER e os imprime. O que deve ficar claro que com esta definio, o relatrio chamado unicamente logo que realizar inseres. Caso 3: RPrintCustomer.Call( CustomerId ) on AfterUpdate; O evento de disparo AfterUpdate ocorre imediatamente depois que atualizada fisicamente cada instancia associada a certo nvel da transao (neste caso, como o nico atributo envolvido na regra CustomerId, se trata de uma regra associada ao primeiro e nico nvel da transao Customer). adequado agregar neste evento de disparo a regra de chamadas ao relatrio, j que o relatrio chamado imediatamente depois que for atualizado fisicamente um cliente. Assim que o relatrio encontrar o cliente com seus dados atualizados na tabela CUSTOMER e os imprimir. O relatrio ser chamado unicamente aps realizar as atualizaes. Caso 4: RPrintCustomer.Call( CustomerId ) on AfterDelete; O evento de disparo AfterDelete ocorre imediatamente depois da eliminao fsica de cada instancia associada a certo nvel da transao (neste caso, como o nico atributo envolvido na regra CustomerId, se trata de uma regra associada ao primeiro e nico nvel da transao Customer). No adequado agregar este evento de disparo a regra de chamadas ao relatrio, porque o relatrio chamado imediatamente depois da eliminao fsica de cada cliente. Em conseqncia, o relatrio no encontra o cliente com seus dados na tabela CUSTOMER. Caso 5: RPrintCustomer.Call( CustomerId ) on AfterInsert, AfterUpdate; RPrintCustomer.Call( CustomerId ) if delete on AfterValidate; Para finalizar, estas duas regras so adequadas para chamar um relatrio na transao Customer, com o objetivo de imprimir os dados de cada cliente com qual trabalhar, abrangendo os trs modos de trabalho. Como podemos observar na primeira regra, possvel incluir vrios eventos de disparo separados por vrgula, quando os mesmos aplicam a uma mesma regra. Isto , o mesmo que definir duas regras independentes: RPrintCustomer.Call( CustomerId ) on AfterInsert; RPrintCustomer.Call( CustomerId ) on AfterUpdate; que esta regra: RPrintCustomer.Call( CustomerId ) on AfterInsert, AfterUpdate;

Caso 6: Se definirmos uma regra a qual inclumos o evento de disparo on AfterInsert, mas a diferena dos exemplos vistos recentemente, referenciada na regra pelo menos um atributo do segundo nvel da transao na qual estamos definindo a regra, a mesma estar associada ao segundo nvel. Portanto, a regra executada imediatamente depois de que inserimos fisicamente cada instancia correspondente ao segundo nvel da transao. Analogamente o caso de disparo de on AfterUpdate e on AfterDelete. Ampliamos o esquema que havamos efetuado antes, das aes que rodeiam aos eventos de disparos visto at agora: VALIDAO DOS DADOS AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRAVAO DO REGISTRO (insert, update, delete segundo corresponda) AfterInsert AfterUpdate AfterDelete
tempo

Este esquema se repete para cada instancia do nvel. Por exemplo, pensamos no ingresso das linhas de uma fatura. Este esquema ocorre para cada linha, podemos pensar num loop que se repete at que a ltima linha seja gravada. A ao depois da ltima linha seria gravada quando sai desse nvel (neste caso as linhas da fatura). E depois dessa ao, exceto que tenha outro nvel, nesse caso voltaria o esquema anterior, ocorrer o commit que a ltima ao de execuo. Entre a ao de abandonar o nvel, e o commit temos um evento (que admite dois nomes distintos) e outro para depois do commit. So o que veremos na continuao mas que j vamos mostrar no esquema: VALIDAO DOS DADOS CABEALHO AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRAVAO DO REGISTRO (insert, update, delete segundo corresponda) AfterInsert AfterUpdate AfterDelete VALIDAO DOS DADOS LINHA AfterValidate BeforeInsert BeforeUpdate BeforeDelete GRAVAO DO REGISTRO (insert, update, delete segundo corresponda) AfterInsert AfterUpdate AfterDelete ABANDONAR NVEL 2 AfterLevel - BeforeComplete COMMIT AfterComplete
tempo

loop

Eventos de disparo: AfterLevel, BeforeComplete O evento de disparo AfterLevel permite definir que uma regra seja executada imediatamente depois de terminar de interagir determinado nvel. SINTAXE: regra [if condio de disparo] [on AfterLevel Level atributo]; ONDE: regra: uma regra das permitidas em transaes condio de disparo: uma expresso booleana que permite envolver atributos, variveis, constantes e funes, assim como os operadores Or, And, Not. atributo: um atributo pertencente ao nvel para o qual se deseja que depois de ser iterado, se execute a regra. FUNCIONALIDADE: Se o atributo que especificamos na continuao do evento de disparo AfterLevel pertencer ao segundo nvel da transao, a regra ser executada quando terminar de interagir com todas as linhas do segundo nvel. E se o atributo especificado em seguida do evento de disparo AfterLevel pertencer ao primeiro nvel, - seguindo o mesmo conceito - a regra ser executada quando tenha terminado de interagir com todos os cabealhos. Observar que isto ocorre no final de tudo, ou seja, uma vez que tivermos inserido todos os cabealhos e suas linhas e fechado a transao (nesse momento tero interagido todos os cabealhos). Portanto, se o atributo especificado pertencer ao primeiro nvel, regra ser disparada uma vez somente antes do Evento Exit ( um evento que executa uma vez quando fechamos uma transao em tempo de execuo, como veremos). Exemplo: Rever o exemplo apresentado anteriormente, onde tnhamos uma transao para representar as Faturas dos fornecedores, e onde tnhamos que controlar que o total calculado de cada fatura coincida com o total informado. Tnhamos a regra: Error(The calculated total doesnt match with the entered total ') if InvoiceCalcTotal<>InvoiceEntTotal; que necessitamos que se dispare depois de todas as linhas da fatura do Fornecedor serem informadas. Portanto, o evento de disparo apropriado ser AfterLevel att, onde att pode ser qualquer atributo das linhas. O evento de nome BeforeComplete, neste caso, coincide com o AfterLevel. Se observarmos o esquema apresentado na pgina anterior, podemos ver que o tempo que tem entre sair do ltimo nvel e a realizao do commit o instante que ocorrem estes eventos. So 02 (dois) nomes para nos referimos ao mesmo. Cuidado que isto sempre assim e quando o nvel abandonado o ltimo. Por exemplo uma transao com dois nveis paralelos. Se agregamos ao cliente suas direes de mail e seus nmeros telefnicos (pode ter vrios): CustomerId* CustomerName {CustomerPhone* } {CustomerEMail* } O momento em que dever disparar uma regra condicionada a: On AfterLevel Level CustomerPhone NO COINCIDIR com o de uma regra condicionada a on BeforeComplete. Enquanto que a primeira se dispara ao sair do nvel dos telefones, e antes de entrar a validar todos os emails, a segunda se disparar depois de sair deste ltimo nvel. Neste caso o evento BeforeComplete coincidir com o AfterLevel Level CustomerEMail. Evento de disparo: AfterComplete Este evento corresponde ao instante de tempo que acontece o commit. Falaremos mais deste evento umas pginas adiantes, quando estudarmos integridade transacional. Se abrir a transao de faturas, se ingressam 3 faturas (cabealho e suas respectivas linhas) e fecha a transao, ocorrero 3 commits (um no final de cada ingresso de cabealho + linhas) e 3 eventos AfterComplete.

Exemplo em uma transao de 2 nveis


Interativamente e antes de confirmar:

REGRAS STAND-ALONE AVALIAO DE REGRAS E FRMULAS SEGUNDO RVORE

PARA CADA LINHA AVALIAO DE REGRAS E FRMULAS SEGUNDO RVORE

O seguinte exemplo pretende mostrar visualmente em que momentos sero disparadas as regras e frmulas definidas numa transao. O disparo de regras e frmulas ir sendo feito de acordo com a rvore de avaliao, seguindo a ordem que esta determina.

Exemplo em transao de 2 nveis


Ao confirmar os dados, na seguinte ordem so executados:

REGRAS STAND-ALONE AVALIAO REGRAS E FRMULAS SEGUNDO RVORE BeforeValidate VALIDAO AfterValidate / BeforeInsert / Update / Delete GRAVAO DO CABEALHO AfterInsert / Update / Delete AVALIAO DE REGRAS E FRMULAS SEGUNDO RVORE PARA CADA BeforeValidate LINHA VALIDAO AfterValidate/BeforeInsert/Udpate/Delete GRAVAO DA LINHA AfterInsert/Update/Delete ABANDONAR NVEL 2 AfterLevel Level attNivel2 - BeforeComplete COMMIT AfterComplete

Regras stand alone As regras stand alone so aquelas que: 1. Podem executar-se com a informao prevista pelos parmetros recebidos. 2. No dependem de nada para serem executadas. Exemplos de regras stand alone (poder executar com a informao prevista pelos parmetros): &A = parmetro2; Msg( ... ) if parmetro1 = 7; Exemplos de regras stand alone (no dependem de nada para serem executadas) : msg( You are in the invoice transaction); &A = 7; Portanto, so as primeiras regras que podem ser executadas. Depois da execuo das regras stand alone, se executam as regras associadas ao primeiro nvel da transao, que no tenham evento de disparo definido, seguindo a ordem de dependncias determinado por GeneXus (assim como as frmulas associadas ao primeiro nvel). Como exemplo, se dispara a regra: Default( InvoiceDate, &Today); Depois de executadas as regras mencionadas para o cabealho, sero executadas todas as regras que tenham como evento de disparo BeforeValidate, j que imediatamente depois ocorre a ao de validao (ou confirmao) da informao desse primeiro nvel. Imediatamente depois da validao do primeiro nvel se executam as regras associadas ao primeiro nvel da transao que incluam em sua definio o evento de disparo AfterValidate, ou os BeforeInsert, BeforeUpdate, BeforeDelete, dependendo do modo em que esteja. Por exemplo: Se no podemos serializar as faturas com a propriedade Autonumber porque o DBMS escolhido no suporta: InvoiceId = PGetNumber.udp(INVOICE) on BeforeInsert;

Aps a execuo das regras associadas ao primeiro nvel com alguns destes eventos de disparo executa-se a ao de gravao; ou seja, que gravar fisicamente a instancia correspondente ao primeiro nvel da transao como registro fsico na tabela correspondente (neste exemplo, na tabela: INVOICE). Imediatamente depois de ter gravado a instancia: se a gravao correspondeu a uma insero: executaro as regras associadas ao primeiro nvel da transao com evento de disparo AfterInsert. se a gravao correspondeu a uma atualizao: executaro as regras associadas ao primeiro nvel da transao com evento de disparo AfterUpdate. se a gravao correspondeu a uma eliminao: executaro as regras associadas ao primeiro nvel da transao com evento de disparo AfterDelete.

Sendo uma transao de dois nveis, como neste caso, sero executadas para cada uma das linhas: Em primeiro lugar, as regras associadas ao segundo nvel da transao que no tenham evento de disparo definido, seguindo a ordem de dependncias determinado pelo GeneXus (assim como as frmulas associadas ao segundo nvel). Exemplos disso so a regra: Subtract( InvoiceDetailQuantity, ProductStock ); a frmula InvoiceDetailAmount = InvoiceDetailQuantity*ProductPrice. Depois das regras mencionadas executadas para uma linha, sero executadas todas as regras que tenham como evento de disparo BeforeValidate, visto que imediatamente depois ocorre a validao da linha; isto uma ao que ocorre depois de terminar de trabalhar com a linha. Imediatamente depois da validao da linha, sero executadas as regras associadas ao segundo nvel da transao que incluam em sua definio algum dos eventos de disparo: AfterValidate, BeforeInsert, BeforeUpdate, BeforeDelete. Em seguida a execuo das regras associadas ao segundo nvel com algum destes eventos de disparo ser executada a ao de gravao; isto , gravar fisicamente a instancia correspondente a linha como registro fsica na tabela correspondente (neste exemplo, na tabela: INVOICEDETAIL). Imediatamente depois de ter gravado a instancia correspondente a linha como registro fsico na tabela correspondente: se a gravao correspondeu a uma insero: so executadas as regras associadas ao segundo nvel da transao com evento de disparo AfterInsert. se a gravao correspondeu a uma atualizao: so executadas as regras associadas ao segundo nvel da transao com evento de disparo AfterUpdate. se a gravao correspondeu a uma eliminao: so executadas as regras associadas ao segundo nvel da transao com evento de disparo AfterDelete. Todas estas operaes sombreadas de cinza claro, so executadas na ordem descrita, para cada uma das linhas.

Aps a interao de todas as linhas, podemos supor a existncia de uma ao que poderamos chamar abandono do segundo nvel. Aps dela so executadas as regras definidas com evento de disparo AfterLevel Level Atributo do 2do nvel. Se no existir outro nvel, como o caso do exemplo, ento coincidir com o evento de disparo BeforeComplete

Declarao Importante: Todas as operaes sombreadas, tanto de cor clara como de cor escura, executam-se unicamente quando for uma transao de dois nveis; de modo que se for uma transao de um nvel, sabemos que tais operaes no so executadas. O motivo dos dois sombreados distintos, para diferenciar o conjunto de operaes que so executadas para cada uma das linhas (sombreado cor clara) das operaes que so executadas somente uma vez ao terminar de interagir com as linhas (sombreado com cor mais escura). Posteriormente, explicaremos as demais operaes que so executadas, seja em uma transao de um nvel ou de dois. Aps de ser executada todas as operaes explicadas at o momento, um commit efetuado. Na continuao sero executadas as regras com evento de disparo AfterComplete. de fundamental importncia que fique claro que todas as operaes explicadas, sero executadas na ordem que foi descrito, para cada fatura com a qual se trabalhe por meio da transao Invoice (seja quando se insere, modifique ou elimine) Pode ser til saber que sero ressaltadas em negrito as aes cada vez que se tenha mencionado. As mesmas so: validao, gravao, abandono do segundo nvel (sair do segundo nvel) e commit. indispensvel assimilar fortemente em que ordem se executam as regras em uma transao, quais so os eventos de disparo disponveis para atribuir, quando so disparadas exatamente, e que aes ocorrem antes e depois de cada evento de disparo, j que somente conhecendo bem todo este tema, poder programar o comportamento das transaes adequadamente. fcil compreender que se necessitamos programar determinados controles ou aes nas transaes, teremos que saber bem se ser feito antes de gravar o cabealho, depois de gravar o mesmo, para cada uma das linhas depois que se tenham gravado, ou antes, depois do commit, ou antes, portanto fundamental ter bem claro todo este tema.

Exemplos
Quando so disparadas as regras seguintes? Something.call( InvoiceId ) if Insert;
Depois de validar o campo InvoiceId e inferido que se est em modo Insert

Something.call( InvoiceId ) on BeforeInsert;


Depois de disparar todas as regras e frmulas segundo rvore, e validar todos os dados do cabealho. Ocorre um instante antes do registro ser inserido.

Something.call( InvoiceId, ProductId ) on BeforeInsert;


Depois que todas as regras e frmulas segundo a rvore serem disparadas, e validados todos os dados da linha. Ocorre um instante antes de inserir o registro.

Something.call( InvoiceId ) on BeforeInsert Level ProductId;


Idem ao anterior. Observar que Level ProductId especifica que se est falando do BeforeInsert das linhas e no do cabealho.

Exemplos
Algumas regras esto mal programadas. Quais? InvoiceDate = &today on AfterInsert;
Incorreto: O ltimo momento para atribuir valor a um atributo do cabealho imediatamente antes de sua gravao (BeforeInsert)

Something.call( InvoiceDate ) on AfterInsert;


Correto: aqui est sendo passado o valor de um atributo do cabealho; enquanto estiver na instncia da fatura esse valor est na memria. ltimo momento possvel para utiliz-lo no AfterComplete.

Something.call( InvoiceId, ProductId ) on AfterLevel Level ProductId;


Incorreto: a regra, o evento de disparo est associada ao 2do. Nvel, isto , disparado para cada linha. Mas o evento de disparo condiciona que seja executada ao sair das linhas. Qual valor teria ProductId?

Regras com o mesmo evento de disparo


So disparadas na ordem em que foram definidas Exemplo 1 xxx.call() On AfterComplete; yyy.call() On AfterComplete;

Exemplo 2 pgmname.call( CustomerId, &flag) On AfterComplete; error(' ') if &flag = 'N On AfterComplete;

Regras com o mesmo evento de disparo Quando em uma transao definimos duas ou mais regras com o mesmo evento de disparo, e no existe nenhuma dependncia entre elas, as mesmas sero executadas respeitando a ordem de definio. Exemplos: 1) Se definem as seguintes regras em uma transao: xxx.Call() on AfterComplete; yyy.Call() on AfterComplete; Como as duas regras definidas esto condicionadas ao mesmo evento de disparo, e no existe nenhuma dependncia entre elas, elas sero executadas na mesma ordem em que foram escritas. 2) Em uma transao, caso seja necessrio chamar a um procedimento que realiza determinada validao e retorna um valor S ou N; e se o valor devolvido N, aparecer uma mensagem de erro. Para resolver isto, avaliaremos duas possibilidades: 2.1) Definir as regras: Pgmname.call(CustomerId, &flag) on AfterComplete; Error( ) if &flag=N on AfterComplete;

2.2) Ou definir as regras: &flag = Pgmname.udp(CustomerId) on AfterComplete; Error( ) if &flag = N on AfterComplete; Na primeira alternativa, temos definida uma regra call e uma regra error. Ambas regras tem o mesmo evento de disparo, e aparentemente existiria dependncia entre elas, j que a regra de error est condicionada ao valor da varivel &flag, e a varivel &flag se passa por parmetro na regra call. Todavia, a dependncia pode parecer evidente porque no procedimento programamos a varivel &flag, de sada, na seo de regras da transao - que onde encontram-se as regras vista at ento -, o especificador do GeneXus no pode saber se os parmetros passados em um call so de entrada, de sada, ou de entrada-sada; em conseqncia o especificador no encontrar inter-dependncia entre as regras call e error, j que a varivel &flag poderia ser passada como varivel de entrada ao procedimento, e nesse caso por Exemplo, no haveria uma dependncia de que primeiro deve-se executar a regra call e depois a regra error. Concluindo, no se detectam dependncias entre as regras call e error da alternativa 2.1), porque as mesmas sero disparadas na Ordem em que esto escritas. importante ver que, se as regras call e error estiverem escritas em ordem inversa (primeiro a regra error e depois a regra call), em muitos casos o comportamento no ser o esperado. A respeito da segunda alternativa, observemos que consiste em uma regra udp e uma regra error. Ambas regras tem o mesmo evento de disparo, e neste caso se existir dependncia entre elas, j que a regra error est condicionada ao valor da varivel &flag, e como as chamadas ao procedimento realizam-se com udp, para o especificador do GeneXus fica claro que a varivel &flag volta modificada do procedimento; portanto, o especificador do GeneXus entende que primeiro deve-se disparar a chamada ao procedimento com udp e depois a regra error, porque a varivel &flag carregada mediante a chamada ao procedimento com udp, e logo que esta varivel tenha valor, que ser avaliada a necessidade de disparar a regra error, ou no. No caso 2.2), ento, independentemente da ordem de definio de ambas as regras, a chamada ao procedimento com udp disparada primeiro, e em seguida dispara a regra error (caso cumpra-se a condio de disparo). Por esta razo recomendamos que sempre que se quer definir validaes desse tipo, se utilize udp ao invs de call.

Eventos em Transaes

Nas transaes permite-se a programao dirigida por eventos, que um estilo de programao na qual se define cdigo que permanece ocioso, at que os eventos provocados pelo Usurio ou pelo sistema, provoquem que o cdigo definido seja executado. Os eventos so aes reconhecidas por um objeto que podem acontecer ou no. A cada evento podemos associar o cdigo, que ser executado somente caso o evento se produza. O cdigo que pode ser associado a um evento, escrito de forma procedural; e quando o evento for produzido, o cdigo associado ao mesmo ser executado seqencialmente.

Eventos em Transaes
Evento Start Evento User Event Evento After Trn Evento Exit Evento TrackContext

Como em Web no se mantm um estado no servidor que permita saber o que est sendo executado no cliente, no possvel saber se est ingressando a primeira instancia de uma fatura, ou se a nsima. Por esta razo, se disparar o evento Start cada vez que se envie ao servidor a informao da instancia com a qual estiver trabalhando. Enquanto que no evento Exit, se excuta por cada iterao, ao final da mesma. O evento TrackContext aplicado para obter interfaces de usurio sensveis ao contexto. Programando este evento pode-se receber informao do contexto para depois tomar as decises necessrias.

Eventos Start
Start: Executado cada vez que o form de uma transao submetido ao servidor.
SINTAXE: Event Start cdigo EndEvent EXEMPLO: Event Start &entrada=Now() EndEvent

O evento Start um evento do sistema, ocorre automaticamente. EXEMPLO: Em uma transao nos interessa capturar a data e hora de entrada da mesma. Para isso no evento Start o atribumos a uma varivel de nome &entrada e tipo de dados DateTime, o resultado da funo Now() que devolve a data e hora atual: Event Start &entrada = Now() EndEvent Se executa cada vez que se submeta o form da transao, ou seja, quando o usurio pressionar qualquer boto do form. Notas gerais: No evento Start fundamentalmente se trabalha com variveis. J a utilizao dos atributos neste evento, seja para avali-los e/ou us-los de algum modo exceto para atualiz-los, se deve considerar que os nicos atributos que esto disponveis so os que so recebidos por parmetro na regra parm. Nenhum outro atributo ter valor neste evento, pois todavia no foi editado a instancia da transao.

Eventos de Usurio
Alm dos eventos oferecidos por GeneXus, o analista pode definir eventos criados por ele, chamados eventos de usurio.
Propriedades

Web:
Ordem de execuo

1. Evento Start 2. Leitura de atributos e variveis do form 3. Evento de usurio selecionado

Como pode-se observar na sintaxe, deve-se dar um nome a um evento do usurio, aps a palavra Event, que encontra-se entre aspas simples. EXEMPLO: Se deseja que na transao "Invoice", o usurio possa imprimir a fatura com a qual esteja trabalhando, pressionando F7 (isto somente vlido para Win): Event Print Invoice // evento definido na transao "Invoice" PrintInvoice.Call( InvoiceId ) EndEvent Como associar um evento de usurio a um controle? Alm dos botes, tambm as imagens e os text blocks admitem a associao de evento de usurio. Para realizar a associao se deve inserir o controle correspondente no form Web e depois nas propriedades do controle, selecionar onde diz OnClickEvent um dos eventos existentes, ou se pode criar um novo.

Evento After Trn


Ocorre imediatamente depois da execuo das regras com evento de disparo AfterComplete. Sintaxe:

Event After Trn cdigo Endevent

Exemplo:

Event After trn Return EndEvent

O evento After Trn das transaes ocorre imediatamente depois da execuo das regras com evento de disparo AfterComplete. Em seguida, o cdigo includo neste evento, ser executado depois que termine cada interao completa por meio da transao (assim que gravado cada cabealho com suas correspondentes linhas como registros fsicos nas tabelas que corresponda e de se ter efetuado o COMMIT). Existem as seguintes alternativas para programar comportamentos que desejam ser executados no final de cada interao completa por meio de uma transao: 1. Definir regras individuais com evento de disparo AfterComplete e deixar o evento After Trn sem cdigo 2. Definir todas as sentenas no evento After Trn com estilo procedural, e no definir regras com evento de disparo AfterComplete 3. Definir as duas coisas: algumas regras com evento de disparo AfterComplete e cdigo no evento After Trn Como vemos explicando, primeiro so executadas as regras definidas com evento de disparo AfterComplete, e imediatamente aps, executamos as regras com cdigo definido no evento After Trn. Um conceito que muito importante ter claro que tanto nas regras com evento de disparo AfterComplete como no evento After Trn, os valores dos atributos do primeiro nvel da transao so conhecidos. Ou seja, sero gravados fisicamente os registros correspondentes ao cabealho e as linhas de certa interao completa, inclusive se efetuou COMMIT, ainda temos disponveis os valores dos atributos do primeiro nvel, podendo ser utilizados para passar por parmetro em uma chamada, ou avaliar seu valor, ou usar de algum modo, exceto atualiz-los . ________________________________________________________________________________ 1 Existem dois motivos pelos quais no possvel atualizar atributos em regras com evento de disparo AfterComplete e After Trn. O primeiro motivo que j foi realizado as gravaes correspondentes e incluso o COMMIT j foi realizado, de modo que j tarde para atribuir valores aos atributos. Alm disso, relacionado ao evento After Trn, nos eventos no permito realizar atribuies aos atributos.

No permitido atribuir valores a atributos nos eventos. Os valores dos atributos podem ser modificados nas transaes: o usurio final fazendo, em tempo de execuo, atravs do form (somente atributos das tabelas bases associadas a transao, ou aqueles da estendida permitidos pela regra update) mediante regras definidas pelo programador (a atributos das tabelas bases associadas a transao e suas estendidas) Os eventos Start e Exit so sem tabela base. Com esta expresso nos referimos que nos eventos Start e Exit no tem consulta ativa base de dados (j que no evento Start ainda no foi feito a consulta e no evento Exit em Win j foi fechado o programa associado a transao e em Web a instancia est sendo fechada e j no dispe da consulta). Por este motivo que no conhecemos valores de atributos nos eventos Start e Exit, exceto os recebidos por parmetro. Ao contrrio, os eventos After Trn e de Usurio so com tabela base, quando os mesmos se executam temos uma consulta feita. Ento, em particular no evento After Trn, conhecemos os valores dos atributos do primeiro nvel (o segundo nvel j foi inserido a essa altura e no tem possibilidade de posicionamento em alguma linha em particular); e no que diz respeito aos eventos de Usurio os atributos de todos os nveis 1 esto disponveis. fundamental que fique claro, que assim que se disponha dos valores de certos atributos ou outros dependendo do evento, os mesmos podero ser utilizados para ser analisados e/ou passados por parmetro a objetos que se chamem, e/ou para alguma outra operao qualquer que no seja atribuir valor. Concluindo, em nenhum evento (no somente das transaes, mas em nenhum objeto GeneXus) permite-se realizar atribuies a atributos.

________________________________________________________________________________________________________________________ 1

Se num evento de usurio so referenciados atributos de um segundo nvel ou outro nvel subordinado, quando o evento de usurio for executado nos atributos daquela linha se tem um posicionamento; no momento que o evento de usurio executado sero considerados os valores dos atributos desta linha. Caso o usurio no se posicionou explicitamente em determinada linha, por default a linha que selecionada a primeira linha, assim sero estes os valores dos atributos considerados.

Integridade Transacional
IT

143

O que o conceito: integridade transacional?


um conjunto de atualizaes de integridade transacional que a base de dados possui quando acontece uma finalizao anormal, a base de dados permanece em estado consistente.

Muitos administradores de bases de dados (DBMSs) contam com sistemas de recuperao antifalhas, que permitem deixar a base de dados em estado consistente quando ocorrem imprevistos tais como apages ou quedas do sistema.

144

O que o conceito: unidade lgica de trabalho (UTL)?


Uma Unidade Lgica de Trabalho (UTL) um conjunto de operaes na base de dados, todas devem ser executadas ou nenhuma delas.

Os administradores de bases de dados (DBMSs) que oferecem integridade transacional, permitem estabelecer Unidades Lgicas de Trabalho (UTLs), que so, nem mais nem menos, que o conceito de transaes de base de dados.

145

O que efetuar COMMIT?


O comando COMMIT permite especificar que certo conjunto de operaes realizadas sobre uma base de dados que foram efetuadas corretamente:
........... Operao sobre Base de Dados
Operao sobre Base de Dados

COMMIT

Finaliza UTL Comea UTL Operao sobre Base de Dados


Operao sobre Base de Dados Operao sobre Base de Dados Operao sobre Base de Dados

COMMIT

Finaliza UTL

Efetuar COMMIT em uma base de dados, significa finalizar uma Unidade Lgica de Trabalho (UTL).

Efetuar COMMIT em uma base de dados, significa finalizar uma Unidade Lgica de Trabalho (UTL).

146

O que efetuar ROLLBACK?


Fazer ROLLBACK (voltar atrs) implica em desfazer todas as operaes efetuadas na base de dados que no tenham recebido COMMIT. Isto resolve-se desfazendo todas as operaes posteriores ao ltimo COMMIT.

147

Unidade lgica de trabalho (UTL) por default em GeneXus


Todo objeto GeneXus transao e todo objeto GeneXus procedimento, por default uma Unidade Lgica de Trabalho (UTL). Ou seja, GeneXus default o mesmos, as transaes e procedimentos so os nicos objetos (*) que permitem atualizar a base de dados, e por GeneXus inclui nos programas gerados associados aos a sentena COMMIT.

No objeto procedimento GeneXus incluiu um COMMIT automtico no final do Source. No objeto transao GeneXus incluiu um COMMIT automtico no final de cada instancia, imediatamente antes das regras com evento de disparo AfterComplete
(*) uma exceo Business Components, mas o commit no realizado automaticamente.

importante comentar que o GeneXus inclui a sentena COMMIT nos programas gerados associados a transaes e procedimentos, somente em ambientes de trabalho Cliente/Servidor (incluindo, portanto, os ambientes Web). O motivo disto que em ambientes Cliente/Servidor, temos um DBMS que assegura a integridade transacional, portanto o GeneXus efetua a tarefa de definir as Unidades Lgicas de Trabalho (UTLs). Onde o GeneXus inclui COMMIT exatamente? Em cada procedimento: ao final do programa fonte. Em cada Transao: imediatamente antes das regras com evento de disparo AfterComplete. Para cada interao completa que for efetuada em tempo de execuo por meio da transao, haver um COMMIT, antes das regras com evento de disparo AfterComplete. Nota: o novo tipo de dados Business Component que estaremos vendo depois permite atualizar a base de dados desde qualquer objeto GeneXus, mas ser visto que no realiza automaticamente um COMMIT.

148

Personalizao de UTL em GeneXus


Propriedade Commit on Exit de transaes e procedimentos:
Valores:

Yes (Default): COMMIT executado No: COMMIT No executado

GeneXus oferece uma Propriedade para cada objeto transao e procedimento, para definir se deseja que seu programa gerado efetue ou no o COMMIT. O nome da Propriedade Commit on Exit e seu valor por default Yes (por isso, toda transao e procedimento por default efetua COMMIT). Se desejamos que certa transao ou procedimento no tenha COMMIT no programa gerado, alterar o valor da Propriedade Commit on Exit para No.

149

Personalizao de UTL em GeneXus


Exemplo de Commit on Exit = No

Trn. X

call

Proc. Y

Commit on Exit = Yes

Commit on Exit = No

Importante: chamar a partir da Trn. X ao Proc. Y utilizando um evento de disparo que consideremos adequado e que ocorra antes da execuo do COMMIT da Trn X.

Por que motivo pode-se querer que no seja realizado COMMIT em uma Transao ou Procedimento? Para personalizar uma Unidade Lgica de Trabalho (UTL). Isto , podemos precisar ampliar uma Unidade de Trabalho Lgica (UTL), para que vrias transaes1 e/ou procedimentos, estejam em uma nica Unidade de Trabalho Lgica (UTL). Exemplo (mostrado acima): A Transao X chama um Procedimento Y, e deseja-se que ambos objetos estejam em nica UTL. A Transao atualiza certos registros, e o procedimento outros, e se deseja que esse conjunto total de operaes, consista em uma nica UTL (para assegurarmos que se ocorrer alguma falha, seja realizado todo o conjunto de atualizaes ou nada na da base de dados). Para isto, podemos eliminar o COMMIT do procedimento, e deixar que seja realizado na Transao (ao retornar do procedimento para a Transao, para que seja executado ao final de todas as operaes); temos que configurar a propriedade Commit on Exit do procedimento com valor: No e deixar a propriedade Commit on Exit da Transao com o valor por default: Yes. Mas alm disso, fundamental que a chamada ao procedimento seja realizada antes que se execute o COMMIT na transao (j que a idia que ambos os objetos tenham uma nica UTL, e para ele o COMMIT deve efetuar na transao ao retornar do procedimento); assim que a chamada ao procedimento definir na Transao com um evento de disparo que ocorra antes da execuo do COMMIT (dependendo se a transao tiver um nvel ou mais, e dos requerimentos, poderia ser AfterInsert por exemplo, AfterUpdate, ou AfterLevel Level Atributo do 2do nvel, ou BeforeComplete mas no AfterCompete). No existe uma nica soluo para personalizar uma UTL. O fundamental analisar qual objeto pode fazer COMMIT (podendo haver mais de uma possibilidade) e uma vez que se decida qual objeto efetuar COMMIT, as chamadas que se requerem fazer, devero ser efetuadas em momentos adequados, considerando se j executou o COMMIT ou no. ____________________________________________________________________________ Em ambiente Web existe uma restrio importante: se uma transao chamar outra transao, o Commit realizada
por uma no aplica sobre os registros ingressados/modificados/eliminados pela outra. Isto , o Commit de cada transao contm somente visibilidade sobre os registros operados por essa transao, e no por outra, onde duas transaes diferentes no podem ficar em uma mesma UTL. No poder realizar-se personalizao neste caso.

150

Por Exemplo, para que a transao e procedimento vistos conformem uma nica UTL, poderamos ter optado tambm pela alternativa de que no efetue COMMIT na transao (Commit on Exit = No), mas sim que seja realizado pelo procedimento ao final de tudo; fazer dessa forma, no seria um erro - como o na soluo anterior - chamar ao procedimento utilizando o evento de disparo AfterComplete, o COMMIT no ser realizado na transao, mas no procedimento. Concluindo, precisamos decidir qual objeto far COMMIT e que as chamadas necessrias sejam feitas em momentos adequados, para que a UTL personalizada fique bem definida. Outro Exemplo: A transao Invoice estudada at o momento, em um modelo de Prottipo cliente/servidor. Caso no modificarmos o valor predeterminado da propriedade Commit on Exit. E o usurio executa a transao, inserindo a fatura 1 e todas as suas linhas. Depois insere a fatura 2 e quando inserir a 3era. Linha da mesma ocorre um apago. Quando a energia volta e reinicializa a execuo, quais os registros que ficaram gravados na tabela e quais foram perdidos? A fatura 1 inteira estar gravada (cabealho e suas linhas). Por qu? Porque ao terminar de inserir e passar a inserir a fatura 2, foi efetuado um commit. A fatura 2 com os registros que gravou at o momento que faltou energia, foi perdido. Por qu? Porque a transao realiza o rollback de tudo que foi efetuado depois do ltimo commit. O cabealho da fatura 2 e as suas linhas informadas no estavam ainda commitadas. Observar ento que o commit no pela transao inteira (ou seja, todas as interaes do cabealho e suas linhas) e sim por cada instancia do cabealho e linhas. Se o commit acontece uma nica vez antes da transao ser fechada, ento se tivesse sido ingressados 29 faturas e o sistema casse na trigsima, todas as 29 faturas anteriores (todo o processo seria desfeito, j que ainda no foi realizado o commit). Isto no assim, quando ocorre a queda do sistema na trigsima fatura informada, ficaram gravadas as 29 anteriores (s no foi trigsima).

151

Personaliza de UTL
Uma UTL composta por vrias transaes Web no pode ser definida call

Trn.X
UTL 1

Trn.Y

UTL 2

Uma transao Web somente pode ter Commit dos registros inseridos por ela mesma, ou pelo procedimento em uma cadeia de chamadas, porm no pode fazer um Commit dos registros inseridos por outra transao.

call

call

Trn.X

(depois do Commit)

Trn.Y

(antes do Commit)

Proc.Z

UTL

No podem ficar dentro de uma mesma UTL

Em ambiente Web os registros visveis para ser commitados por uma transao so os atualizados pela prpria transao, e pela prpria transao, e pelos procedimentos que esta chame antes do seu Commit, porm no os de outra transao. Cada transao trabalha com diferentes UTLs. por este motivo que no primeiro exemplo acima apresentado, onde a transao X chama a transao Y logo de ter inserido um registro, embora a transao Y realize um Commit ao final do cabealho e linha so ingressadas, este Commit no valer sobre o registro que teria sido ingressado previamente pela transao X. Este registro ficar perdido, sem Commit. Internet trabalha de forma diferente, as transaes Web vivem somente o tempo em que o usurio de um navegador seleciona o link ou pressiona um boto e a nova pgina mostrada. Toda modificao da base de dados que se faa durante a vida da transao deve ser confirmada ou eliminada antes que a transao Web finalize sua execuo e retorne pgina resultante. Como conseqncia, uma transao Web inicia uma UTL (Unidade Lgica de Trabalho) ao comear a executar e fecha-a (seja por COMMIT ou ROLLBACK) antes de terminar. No pode formar parte de outra UTL. Se um programa chama uma transao Web, esta iniciar outra (nova) UTL. No acontece isso com os procedimentos. No segundo exemplo mostrado acima, vemos que podemos formar uma UTL que envolva transao Y e ao procedimento Z...com tudo no podemos incluir a transao X na mesma UTL.

152

Personalizao de UTL
Se desejarmos ter uma mesma UTL para duas transaes diferentes:

Trn.X

Trn.Y

Soluo: utilizar Business Components e o comando Commit aps inserir variveis Business Components dos registros associados a ambas transaes (ser visto mais adiante).

Caso seja necessrio que as operaes de duas ou mais transaes (com ou sem procedimentos includos) estejam em uma mesma UTL, pode-se usar as transaes com Web Panels e Business Components; e utilizar o comando Commit. Aqui simplesmente vamos deixar o tema sinalizado, voltaremos nele aps estudar Business Components, onde vamos compreender esta soluo.

153

Comandos COMMIT e ROLLBACK de GeneXus


GeneXus oferece os comandos: COMMIT e ROLLBACK Podem ser includo em Procedimentos e Web Panels, assim como combinados com Business Components. Exemplo (usurio final decide executar Commit ou Rollback): A partir de uma transao chamado vrios procedimentos consecutivos, e a todos eles se configura a propriedade Commit on exit = No e no ltimo procedimento se pergunta ao usurio se confirma; dependendo da resposta do usurio, ter que executar o comando COMMIT ou ROLLBACK

154

Objeto Procedimento

155

Procedimentos
Definio Processos no interativos de consulta e atualizao da base de dados.

Procedimentos: Definem processos no interativos de consulta e atualizao da base de dados. Os procedimentos podem gerar um arquivo formato PDF, mediante o qual possvel listar informao na tela ou impressora. Alm disso, os procedimentos podem atualizar a base de datos1.

__________________________________________________________________________ veremos mais adiante, existe um tipo de dados especial, que no estritamente um tipo de dados, mas algo um pouco mais complexo, o business component, por meio do qual sero realizados atualizaes a base de dados em qualquer objeto GeneXus. Portanto, utilizando variveis de tipo de dados business component, podero ser realizadas atualizaes incluso nos objetos que por natureza no oferecem esta possibilidade, como as web panels.
1 Como

156

Caractersticas
Definio procedural Definio sobre a base de conhecimento Independncia da base de dados: definio a nvel de atributos

Definio procedural A diferena das regras das transaes onde as especificaes se realizam de forma declarativa e GeneXus determina no momento de gerar o programa a seqncia de execuo, nos procedimentos as especificaes se realizam de forma procedural. Desta forma, a seqncia de execuo determinada pelo analista, utilizando para isso uma linguagem simples que contem comandos de controle, de impresso, de acesso a base de dados, etc. Definio sobre a base de conhecimento A grande potencia da linguagem dos procedimentos est que as definies so realizadas sobre a base de conhecimento e no diretamente sobre o modelo fsico (tabelas, ndices, etc.). Isto nos permite utilizar automaticamente todo o conhecimento j incorporado ou gerado por GeneXus a partir das especificaes realizadas. Por exemplo, se desejamos mostrar o resultado de uma frmula suficiente nomear o atributo frmula no lugar adequado e GeneXus dispara o clculo mostrando o resultado, sem necessidade do analista oferecer nenhuma outra informao. A informao de como se calcula um atributo frmula est contida na base de conhecimento. Tambm podemos utilizar o conceito de tabela estendida, j que GeneXus conhece as relaes entre as tabelas da base de dados, o analista no precisa explicitar estas relaes na hora de recuperar dados. Independncia da base de dados: definio a nvel de atributos A definio dos procedimentos se faz a nvel de atributos: no necessrio indicar explicitamente quais tabelas sero percorridas e nem mediante quais ndices. Somente mencionando os atributos que deseja acessar suficiente para que o GeneXus determine esta informao. Isto possvel porque GeneXus possui um completo conhecimento da estrutura da base de dados. Desta maneira obtemos uma real independncia da base de dados, j que qualquer alterao nas tabelas ser gerenciado automaticamente pelo GeneXus e desta forma, para atualizar os programas alcana em grande parte das vezes, como regerar os objetos sem ter que modificar nada do programado neles.

157

Elementos

Assim como nas transaes, variveis podem ser definidas e so locais ao objeto.

Para cada procedimento se pode definir: Source: Aqui se escreve o cdigo correspondente a lgica do procedimento. Tambm podem definir-se ao final do cdigo subrotinas1 que podem ser chamadas a partir do prprio cdigo mediante o comando adequado. Layout: Assim como as transaes possuem uma tela (form), os procedimentos possuem um layout de sada. Nesta seo se define apresentao do procedimento: os dados que se quer listar e o formato da sada. Regras-Propriedades: Definem aspectos gerais do procedimento, como seu nome, descrio, tipo de sada (impressora, arquivo, tela), parmetros que recebe o objeto, etc. Condies: Condies que devem cumprir os dados para ser recuperados (filtros). Variveis: Variveis locais ao objeto. Ajuda: Permite a incluso de texto de ajuda, para ser consultado pelos usurios em tempo de execuo, para o uso do procedimento. Pode ter uma ajuda para cada linguagem. Documentao: Permite a incluso de texto tcnico, para ser utilizado como documentao do sistema.

__________________________________________________________________________________
1

No sero vistas no presente curso. Ver no Curso No Presencial de GeneXus.

158

Exemplo
Queremos implementar a listagem abaixo:
rea com dados fixos rea com dados fixos rea com dados variveis (acesso a base de dados)

Por exemplo, vamos supor que queremos implementar um procedimento para imprimir o identificador, nome e pas de todos nossos clientes e queremos que a listagem saia como mostrada na figura. Para isso, devemos identificar na sada da listagem das distintas reas que o compem. A cada uma delas a representaremos com um Printblock. Os primeiros dois Printblocks ilustram no GeneXus tal qual as primeiras duas reas pois contem unicamente textos, linhas, retngulos. Tambm poderamos ter colocado estas duas reas convertendo-as em uma e utilizando portanto um nico Printblock. O terceiro Printblock ser o correspondente da rea de dados variveis da figura anterior, que representa informao que deve ser extrada da base de dados. O que queremos mostrar neste caso o identificador e nome de cada cliente, junto com o nome do pas ao que pertence. Esta informao a representada pelos atributos CustomerId, CustomerName e CountryName da base de conhecimento da aplicao, o terceiro Printblock conter os trs controles atributo CustomerId, CustomerName e CountryName. Transformando as reas em Printblocks, o Layout do procedimento ficar como o da figura na pgina seguinte.

159

Layout
Nome de cada Printblock Printblock

Sucesso de Printblocks No importa a ordem de definio Cada Printblock deve ter um nome nico Somente so declarados, so chamados a partir do Source com o comando print (Ex.: print header)

O Layout de um procedimento ser uma sucesso de Printblocks que no tem por que seguir a ordem em que deseja que apaream na sada. No exemplo anterior, o mesmo procedimento teria sido impresso se houvesse especificado os Printblocks na ordem inversa (ou em qualquer ordem). Aqui simplesmente so declarados. A ordem que so executados fica determinado na seo Source que a que contem a lgica do procedimento. A partir dali sero chamados mediante um comando especfico para tal finalidade (o comando print). Por esta razo, cada Printblock deve ter um nome nico para poder ser referenciado depois a partir do Source. No exemplo, para listar todos os clientes, o Printblock de nome customer deve ser chamado dentro de uma estrutura repetitiva no Source. Esta estrutura repetitiva o comando For each que estudaremos depois.

160

Layout: Printblock
Para definir os Printblocks temos os seguintes controles disponveis:

e para inserir um Printblock boto direito sobre o layout e escolhemos Insert Printblock

O Printblock um tipo de controle vlido somente nos procedimentos, que inserido e eliminado do Layout pelo analista, e que contem outros controles -atributos, textos, retngulos, linhas, etc.-, sendo estes ltimos os que efetivamente especificam qual o que se quer mostrar na sada. Para inserir os controles no Form de uma transao contamos com uma toolbox. A mesma toolbox se utiliza para inserir os controles no Layout. De fato esta toolbox est disponvel para todos os objetos GeneXus criados, e em cada caso ter os controles disponveis segundo o tipo de objeto. Para inserir um Printblock - boto direito em qualquer lugar do layout e selecionamos Insert Printblock. Como todo controle, o Printblock possui propriedades que podem ser configuradas pelo usurio. Em particular, tem a propriedade Name, muito importante visto que o identificador do Printblock. Com este identificador que o Printblock pode ser chamado a partir do Source para ser impresso. Para acessar as propriedades de um Printblock, o selecionamos e pressionamos F4 ou View/Properties.

161

Source
Define a lgica do procedimento mediante programao procedural Linguagem simples
Comandos usuais de controle: If, Do-case, Do-while, For Comandos de impresso: Print, Header, Footer Comando de acesso e atualizao da BD: For each, New, Delete Comandos para sair de um loop, abandonar o programa, chamar outro objeto, chamar uma subrotina, etc.: Exit, Return, Call, Do

Nesta seo se define a lgica do procedimento . A linguagem utilizada para programar o cdigo fonte dos procedimentos muito simples, e consta de alguns comandos que veremos. O estilo de programao procedural imperativo o Source ser uma sucesso de comandos onde a ordem fundamental: a ordem em que estejam especificados corresponder, exceto excees, a ordem em que sero executados. Existem, como em toda linguagem imperativa, comandos de controle para a execuo condicional (if, do case), o repetitivo (do while, for), para chamar a outro objeto (call), para cortar as iteraes dentro de um loop (exit) ou abandonar o programa (return), assim como tambm comandos especficos desta linguagem: para imprimir um Printblock do Layout (print), para acessar a base de dados (For each), para inserir novos registros em uma tabela (new), para chamar a uma subrotina (do), etc. No final da sucesso de comandos que constitui o cdigo geral ou principal do procedimento, podem definir-se subrotinas que podem ser chamadas (mediante o comando do) a partir do cdigo geral. No podem ser chamadas a partir de outro objeto (so locais). Por sua importncia, comeamos estudando detalhadamente o comando de acesso a base de dados, fundamental na hora de recuperar a informao armazenada. Depois sero tratados brevemente os comandos de controle, que so comuns a todos as linguagens de programao imperativa, os comandos de atribuio e os de impresso.

162

Comando For each


Utilizado para acessar a informao da base de dados. Com um For each se percorre uma tabela da base de dados: a tabela base do For each. Para cada registro dessa tabela pode ser feito algo com a informao associada. (Exemplo: imprimir) Todo comando For each termina com um Endfor

A definio do acesso a base de dados para recuperar a informao se realiza com um nico comando: o comando For each1. Usando o For each se define a informao que vai acessar. A forma de o fazer baseada em nomear os atributos a utilizar. Assim, com este comando se definem quais atributos so necessrios em qual ordem vai ser recuperada, e GeneXus se encarrega de encontrar como fazer. No se especifica de quais tabelas se devem obter, nem quais ndices se devem utilizar para acessar a essas tabelas: isso GeneXus infere. Evidentemente isto nem sempre possvel, e em tais casos GeneXus d uma srie de mensagens de erro indicando por que no se podem relacionar os atributos envolvidos. A razo pela qual no se faz referencia ao modelo fsico de dados porque desta maneira a especificao do procedimento de mais alto nvel possvel, de tal forma que ante mudanas na estrutura da base de dados a especificao do mesmo se mantenha vlida a maior parte das vezes. Quando aparece um For each se est indicando que se quer recuperar informao da base de dados. Concretamente GeneXus sabe que com um For each se quer percorrer (ou navegar) uma tabela. Para cada registro dessa tabela, se quer fazer algo com a informao associada (ex: imprimir). Portanto, todo comando For each possui uma tabela fsica associada: a tabela que ser percorrida ou navegada. A esta tabela vamos chamar tabela base do For each. ___________________________________________________________________________
1

Quando estudarmos os business components veremos que utilizando seu mtodo Load tambm se consegue consultar a base de dados.

163

Comando For each


Exemplo: Listagem de clientes CUSTOMER Layout: COUNTRY

Source: For each print customer Endfor

Intuitivamente com este comando queremos listar identificador, nome e pas de cada um dos clientes da base de dados. Ou seja, queremos percorrer tabela CUSTOMER, e para cada cliente seja recuperado da tabela COUNTRY o nome do pas ao qual pertence, imprimindo esta informao, junto com o identificador e nome do cliente. (Observar que a tabela COUNTRY pertence estendida de CUSTOMER) Como o GeneXus infere isto, s o que fizemos foi For each do exemplo informar os atributos que nos interessava mostrar?

164

Comando For each


Tabela percorrida: CUSTOMER Tabela acessada para cada cliente: COUNTRY CUSTOMER INTERPRETAO:
For each record in table CUSTOMER Find the corresponding CountryName in table COUNTRY print customer Endfor

COUNTRY

Dentro de todo For each navega-se - percorre ou itera - a tabela base, mas podemos acessar as tabelas que constituem sua tabela estendida para recuperar a informao, por pertencer a estendida est relacionada com cada registro da tabela base com que esteja trabalhando em cada interao (o conceito de tabela estendida muito importante neste comando e sugerimos repassar sua definio). por isso que no For each do exemplo, a tabela base ser CUSTOMER, e acessa para cada cliente, no somente os dados de seu registro, como tambm do registro associado na tabela COUNTRY (que est na estendida de CUSTOMER). Dizemos ento que se percorre CUSTOMER e se acessa alm disso a de COUNTRY para buscar o resto da informao requerida. Como podemos ver claramente no exemplo apresentado, no apresentamos de forma explcita ao GeneXus esta informao. No necessrio, j que o GeneXus conhece as relaes entre as tabelas, e na base os atributos mencionados dentro do For each e pode encontrar sem necessidade de mais informaes uma tabela estendida que os contenha. A tabela base dessa estendida escolhida como tabela base do For each.

165

Comando For each: determinao de tabela base


O acesso a base de dados fica determinado pelos atributos que so utilizados dentro do comando For each. Para esse conjunto de atributos, GeneXus busca a mnima tabela estendida que os contenha. Sua tabela base ser a tabela base do For each.

A tabela base correspondente a essa tabela estendida chamada de tabela base do For each e ser percorrida seqencialmente, executando para cada registro o que for indicado nos comandos internos do For each.

166

Comando For each: determinao de tabela base


{CustomerId, CustomerName, CountryName} est(CUSTOMER) {CustomerId, CustomerName, CountryName} est(INVOICE)

Mas: est(CUSTOMER) < est(INVOICE)

est(CUSTOMER) a mnima tabela estendida que contenha os atributos do For each.

Tabela base: CUSTOMER

Para o exemplo apresentado onde queremos uma lista dos clientes: seu identificar, nome e nome de pas, observamos os atributos utilizados dentro do For each, e percebemos que eles so os contidos no print block de nome customer: CustomerId, CustomerName e CountryName. Em que tabelas esto estes atributos? CustomerId est em 2 tabelas: - CUSTOMER como chave primria (PK). - INVOICE como chave estrangeira (FK). CustomerName est somente em CUSTOMER ( um atributo secundrio). CountryName est somente em COUNTRY ( um atributo secundrio). GeneXus conhece as relaes entre as tabelas. Podemos ver o diagrama correspondente s tabelas nas quais aparecem os atributos do For each (Tools/Diagrams). Aqui podemos ver porque do requerimento da tabela estendida seja a mnima (entendendo por mnima aquela que envolve um nmero menor de tabelas). A tabela estendida de INVOICE tambm contm todos os atributos do For each, mas no mnima, pois a de CUSTOMER tambm os contm. Portanto, se vamos percorrer seqencialmente tabela CUSTOMER, e para cada registro dessa tabela, vamos acessar a tabela COUNTRY, e recuperar o registro da mesma que cumpre: COUNTRY.CountryId = CUSTOMER.CountryId e para o mesmo recupera-se o valor do atributo CountryName, para poder imprimi-lo, junto com o cdigo e nome do cliente.

167

Listagem de navegao

tabela base A consulta ordenada pela PK da tabela base

Acessa para recuperar info relacionada (CountryName) tabela base: a navegada

Listagem de navegao GeneXus oferece para todos os objetos uma lista conhecida como listagem de navegao, que o resultado da especificao do objeto. Esta listagem muito til para os relatrios, j que indica quais so as tabelas que so acessadas em cada For each do Source, se existe um ndice para recuperar os dados da tabela base, e em caso de que assim seja qual esse ndice (seu nome), se aplicam filtros sobre os dados ou se devemos listar todos, etc. Desta maneira, o analista no tem que executar o objeto para verificar se a lgica a esperada. Estudando a listagem de navegao j tm a informao necessria para saber se est percorrendo a tabela esperada, se esto aplicando corretamente os filtros desejados, etc. Como pode ser visto, esta listagem mostra para o comando For each que aparece no Source, qual a tabela base do mesmo, por que ordem essa consulta resolvida (a ordem que os resultados so impressos), se existe um ndice que satisfaa essa ordem, qual seu nome, e aparecem mais duas informaes envolvidas: os filtros de navegao e o diagrama de tabelas. Os filtros da navegao indicam que faixa da tabela base que vai ser percorrida. No Exemplo percorrida toda a tabela base do For each: comeando pelo primeiro registro de CUSTOMER, at que chegue ao fim de tabela (utilizando o ndice ICUSTOMER). Tambm mostrado num pequeno diagrama de tabelas, a tabela base do For each com sua chave primria, e endentadas todas as tabelas da estendida que devam ser acessadas para recuperar a informao associada ao registro da tabela base que est sendo trabalhada em cada interao do For each. Neste caso se mostra somente a tabela COUNTRY. No comando For each do Exemplo no aparece explicitamente nenhuma informao referente a ordem desejada da impresso da informao do relatrio. Neste caso GeneXus escolhe a ordem da chave primria da tabela base do For each. por esta razo que no For each do Exemplo, GeneXus determinou que a ordem realizado pelo atributo CustomerId, chave primria da tabela CUSTOMER.

168

For each: clusulas Where


Permitem estabelecer filtros sobre os dados que sero recuperados . Exemplo:
For each where CustomerName >= &Start when not &Start.IsEmpty() where CustomerName <= &End when not &End.IsEmpty() print customer Endfor

Somente para os registros que cumpram as condies booleanas das clusulas where so executados os comandos internos ao For each. As clusulas where so aplicadas somente se satisfizer as condies de suas clusulas when (somente so vlidas para arquitetura cliente/servidor).

Para restringir os dados que queremos listar no For each so utilizadas as clusulas where do comando. Se na listagem de clientes no queremos listar todos os clientes, mas apenas aqueles cujo nome esteja dentro de uma faixa inserida pelo usurio, ento devemos agregar ao For each que havamos visto uma clusula where, para especificar os filtros desejados sobre os dados: For each where (CustomerName >= &Start) and (CustomerName <= &End) print customer Endfor onde as variveis &Start e &End devem ser definidas no procedimento com o mesmo tipo de dados que CustomerName, e as carregar com valores fixos ou recebidos por parmetro1. Com a clusula where definida estamos dizendo ao GeneXus que no queremos todos os registros da tabela base, e sim, somente aqueles que satisfaam a condio booleana da clusula. No exemplo escrevemos uma clusula somente where com uma condio composta, mas poderamos ter programando o mesmo com duas clusulas where, como mostramos no slide acima. Quando aparecem vrios where a condio de filtro que vai ser aplicada sobre os dados a conjuno booleana de todas as Condies dos where que apareceram. Observemos que no slide os comandos where estejam condicionadas com as clasulas when. Se interpreta da seguinte forma: os filtros estabelecidos pelo where so aplicados somente quando o when satisfeito. Isto lido da seguinte forma: o filtro estabelecido ser aplicado pelo where somente quando satisfaa a condio do when. No exemplo, somente aplicado o primeiro filtro: CustomerName >= &Start se a varivel &Start no for vazia. Se for vazia, este filtro no ser aplicado. Igual ao caso da segunda clusula when. Observar que se &Start e &End estejam vazios, no sero aplicados nenhum dos comandos where, e portanto sero listados todos os clientes (como se no existissem os comandos where). Cada condio booleana de um where pode estar composta de vrias expresses booleanas concatenadas com os operadores lgicos and, or e not. __________________________________________________________________________________
1A

travs de um objeto que pedido ao usurio, por exemplo um Web Panel.

169

Listagem de navegao

Listagem de navegao Aparece um novo elemento nesta listagem que no existia, quando no tnhamos clusulas where: os constraints (restries). Que informao ganhamos com esta listagem de navegao? que a tabela base do For each continua sendo CUSTOMER que a ordem correspondente da consulta continua sendo por CustomerId, utilizando o ndice ICUSTOMER

que continua percorrendo toda a tabela CUSTOMER em busca da informao mas para cada cliente avalia se cumpre as restries que aparecem enumeradas (CustomerName>= &Start se &Start no estiver vazia e CustomerName<=&End se &End no estiver vazio) e somente caso se cumpra, executar para esse cliente os comandos que aparecem dentro do For each. Neste caso, imprime os valores dos atributos do Printblock customer: CustomerId, CustomerName, CountryName. que deve acessar a tabela COUNTRY cuja chave primria CountryId para obter algum dado (CountryName)

170

For each: clusulas Where


Atributos permitidos: os atributos da tabela estendida da tabela base do For each Exemplo:
For each where CountryName = Uruguay print customer Endfor

Os atributos utilizados nas condies de filtro podem ser de qualquer tabela estendida do For each. No exemplo, a tabela base do For each CUSTOMER, estamos filtrando os dados a serem recuperados utilizando o atributo CountryName, que da tabela COUNTRY, pertencente tabela estendida de CUSTOMER. Neste exemplo nada foi feito em relao ordem, os dados aparecero ordenados pela chave primria da tabela base, ou seja, pelo identificador de cliente, CustomerId. .

171

For each: clusula Order


Permite estabelecer a ordem que os dados sero recuperados. Exemplos:
For each order CustomerName print customer Endfor For each order CustomerName when not (&Start.IsEmpty() and &End.IsEmpty()) print customer Endfor

Para determinar que a ordem seja descendente o atributo deve estar entre parnteses. Ex: order (CustomerName)

Se queremos realizar uma lista de todos os clientes, ordenado por nome do cliente ao invs do cdigo, precisamos modificar o comando For each agregando esta informao da ordem. Fazemos isso utilizando a clusula order do For each, como mostramos no primeiro exemplo. Como no existe um ndice definido na tabela CUSTOMER por atributo CustomerName, o GeneXus indicar na listagem de navegao mediante uma advertncia (warning) que no existe um ndice para satisfazer a ordem, o que pode ocasionar problemas de performance, dependendo da plataforma de implementao, da quantidade de registros que devem ser lidos da tabela, etc. Em ambientes cliente/servidor, se no existe ndice para satisfazer a ordem, o For each se traduz numa consulta SQL (select) que resolvida pelo motor do DBMS da plataforma. Igual o caso dos comandos where, em plataformas cliente/servidor a clusula order pode ser condicional, como o exemplo dois. Caso a condio when no for cumprida, essa ordem no ser utilizada e no existir ordem incondicional (sem a clusula when) como no exemplo, a ordem ser indefinida, isto , a ordem poder variar de DBMS a DBMS e inclusive entre execues seguidas. Podem ter vrias clusulas order consecutivas condicionais (com clusula when) em arquiteturas cliente/servidor e uma sem condio (a ltima da lista). O primeiro comando order cuja condio do when for satisfeita, ser a ordem escolhida para ser utilizada. Clsula Order None: clsula que evita que GeneXus escolha por default a ordem dos atributos da chave primria da tabela base e utiliza uma ordem de navegao indefinida. Se utilizar a clusula Order None, GeneXus entende que no deseja estabelecer nenhuma ordem em particular e delega esta tarefa ao DBMS. A clusula order none pode ter condio (when).

172

Listagem de navegao

For each order CustomerName print customer Endfor

Listagem de navegao Quando no existe um ndice que satisfaa o ordem de um For each, como o caso do Exemplo, o analista GeneXus pode resolver cri-lo (ndice de usurio). Na maioria dos casos o relatrio ser mais eficiente desta maneira, mas o ndice mantido (implicando num maior armazenamento e maior processamento para que o ndice seja mantido atualizado) No possvel recomendar a priori qual das duas solues a melhor (ndice temporrio vs ndice de usurio), portanto deve-se estudar, caso por caso, a soluo particular levando em considerao a plataforma de implementao e sendo fundamental a analisar a freqncia que o relatrio executado. De qualquer maneira, se no incio no foi definido o ndice de usurio e posteriormente decide-se faz-lo, somente preciso que o relatrio seja gerado novamente (sem modificar nada do que foi programado) e o relatrio passar a utiliz-lo. A listagem de navegao anterior mostra o seguinte: a tabela base do For each CUSTOMER a ordem por CustomerName no existe um ndice definido para esse atributo toda a tabela CUSTOMER com a ordem especificada ser recorrida no tem condies de filtro, todos os registros da tabela executaro os comandos dentro do For each (neste caso, o comando print)

173

OTIMIZAO: Ordem compatvel com os filtros


For each where CustomerName >= &Start where CustomerName <= &End print customer Endfor For each order CustomerName where CustomerName >= &Start where CustomerName <= &End print customer Endfor Toda a tabela base percorrida.

No se percorre toda a tabela base: otimizado!

Se queremos filtrar os clientes por determinada faixa de nomes, o primeiro exemplo, como no foi especificada a clusula order, GeneXus ordena pela chave primria, ou seja, CustomerId. Neste caso, a listagem de navegao mostra que deve-se percorrer toda a tabela CUSTOMER, e para cada registro da mesma deve-se analisar se o registro cumpre ou no as condies (restries ou constraints). Em caso afirmativo, ser impresso o mesmo os dados correspondentes. Ao invs de ordenar os dados por CustomerId vamos fazer uma ordenao por CustomerName, como no segundo exemplo, a tabela base percorrida ordenada por CustomerName e como nos filtros estabelecemos que queremos somente aqueles clientes cujo nome, CustomerName, esteja na faixa determinada, j no sendo necessrio recorrer toda a tabela base para obter os dados que cumprem com as Condies! A segunda consulta est otimizada nesse sentido. Prestar ateno que o GeneXus no criou um ndice por CustomerName de forma automtica, e aqui temos que avaliar se conveniente criar um ndice de usurio (ser mantido pelo GeneXus depois de criado) ou no criar o ndice e deixar que seja criado um ndice temporrio em execuo para resolver a consulta se o DBMS no pode fazer de outra forma. A listagem de navegao mostra se a consulta est ou no otimizada, de acordo se toda a tabela percorrida (desde First Record at End of table) ou apenas uma faixa mais reduzida

174

OTIMIZAO: Ordem compatvel com os filtros


GeneXus sempre tenta encontrar a melhor ordem para que a consulta seja otimizvel, isto , coincida com algum ndice definido na base de dados.

A listagem de navegao nos informa que a consulta est otimizada j que percorre somente os registros includos no filtro (desde CustomerName>=&Start at CustomerName <=&End). Para determinar a ordem levar em considerao: Os atributos da clusula Order especificada pelo usurio As restries que aplicam ao nvel (atributos mencionados na regra Parm do procedimento, condies explcitas tanto no Where como nas Conditions) A existncia de ndices sobre estes atributos. Distinguimos 2 casos: 1) Se escreve uma clusula order O For each fica ordenado por esses atributos, exista ou no um ndice por estes. Se no existe um ndice com os atributos do order, mas existem condies implcitas ou condies explcitas por igualdade, se busca se existe um ndice que contenha os atributos das condies mais os do Order. A condio explcita prevalece sobre a implcita para a determinao do Order, em caso que sejam diferentes e exista ndice por cada uma delas. Se existe um ndice, os atributos das condies sero agregadas na lista do Order para que dito ndice seja considerado em seu lugar. 2) No se escreve clusula order Neste caso, se existe algum ndice para os atributos da condio, o Order fica determinado pelos atributos do ndice. Se no existe um ndice que corresponda com as condies, ou seja que no se pode otimizar a percorrida segundo as condies do nvel, ento se ordena pelos atributos da Primary Key.

175

Por exemplo, se temos as transaes: COUNTRY { CountryId* } O For each: For Each order CityId Where CountryId = 1 ... Endfor Percorre a tabela CITY, ordenando por: CountryId, CityId e utilizando o ndice ICITY (ndice por chave primria que contem ambos atributos). Ainda o prprio DBMS que resolve o plano de acesso mais apropriado, a informao antes mencionada influir em sua determinao. CITY { CountryId* CityId* }

176

For each: clusula Defined by


For each defined by InvoiceDate print customer Endfor No oferece funcionalidade alguma referente aos dados a serem recuperados. Utilizada exclusivamente para ter um elemento a mais para a determinao da tabela base do For each desejado.
Exemplo: Mn. estendida que contenha CustomerId, CustomerName, CountryName: est(INVOICE) InvoiceDate,

tabela base INVOICE

Pode ocorrer de que um For each tenha mais de uma tabela base cuja estendida contenha os atributos do For each, sendo mnima. Frente esta ambigidade, GeneXus escolhe a primeira destas tabelas estendidas mnimas. Para resolver este tipo de ambigidade surge a clusula defined by, que permite usar atributos da tabela base desejada, que no sero utilizados para devolver a consulta ordenada por esses atributos, nem para filtrar informao, nem para ser mostrados no relatrio (no tem nenhuma funcionalidade com respeito aos dados recuperar), apenas para aportar mais informao que permita determinar a tabela base do for each. Na clusula Defined by devemos fazer referncia pelo menos um atributo da tabela base desejada. Da mesma forma, pode ser utilizada para modificar qual a tabela base em caso de no utilizar nenhum atributo mais dentro do For each. Este o caso do exemplo apresentado, no que no queremos listar todos os clientes da tabela CUSTOMER, pelo contrrio, queremos listar todos os clientes das faturas. Se no utilizar nenhum atributo dentro do For each de INVOICE , a tabela base a de CUSTOMER. Na maioria dos casos no necessrio utilizar este comando. Para procedimentos mais ou menos complexos, quando no exista problema de ambigidade, recomenda-se o uso do Defined by pois melhora bastante o tempo de especificao do procedimento. Contudo, no aconselhvel seu uso indiscriminado. A desvantagem de utilizar esta clusula quando no necessrio que ata um pouco mais o cdigo ao desenho das tabelas. Por exemplo, no foi criada uma tabela COUNTRY, e para cada cliente o pas que ele pertence, como atributo secundrio. Se quisermos uma listagem dos clientes e seu pas, seriam equivalentes: For each print customer Endfor For each Defined by CountryName print customer Endfor

onde customer um Printblock com os atributos CustomerId, CustomerName e CountryName. Se agora decidir criar a tabela COUNTRY e ter na transao Customer a CountryId como FK, o primeiro For each continuar sendo vlido e fazendo o que queremos, o segundo deixar de funcionar, ja que no Defined By no tem nenhum atributo da tabela base.

177

For each: clusula Defined by


Atributos permitidos: podem aparecer vrios atributos da tabela estendida, mas pelo menos um deve corresponder a tabela base desejada (caso contrrio ocorre um erro). Sugere-se que seja utilizado atributos secundrios, visto que os mesmos esto em uma nica tabela do modelo e isto evita ambigidades.

Podem aparecer vrios atributos, no caso de um nico atributo no determinar a tabela base, onde ao menos um deles dever estar associado tabela base desejada. Recomenda o uso do defined by de atributos secundrios da tabela base que desejamos navegar, j que os atributos secundrios somente podem estar em uma tabela do modelo e desta forma eliminamos por completo toda possvel ambigidade. Isto no obrigatrio, podemos usar no Defined by para atributos primrios quando notarmos que no haver ambigidade na eleio da tabela base. Um erro comum acreditar que quando um For each tem esta clusula, a tabela base do mesmo fica determinada exclusivamente a partir dos atributos mencionados no defined by. A realidade que os atributos do defined by determinam uma ou mais tabelas base candidatas a serem a tabela base do For each, mas tendo selecionado a tabela base candidata, sua estendida contm todos os demais atributos do For each, alm dos do defined by. Se nenhuma das possveis tabelas base candidatas cumprem esta condio, ento o relatrio dar um erro ao ser especificado, e no poder ser gerado (recordemos que todos os atributos do For each devem estar contidos em uma mesma tabela estendida).

178

For each: clusula When none


Permite executar determinado cdigo quando no encontrar nenhum registro no For each que cumpra as condies. Exemplo: For each where CustomerName >= &Start where CustomerName <= &End
print customer

When none
print message

Endfor

O Printblock menssage (poder ter um texto advertindo ao usurio que no existam clientes que cumpram os filtros) executa somente quando no entrar no For each, isto , quando no tem nenhum registro correspondente na tabela base do For each para que se cumpram as Condies de filtro Tambm aplica-se o For each [selected] line, XFor Each y XFor First, comandos que veremos mais adiante. A clusula when none deve ser a ltima dentro do For each. As aes a serem realizadas quando no existe nenhum registro que cumpra as condies, ficam determinadas pelo bloque de cdigo que tem dentro clusula when none do For each e do endfor. Quando um For each no tem condies de filtro, os comandos do When none sero executados somente no caso em que a tabela base do For each esteja vazia, porque somente nesse caso no haver nenhum registro que cumpra as condies de filtro. Importante: Se aparecer atributos no bloque de cdigo correspondente ao When none, estes no so levados em considerao para determinar a tabela base do For each. Se incluir For eachs dentro do When none no se inferem Joins nem filtros de nenhum tipo com respeito ao For each que contm o When none, j que so considerados dos For eachs paralelos.

179

Comando For each - Sintaxe


For each [{[order] order_attributesi [when condi]}... | [order none] [when condx]] [using DataSelectorName([[parm1 [,parm2 [, ...] ])] [{where {conditioni when condi} | {attribute IN DataSelectorName([[parm1 [,parm2 [, ...] ]} }...] [defined by defined_attributes] [Blocking NumericExpression] code1 [when duplicate code2] [When none code3] Endfor

A Sintaxe apresentada generaliza o exemplo com o que estamos trabalhando. Order order_attributes::= att1, , attn uma lista de atributos, que indica a ordem da consulta, sendo atti um atributo da base de conhecimento escrito simples, ou entre parnteses. Quando um atributo do order aparece entre parnteses est indicando a ordem descendente para o mesmo. Podem se mencionar atributos da tabela estendida. possvel definir vrias clusulas order condicionais, e uma incondicional, que deveria ser a ltima listada. Respondendo ao fato de que somente uma dessas clusulas order tomar efeito, se vo avaliando suas condies (as do when) at a primeira que de True, e com essa fica. Se nenhuma der true e existe uma clusula incondicional (isto , sem when), pega essa ordem. Se no existe tal clusula, ou ordem ser indefinido, querendo isto significa que depender da plataforma, e incluso poder variar entre execues sucessivas. A justificatova para escrever clusulas order condicionais, deriva se quisermos aplicar clusulas where condicionais. Isto , por motivos de otimizao das consultas. Por exemplo, se queremos filtrar por CustomerName > &Name when not &Name.IsEmpty(), ento para otimizar a consulta deveramos ordenar por CustomerName, mas se no aplicar o filtro, visto que &Name est vazio, ento ser melhor deixar uma ordem indefinida. Para isso especificamos a clusula order condicional: order CustomerName when not &Name.IsEmpty() Ao invs do exemplo anterior, tambm pode ser especificado uma clusula order none que utilizada quando no nos interessa uma ordem em particular e queremos que fique indefinido.

180

Escolha do ndice: GeneXus escolhe automaticamente o ndice que utilizar para satisfazer a ordem. GeneXus sempre tentar encontrar a melhor ordem possvel para que a consulta seja otimizvel, isto , coincida com algum ndice definido na base de dados. Para determinar a ordem levado em considerao: Os atributos da clusula Order especificada pelo usurio As restries que aplicam ao nvel (atributos mencionados na regra Parm do procedimento, condies explcitas tanto no Where como nas Conditions) A existncia de ndices sobre estes atributos. Ainda o prprio DBMS que resolve o plano de acesso mais apropriado, a informao antes mencionada influir em sua determinao. Os atributos do order so levados em considerao na hora de determinar a tabela base do For each. Mas eles por si s no determinam. Devem examinar-se tambm outras partes do For each. Using DataSelectorName Permite definir filtros de acordo ao critrio definido no DataSelector1 definido em DataSelectorName. Where Condition Condio booleana que devero cumprir os dados para ser processados dentro do For each, podendo ser uma condio composta, utilizando os operadores lgicos and, or e not. Os atributos que apaream na condio booleana podem ser tanto da tabela base do For each como da estendida. Como se desprende da sintaxe, para um mesmo For each podem especificar-se n clusulas where sucessivas, cada uma com uma condio: where cond1 where cond2 ... where condn A ocorrncia de n clusulas where equivalente a ocorrncia de uma nica clusula, com a conjuno booleana das condies: where cond1 and cond2 and and condn Os dados da tabela estendida do For each que cumpram com todas as condies dos where sero os processados nos comandos internos ao For each (os do bloque de cdigo code1). Da mesma forma que ocorre com a clusula order, pode condicionar os filtros (com clusulas when). Desta maneira, primeiro se avalia a clusula when de cada clusula where, e caso a condio seja cumprida, aplicam o filtro especificado no where. Para que uma restrio condicional possa ser gerada como tal, a condio do when tem que ser avalivel" pelo DBMS que se est utilizando, isto , GeneXus tem que saber como escrever a condio na linguagem prpria do DBMS utilizado. Se no puder gerar como tal (porque o gerador no o suporta ou porque a condio no pode ser escrita na linguagem do DBMS) se transformar em um filtro "comum" substituindo o WHEN por um OR. Alm disso, se gerar a mensagem de cdigo spc0053 Unsupported conditional constraint%1 changed to standard constraint %2. - no Diagrama de Navegao. Nota: Existe tambm a clusula Option Distinct do For Each que permite retornar os registros que cumpram unicidade de valores dos atributos referenciados. No veremos esta clusula. O leitor interessado pode recorrer as distintas fontes de documentao para estud-la (Help, Wiki, Release Notes, etc.) Defined by defined_attributes::= att1, att2,,attp um conjunto de atributos que sero utilizados somente efeitos de determinar a tabela base do For each. Ao mencionar aqui alguns atributos da tabela que se deseja percorrer, estes participaro na determinao da tabela base do For each. A clusula defined by aparece para solucionar alguns problemas de ambigidade na determinao da tabela base (quando existem vrias tabelas estendidas mnimas que contenham os atributos do For each) ou quando se deseja que a tabela base seja outra, diferente da que seria determinada pelos atributos que aparecem no resto do For each (este caso tem sentido quando se estude controle de corte). Tambm se utiliza para melhorar o tempo de especificao em procedimentos complexos. Os atributos desta clusula no determinam por si s a tabela base do For each. Poderia acontecer que estes atributos determinam tabela como a candidata a tabela base, mas se depois os outros atributos do For each no esto contido na estendida dessa tabela, o For each dar um error e o objeto que o contem no poder ser gerado. code1 uma sucesso de comandos que podem utilizar atributos da tabela estendida do For each. A este bloque de cdigo o chamaremos corpo do For each. Os atributos que figurem neste bloque de cdigo participam na determinao da tabela base do For each. ______________________________________________________________________________________________
1

O objeto DataSelector ser visto mais adiante no curso.

181

Os comandos especificados sero executados seqencialmente para os dados da tabela estendida que cumpram as Condies de filtro, considerando os dados na ordem especificado. Blocking Este tema ser abordado mais adiante do curso, mas a idia geral que a especificao desta clsula permite realizar atualizaes e eliminaes em blocos, reduzindo assim o nmero de acesso a base de dados. When Duplicate Esta clusula tem sentido somente em procedimentos (j que trata de atualizao) e ser visto mais adiante. Esta clusula executada se dentro do corpo do For each code1, atualizar um atributo que chave candidata (possui ndice nico) e j existir um registro com esse valor. GeneXus utiliza o ndice nico para assegurar a unicidade dessa chave candidata e caso encontre duplicao, se o For each tem essa clusula programada, executar seu cdigo: code2. No existindo a clusula nenhum cdigo ser executado. When none Em caso de que no existam dados que cumpram as Condies de filtro no ser executado os comandos do code1 e sim os bloque de cdigo code3. Tanto para When Duplicate como para When none: incluindo um comando For each dentro dentro de um dos dois, no so inferidos nem joins nem filtros com respeito ao For each que o contm (when none|when duplicate). So considerados navegaes independentes (code1, code2 e code3).

182

Comando For each


Podemos fazer que o GeneXus escreva o cdigo do For each, inserindo snippets (menu Insert ou a partir do Toolbox):

Os code snippets so moldes de cdigo que GeneXus tem predefinido, que nos ajudam a escrever o cdigo fonte. Quando estamos trabalhando no Source de um procedimento, a Toolbox nos mostra vrios snippets que nos facilitam a escrita do comando For each. Os snippets possui por sua vez um atalho (shorcut), que fazem que a escrita do cdigo seja mais rpida todavia. Por exemplo, digitando simplesmente fe se escreve automaticamente o seguinte cdigo: For each /*For each Code*/ Endfor Depois o usurio substitui a linha de comentrios com o cdigo necessrio. A lista dos atalhos de cada snippet, a seguinte: fe (For each) feu (For each using) fen (For each When none) feun (For each using When none) few (For each where) feuw (For each using where) fewn (For each where When none) feuwn (For each using where When none)

183

For eachs paralelos


Chamamos assim os casos dos For eachs que esto escritos de forma sequencial (no aninhada) . Exemplo:
For each print invoice Endfor For each print bill Endfor

Tambm utilizado quando um For each aparece dentro da clusula When none ou when duplicate de outro. As navegaes so totalmente independentes

O For each um comando como outros, e portanto pode aparecer vrias vezes dentro do Source, tanto em forma paralela (independente), como aninhado a outro For each. Quando dentro do corpo do For each (code1) aparece outro For each, dizemos que trata-se de For eachs aninhados. GeneXus suporta vrios nveis de aninhamento para os For eachs. Se um For each aparece no bloque de cdigo code3, pode ser visto como For eachs aninhados porque um aparece dentro de outro, muda o comportamento, igual a ter For eachs paralelos. Um For each aninhado no when none de outro, somente executado se no tem nenhum registro da tabela base do For each que o contm que cumpra as condies de filtro. No exemplo, invoices e bill so dois Printblocks do Layout que contm os atributos das tabelas INVOICE e BILL (recibo) respectivamente. Temos definido dois For eachs paralelos. O primeiro percorre todas as faturas e o segundo todos os recibos.

184

For eachs aninhados


Para cada registro do For each principal se busca recuperar muitos registros do aninhado For each ... For each ... Endfor ... When none ... Endfor

Corpo do For each principal

O For each uma estrutura repetitiva, que permite recuperar muitos registros de uma tabela. Quando pensamos em For eachs aninhados, evidente que o que buscamos recuperar , para cada registro do principal, muitos registros do aninhado. O que o GeneXus detecta que se quer fazer com este tipo de estruturas, de forma de inferir o comportamento automaticamente com o menor codificao possvel? para cada registro de uma tabela recuperar alguns de outra: os relacionados. para cada registro de uma tabela recuperar todos de outra. processar informao por grupos, isto , agrupar os registros de uma tabela segundo o valor de um atributo ou conjunto de atributos e para cada grupo, recuperar alguns registros: os correspondentes ao grupo. Sempre a relao um a muitos: para cada registro de uma tabela recuperar muitos da outra (podendose tratar da mesma tabela). Utilizando esta lgica que o GeneXus infere as tabelas base e o comportamento dos For eachs aninhados, sabendo que o que desejamos implementar alguma das trs opes anteriores. Por exemplo, se queremos elaborar uma lista de todas as faturas do sistema, sendo que imprimiremos detalhe de cada uma, devemos navegar por duas tabelas: INVOICE (que armazena os cabealhos) e INVOICEDETAIL (que armazena as linhas), e o faremos de uma forma bem simples, sem colocar o nome das tabelas, e sem que explicar tudo, como veremos. Outro Exemplo de uma lista de todos os clientes, onde para cada um se quer imprimir, alm de seus dados pessoais, os dados de todas suas faturas. Este comportamento se d com um par de For eachs aninhados, onde o primeiro navega pela tabela CUSTOMER e o segundo navega pela tabela INVOICE, recuperando somente as faturas desse cliente, como veremos em seguida.

185

For eachs aninhados


Exemplo: imprimir todas as faturas com suas respectivas linhas

For each print invoice_header For each print invoice_lines Endfor print invoice_total Endfor

{InvoiceId, InvoiceDate, CustomerName} {ProductDescription, ProductPrice, InvoiceLineQuantity, InvoiceLineAmount} {InvoiceTotal}

Se queremos realizar uma lista de todas as faturas do sistema, onde para cada uma se mostre tanto a informao do cabealho como das linhas. No Source programado, percorremos tabela INVOICE, imprimindo os atributos que nos interessam do cabealho e para cada registro dessa tabela, percorremos a tabela INVOICEDETAIL, para imprimir os atributos que nos interessam de suas linhas. Podemos perceber o quo simples esse processo, simplesmente utilizando os atributos que queremos usar, ficando o GeneXus encarregado do resto. Observemos que nem sequer tivemos que especificar a condio de filtro sobre os registros de INVOICEDETAIL a recuperar. O GeneXus se d conta da relao existente entre as tabelas, e aplica automaticamente a condio de filtro sobre os dados, de maneira que s sejam impressas as linhas dessa fatura (lembrar que algo idntico acontece com as frmulas verticais, como InvoiceTotal, onde a condio de filtro sobre os registros a serem somados ou contados ficava implcita, e no precisa que especific-la).

186

For eachs aninhados


Exemplo: imprimir todas as faturas com suas respectivas linhas INVOICE INVOICEDETAIL

Para cada registro de INVOICE imprimir alguns de seus dados (InvoiceId, InvoiceDate) e de sua estendida (CustomerName). Depois navega por INVOICEDETAIL e recupera os registros que correspondam a fatura que se est imprimindo. Os que cumpram a condio implcita: INVOICEDETAIL.InvoiceId = INVOICE.InvoiceId

Como para um For each simples, o GeneXus deve determinar para cada For each (principal e aninhado) qual sua tabela base. E a partir dessa determinao, utilizar a lgica correspondente. Mais adiante veremos com exatido como que o GeneXus determina cada tabela base. Aqui ficaremos com idia intuitiva de que o faz de forma similar como o fazia no caso de um For each simples. Encontra, pois, que deve percorrer as tabelas INVOICE e INVOICEDETAIL. Como essas tabelas esto relacionadas de acordo a uma relao 1-N infere mais que isso: infere tambm na aplicao da condio sobre os dados de INVOICEDETAIL que indicamos acima.

187

For eachs aninhados


GeneXus deve:
Determinar a tabela base de cada For each.

A partir disso se define as navegaes que realizar para cada For each (existem 3 casos possveis). A lgica dos For eachs depender das relaes encontradas entre as tabelas determinadas.

Quando temos dois For eachs aninhados,GeneXus deve determinar a tabela base de cada um, e essas sero as tabelas que se navegaro. Para cada registro da tabela base do For each principal, sero executados os comandos do corpo do mesmo. Entre esses comandos, encontra-se o For each interno, que ser executado, como qualquer outro comando, no lugar onde estiver realizando uma navegao sobre sua tabela base. Para a determinao da tabela base do For each aninhado, influencia a tabela base do For each principal, mas as determinaes no so por completo independentes, como se pode pensar equivocadamente. A partir da determinao das tabelas base de cada For each e das relaes que encontre o GeneXus entre as tabelas envolvidas, surgem trs possveis casos de For eachs aninhados, que correspondem aos casos enunciados anteriormente: join, Produto cartesiano e corte de controle, respectivamente. Estudaremos cada um desses casos com exemplos.

188

For eachs aninhados: determinao das tabelas base


Acontece de forma ordenada, determinando For each cada vez a tabela base de um nvel de encadeamento, ... de fora para dentro: primeiro se For each ... determina a tabela base do For each mais Endfor externo, depois do aninhado a este ... e assim sucessivamente. Para cada For each, intervm unicamente os atributos do prprio For each: do order, where, defined by e todos do corpo que no pertenam a um For each aninhado (tampouco intervm os da clusula When none).
When none ... Endfor

Consideremos o caso mais simples, de um par de For eachs aninhados. A determinao da tabela base do For each principal, anloga ao caso de For each simples (sem aninhamentos). Neste caso consideram-se todos os atributos do For each principal, descartando os For eachs aninhados que este contenha (e todos seus atributos). GeneXus encontra a mnima tabela estendida que os contenha e define assim a tabela base atravs da qual chega a todas as outras. Para determinar da tabela base do for each aninhado, GeneXus fixa os atributos utilizados dentro do corpo do mesmo, onde esto includos ou dentro da tabela estendida previamente determinada (a do For each principal). Em caso afirmativo, GeneXus determina que a tabela base do For each aninhado ser a mesma que a do For each principal. Em caso contrrio, busca-se a mnima tabela estendida que cumpra e contenha todos os atributos do For each aninhado e que tenha alguma relao com a tabela base do For each principal. A tabela base de dita tabela estendida, ser a tabela base do For each. Se no puder encontrar uma tabela estendida mnima que cumpra ambas condies, mas cumpre que contenha os atributos, finalmente a escolhe, mas sempre busca a forma de encontrar relaes entre ambas tabelas bases. Somente neste ltimo caso de no se encontrar relaes, se procede a determinar a tabela base como se fosse For eachs independentes. Estudaremos um esquema resumindo o anterior depois.

189

For eachs aninhados: determinao das tabelas base


Tabela base For each externo For each print invoice_header For each print invoice_lines Endfor print invoice_total Endfor For each print invoice_header For each print invoice_lines Endfor print invoice_total Endfor {InvoiceId, InvoiceDate, CustomerName} {InvoiceTotal} INVOICE

Tabela base For each interno {ProductDescription, ProductPrice, InvoiceLineQuantity, InvoiceLineAmount} INVOICEDETAIL

Para o exemplo apresentado anteriormente, mostramos acima como se determina cada tabela base. Para a do aninhado, como os atributos que figuram no estejam contidos na tabela estendida de INVOICE (que a tabela base do principal), ento se passa a determinar sua tabela base como se explicou anteriormente: se busca a tabela estendida mnima que contenha a ProductDescription, ProductPrice, InvoiceLineQuantity e InvoiceLineAmount, e caso possvel esteja reacionada com INVOICE. A tabela que cumpre ambos requisitos em INVOICEDETAIL.

190

For eachs aninhados: lgica associada


Tabelas base distintas Fe externo
1 N

Existe relao implcita que vincule o For each externo com um nmero N de registros do For each aninhado? Join: se recuperam alguns registros do Sim
aninhado, os relacionados.

(Caso 1)

? Fe aninhado

No

Produto cartesiano: se recuperam todos os registros do aninhado. (Caso 2)

Tabelas base iguais


Controle de Corte: Corresponde ao caso para recuperar informao por (Caso 3) grupos.

Da determinao das tabelas base, surgem os trs casos de For eachs aninhados que foram mencionados e que estudaremos um a um em seguida. Este tema de vital importncia, j que a maioria das aplicaes requerem navegaes complexas sobre as tabelas, onde se requer uma mistura de todos estes casos.

191

Caso 1: Join
Distintas tabelas base mas existe uma relao 1-N direta ou indireta entre elas Exemplo: Listagem de todos os clientes e suas faturas For each print customer For each print invoice Endfor Endfor CUSTOMER
{CustomerId, CustomerName} {InvoiceId, InvoiceDate, InvoiceTotal} CustomerId

INVOICE

est(principal) base(aninhado) = {CustomerId}

No For each aninhado ordenado pelo atributo relao: CustomerId

Este o caso em que o GeneXus determina que as tabelas base de cada For each so distintas e tem uma espcie de relao 1-N (podendo ser esta indireta) entre as tabelas que se percorre Ou seja, para cada registro da tabela base do For each principal, GeneXus encontra que tem N relacionados com ele, direta ou indiretamente, na tabela base do For each aninhado. Ao encontrar esta relao, aplicar condies de filtro automticas no For each aninhado, de forma a ficar somente com esses registros relacionados. O exemplo do procedimento que imprime todas as faturas do sistema, com seus detalhes, cai dentro desta categoria. Nesse caso tem uma relao 1-N direta entre as tabelas que se percorre: para cada cabealho da fatura, lista-se o mesmo, junto com todas suas linhas da fatura, ou seja, todos os registros de INVOICEDETAIL que esto relacionados com o registro de INVOICE que se est posicionado em cada interao. Este um dos casos mais comuns de For eachs aninhados, onde se quer percorrer uma tabela, e para cada registro da mesma, percorrer outra tabela, relacionada com a primeira por uma relao N-1. O GeneXus encontra nesta relao, e na navegao interna, somente recupera os registros associados, e a o nome join para este caso. No exemplo apresentado acima ocorre o mesmo. A tabela base do primeiro For each CUSTOMER, e a do segundo, INVOICE. Como encontra atributo em comum entre a tabela estendida do For each principal e a tabela base do aninhado1, CustomerId, determina que esse atributo atue como condio de filtro na percorrida da tabela do For each aninhado. -----------------------------------------------------------------------------------------------------------Esta uma forma de expressar formalmente o que havamos dito em trminos informais: relao direta ou indireta 1-N entre as tabelas base. A relao ser direta quando a tabela base do principal tenha relao 1-N com a tabela base do aninhado, isto , seja superordinada desta ltima. A relao ser indireta quando isto no exista uma relao direta entre as tabelas base, mas sim entre a tabela estendida do primeiro e a tabela base do segundo. Tambm ser indireta quando a tabela estendida do aninhado inclua a tabela base do principal. Veremos exemplos em seguida.
1

192

Caso 1: Join

Vejamos, como o GeneXus faz para determinar as tabelas base. Os atributos utilizados no For each externo so CustomerId e CustomerName, e a tabela base deste For each ser CUSTOMER. Observemos que somente participam na determinao desta tabela base os atributos do For each principal, no os do aninhado. Depois, GeneXus deve encontrar a tabela base do For each aninhado. Os atributos que participam so InvoiceId, InvoiceDate e InvoiceTotal, ou seja, os atributos internos a este For each. Observemos que estes atributos no pertencem a tabela estendida do principal, que era CUSTOMER. Portanto passa a determinar sua tabela base como a de qualquer For each simples: a tabela estendida INVOICE contem todos os atributos do For each aninhado, e a mnima tabela estendida que os contenha. Portanto, INVOICE ser escolhida como tabela base do segundo For each. Observemos, novamente, que no explicitamos clusula where no For each aninhado para filtrar as faturas do cliente do For each principal. Justamente, por tratar-se de tabelas relacionadas por uma relao 1-N direta, esta condio aplicada implicitamente pelo GeneXus e pode ser visto na listagem de navegao acima. Outro fato interessante que pode ser observado nesta lista: no For each aninhado no foi especificado a clusula order, GeneXus no escolheu a ordem da chave primria da tabela base e sim pelo atributo da relao, CustomerId. Desta maneira, est otimizando automaticamente a consulta. Esse caso uma exceo a regra que fala que quando nenhuma clusula order em um For each especificada, GeneXus determina como ordem o atributo da chave primria da tabela base de dito For each.

193

Caso 1: Join
Exemplo: Listagem de todas as faturas por pas
{CountryId, CountryName}

For each print country For each print invoice Endfor Endfor
base(principal) est(aninhado)

CountryId CUSTOMER CustomerId INVOICE COUNTRY

{InvoiceId, InvoiceDate, InvoiceTotal}

COUNTRY est(INVOICE) porque tem uma relao 1-N indireta condio implcita: todas as faturas do pas so listadas

Se queremos realizar uma listagem das faturas emitidas pelo pas, teremos outro caso de For eachs aninhados com distintas tabelas base, onde a informao que queremos listar est relacionada. Aqui queremos percorrer s tabelas COUNTRY e INVOICE. Observemos que elas no esto relacionadas diretamente, mas esto de forma indireta. De fato, COUNTRY pertencem tabela estendida de INVOICE. Portanto, para cada fatura pode-se encontrar somente um pas relacionado mesma. Este um caso um pouco mais complexo que o anterior, porque a tabela estendida do For each principal no tem interseco com a tabela base do aninhado (est(COUNTRY) INVOICE = ), mas existe uma relao 1-N indireta, e o GeneXus a encontra. Neste caso, a tabela base do For each principal est includa na estendida do aninhado (COUNTRY est(INVOICE)), mas tem uma relao 1-N indireta. Por este motivo, no necessitamos especificar clusula where no For each interno para filtrar as faturas do pas do For each principal. Isto pode ser visto claramente na listagem de navegao, que mostrar o filtro: CountryId = CountryId para o segundo For each, mas desta vez como Constraint visto que no pode otimizar a percorrida. O leitor pode testar este caso em GeneXus e estudar detalhadamente a listagem de navegao resultante.

194

Caso 2: Produto Cartesiano


Distintas tabelas base, mas no existe relao 1-N direta nem indireta entre as mesmas. O resultado obtido o produto cartesiano de ditas tabelas: para cada registro da tabela base do For each principal, se recuperam todos os registros da tabela base do aninhado.
est(principal) base(aninhado) = e base(principal) est(aninhado)

Neste caso o GeneXus no encontra uma relao 1-N direta ou indireta entre as tabelas e portanto no aplica filtros implcitos aos registros do For each aninhado, ou seja, realiza um produto cartesiano entre as tabelas. O caso ocorre quando: est(For each principal) base(For each aninhado) = e base(For each principal) est(For each aninhado) Para cada registro da tabela base do For each principal se recorre toda a tabela base do For each aninhado. Por exemplo, se a tabela base de um For each foi COUNTRY e a do aninhado PRODUCT, evidentemente no existir relao e haver um produto cartesiano e se percorre para cada pas, todos os produtos. O programador pode estabelecer filtros sobre os dados a recuperar, mas estes j no sero condies implcitas inferidas pelo GeneXus, mas sim especificadas explicitamente pelo programador. .

195

Caso 3: Controle de Corte


Exemplo: Para cada cliente que possui faturas, listar os clientes e suas faturas.

No exemplo que vimos anteriormente, da listagem de clientes e suas faturas, o que acontece se um cliente no possuir faturas? Como a tabela base do For each principal CUSTOMER, o cliente sai impresso antes de saber-se se tem ou no faturas. Se no desejamos que isto ocorra, isto , que apaream listados clientes que no tenham faturas, ento a soluo acessar unicamente as faturas, pois se um cliente est nesta tabela, porque est em uma fatura!. Mas para poder agrupar as faturas por cliente, de tal forma de poder mostr-las desse modo, devemos percorrer a tabela INVOICE ordenada por CustomerId. Desta forma processaremos a informao de um cliente, e depois passaremos ao seguinte, para processar sua informao, e assim sucessivamente. Se imaginamos um ponteiro que se vai mostrando sequencialmente pela tabela INVOICE, podemos escrever o pseudocdigo de nosso procedimento como segue: 1. Para o registro apontado, reter o valor do atributo de corte ou agrupamento, CustomerId. 2. Acessar a tabela CUSTOMER (que est na estendida de INVOICE) para recuperar o CustomerName e imprimi-lo junto com o CustomerId (print customer) 3. Enquanto o valor de CustomerId do registro apontado coincida com o valor retido no passo 1 (aqui se processam todas as faturas do cliente) a. Imprimir InvoiceId, InvoiceDate e InvoiceTotal do registro apontado. (print invoice) b. Avanar o ponteiro ao seguinte registro e voltar ao passo 3. 4. Voltar ao passo 1. (quando se chega a este ponto, porque se chegou no final da tabela ou mudou o cliente).

196

Caso 3: Controle de Corte


Exemplo: Para cada cliente que possui faturas, listar suas faturas.
Source

For each order CustomerId defined by InvoiceDate print customer For each print invoices Endfor Endfor

ordem determina o critrio de corte Cada vez que muda o cliente definido um grupo novo

O defined by foi utilizado para que tabela base seja INVOICE e no CUSTOMER e assim implementar um controle de corte e no um join.
Layout

GeneXus oferece uma forma de programar o que foi visto de uma forma simples. O pseudocdigo visto na pgina anterior se programa em GeneXus com um par de For eachs aninhados que esto no slide acima. Comparando este cdigo com o que vimos anteriormente para o caso de join, vemos que existem somente duas diferenas: a clusula order que aparece neste cdigo, junto com o defined by. Somente com essas mudanas da lista original, mudamos radicalmente o comportamento, neste caso somente sero listados os clientes que possuem faturas. Neste caso, ambas clusulas (order e defined by) so indispensveis para que este relatrio funcione como queremos. Se agregamos somente uma delas, o resultado outro. No em toda programao de controle de corte que dever ter uma clusula defined by no For each principal, mas sim uma clusula order. A clusula order indispensvel, porque ela que especifica por qual atributo ou conjunto de atributos o corte (ou agrupamento) ser realizado. Isto , especifica essa informao comum ao grupo, que ser processada uma nica vez (dentro do cdigo do For each externo). A clusula defined by no indispensvel em todos os casos. Neste caso foi, porque no especificla, GeneXus determinaria como tabela base do For each principal CUSTOMER, que no o que queremos (pois no queremos implementar um join, como foi feito antes, e sim um corte de controle, para ler somente a tabela INVOICE). Poderamos ter utilizar outra soluo para modificar a tabela base do For each principal: utilizar em vez do defined by o comando print if detail dentro do corpo do primeiro For each (este comando diz ao GeneXus que tome como tabela base do For each, a mesma que determinar para o aninhado).

197

Caso 3: Controle de Corte


Devem ser cumpridas as condies seguintes para implementar o Controle de Corte: 1. For each aninhados 2. Mesma tabela base 3. Quantos For each? Um a mais que a quantidade de cortes 4. Devemos estabelecer na clusula order de cada For each externo, o atributo ou conjunto de atributos que queremos cortar (agrupar).

Um controle de corte fcil de programar e pode ser feito seguindo as consideraes anteriores. Na ordem do For each mais extremo, devemos mencionar o primeiro atributo de corte, na ordem do segundo For each devemos mencionar o segundo atributo de corte e assim sucessivamente. No obrigatrio mencionar atributo/s na ordem do For each mais interno (em todos os demais For each assim). utilizado quando desejamos trabalhar com a informao de uma tabela, mas agrupada por algum atributo ou conjunto de atributos. Os controles de cortes podem ser simples, duplos, triplos, etc. A seguir veremos um exemplo de um controle de corte duplo.

198

Exemplo: Controle de corte duplo Vamos supor que queremos como antes listar os clientes e suas faturas, mas queremos agrupar as faturas de cada cliente por data. Isto , queremos mostrar, para cada cliente, para cada data, as faturas existentes. Exemplo: Customer: 1 Joo Silveira Date: 12/05/05 Invoice Total 1 15 Date: 01/01/06 Invoice Total 9 35 3 30 Customer: 3 Maria Silva Date: 06/06/05 Invoice 2 Date: 12/08/05 Invoice 4 8 Date: 02/02/06 Invoice 7 Como agora queremos agrupar por cliente, e dentro desse grupo por data de fatura, necessitamos trs For eachs aninhados: For each order CustomerId defined by InvoiceDate print customer For each order InvoiceDate print date For each print invoice Endfor Endfor Endfor Como exerccio, vamos seguir todos os passos que realiza GeneXus para inferir o comportamento do procedimento. 1. Determinao da tabela base de cada For each Como sempre, para determinar as tabelas base de For eachs aninhados, se comea de fora para dentro, determinando de cada For each, sem levar em considerao os atributos dos For eachs internos ao que se est considerando. Total 20 Total 40 15 Total 20

199

For each order CustomerId defined by InvoiceDate print customer For each order InvoiceDate print date For each print invoice Endfor Endfor Endfor

Tabela base 1er. For each Somente so considerados os atributos dos lugares que esto em negrito. Mnima tabela estendida que os contem: est(INVOICE)

For each order CustomerId defined by InvoiceDate print customer For each order InvoiceDate print date For each print invoice Endfor Endfor Endfor

Tabela base 2do. For each Consideram os atributos dos lugares que esto em negrito e como todos eles esto includos na estendida do 1er. For each, ento se determina a mesma tabela base: INVOICE

For each order CustomerId defined by InvoiceDate print customer For each order InvoiceDate print date For each print invoice Endfor Endfor Endfor

Tabela base 3er. For each Consideram os atributos dos lugares que esto em negrito e como todos eles esto includos na estendida do 2do. For each, ento se determina a mesma tabela base: INVOICE

2. Determinao da navegao Depois de determinadas as tabelas base, GeneXus determina a navegao. Como neste caso so trs For eachs sobre a mesma tabela base, se trata de um controle de corte duplo. Podemos pensar que quando falamos de controle de corte, seja simples, duplo, triplo, qudruplo, etc, temos somente um ponteiro utilizado para avanar nos registros da tabela base. Lembremos que a clusula order fundamental para estabelecer o critrio de corte em cada par de For eachs. Como em nosso caso queremos agrupar por CustomerId e depois, para todas as faturas com esse cliente, agrupar por InvoiceDate, ento teremos que ordenar o primeiro For each por CustomerId e ou imediatamente aninhado por InvoiceDate. No exemplo estamos dizendo que: Enquanto no encontrar o final da tabela Imprimir os dados do cliente da fatura atual Enquanto no mude o cliente Imprimir a data da fatura atual Enquanto no mude a data Imprimir os dados da fatura atual (nro e total) Avanar o ponteiro ao seguinte registro

200

Recomendamos programar em GeneXus este procedimento e observar cautelosamente a listagem de navegao. Ver que GeneXus escolhe uma nica ordem, quando no tem um ndice criado: o composto pela concatenao das ordens de cada For each com clusula order. Este resultado claro se pensarmos que um nico ponteiro vai se deslocando pela tabela base. Uma vez determinado a Order do Controle de Corte se otimiza, buscando o melhor ndice levando em considerao as condies explcitas ou implcitas do nvel.

Resumo: Determinao geral das tabelas Base Acontece de forma ordenada, determinando cada vez a tabela base de um nvel aninhado, vendo de fora para dentro: primeiro determina-se a tabela base do For each mais externo, depois o que est aninhado a este e assim sucessivamente.
Determinao da Tabela Base do For Each Externo Determina a partir dos atributos que aparecem dentro desse For each: clusulas order, where, defined by e corpo do For each, exceto os atributos que estejam dentro do For each aninhado. No participam os atributos que esto dentro do When none, no caso do For each principal ter esta clusula. Como no caso de um For each simples, que se encontra a mnima tabela estendida que contenha ditos atributos. Determinao da Tabela Base do For Each Aninhado Podemos chegar a pensar por analogia que deveramos extrair os atributos do For each aninhado, e fazer o mesmo que antes, ou seja, encontrar a mnima tabela estendida que contenha esses atributos, como se fosse um For each independente. Mas no so For eachs independentes! Para o For each aninhado, o GeneXus verifica se os atributos utilizados dentro do corpo do mesmo esto includos ou no dentro da tabela estendida previamente determinada. Em caso afirmativo, o GeneXus determina que a tabela base do For each aninhado ser a mesma que a do For each principal ( e ser um caso de controle de corte) Caso contrrio, se determina da seguinte maneira: busca a mnima tabela estendida que contenha a todos os atributos do For each aninhado, tratando de encontrar aquela que tenha alguma relao com a tabela base do For each principal. Se no encontra uma tabela estendida que contenha a todos os atributos do For each aninhado e que alm desta relacionada, fica com a tabela estendida mnima que contenha os atributos ainda que no tenha relao.

201

Comandos de controle
if cond bloque1 [else bloque2] endif do while cond bloque enddo do case case cond1 bloque1 [case cond2 bloque2] ...... [case condn bloquen] otherwise bloquen+1 endcase

for &var=inicio to fin [step salto] bloque Endfor for &var in Expression bloque Endfor

Os comandos introduzidos so similares aos existentes nas linguagens de Programao imperativa conhecidas, por isso no inclumos a documentao deste tema. Pode ser encontrada no curso no presencial ou no Help do GeneXus. Os dois ltimos, incorporam alguns elementos importantes sobre administrar arrays e de colees1 em GeneXus. Pelo qual mostraremos alguns exemplos: For to step: inicio, fin so expresses numricas salto uma constante numrica var alguma varivel numrica bloque uma sucesso de comandos vlidos da linguagem Permite interagir certa quantidade de vezes: desde o valor incio que toma a varivel &var quando se ingressa ao loop, at o valor fim que toma a mesma quantidade de interaes. De interao em interao a varivel &var vai incrementando automaticamente numa quantidade igual a passo. O valor por default de salto 1, seno especificarmos a clusula step o incremento da varivel ser de um em um. O valor de salto pode ser negativo e nesse caso ir decrementando a varivel de interao em interao. Exemplo For &i = 1 to 5 &ok = PInvoicing.udp( &month ) Endfor __________________________________________________________________________
1 As colees representam listas de tamanho varivel. Sero vistas quando estudarmos o tipo de dados estruturado (SDT).

202

For in Expression: Expression qualquer expresso cujo valor seja uma coleo, vetor ou matriz. var uma varivel que deve ter o mesmo tipo de dados que os elementos de Expression. Esta estrutura de programao permite percorrer com menos cdigo uma coleo ou uma varivel vetor de uma ou mais dimenses. Se armazena na varivel &var os valores de cada elemento da coleo, vetor ou matriz. Para o caso de vetores de uma dimenso: for &var in &varArray() // code Endfor o cdigo se expande ( equivalente) a: &x = 1 do while &x <= rows(&array()) &var = &Array(&x) bloque &x += 1 enddo No caso de duas dimenses: for &var in &varMatrix() // code Endfor o comando se expande ( equivalente) a: &x = 1 do while &x <= rows( &array() ) &e = 1 do while &e <= cols( &array() ) &var = &array( &x, &e ) bloque &e += 1 enddo &x += 1 enddo Tambm pode ser uma varivel coleo de qualquer tipo, incluindo uma varivel com a propriedade Collection em 'False' mas de um tipo de dados 'SDT collection' . for &var in &collection ... endfor A expresso tambm pode no ser uma varivel, por exemplo no caso do resultado de um DataProvider ou de um Procedure: for &var in DataProvider(parms) ... Endfor for &var in Procedure(parms) ... endfor Consideraes: No possvel modificar os valores da coleo, vetor ou matriz na percorrida. Isto significa que alteraes no valor de &var no alcance da estrutura, no afetam ao correspondente valor da &collection o do &array(&x), ou de &array(&x, &e)). No possvel obter a posio da coleo/array/matriz durante a percorrida, para isto necessrio definir uma varivel que atue como contador. Estas estruturas podem aninhar para percorrer vrios arrays, matrizes ou colees. Isto inclui o caso de que se chame uma Subrotina que tambm possui um For In Expression. Igual que em um For Each ou um Do While, possvel incluir comando que corte a percorrida, como Exit ou Return.

203

Comandos de impresso
Print
Utilizado para imprimir a sada de um Printblock definido no Layout Sintaxe: Print nomePrintBlock

Header
Utilizado para definir o que se quer imprimir como cabealho de cada pgina da listagem Sintaxe: Header bloque end

Footer
Define as linhas de rodap da pgina a ser impressa ao final de cada pgina do procedimento. Sintaxe: Footer bloque

end

Aqui veremos alguns comandos de impresso, que permitem desenhar a sada do procedimento. Print Onde nomePrintBlock o identificador de um Printblock do Layout. No existindo no Layout um Printblock com esse nome, ao tentar salvar o objeto mostra-se uma mensagem de error informando sobre esta situao. Desta forma implementa-se a impresso na sada dos Printblocks do Layout. Quando o Printblock que se quer imprimir no contm atributos, ento este comando pode ser utilizado em qualquer lugar do Source. Os atributos indicam acesso a base de dados e este acesso no pode ser realizado em qualquer lugar, somente dentro do comando especfico para ele, isto , o comando For each. Portanto, no correto escrever o comando print fora de um For each se o Printblock que desejamos imprimir contm atributos. A nica exceo desta regra se produz quando os atributos do Printblock esto includos entre os parmetros recebidos pelo procedimento, pois neste caso no necessrio acessar a base de dados para recuperar seus valores, visto que j vem instanciados. Header Aqui se define o que se quer imprimir como cabealho de cada pgina da listagem. Este cabealho opcional. Se no for especificada, ento as pginas da listagem no tero cabealho. Exemplo: No procedimento que queramos imprimir uma listagem com o cdigo, nome e pas de cada um dos clientes de nosso sistema, se queremos que em cada pgina da listagem aparea o cabealho: CUSTOMERS REPORT, ento suficiente escrever no Source: Header Print title End Onde title o nome de um Printblock do Layout que contem este texto.

204

Tambm poderamos ter escrito diretamente: Print title no incio do Source, mas neste caso, se a listagem tem vrias pginas, somente sair impresso este texto na primeira. No outro caso, sair em cada uma das pginas, como cabealho. Footer Define as linhas no rodap da pgina a ser impressas ao final de cada pgina do procedimento. Os comandos do bloque de cdigo so executados quando se chega ao final de uma pgina. Exemplo: Footer print endOfPageText end onde endOfPageText o nome de um Printblock do Layout

205

Desenho da sada
Existem alguns comandos para desenhar efeitos da documentao. a sada do procedimento. Apresentamos aqui alguns

MT nlines: nlines o nmero de linha em que se quer comear a imprimir a listagem. Caso no seja especificado um valor se assume o valor por default que 0. MB nlines: nlines o nmero de linhas que se deseja deixar como margem inferior. Caso no seja especificado um valor se assume o valor por default que 6. PL nlines: Seta o tamanho de pgina. O nmero de linhas que ser impresso o nmero especificado menos a margem de baixo (valor por default 6). Ex: PL 66 Seta o tamanho da pgina a 66 linhas, ainda que somente 60 linhas sejam impressas no form, com uma margem inferior de 6 linhas. CP nlines: Se quiser na pgina atual um nmero de linhas maior ou igual ao nmero especificado, continua imprimindo na mesma pgina. Do contrario, passa a imprimir na prxima pgina (fora um salto de pgina). Lineno nlines: Define o nmero de linha onde vai ser impressa a seguinte linha. Se o nmero de linha atual maior ao nmero especificado, ento, a linha ser impressa na prxima pgina. O de linhas comea na linha 0. Eject: Fora a um salto de pgina. Noskip: Tem que estar imediatamente depois de um Printblock. Se o comando se encontra entre duas linhas, este comando as imprimir na mesma linha.

206

Procedimentos PDF
Configurar as propriedades:
Main Program = True Call Protocol = HTTP Report Output = Only to file

Regra
Output_file( xx.pdf, PDF)

Em Web as listagens somente podem ser PDF e devem ser configuradas as propriedades e regras anteriores para que funcionem. Definio de um objeto como main Ao definir que um objeto main (neste caso um procedimento, mas poderia ser uma transao, web panel, etc.), GeneXus gera um programa executvel com a lgica do objeto mesmo e a de todos os objetos chamados direta ou indiretamente por ele. O programa executvel gerado pode compilar e executar de forma independente, isto , ao selecionar Build / Run se ver como programa independente do Developer Menu e poder compilar-se e executar-se. A definio de um objeto como main se realiza editando as propriedades do objeto, e configurando a propriedade Main program do mesmo com valor True.

207

Condies
Permite especificar condies globais que devem ser cumpridas para que os dados sejam recuperados. Exemplo:

Nesta seo se permite estabelecer condies que devem cumprir os dados para ser recuperados. Uma condio equivalente a clusula where do comando for each (tem a mesma sintaxe) com uma diferena: enquanto a clusula where est ligada um For each especfico - aquele ao que pertence -, as condies esto ligadas todos os For each do Source que tenha sentido aplic-las. E para que For eachs tem sentido aplic-las? As Condies geralmente envolvem atributos. Se na tabela estendida de um For each encontra-se algum dos atributos que interferem numa condio, ento a mesma pode ser aplicada este For each para filtrar os dados ficando unicamente com aqueles que satisfaam tal condio. Na listagem de navegao do procedimento indicam-se os For eachs que aplicam-se a cada condio das especificadas na seo Conditions. Se no Source do procedimento PrintCustomers temos: For each Print customer Endfor Ento ao especificar as condies que se mostram no slide, estaremos filtrando os clientes, de acordo com as condies ( equivalente ter as condies como where).

208

Condies
Sendo o Source do procedimento :
For each Print customer Endfor For each Print invoice Endfor For each Print product Endfor For each where CustomerName>=&start Print customer Endfor For each where CustomerName>=&start where InvoiceId < 100 Print invoice Endfor For each Print product Endfor InvoiceId < 100;

Conditions: CustomerName >= &Start;

onde: customer um Printblock que contem os atributos CustomerId, CustomerName, CountryName invoice um Printblock que contem os atributos InvoiceId, CustomerId, CustomerName, InvoiceDate, InvoiceTotal product um Printblock que contem os atributos ProductId, ProductDescription, ProductStock Se o procedimento anterior tem definido as condies mostradas acima, o procedimento ser equivalente a um que no tiver condies e com o Source que se mostra a direita. Observemos que neste caso as condies se traduzem em clusulas where mas que se aplicam somente aos For eachs para os que tem sentido aplic-las. Na tabela estendida do ltimo For each no se trabalha com nome de cliente, nem com identificador de fatura. No tem sentido aplicar as condies neste For each j que no existe nenhuma relao. No primeiro, somente tem sentido aplicar se utilizar CustomerName e no a outra. Observao Os atributos envolvidos nas condies no participam na determinao das tabelas base dos For eachs do Source (a diferena dos filtros que se especificam mediante clusulas where). Isto , as tabelas base dos For eachs que apaream no Source se determinam sem olhar as condies. Uma vez determinadas, nesse momento as condies so examinadas para determinar a quais For eachs se aplicam e a quais no. O mesmo ocorre com os atributos recebido como parmetro. Aplicam como filtro global por igualdade para os For eachs que tenha sentido, mas no participam na determinao das tabelas base.

209

Filtros na navegao
Formas de filtrar os dados:
Clusulas Where Participam na determinao da tabela base

Condies

NO participam na determinao da tabela base

Regra Parm (Atributos recebidos como parmetros) Exemplo: Parm(Att1 ... Attn)

Resumimos aqui as distintas formas de filtrar em um procedimento a informao da base de dados a ser recuperada: a. clusulas where b. condies c. parm( att, ..., att ) Estudemos as diferenas e similaridades entre elas. 1. As clusulas where aplicam exclusivamente ao For each em que se encontram, enquanto que os filtros especificados como condies ou os que ficam determinados pelos atributos na regra parm so globais, isto , aplicam a todos os For eachs do Source em que faa sentido aplic-las. 2. Os filtros que ficam determinados ao receber atributos na regra parm so filtros por igualdade, isto , para os For eachs que tenha sentido aplic-los, se instanciaro unicamente os registros que tenham o mesmo valor que o recebido por parmetro. Por outro lado, os filtros especificados nas clusulas where de um For each ou nas condies podem ser expresses booleanas quaisquer, incluso compostas. 3. Enquanto que os atributos que aparecem nas clusulas where participam na determinao da tabela base do For each onde se encontram, os que aparecem nas condies ou na regra parm no o fazem. So aplicados ASSIM que determinadas as tabelas base dos For eachs do Source.

210

Objeto Data Selector


DS

211

Data Selectors - Conceito


um objeto GeneXus que permite armazenar um conjunto de ordens, filtros, defined by, com o objetivo de ser referenciado em diferentes consultas e clculos, permitindo assim reutilizar navegaes

Exemplo: Customer { CustomerId* CustomerName CustomerAddress CustomerGender CustomerStatus } Por exemplo: Em vrios objetos, se repete a necessidade de consultar os clientes ativos (CustomerStatus= Active)

Procedimento que imprime clientes ativos, agrupados por sexo Procedimento que aplica um desconto, somente para clientes ativos Web Panel que mostra o total de vendas por cliente, somente dos clientes ativos

CRIAMOS O DATA SELECTOR COM DITO FILTRO (+ ORDER + DEFINED BY) E O REFERENCIAMOS A PARTIR DOS LUGARES NECESSRIOS

O atributo CustomerStatus est baseado em um domnio enumerado, Status, que possui 3 valores: Active On Hold Closed Os clientes ativos sero aqueles que tenham o valor Status.Active.

Data Selectors - Definio


Criar o objeto de tipo Data Selector, dar um nome e definir:

A estrutura consta de: Parameters: Parmetros recebidos a partir da chamada do Data Selector, para serem usados em condies Conditions: Condies para filtrar os dados a serem recuperados Orders: Ordens condicionais (cada ordem com seus atributos separados por vrgula e when opcional) Defined by: Atributo ou lista de atributos que participam na definio da tabela base final

Data Selectors - Exemplo


Primeiro exemplo apresentado (Cont.): Em vrios objetos de uma KB, se deseja consultar os clientes ativos

Exemplo: Customer { CustomerId* CustomerName CustomerAddress CustomerGender CustomerStatus }

CustomerStatus= Status.Active

Depois de definir um Data Selector, ele pode ser referenciado em: Comandos For Each Grupos de Data Providers Frmulas Aggregate Grids em Web Panels

A forma de referenciar um Data Selector depender a partir de qual caso se deseja chamar. Veremos a sintaxe para cada caso.

Data Selectors - Benefcios

Economia e reutilizao de cdigo: A definio feita uma vez e se reutiliza em vrias consultas e clculos na KB.

Facilitam a manuteno: A definio alterada num nico lugar e a alterao aplicada automaticamente em todos os lugares da KB que forem utilizados.

Otimizam o funcionrios.

conhecimento:

Facilitam

treinamento

dos

novos

Data Selectors Usos


Em For Each

Duas maneiras de uso: Com clusula USING Com operador IN na clusula WHERE Importante: Um Data Selector sempre tem tabela base. Dependendo da forma que for utilizado, os atributos presentes na definio do Data Selector intervm ou no na determinao da tabela base do For Each, Grupo, Grid ou Frmula:

Com clusula USING: intervm na determinao da tabela base. Com operador IN: no intervm na determinao da tabela base.

Data Selectors Usos


Em For Each

For Each com clusula USING


Sintaxe:
For Each USING DataSelectorName([[parm1 [,parm2 [, ..] ]) EndFor

Exemplo 1:

For Each USING ActiveCustomers() EndFor

Exemplo 2:

For Each USING ActiveCustomers() Where CountryName = "Uruguay" EndFor For Each Where CustomerStatus = Status.Active Where CountryName = "Uruguay" EndFor
ATRIBUTOS DO DATA SELECTOR PARTICIPAM NA DETERMINAO DA TABELA BASE DO FOR EACH

Isto se Expande a:

Nota: A performance ser a mesma escrevendo 2 where no For Each que seja referenciado um Data Selector no For Each (que tem definida uma condio) + um where no For Each. GeneXus sempre tratar de otimizar o cdigo gerado, todavia no mais por utilizar o conceito de Data Selectors, j que seu objetivo como explicamos, : centralizar o conhecimento reutilizvel em uma nica definio e depois referenciar essa definio em todas as consultas e clculos da KB que aplique.

Data Selectors Usos


Em For Each
O atributo que antecede o operador IN deve pertencer a tabela estendida da tabela base do Data Selector

For Each com operador IN (em clusulas WHERE)

Sintaxe:

For Each Where <attribute> IN DataSelectorName([[parm1 [,parm2 [, ..] ]) EndFor For Each Where CustomerId IN InvoicesByDate(&FromDate, &ToDate) CONSISTE NUMA CONSULTA A PARTE / INDEPENDENTE DO FOR EACH EndFor

Exemplo:

Definio do Data Selector InvoicesByDate:


GERADO UM SELECT PARA O DATA SELECTOR, INDEPENDENTE DO SELECT QUE SE GERA PARA O FOR EACH ATRIBUTOS DO DATA SELECTOR NO PARTICIPAM NA DETERMINAO DA TABELA BASE DO FOR EACH

TABLA BASE: INVOICE

Neste exemplo: - A tabela base do Data Selector : INVOICE - O atributo que antecede ao operador IN pertence a tabela estendida de INVOICE (CustomerId) e a consulta associada ao Data Selector devolver uma lista de valores correspondentes a dito atributo (devolve uma lista de clientes que tem faturas na faixa de datas dada). - O For Each tem sua tabela base determinada pelos atributos includos no For Each e sem levar em considerao a informao armazenada no Data Selector. - O For Each navegar sua tabela base e estendida, filtrando os registros que contenham algum dos clientes da lista devolvido pelo Data Selector.

Data Selectors Usos


Em Frmulas Aggregate
possvel utilizar Data Selectors em frmulas Aggregate tanto globais como locais
Sintaxe: NomeFormulaAggregate '(' <Expresso> ',' [<CondioAgg>] ',' [<ValorDef>]')'

Find | Max | Min | Sum | Count | Average Expresso de busca, maximizada, minimizada, somada ou mdia [<CondioBusca] ['USING' <DataSelector> '(' <Parmetro1> ',' <Parmetro2> ',' <Parmetro3>')'] Valor a ser devolvido caso no exista registros que cumpram com <CondioAgg>

Exemplo:

atributo frmula quantidade de clientes ativos do pas

Consideraes referente a sintaxe das frmulas Aggregate: Como foi detalhado no slide, na sintaxe das frmulas Aggregate a expresso corresponde a expresso de busca, maximizada, minimizada, somada ou mdia. Pode ser um atributo (armazenado ou frmula) ou bem uma expresso que envolve atributos, constantes, variveis. Todavia tem que levar em considerao que: - Variveis somente podem estar envolvidas nas frmulas locais - Para Sum e Average, o resultado da Expresso deve ser um valor numrico - Unicamente para o caso de Count, no vale uma Expresso e sim um atributo

Data Selectors Usos


Consideraes

Podem ser includos tanto variveis como atributos nos parmetros do Data Selector. Incluir atributos implica que tenha um filtro por igualdade.

Observar que na mesma definio de um Data Selector, ter tabela base e certo comportamento, ou no ter tabela base e outro comportamento dependendo de como seja chamado no contexto que for usado.

FRMULAS LOCAIS

221

Frmulas Locais
Generalidades

Alm de definir frmulas associadas aos atributos (globais, a nvel da KB) tambm possvel definir frmulas no prprio cdigo

Chamamos neste caso de frmulas: frmulas inline ou frmulas locais

possvel definir frmulas inline = locais subrotinas, eventos, etc.

no source de procedimentos,

O Comportamento depende: 1) Dentro do For Each 2) Fora do For Each

222

Frmulas Locais
Dentro do For Each

Tabela base da frmula = Tabela base do For Each possvel incluir na definio da frmula: - atributos da tabela base da frmula + estendida - atributos da tabela navegada pela frmula + estendida - variveis

Exemplo:

TABELA BASE FOR EACH = COUNTRY TABELA BASE FRMULA = COUNTRY TABELA NAVEGADA FRMULA = CUSTOMER ATRIBUTO EM COMUM: CountryId

For Each order CountryId &NumberCustomers = Count(CustomerName) EndFor


ATRIBUTOS QUE PERTENCEM NA DEF. DA FRMULA NA DETERMINAO DA TABELA BASE DO FOR EACH NO PARTICIPAM

Outro exemplo de codificao possvel o que segue, na qual a frmula definida no prprio where do For Each, para filtrar por dito clculo: For each order CountryId where Count(CustomerName)>50 Endfor

223

Frmulas Locais
Fora do For Each Se no estiver posicionado em nenhuma tabela no momento de disparo da frmula no tem tabela associada a frmula possvel incluir na definio da frmula: - atributos de tabela a ser navegada + tabela estendida - variveis Neste caso de uso, no tem filtros implcitos:
For each defined by CustomerName &total=sum(InvoiceTotal) Endfor SOMA AS FATURAS FILTRANDO POR CLIENTE VERSUS &total=sum(InvoiceTotal) SOMA TODAS AS FATURAS

Considerao importante: O disparo da frmula realizado no incio do grupo onde se encontra. Portanto:
&CustomerId = 1 &total = Sum(InvoiceTotal, CustomerId = &CustomerId)

Soluo:
&CustomerId = 1 do calctotal

&CustomerId no tem valor sub calctotal &total = Sum(InvoiceTotal, CustomerId = &CustomerId) endsub

Considerao importante Uma frmula se dispara quando comea o grupo que a contm. Isto significa que se possui uma frmula definida com seus parmetros em determinada linha de cdigo, os valores dos parmetros sero aqueles que foram lidos quando o grupo foi executado na base de dados. Ento, se o grupo foi executado na base dados, e depois disso atribuir valores aos diferentes parmetros envolvidos na definio da frmula, os valores dos parmetros que sero levados em considerao no sero os que voc atribuiu; pelo contrrio sero os lidos quando se executou o grupo que contem a frmula na base de dados. E quando os grupos so executados? - Quando comea um programa - Quando comea um For Each - Depois de um Endfor Quando

comea

uma

subrotina

ou

um

evento

Em particular como neste caso estamos explicando frmulas locais definidas fora de comandos For Each, os itens aplicados so 1. 3. e 4. O mesmo ocorre com as variveis. Os valores das variveis que so considerados no momento de disparar as frmulas, so os valores que as variveis tem atribudo quando o grupo que contem a frmula executada. Se escrevermos o seguinte cdigo: &CustomerId = 1 &total = Sum(InvoiceTotal, CustomerId = &CustomerId)

224

A varivel &CustomerId no ter valor quando a frmula disparada. Isto pode ser resolvido assim: &CustomerId = 1 do calctotal Sub calctotal &total = Sum(InvoiceTotal, CustomerId = &CustomerId) Endsub J que assim obtemos um novo comeo de grupo (quando a subrotina comea), e nesse momento a varivel j est carregada com o valor desejado. De tal maneira que com esta soluo, quando a frmula executada a varivel &CustomerId ter valor 1.

225

Tipos de dados estruturados


SDT

226

SDT: Introduo
Linguagens de programao gerenciam:
Tipos de dados simples (Numeric, Character, etc.) Tipos de dados compostos.

Exemplo de Tipos de dados compostos (registros ou tipos de dados estruturados)


Type Client = Record Name: Character(30)

Depois so definidas as variveis com este tipo de dados e se trabalha com elas...
end;

Country: Character(20) City: Phones: Character(20) Record Home: Character(15)

CellPhone: Character(15) end;

227

SDT em GeneXus
So criados como qualquer outro objeto GeneXus. Editor similar ao das estruturas de transaes. SDT se compe de: membros, subestruturas e colees:
boto direito

O editor de tipos de dados estruturados similar ao editor de transaes. Contem: Propriedade Name, com o nome que identifica ao membro, subestrutura ou coleo. Propriedade Type, na qual se deve selecionar um tipo de dados simples, um domnio, ou um tipo de dados estruturado que j tenha sido definido na KB (propriedade Type somente adquire valor se estiver definindo um membro e no uma subestrutura ou coleo). Propriedade Is Collection, para indicar se o membro representa uma lista (em seguida veremos um exemplo). Observe que uma subestrutura um membro composto, ao invs de ser um simples. Em particular ele tambm um tipo de dados estruturado. Fazendo boto direito sobre um membro da estrutura, se mostra a janela que se v a esquerda, onde se pode inserir outro membro, ou uma subestrutura. Tip: Se desejar criar um SDT com exatamente a mesma estrutura que a de uma transao, ento ao invs de definir um a um todos os membros, subestruturas e colees, basta arrastar (fazer Drag & Drop) o nome da transao desde o Folder View para a estrutura em edio do SDT. Da mesma forma, se desejar que um membro da estrutura corresponda a um atributo, pode selecionar e arrastar o atributo desde o Work With Attributes (janela editvel da opo View do menu de GeneXus) ou inserir com o dilogo Insert/Attribute do menu de GeneXus.

228

SDT em GeneXus
Exemplo contendo coleo:

Um pas tem muitas cidades...

Marcando o check box Is Collection se abrir um ramo da estrutura como se poder, onde pedido dois nomes: o da coleo em si, e o de cada item da mesma. Como veremos em seguida, quando se define uma coleo, junto com o SDT se estar criando implicitamente outro, que corresponder aos itens da coleo. Isto ocorre desta forma para que depois possa ser definido uma varivel do tipo de dados do item, para depois agreg-la para a coleo.

229

SDT: Utilizao
So utilizadas atravs de variveis. Os atributos no podem ser definidos como SDT.
&country
Id Name Cities
1 Brasil

CityName CityName CityName Goinia Santa Catarina So Paulo

A direita pode se ver o dilogo de propriedades de uma varivel &country que se est definindo dentro de algum objeto. O SDT Country definido na KB tal como se aprecia na pgina anterior, da lugar a criao de dois outros correspondentes aos itens da coleo country.City. Este ltimo devido ao caso de poder querer definir uma varivel somente desse tipo de dados, para depois agreg-la com o mtodo Add que j mencionaremos, na coleo. Observe que a varivel &country foi definida do tipo de dados country que aparece na lista obtida ao fazer clique no combo box da propriedade Data Type do dilogo de definio de propriedades da varivel.

230

SDT: Utilizao
Para dados no repetitivos, cada membro acessado pelo nome, como propriedade varivel.
Name Country City Phones
Julia Silveira Brasil So Paulo
Home CellPhone 555-155.55.44 092-155.12.33

&client.Name = Julia Silveira &client.Country = Brasil &client.City = So Paulo &client.Phones.Home = ... &client.Phones.CellPhone = ...

231

SDT: Utilizao
Exemplo: Transao que registra os recibos efetuados aos clientes e SDT
baseado na transao:

drag & drop

Na proc. se carrega &bill com dados do recibo 7 da BD... ...poderia devolver: parm(..., out: &bill)

For each where BillId = 7 ...da tabela BILL &bill.BillDate= BillDate &bill.CustomerId = CustomerId &bill.CustomerName = CustomerName &bill.BillInvoicePeriodStartDate = BillInvoicePeriodStartDate &bill.BillInvoicePeriodEndDate = BillInvoicePeriodEndDate &bill.BillAmount = BillAmount endfor

Aqui se apresenta um exemplo com o qual continuaremos trabalhando. Agregamos a nossa realidade uma transao de recibos. Vamos supor que uma vez no ms, se lana um processo de faturamento, se escolhe perodo de faturamento (usualmente todo o ms anterior) se contabilizam todas as faturas efetuadas por cliente, e se gera um recibo para o mesmo (autonumber). A gerao do recibo ser automtica (ser realizada pelo nosso sistema); esse um tema que veremos em breve. Por agora, vamos supor que necessitamos um procedimento que devolva os dados de um recibo dado (por exemplo, o de id. 7). Uma opo acessar mediante um for each a tabela BILL criada a partir da transao com o mesmo nome, e junto com a regra parm: parm( out: BillDate, out: CustomerId, BillInvoicePeriodEndDate, out: BillAmount); implementar o pedido. A outra opo, devolver toda essa informao em somente uma varivel estruturada! parm( out: &bill); carregada como se mostra acima. Para isso se define um SDT baseado na transao Bill (os SDTs no podem ter o mesmo nome que uma transao, razo pela qual a chamamos BILL_SDT). Para no ter que ingressar um por um os membros do SDT com o mesmo nome que os atributos da transao, basta arrastar a transao Bill desde o Folder View, dentro da estrutura do SDT e automaticamente se inicializar como se mostra acima. out: CustomerName, out: BillInvoicePeriodStartDate, out:

232

SDT: Utilizao
E se quisermos devolver uma lista de recibos? Opo 1: no modificar o SDT e agregar a varivel &bills coleo:

For each where... &bill.BillDate = BillDate &bill.CustomerId = CustomerId &bill.CustomerName = CustomerName &bill.BillInvoicePeriodStartDate = BillInvoicePeriodStartDate &bill.BillInvoicePeriodEndDate = BillInvoicePeriodEndDate &bill.BillAmount = BillAmount
&bills.Add( &bill ) &bill = new Bill_SDT()

endfor

Vamos supor que queremos devolver uma lista de recibos (por exemplo, os que foram efetuados numa faixa de datas dado).

233

SDT: Utilizao
&bills
add

&bill.BillDate= BillDate &bill.CustomerId = ... &bill.CustomerName = ... &bill.BillInvoicePeriodStartDate = ... &bill.BillInvoicePeriodEndDate = ... &bill.BillAmount = ...

&bill

new

&bills.Add( &bill ) &bill = new Bill_SDT()

Baixo nvel! No existe outra forma?

Tem que pedir novo espao de memria para a varivel &bill, para a seguinte iterao. Como veremos em breve, existe um modo muito mais simples, de nvel mais alto, DECLARATIVO, de obter a coleo de SDTs carregada, sem ter que nos preocuparmos em realizar as operaes de baixo nvel, como agregar uma varivel na coleo e pedir memria...

234

SDT: Utilizao em Data Provider

Bills { Bill where ... { BillDate= BillDate CustomerId = CustomerId CustomerName = CustomerName BillInvoicePeriodStartDate = BillInvoicePeriodStartDate BillInvoicePeriodEndDate = BillInvoicePeriodEndDate BillAmount = BillAmount
} }

Data Provider: procedimento especializado, devolve info estruturada

...este modo declarativo, portanto de alto nvel, de carregar uma coleo de SDTs se conhece com o nome de Data Provider. Podemos pens-lo como um procedimento especializado, que devolver sempre informao estruturada (seja simples ou como coleo). Aqui apresentamos o exemplo, que depois ampliaremos quando entrarmos de fato neste tema.

235

SDT: Utilizao
Opo 2: modificar o SDT para que seja uma coleo e depois se trabalha da mesma forma, definindo as variveis:

&bills &bill

236

SDT: Utilizao
Para dados repetitivos, se acessa a cada item mediante comando: For &var in expression code endfor
&var: varivel de tipo de dados A expression: expresso cujo tipo de dados coleo de A, ou array de A

possvel incluir comandos de corte da percorrida, da mesma forma que em for each ou do while, como exit ou return.

Exemplo: A = SDT

For &bill in &bills msg( &bill.Id.ToString() ) msg( Name: + &bill.CustomerName ) ... endfor

A varivel &var vai tomando os valores de cada posio da lista. No possvel obter a posio do item durante percorr-la, para isto necessrio definir uma varivel que atue como contador. Como pode ser facilmente inferido, este comando vlido para colees de qualquer tipo de dados, no somente SDTs.

237

SDT: propriedades
Os nomes dos membros de uma varivel do tipo SDT collection so mostrados como propriedades: Alm disso, para variveis collection:

&cVar.Count() &cVar.CurrentItem()

Retorna a quantidade de itens da coleo. Quando uma varivel SDT collection mostrada no form (como grid) se permite selecionar o item selecionado com o mouse como linha do grid.

As propriedades Count e CurrentItem somente esto disponveis para variveis SDT Collection.

238

SDT: operadores e mtodos


&var = new SDT() &cVar.Add( &item [, Position]) &cVar.Clear() &var.Clone() &var.FromXML( &xml ) &cVar.Item( Position ) &cVar.Remove( Position ) &cVar.Sort( memberName ) &var.ToXml() Retorna uma nova referncia ou ponteiro ao SDT especificado Agrega o item a coleo na posio relativa especificada. Se omitir agregada ao final. Position comea em 1. Elimina todos os itens da coleo Cria uma nova rea de memria e copia os dados da varivel nesta: &var1 = &var2.Clone() A Carrega varivel SDT a partir da string contendo uma estrutura xml. Retorna referncia ao elemento com posio relativa Position na collection. Elimina item que se encontre na posio especificada e corre um lugar todas as posies. Ordena os elementos da coleo de acordo ao membro. Retorna uma string com o formato XML dos dados da varivel SDT (que pode ser collection): ml = &var.ToXml()

Aqui se apresentam a maioria dos mtodos de tipos de dados estruturados. Alguns se aplicam a variveis SDT no coleo, se representam com &var, outros a colees, se representam com &cVar. Para a lista completa, assim como exemplos, acessar ao wiki ou ao help da verso.

239

SDT: Exemplo
Mtodo ToXml:
Name Country City Phones
Julia James Uruguay Montevideo
Home CellPhone 555-155.55.44 092-155.12.33

&xml = &client.ToXml()

<Client> <Name> Julia James </Name> <Country> Uruguay </Country> <City> Montevideo </City> <Phones> <Home> 555-155.55.44 </Home> <CellPhone> 092-155.12.33 </Home> </Phones> </Client>

240

SDT collection em FORM


Ao inserir num form uma varivel SDT collection:
aparece uma janela para selecionar os membros a serem inseridos que sero apresentados como grid e ser carregado automaticamente :

Pode selecionar-se do SDT os membros que se querem carregar como colunas do grid. Observe que em nosso caso temos omitido os membros CustomerId, BillInvoicePeriodStartDate e BillInvoicePeriodEndDate.

241

Objeto Data Provider


DP

242

DP: Cenrio
Troca de informao hierrquica entre aplicaes ou dentro de uma mesma aplicao.
APPLICATION A

Data Interchange

APPLICATION B

Sistema de Faturamento

envio de info dos recibos


Bill
Id: Customer: Date: Amount: 2516 John Drotts 12/12/2008 1000

Sistema de Devedores/Credores

Fa Bill
Id: Customer: Date: Amount: 158 Dane Smith 12/12/2008 750

...

Vamos supor que a partir de nosso Billing System, queremos enviar um sistema de devedores e credores, uma listagem dos recibos correspondentes ao ltimo faturamento. Se trata de informao hierrquica (a informao a ser enviada a de recibos, cada um dos quais possui determinados dados). XML o formato mais usual de troca de informao hierrquica, ainda no sabemos o que vai acontecer no futuro neste aspecto (por exemplo se vai voltar a ser um formato comum ou formato Json).

243

Procedimentos procedurais
Como obter os recibos para um faixa de datas informada?
Utilizando um procedimento que receba a faixa de datas para o faturamento: &start e &end e devolva uma coleo de recibos: Bill
for each using ActiveCustomers() &bill.BillDate = &today &bill.CustomerName = CustomerName &bill.BillInvoicePeriodStartDate = &start &bill.BillInvoicePeriodEndDate = &end &bill.BillAmount = sum( InvoiceAmount, InvoiceDate>= &start and InvoiceDate <= &end and InvoicePendingFlag ) &bills.Add( &bill ) &bill = new Bill () ... endfor

Tendo o mesmo SDT Bill que definimos quando estudamos os tipos de dados estruturados (ali o chamamos Bill SDT, aqui o chamaremos Bill), estamos utilizando um procedimento com os seguintes parmetros: parm( in: &start, in: &end, out: &bills ); sendo &start e &end variveis de tipo Date que recebem a faixa de faturamento, e &bills uma varivel collection do SDT Bill. Observe que estamos utilizando o Data Selector ActiveCustomers para filtrar pelos clientes ativos e utilizando a frmula inline sum, onde unicamente somamos os totais daquelas faturas que pertencem ao cliente da atual iterao do For each e cujas datas se encontrem na faixa informada e tenham o valor True no atributo Booleano InvoicePendingFlag. Este atributo ser alterado a False uma vez que a fatura foi processada dentro do processo de gerao de recibos que iniciamos aqui mas que completaremos mais adiante, quando estudarmos as formas de atualizar a informao da base de dados (aqui somente estamos obtendo a informao dos recibos, mas ainda no os registraremos na base de dados... ).

244

Procedimentos procedurais
Linguagem de Input Linguagem de Transformao Linguagem de Output Exemplo: For each using ActiveCustomers() &bill.BillDate = &today &bill.CustomerName = CustomerName &bill.BillInvoicePeriodStartDate = &start &bill.BillInvoicePeriodEndDate = &end &bill.BillAmount = sum( InvoiceAmount, ...) &bills.Add( &bill ) &bill = new Bill() endfor
INPUT

Transformation

OUTPUT

Situado dentro do cdigo

Qual o propsito do procedimento?

Todo procedimento toma um Input, e mediante alguma transformao, obtm um Output. Para obter o Input tendo certa linguagem (em GeneXus se trata da base de dados, basta nomear os atributos, como pode ser visto no exemplo, a direita das atribuies; assim como tambm se obtm os parmetros). Para realizar a Transformao possui outra linguagem (o cdigo que podemos ver no exemplo) e depois para expressar o Output outro mais. Como pode ver-se, no caso dos procedimentos GeneXus, tanto o Input como o Output se encontram situados dentro do prprio cdigo de Transformao. Pode se dizer que o foco est colocado na transformao. Desta forma o propsito do procedimento, sua sada, fica obscura dentro desse cdigo, que mescla: elementos de sada, com elementos de transformao (em nosso caso, o comando for each, o mtodo add e o operador new, que implementam o armado da coleo de recibos) e com elementos de entrada.

245

Procedimentos declarativos
Linguagem de Input Linguagem de Transformao Linguagem de Output
Transformation INPUT FORMAT OUTPUT TXT HTML XML JSON SDT ...

Data Provider

hierarchical structure

Bills using ActiveCustomers() { Bill { BillDate = &today CustomerName = CustomerName BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, ...)
} }

Propsito claro
Bills Bill BillDate: 12/12/08 CustomerName: John Drotts ... BillAmount 1000 Bill BillDate: 12/12/08 CustomerName: Dane Smith ... BillAmount: 750 ...

Com um Data Provider, o foco est situado na linguagem de sada: observe que indicado numa estrutura hierrquica do que composto esse Output. Depois, para cada elemento da estrutura hierrquica, ter que indicar no Source do Data Provider, como se calcula. Portanto, basta observar o lado esquerdo para deduzir qual ser a estrutura resultante. Depois, suficiente indicar o formato desejado para essa estrutura hierrquica resultante...

246

Procedimentos declarativos
Linguagem de Input Linguagem de Transformao Linguagem de Output
Transformation INPUT FORMAT OUTPUT TXT HTML XML JSON SDT ...

Data Provider

hierarchical structure Bills Bill BillDate: 12/12/08 CustomerName: John Drotts ... BillAmount: 1000 Bill BillDate: 12/12/08 CustomerName: Dane Smith ... BillAmount: 750 <Bills> <Bill>
<BillDate>12/12/08</BillDate> <CustomerName>John Drotts</CustomerName> ... <BillAmount>1000</BillAmount>

Bill
BillDate CustomerName ... BillAmount 12/12/08 John Drotts ... 1000

</Bill> <Bill>
<BillDate>12/12/08</BillDate> <CustomerName>Dane Smith</CustomerName> .... <BillAmount>750</BillAmount>

Bill
BillDate CustomerName ... BillAmount 12/12/08 Dane Smith ... 750

Bills

</Bill> ... </Bills>

...

Depois, uma mesma informao estruturada, pode ser representada utilizando diferentes formatos existentes. Essa a idia do Data Provider. Se num futuro aparecer um novo formato de representao de informao estruturada, o Data Provider continuar sendo o mesmo. GeneXus implementar o mtodo de transformao para esse formato, e somente ter que utiliz-lo.

247

Data Providers
Estruturas hierrquicas em GeneXus? SDTs
Bill
BillDate CustomerName 12/12/08 John Drotts ... 1000

OUTPUT

... BillAmount

Bill
BillDate CustomerName ... BillAmount 12/12/08 Dane Smith ... 750

INPUT

CustomerId 1542

CustomerName John Drotts Dane Smith ...

CustomerStatus A A ...

DB

1543 ...

invoices...

At aqui fizemos uma anlise descritiva. Surge a seguinte pergunta: Como em GeneXus representamos as estruturas hierrquicas de dados? A sada de um Data Provider ser um SDT (ou uma coleo de SDTs). Depois, com essa sada se realiza o desejado, em particular, convert-la ao formato XML, com o mtodo toXml dos SDTs. Vejamos como declaramos a sada... no ser da forma convencional (como parmetro de out da regra parm)...

248

Data Providers
Bill
BillDate CustomerName ... BillAmount 12/12/08 John Drotts ... 1000

Bill
BillDate CustomerName ... BillAmount 12/12/08 Dane Smith ... 750

OUTPUT

Aqui vemos para o exemplo que estamos estudando, que tendo o SDT definido Bills, collection, que coincide com a estrutura que se infere do Source do Data Provider GetBills, ter que declarar esse SDT na propriedade Output do Data Provider. Mas no a nica possibilidade ... veremos outra na pgina seguinte, onde ter sentido a propriedade Collection.

249

Data Providers
Outra possibilidade (mesmo resultado):
Bill
BillDate CustomerName ... BillAmount 12/12/08 John Drotts ... 1000

Bill
BillDate CustomerName ... BillAmount 12/12/08 Dane Smith ... 750

OUTPUT

Se ao invs de ter o SDT collection Bills, tivssemos o que aparece acima, Bill, ento, poderamos programar o Source do Data Provider como vemos e depois configurar a propriedade Collection em True, e uma nova propriedade aberta, Collection Name, que permitir dar nome para a coleo. Este Data Provider equivalente ao anterior. Observe que neste caso no necessrio colocar a raiz da hierarquia, Bills, que se infere a propriedade Collection Name. De todas as formas, mesmo no sendo requerido pode-se programar o Source da mesma forma que o anterior, isto , com o grupo Bills iniciando a hierarquia. Bills { Bill using ActiveCustomers() { ... } } Nota: a clusula using, assim como os where que veremos em seguida, o order, etc., podero ser especificadas tanto no grupo Bills, como no grupo Bill, em casos como este. Em seguida voltaremos nesse tema.

250

Data Provider
Objetivo: Retorno de dados estruturados. Com Procedimento: o SDT feito com operaes de baixo nvel. Com Data Provider: facilidade de escrita e clareza. declarativo independe de implementao. para devolver dados estruturados vamos utilizar um DP ao invs de um Procedimento.

Os Data Providers resolvem eficientemente um tipo de problema: aquele que consiste em retornar dados estruturados. Para esse tipo de problemas contvamos com os procedimentos, mas sua desvantagem evidente era que necessitvamos implementar a forma de armar essas estruturas com operaes de baixo nvel, como agregar um item a uma coleo com Add, e pedir memria (new). Assim mesmo, se tivesse que fazer clculos complexos para dar valor a cada membro da estrutura, os elementos de sada estariam incorporados no cdigo, o resultado do Procedimento no acaba sendo de fcil visualizao. Todos estes inconvenientes so evitados com Data Provider. O foco aqui est na sada, razo pela qual ao olhar j se sabe a estrutura do Output. Sendo declarativo, livre da forma que est implementada a carga do SDT. GeneXus se encarrega disso. Quanto mais declarativo for uma ferramenta, mais fcil de programar, mais adaptvel as mudanas, mais independente de uma implementao particular. GeneXus tende a ser o mais declarativo possvel e cada vez programar menos procedural. A forma declarativa tira do programador o problema e passa para a implementao da ferramenta. Quanto mais inteligente for ferramenta, menos o programador precisa resolver o problema: basta enunci-lo.

251

Data Provider
Utilizao Da mesma forma que um procedimento que devolve informao estruturada:
Procedimento GetBills
Parm( in: par1, ..., in: parn, out: &bills );

Objeto GeneXus
&TheBills = GetBills( par1, ..., parn) udp

Data Provider GetBills


Parm( in: par1, ..., in: parn); Output: Bill Collection: True CollectionName: Bills

Objeto GeneXus
&TheBills = GetBills( par1, ..., parn)

&xml = &TheBills.ToXml()

Um Data Provider tambm pode receber parmetros atravs da regra parm, mas se diferencia de um procedimento onde todos os parmetros podem ser de entrada/sada, aqui somente podero ser de entrada. Por outro lado, um procedimento que devolve informao estruturada feito mediante uma varivel que se carrega no cdigo, e que deve declarar-se como de sada, no ltimo parmetro da regra parm. Em um Data Provider, a declarao do tipo de dados de sada se faz mediante as propriedades Output, no na regra parm. A chamada a partir de qualquer objeto GeneXus de um Data Provider idntica a chamada de um procedimento, isto , com udp. Lembre que ao chamar um objeto e no especificar o mtodo de chamada, se assume udp. A varivel &TheBills dever estar declarada no objeto GeneXus que se realiza a chamada. a varivel na qual se devolve o resultado. Lembre que se o SDT definido na KB o correspondente aos itens individuais: Bill, (e no a coleo Bills), ento a varivel &TheBills ser definida como Collection, de tipo de dados Bill. Depois, com a estrutura hierrquica devolvida pode, por exemplo, ser convertida ao formato desejado, como XML. Importante: Como veremos, um Data Provider no somente pode retornar um SDT ou coleo de SDT, como tambm outro tipo, o Business Component, que tambm representa informao estruturada. Olhar esse tema para completar o conhecimento de Data Providers.

252

Linguagem de DP
Componentes bsicos:
Grupos Elementos Variveis
BillsInfo { Bills { Bill { BillDate = &today CustomerName = CustomerName BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, ... ) &quantity = &quantity + 1 } } BillQuantity = &quantity }

O exemplo que podemos ver aqui parecido ao que trabalhamos. Agregamos o elemento BillQuantity. Tire uns instantes para pensar como dever ser o SDT BillsInfo, para que se iguale com este Source. A esquerda o que apresentamos. O Source no precisa ser escrito da mesma forma que a estrutura do SDT. Se o SDT ter um membro collection de um item determinado, podemos omitir do Source o Item como grupo. Exemplo: com o SDT que temos acima, poderamos ter escrito o Data Provider: Billsnfo { Bills { BillDate = &today CustomerName = CustomerName BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum (InvoiceAmount, ... ) &quantity = &quantity + 1 } BillQuantity = &quantity } Com o mesmo resultado. GeneXus tem inteligncia suficiente para matchear com o SDT.

253

Linguagem de DP
Grupos Agrupam elementos, grupos, variveis em um mesmo nvel hierrquico. Pode ser repetitivo como pode no ser (ele tem inteligncia para determinar).
BillsInfo { Bills { Bill { } } BillQuantity = &quantity }

Ser uma coleo de muitos

BillsInfo { Bills { Bill { BillDate = &today CustomerName = CustomerName ... &quantity = &quantity +1 } } BillQuantity = &quantity }

254

Linguagem de DP
Grupos Um grupo repetitivo anlogo a um for each:
Determina a tabela base (da mesma forma que num for each) Tem disponvel as mesmas clusulas que um for each:
BillsInfo { Bills { [{[order] order_attributesi [when condi]}... | [order none] [when condx]] [using DataSelectorName([[parm1 [,parm2 [, ...] ])] [{where {conditioni when condi} | {attribute IN DataSelectorName([[parm1 [,parm2 [, ...] ]} }...] [defined by att]

Bill {

BillDate = &today CustomerName = CustomerName BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, ...) &quantity = &quantity + 1

Ver mais adiante em opes avanadas

} }
BillQuantity = &quantity &quantity = 0 }

No exemplo, o grupo de nome Bill ser repetitivo. Por que? Para responder a pergunta, vamos fazer outra: e se for um for each, onde substitua os elementos da esquerda das atribuies por variveis? Neste caso a presena de CustomerName a direita da segunda atribuio permite afirmar que tem tabela base: CUSTOMER. Por tanto o grupo ser repetitivo, iterando sobre a tabela CUSTOMER. No exemplo que estamos trabalhando, temos a clusula: Bill using ActiveCustomers() igual: For each using ActiveCustomers() se o atributo CustomerName no estivesse na segunda atribuio, da mesma forma seria com tabela base, pela presena do atributo CustomerStatus no Data Selector ActiveCustomers. Observe que o grupo de nome BillsInfo, de forma diferente, no ser repetitivo, no possui clusulas associadas, e os elementos que contm esto definidos a base de variveis e no de atributos: BillQuantity = &quantity &quantity =0 E o que acontece com o grupo Bills? Observe que neste caso, um grupo que somente possui outro grupo. O grupo contido ser repetitivo, porque Bills ser uma coleo de Bill. Por este motivo, o subgrupo Bill poderia ser omitido (somente deixar Bills) e que fique implcito. Deste modo, as clusulas do grupo que permitem definir order, filtros, defined by, podem ser associadas a este grupo.

255

Linguagem de DP
Grupos Grupos tambm podem ser repetidos:
Clients { Client {
Name = Lou Reed Country = United States City = New York

} Client where CountryName = Mexico {


Name = CustomerName Country = CountryName City = CityName

O resultado retornado ser uma coleo de N+1 itens: sendo N o nmero de clientes do Mxico.

} }

Se a condio estiver no grupo Clients, seria aplicada para os dois subgrupos Client. Por isso permitido que as clusulas operem nos grupos repetitivos (itens), e no somente do grupo que coleo de itens.

256

Linguagem de DP
Elementos Um Elemento um valor atmico no Output. Cada Elemento deve ser atribudo e sua sintaxe igual a das frmulas.
Exemplo: Clients { Client { Name = CustomerName Active = True if CustomerStatus = Status.Active; False otherwise; } }

257

Linguagem de DP
Elementos Elementos e Atributos usualmente possuem o mesmo nome notao mais compacta:
Exemplo:
BillsInfo { Bills { Bill { BillDate = &today CustomerName = CustomerName BillInvoicePeriodStartDate = &start ... } } } BillsInfo { Bills { Bill { BillDate = &today CustomerName BillInvoicePeriodStartDate = &start ... } } }

258

Linguagem de DP
Variveis Algumas vezes necessrio realizar clculos internos:
Exemplo:
BillsInfo { Bills { &quantity = 0 Bill { BillDate = &today CustomerName BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, ... ) &quantity = &quantity + 1 } } BillQuantity = &quantity }

259

Linguagem de DP
Grupos: Opes avanadas
Clusula Default (~ When none)
o grupo somente ser de sada se o grupo precedente (com o mesmo nome) no estiver presente.

Clusulas de Paginao: Count e Skip


Para gerenciar quantos registros sero de sada.

Clusula NoOutput
em um Grupo significa que o grupo no deve estar presente na sada, mas somente os seus elementos subordinados.

Clusula OutputIfDetail
Para o grupo cabealho contendo grupo com suas linhas: somente se apresenta o primeiro de sada se tiver linhas.

Clusula Input
se necessita trabalhar com colees (devolvidas por Procedimento ou Data Provider) como Input do DP.
http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Data+Provider+Language

A informao completa desse tema em ingls pode ser encontrada em nossa comunidade wiki, na pgina: http://wiki.gxtechnical.com/commwiki/servlet/hwiki?Data+Provider+Language

260

Linguagem de DP
Grupos: clusula Default Clusula Default: o grupo somente ser de sada se o grupo precedente
(com o mesmo nome) no estiver presente.
(~ When none em for each) CurrentTaxes Where TaxInitialDate >= today() Where TaxFinalDate <= today() { VAT = TaxVAT Income = TaxIncome } CurrentTaxes [Default] { VAT = 0.7 Income = 0.3 } Tabela TAXES TaxInitialDate* TaxFinalDate* TaxVAT TaxIncome

No se inclui no Output se no encontrou registro no dia de hoje

261

Linguagem de DP
Grupos: clusulas de paginao Count e Skip. Para gerenciar quantos registros sero de sada.

Customers { Customer [Count = 20] [Skip = 100] { Code = CustomerId Name = CustomerName } }

So omitidos os 100 primeiros clientes e so includo no Output os 20 seguintes.

262

Linguagem de DP
Grupos: clusula NoOutput Em um Grupo significa que o grupo no dever estar presente na sada:
somente os seus elementos subordinados.
<Employees> <Employee> <Id>123</Id> <Name>John Doe</Name> <EarningInfo> <Salary>30000</Salary> <Bonus>5000</Bonus> </EarningInfo> </Employee> ... </Employees>

Employees { Employee { Id = EmployeeId Name = EmployeeName EarningInfo [NoOutput] Where IsAutorized(&UserId) { Salary = EmployeeSalary Bonus = EmployeeBonus } } }

<Employees> <Employee> <Id>123</Id> <Name>John Doe</Name> <Salary>30000</Salary> <Bonus>5000</Bonus> </Employee> ... </Employees>

ao invs de

263

Linguagem de DP
Grupos: clusula OutputIfDetail
Cada item da coleo de sada tem um cabealho e algumas linhas: clusula para o nvel do grupo cabealho somente sero apresentados na sada aqueles grupos que tenham linhas.
Countries { Country [OutputIfDetail] { Id = CountryId Name = CountryName Customers { Id= CustomerId Name = CustomerName &quantity = &quantity + 1 } Quantity = &quantity } }

Tabla base: COUNTRY

Tabla base: CUSTOMER Se um pas no possuir clientes associados no aparece como item da coleo Countries na sada.

No mencionamos, mas de forma intuitiva podemos pensar, de ter um par de grupos aninhados (um grupo que, entre outras coisas, contm outro), se cada um deve acessar a base de dados, ento as tabelas base, assim como o critrio de navegao so determinados exatamente da mesma forma que no caso de um par de for eachs anhidados. Por esse motivo, no exemplo, o grupo Country possui tabela base COUNTRY; o grupo Customers possui tabela base CUSTOMER, e ter um join entre ambas tabelas na hora de recuperar a informao para carregar a coleo de pases. Isto , para cada registro de COUNTRY ser carregada a informao de seus atributos CountryId e CountryName nos elementos Id e Name do item Country do SDT coleo Countries que estiver carregando, e depois percorrer a tabela CUSTOMER filtrando por aqueles registros para os quais CUSTOMER.CountryId = COUNTRY.CountryId, carregando para cada um os elementos Id e Name. A presena da clusula OutputIfDetail faz que somente se apresentam na sada aqueles pases que possuam clientes associados. Se um pas da base de dados no tiver nenhum cliente, ento no ser apresentado como item da coleo de sada, Countries.

264

Linguagem de DP
Clusula Input At aqui assumimos que o Input vinha da BD; mas tambm necessrio outro tipo de entrada. Por exemplo, a sada de um Procedimento ou Data Provider. A forma mais clara de trabalho atravs de variveis, que uma vez atribudas so manipuladas de forma usual:
&var = Proc.udp( parm1, ..., parmn) &SdtVariable = DataProvider( parm1, ..., parmn )

Mas se for necessrio trabalhar com uma coleo necessrio utilizar a clusula Input

265

Linguagem de DP
Clusula Input Para trabalhar com colees.
VerySimple { Month Input &i = 1 to 12 { MonthNumber = &i } }

Similar ao For &i=1 to 12 da linguagem procedural

Outro Input pode ser um SDT collection:

CustomersFromAnotherDataProvider { &CustomersSDT = GetCustomers() // a DataProvider that Outputs Customers collection Customer Input &Customer in &CustomersSDT { Id = &Customer.Code Similar ao For &var in Expression Name = &Customer.Name da linguagem procedural } }

266

Atualizao da Base de Dados

267

Atualizao BD
Insert-Update-Delete

Atualizao interativa:
Transaes: Atravs do form o usurio ingressa/modifica/elimina os dados. Vantagens:
As regras de negcio so executadas (e no se atualiza registro que viole regra Error especificada) No se atualiza registro que viole integridade referencial.

Business Components (BC)

Atualizao no interativa:
Business Components (BC) Procedures

At aqui somente conhecemos uma forma de atualizar a base de dados de nossa aplicao: as transaes. Como sabemos, uma transao determina a ou as tabelas requeridas para armazenar sua informao. Por sua vez, ao ser gerada, se converte no programa que implementa a lgica de insero, eliminao e modificao de dados nessas tabelas, de forma totalmente transparente para o programador. Tambm a transao permite definir todas as regras de negcio que os dados associados devero cumprir. O programa gerado se encarrega de execut-las. Assim, se em uma transao temos uma ou vrias regras Error, que se disparam ao satisfazer determinadas condies, essas regras estaro includas no cdigo gerado, e no se permitir atualizar a base de dados at as condies que disparam essas regras deixarem de satisfazer para os dados que esto manipulando nessa oportunidade. Assim mesmo, como vimos, as transaes asseguram o controle de integridade referencial, muito importante para assegurar a consistncia da base de dados. Mas as transaes no cobrem todas as necessidades referente a atualizao de dados. Tambm ser necessrio uma forma no interativa, batch, para realizar atualizaes sobre as tabelas. Para isso existem duas alternativas: atualizao utilizando o que se conhece como Business Component, absolutamente relacionado com as transaes, ou utilizar comandos especficos para tal fim dentro de objetos de tipo Procedure. Depois veremos que os Business Components permitem grande flexibilidade, visto que permitem atualizar a base de dados de qualquer forma: tanto interativa como no interativa. Em seguida introduziremos os Business Components e depois os comandos de atualizao direta dentro dos Procedimentos.

268

Business Components
Cenrio

Necessitamos registrar os recibos que efetuamos aos nossos clientes.


autonumber
Regras: Default( BillDate, &today); Error( The invoice period considered must be past ) if BillInvoicePeriodEndDate >= BillDate; Error( Wrong invoice period ) if BillInvoicePeriodStartDate > BillInvoicePeriodEndDate;

Mas este um caso que no nos serve a transao, visto que a gerao de recibos uma tarefa batch: se lana uma vez ao ms um processo que calcula e registra todos os recibos correspondentes as faturas dentro de determinado perodo.

269

Business Components
Cenrio

J tnhamos declarado o Data Provider GetBills que realizava o processo de gerao de recibos desejado, mas no gravava:
Bill { BillDate = &today CustomerId BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, InvoiceDate >= &start and InvoiceDate <= &end and InvoicePendingFlag ) }

parm( in: &start, in: &end); Output: Bill Collection: True Collection Name: Bills

E nos devolvia uma coleo de tipos de dados estruturados (SDT). Se observarmos, a estrutura hierrquica deste DP quase idntica a estrutura da transao Bill...

270

Business Components
Cenrio

...e se pudssemos guardar em uma estrutura os dados e depois grav-los na base de dados?
Bill
BillDate CustomerId ... BillAmount 12/12/08 2516 ... 1000

For &bill in GetBills( &start, &end ) &bill.Save() endfor


Bills

Bill
BillDate CustomerId ... BillAmount 12/12/08 158 ... 750

e alm de gravar, executar as mesmas regras que se executam quando se grava mediante a transao Bill, e controlando alm disso a integridade referencial?

&bill no ser uma varivel de tipo SDT, mas sim Business Component!

271

Business Components
BC

A partir de uma transao, pode-se criar Business Component (BC).


Permite encapsular a lgica da transao (regras, eventos, controles de integridade referencial, estrutura dos dados) de tal forma que possa realizar inseres, modificaes e eliminaes sem necessidade do form...

criado automaticamente na KB um tipo de dados Business Component, que pode ser associado a variveis, e cujo nome ser o da transao.

Por default a propriedade Business Component estar apagada. Isso significar que a lgica de negcio dada pela transao, somente ser utilizada dentro da prpria transao, e no ao se criar um tipo de dados com o mesmo nome da transao, Bill, que permita encapsular a lgica da transao para utiliz-la a partir de outros objetos.

272

Business Components
Em qualquer objeto GeneXus (ex: um procedimento): A varivel &bill ter a mesma estrutura que o SDT obtido a partir da transao, e se trabalha de forma anloga, mas alm disso oferece mtodos para atualizar a base de dados em funo desses valores.

&bill.BillInvoicePeriodStartDate = #10-10-08# &bill.BillInvoicePeriodEndDate = #09-10-08# &bill.Save()

Ser inserido registro na tabela BILL?

273

Business Components
Insert
O que acontece na transao se tentssemos gravar com estes dados?

&bill.CustomerId = 3456 &bill.BillInvoicePeriodStartDate = #10-10-08# &bill.BillInvoicePeriodEndDate = #09-10-08# &bill.Save()

Default( BillDate, &today); Error( The invoice period considered must be past ) if BillInvoicePeriodEndDate > BillDate; Error( Wrong invoice period ) if BillInvoicePeriodStartDate > BillInvoicePeriodEndDate;

No ser inserido!

10/10/08

>

09/10/08

Observe que se consideram alguns membros da estrutura da varivel &bill, Business Component, e depois se executa o mtodo Save (inexistente em SDTs). Isto equivalente ao que ocorria de forma interativa se o usurio final insere esses mesmos valores nos atributos correspondentes do form da transao, e depois pressionar o boto Confirm. Portanto, da mesma forma que ocorre com a transao, devero ser disparadas as regras e serem realizadas os controles de integridade referencial. O que acontecer com esse conjunto de dados se tentar gravar mediante a transao? A gravao impedida, devido que est cumprindo a condio da segunda regra de error. Por outro lado, se no existisse na tabela CUSTOMER um cliente com identificador 3456, a integridade referencial vai falhar e assim tampouco deixaria de ingressar o registro na tabela BILL da base de dados.

274

Business Components
Insert
E agora que os dados no violam regras e supondo que o cliente 3456 existe e &today>10/10/08? &bill.CustomerId = 3456 &bill.BillInvoicePeriodStartDate = #09-10-08# &bill.BillInvoicePeriodEndDate = #10-10-08# &bill.Save()

Ser inserido registro na tabela BILL!

Com quais valores de BillId, BillDate e BillAmount?


BillId era autonumber... BillDate = &today... se dispara regra Default BillAmount vazio... no tem regra

e CustomerName?

Antes de executar o mtodo Save do Business Component, o valor de BillId na estrutura de &bill ser vazio. Portanto, uma vez que se execute o Save, como o atributo BillId era autonumber na tabela BILL, se executa a propriedade a nvel da tabela e o registro ser inserido com o nmero seguinte ao ltimo dado. No caso de BillDate, da mesma forma, como no se atribui valor na estrutura de &bill, antes do Save estar vazio, mas quando este se execute, ser disparada a lgica da transao, e em particular a regra Default( BillDate, &today ) declarada. Portanto no registro inserido na base de dados, o valor do atributo BillDate corresponder a data de hoje. Para BillAmount poderamos fazer a mesma anlise. Mas a diferena do caso anterior, no tem regra que atribui valor, pela qual se insere o registro com valor vazio neste atributo. Se atribuir valor para &bill.CustomerName no ser considerado na hora da insero, visto que CustomerName um atributo inferido, e no tem regra Update que permita modific-lo. O mesmo acontece para atributos definidos a nvel da estrutura da transao mas que foram frmulas. Isto , so atributos virtuais na transao, e tambm so a nvel do Business Component. Seu valor disparado.

275

Business Components
Update-Delete
E se o desejado atualizar um registro, no inserir um registro novo? &bill.Load( 100 ) &bill.BillDate = #06-01-08# &bill.CustomerId = 1258 &bill.Save()

Se atualiza o registro 100 da tabela BILL!


(sempre que exista cliente 1258 e 06/01/08>=BillInvoicePeriodEndDate)

E para eliminar o recibo 100?

&bill.Load( 100 ) &bill.Delete()

Se realiza sempre e quando no exista nenhuma tabela que referencie ao Bill 100!

276

Business Components
Gerncia de erros
Em transaes vemos os erros interativamente (e no Error Viewer).

Como nos inteiramos dos erros ou mensagens resultantes ao tentar atualizar via BC?
&bill.Load( 100 ) &bill.BillDate = #06-01-08# &bill.CustomerId = 1258 &bill.Save()

Temos os mtodos

Booleanos:
&bill.Fail() &bill.Success()

E em caso de falha (por regra Error, falha de IR ou de duplicao) e/ou de regras Msg podemos obter a lista de mensagens de advertncia ou de error: &messages = &bill.GetMessages()
de tipo prdefinido SDT...

enum

Warning Error

Para gerenciar os erros ter que definir uma varivel de tipo de dados SDT pr-definido (vem com a KB) Messages (collection).

Quando se executam os mtodos: Save, Check, Load, Delete se disparam e carregam as mensagens gerados automaticamente por GeneXus assim como as regras Msg e Error definidos na transao. Se recomenda que sempre se recupere a lista destas mensagens e se faa uma gerncia de erros. As mensagens mais comuns geradas automaticamente por GeneXus so:

As regras Msg e Error aceitam em sua definio alm do parmetro com a mensagem a mostrar, um segundo parmetro que define o Identificador da mensagem. O objetivo que quando se execute a transao como Bussiness Component, e se obtenha a lista de mensagens ocorridas depois de executar uma ao sobre a base de dados, se tenha de cada mensagem, alm da mensagem em si, seu identificador, sendo possvel assim avaliar o identificador da mensagem para codificar o comportamento como conseqncia: Msg|Error(<mensaje>, <Id do mensaje>) Exemplos de <Id do mensaje>: "CustomerNameCannotBeEmpty", etc. "1", "2", "Error1", "Error2" ou uma descrio como ser

Se no especificar um identificador para a mensagem,, ter que perguntar pelo texto da mensagem. Nota: Para as mensagens geradas automaticamente por GeneXus, o Id sempre em Ingls (independentemente do idioma selecionado no modelo).

277

Business Components
Caso de uso Data Provider tem como output uma coleo de Business Component Bill!

Business Component omite valor da propriedade Commit on Exit da transao: tem que utilizar comando Commit/Rollback de forma explcita!
Necessitamos mudar para False atributo InvoicePendingFlag de invoices faturados...

Aqui completaramos o processo de gerao de recibos. Observemos primeiramente um fato importante: um data provider no somente pode devolver um SDT simples ou coleo, mas tambm um BC simples ou coleo. Importante: o BC devolvido somente poder inserir na base de dados. Isto , um Data Provider somente permite satisfazer sua estrutura, para depois fazer uma operao de INSERT sobre a base de dados. No ser possvel fazer uma atualizao ou eliminao com um BC carregado via Data Provider. Observe por outro lado como foi definido a varivel &message de tipo de dados Messages.Message, correspondente a os itens do SDT pr-definido Messages devolvido pelo mtodo GetMessages do BC. Uma vez que obtemos e ingressamos na tabela BILL todos os recibos correspondentes ao faturamento, deveramos percorrer as faturas consideradas, e modificar o valor de seu atributo InvoicePendingFlag, passando-o para False. Lembremos que o valor deste atributo se utiliza para no processar duas vezes uma mesma fatura. Lembremos que este valor se utiliza no Data Provider no clculo do elemento BillAmount: sum( InvoiceAmount, InvoiceDate >= &start and InvoiceDate <= &end and InvoicePendingFlag ) Deixaremos pendente esta ltima parte para quando estudarmos, umas pginas mais adiante, as formas de atualizao direta, dentro de procedimentos exclusivamente, dos registros das tabelas.

278

Business Components
Outra opo
Este objeto do tipo Web Panel. O utilizamos para pedir ao usurio final o perodo de faturamento

A partir de uma Web Panel tambm pode ser utilizado &EndDate BC para atualizar a base de dados
&StartDate

Adiantamos aqui em apresentar outro tipo de objeto interativo que estudaremos um pouco mais adiante, a Web Panel, mostramos um objeto deste tipo em execuo. Sua funo ser pedir ao usurio final um par de valores, que armazenem nas variveis correspondentes de tipo Date (&startDate e &endDate) e depois, quando o usurio pressione o boto associado ao Evento Enter da Web Panel, se execute seu cdigo. Observe que o cdigo idntico ao do procedimento visto antes. Com este exemplo pretendemos mostrar que mediante um Business Component pode se atualizar a base de dados a partir de qualquer objeto GeneXus.

279

Business Components
Caso de uso interativo

Problema: inserir pas somente se existir um cliente novo para o mesmo e no pode ficar pas sem cliente no sistema.
1 3 se o sistema cair aqui?

2 commit automtico

commit automtico

Lembremos que no se pode ter somente uma UTL com duas transaes. Ento?

Vamos supor que cada vez que se insere um novo pas no sistema, necessariamente devido a que se tem um novo cliente desse pas. Vamos supor que como requerimento, alm disso, no deve ficar abaixo nenhuma circunstncia ingressado um pas sem pelo menos um cliente associado. Tal como temos implementada a aplicao, isto no se est controlando. Como se insere um pas e um cliente para o mesmo? O usurio deve executar a transao Country, ingressar o pas. Depois abrir a transao Customer, e ingressar os dados do cliente e confirmar. Mas o que acontece se cair o sistema quando se est ingressando o cliente? Ficar o pas ingressado (lembrar que cada transao por default faz commit ao final).

280

Business Components
Caso de uso interativo

Soluo: na transao Country, criar varivel &customer de tipo BC Customer e inseri-la no Form e agregar a regra Accept.
1 2
&customer.CountryId = CountryId on AfterInsert; &customer.Save() on AfterInsert; msg( It fails) if &customer.Fail() on AfterInsert; Commit automtico

Desvantagem: no so disparadas de forma interativa as regras associadas a Customer...

Necessitamos que a insero do pas na tabela COUNTRY e a insero do cliente na tabela CUSTOMER se realizam dentro de uma mesma UTL. Como temos visto, as operaes efetuadas por 2 transaes no podem ser includas numa nica UTL. Por esta razo, necessitaremos fazer a insero dentro da mesma transao. Como? Dentro da transao Country, definimos uma varivel &customer, de tipo business component Customer (para isso, teremos previamente que ter setado a propriedade Business Component da transao Customer, de tal maneira que se crie este tipo de dados na KB). Umaa vez efetuado isto, simplesmente inserindo no form a varivel (da mesma forma que acontecia com um SDT), GeneXus colocar controles para cada um dos membros da estrutura: &customer.CustomerId, &customer.CustomerName, &customer.CustomerAddress, etc. As variveis por default nas transaes so de sada, ter que especificar regra Accept para que possam ser escritas em execuo e o possa ingressar valores para as mesmas. O Save do customer dever realizar-se necessariamente depois de inserir o pas em sua tabela (do contrrio a integridade referencial falha). Portanto nas regras: &customer.Save() on AfterInsert; Sabemos que neste momento o registro correspondente ao pas j ter sido gravado, e depois neste Save... na continuao, o commit automtico.

281

Business Components
Resumo

Objetivo:
Reutilizar a lgica do negcio definida nas transaes. Usar o poder das transaes (sem seus forms) desde outros objetos GeneXus: Procedimentos, Web Panels... A partir de outra Transao (da mesma forma que uma varivel podia de forma interativa inseri-la no Form, tambm um BC)

Benefcios:
Atualizao na BD garantindo integridade dos dados e execuo das regras do negcio. Reutilizao de cdigo (as regras de negcio no precisam ser duplicadas) Vrios objetos GeneXus podem atualizar a BD.

282

Business Components
Regras e Eventos

Regras: so executadas todas as regras da transao exceto (so ignoradas pelo especificador):
as que incluem user interface ( Ex: Customer.call()) as que no aplicam: parm, prompt, NoPrompt, Default_mode, etc

Eventos: todos os eventos da transao so ignorados, exceto os eventos Start e After TRN (e eles tambm so ignorados se inclurem referncias a objetos com user interface).
Nota: quando falamos so ignorados nos referimos no contexto da atualizao utilizando BC, no quando a atualizao realizada atravs da prpria transao.

Se existe uma regra que chama um objeto que possui interface, isto , form, essa regra no includa no BC. Existe uma forma de especificar que uma regra declarada na transao no seja aplicada quando se executa a transao, mas somente quando se executa o Business Component associado: qualificando a regra com [BC]. Exemplo: [BC] Default( BillDate, &today); Se quiser qualificar de uma s vez um conjunto de regras: [BC] { regra1; regra2; ... regran; } O mesmo vale para eventos. Analogicamente, existem qualificadores para indicar que uma regra somente se execute se estiver correndo a transao com seu form web: [WEB].

283

Atualizao no interativa direta


Procedimentos

284

Procedimentos
Update

No tem um comando especfico para modificar um registro: se realiza de forma implcita dentro do comando For each.
Exemplo:
parm( in: CustomerId, in: &StartDate, in: &EndDate);

A modificao de dados da base de dados se realiza em forma implcita: no tem um comando especfico de atualizao. Para atualizar um ou vrios atributos de uma tabela se utiliza o comando For each, e dentro do mesmo o comando de atribuio Podem ser realizadas vrias atualizaes dentro do mesmo For each, podendo estes pertencer tanto a prpria tabela base como a tabela estendida. O exemplo que apresentamos completa o que havamos iniciado a respeito ao processo de gerao de recibos. Observe que aqui se est percorrendo a tabela INVOICE, filtrando por InvoiceDate, por InvoicePendingFlag, assim como por CustomerId (na listagem de navegao se observa que mesmo no tendo sido especificado order, ao receber no atributo CustomerId, que foreing key, se ordena por este atributo para otimizar). Dentro do for each, para cada fatura que cumpre as condies, se atualiza o valor do atributo InvoicePendingFlag. Aqui poderiam atualizar-se no somente esse atributo, mas qualquer da prpria tabela INVOICE, ou de sua estendida, com as excees indicadas na continuao.

285

Procedimentos
Update

Atributos atualizveis: os da tabela estendida do For each.


Exceto: os que formam parte da chave primria da tabela base. os que formam parte do ndice pelo qual se est acessando a tabela.

A atualizao se realiza no Endfor. A integridade referencial no controlada.


Se atualizar um atributo que FK no se controla existncia.
For each ... bloque1 [when duplicate bloque2...] Endfor

Somente se realiza controle de duplicados:


Se dentro do for each tentar atualizar um atributo que tem definido um ndice unique, e existe o valor duplicado, no se atualiza... existindo a clusula when duplicate seu cdigo executado.

Vamos supor que temos o seguinte diagrama de Bachman genrico:


A* B C D B* E F

E no Source de um procedimento fazemos: For each C = &C E = &E D = &D Endfor Aqui a tabela base do For each ser claramente a de chave primria A e dentro do For each estamos atualizando tanto atributos da prpria tabela base como da estendida. Em que momento ocorre efetivamente a atualizao dos registros envolvidos? A atualizao no ocorre quando encontra um comando de atribuio dentro do For each, mas sim depois que se encontram todos, para cada instancia da tabela base, isto ,quando se chega ao Endfor para cada iterao. Como vimos antes, no podemos atualizar dentro do comando For each atributos da chave primria. Todavia poderamos querer atualizar um atributo que no est definido como chave primria, est definido como chave candidata (mediante um ndice unique). Se o atributo chave candidata, deve controlar-se que no se dupliquem seus valores, caso encontre duplicado, no permite fazer a atualizao. Se desejar tomar uma ao no caso disso ocorrer, o comando For each agrega a clusula when duplicate. Somente tem sentido se existe alguma chave candidata para esse For each.

286

Procedimentos
Update

Eficincia:

Se tiver um milho de registros para serem atualizados?


Para cada um se envia um comando UPDATE ao servidor de BD (que no tem por que estar na mesma mquina que o Web Server) eficincia?

for each where InvoiceDate >= &StartDate where InvoiceDate <= &EndDate InvoicePendingFlag = False endfor

Atualizao massiva: clusula Blocking reduz nmero de acessos a BD.


for each where InvoiceDate >= &StartDate where InvoiceDate <= &EndDate Blocking 1000 InvoicePendingFlag = False endfor

At a N-sima (1000) iterao, o Update se realiza em um buffer. Com a N-sima se envia comando: Update massivo na BD e se atualizam os dados do buffer.

Realizar um blocking nas operaes de atualizao da BD significa armazen-las em memria e envi-las em grupo ao DBMS. Ao invs de interagir com o DBMS em cada operao de atualizao, a interao tem lugar somente cada N operaes de atualizao, onde N o nmero que se estabelece na clusula Blocking. No ser o caso de nosso exemplo, mas o que aconteceria se estiver fazendo uma atualizao massiva que inclui algum atributo chave candidata da tabela, e se encontram duplicados para alguns dos registros do grupo de 1000 que se est processando? Nesse caso, uma vez chegado o buffer com as 1000 atualizaes, ao enviar ao BD o comando UPDATE do grupo, saltar o error de duplicados e se iterar sobre o grupo, realizando um comando UPDATE individual de BD, um por um.

287

Procedimentos
Delete

Para eliminar registros de uma tabela: Comando Delete. Deve ir dentro de um For each. Elimina o registro da tabela base em que estiver posicionado. Se executa assim que encontra o comando (e no no Endfor). No controla a Integridade Referencial Exemplo:
For each defined by InvoiceDate Blocking 1000 Delete Endfor
Elimina todos os registros da tabela base: INVOICE, eliminando-os em grupos de 1000 (para faz-lo de forma mais eficiente).

Para eliminar dados se utiliza o comando Delete dentro do comando For each. O comando Delete elimina o registro que estiver posicionado no momento dado. por isso, que no pode aparecer solto dentro do Source. Deve estar dentro de um comando For each, cuja tabela base seja a tabela que se quer eliminar registros. Somente se eliminam os registros da tabela base, no da estendida. Sei desejamos eliminar todas as faturas anteriores a uma data informada, podemos programar um procedimento: For each where InvoiceDate <=&date For each defined by InvoiceDetailQuantity DELETE // se eliminam as linhas Endfor DELETE //depois de eliminar as linhas se elimina o cabealho Endfor Para uma eliminao mais eficiente, dependendo do nmero de registros da base de dados, convm agregar clusula Blocking com um fator de bloqueo, N, adequado. Por exemplo, se agregar Blocking 1000 a eliminao fsica no realizada em cada iterao, mas sim a cada 1000 vezes que se chegue ao Endfor, se eliminaro o grupo de 1000 registros em um nico acesso a Base de Dados (ao invs de 1000).

288

Procedimentos
Insert

Comando New: permite inserir um registro em uma tabela.


Procedimento NewPrice New ProductId ProductPriceListDate ProductPriceListPrice endnew = &ProductId = &today = &price

Realiza o controle de duplicados:


Se j existe o registro para o produto e data? atualizar o preo: clusula when duplicate.

New ProductId = &ProductId ProductPriceListDate = &today ProductPriceListPrice = &price when duplicate for each ProductPriceListPrice = &price endfor endnew

Vamos supor que queremos implementar um procedimento que faa o seguinte: para o produto cujo cdigo recebido por parmetro, insere um novo preo (tambm recebido por parmetro) em sua lista de preos, para a data correspondente ao dia em que se executa o procedimento. Este deve criar um novo registro na tabela PRODUCTPRICELIST, que est composta pelos atributos ProductId, ProductPriceListDate e ProductPriceListPrice, sendo sua chave primria composta, conformada por ProductId e ProductPriceListDate. Para isso se utiliza o comando new que escrevemos acima. Observemos que dentro do mesmo aparecem comandos de atribuio, onde se d valor aos atributos da tabela que se quer inserir o registro. Cada vez que GeneXus encontra um new, deve determinar a tabela na qual se realizar a insero (tabela base do new). determinada a partir dos atributos que aparecem dentro do comando new, do lado esquerdo numa atribuio. O nico controle que realiza, o de duplicados. Em nosso caso, se existir um registro com os valores de ProductId e ProductPriceListDate, no se realizar a insero. Se programar a clusula when duplicate, se atualiza o registro encontrado. Observemos que para realizar a atualizao do atributo, a atribuio deve estar dentro de um comando For each. Se no colocamos o For each no se realizar a atualizao do preo para esse registro, isto , como se no tivesse includo clusula when duplicate. Se quiser inserir um registro para o qual exista chave candidata duplicada, tambm se controla e no se realizar a insero. Em caso de existir clusula when duplicate, se executa.

289

Procedimentos
Insert

Exemplo: se quisermos realizar a gerao de recibos diretamente em um procedimento (no atravs de BC).
For each using ActiveCustomers() New Blocking 1000 BillDate = &Today BillInvoicePeriodStartDate = &start BillInvoicePeriodEndDate = &end BillAmount = sum( InvoiceAmount, InvoiceDate >= &start and InvoiceDate <= &end and InvoicePendingFlag ) Endnew endfor

No for each se percorrem os clientes ativos e o new insere na tabela BILL um recibo novo para esse cliente (por que CustomerId no aparece atribudo?).

Se so milhares de clientes, pode otimizar a insero e fazer em blocos

O caso mais comum ser ter o comando new dentro de um for each, visto quem em geral se quer inserir registros na base e clculos efetuados em funo de outros. O mesmo processo de gerao de recibos que havamos resolvido anteriormente utilizando Data Provider e Business Component, poderamos realiz-lo com um procedimento que utilize o comando new de insero. Qual alternativa voc escolheria? Lembre que com os comandos de atualizao dentro de procedimentos, o nico controle que ser realizado o de duplicados. Se as inseres so muitas, assim como vimos para o caso das atualizaes, dispomos da clusula blocking para ir guardando em um buffer e depois fazer a insero de todos os registros uma vez. Em nosso caso no falhar a insero, devido que a chave primria autonumber, e que no temos chaves candidatas (atravs de ndices unique) na tabela de recibos (BILL). Mas se no for o caso, como as inseres vo sendo realizadas no buffer at chegar a 1000, no possvel at completar o buffer saber se alguma operao falhar. Quando se executa o INSERT massivo da base de dados, ali se pode falhar alguma insero. Nesse caso, se itera nos elementos do buffer, executando o INSERT simples, um por um. Se existe clusula When duplicate no New, ento pelos registros que falhem, se executa a clusula.

290

Procedimentos
Insert

Sintaxe do new
new [ Defined by att1,, attN ] [ Blocking NumericExpression ] bloque_asignaciones1 [ when duplicate For each bloque_asignaciones2 Endfor ] endnew att1,, attN attx1 = ... ... attxm = ...
devem pertencer a uma tabela fsica tabela base

Nota: No necessrio atribuir valor a todos e cada um dos atributos da tabela. Alguns vem instanciados pelo contexto do new (ex: se est dentro de um for each), no necessrio atribuir valor para o registro a ser inserido (pegam do contexto).

Na sintaxe apresentada, bloque_asignaciones1 um bloque de cdigo composto na sua maioria por sucessivos comandos de atribuio (aqui se atribui valor aos atributos da tabela na que vai inserir o registro, podem tambm atribuir-se valores a variveis). A clusula Defined By opcional, se incorpora os mesmos efeitos que no comando For each: ajudar a determinar a tabela base. A tabela base do new se obtm dos atributos do Defined By e os que apaream do lado esquerdo de atribuies dentro do bloque_asignaciones1. Aqui no se utiliza a tabela estendida. No caso de que o comando new esteja dentro de uma clusula repetitiva (ex. For each), possvel reduzir o nmero de acessos a base de dados usando a clusula blocking. O comando new realiza um controle de duplicados, de tal maneira que no se permite inserir um registro que j exista na tabela. A clusula when duplicate do comando permite programar a ao em caso de que o registro j exista na tabela base (tanto por chave primria como por chave candidata). Normalmente, ao ocorrer o que acabamos de falar, se quer atualizar alguns dos atributos de dito registro. Para isso, em bloque_asignaciones2 se realizam tais atribuies, mas como o que se faz atualizar um registro (e no inserir um novo), estas atribuies aparecem entre For each Endfor, como vimos, as atualizaes somente podem ser realizadas dentro de um For each. Se a clusula when duplicate para um new no for especificada, se o registro que se quer inserir se encontra duplicado no se realizar nenhuma ao e a execuo continuar no comando seguinte. Isto , como no pode inserir o registro porque j existe um, no faz nada e segue adiante com o prximo comando.

291

Atualizao BD
BC versus Proc

Atualizao via Business Component:


Se realizam controles de integridade referencial. Se controlam duplicados. Se disparam as regras do negcio. -

Atualizao via comandos em procedimentos:


No se realiza controle de integridade referencial. + O nico controle que se realiza o de duplicados. No tem nenhuma relao com transao aqui no tem regras.

Nos procedimentos o nico controle de integridade que se realiza automaticamente o controle de duplicados. O controle de integridade referencial fica por conta do programador, o que no ocorre nas transaes (em um Business Component). Fica claro da numerao mostrada acima que os Business Components oferecem todas as garantias e constituiro a forma de atualizao privilegiada. Cabe perguntar-se ento: quando atualizar utilizando estes comandos? A resposta : quando a performance for um problema. Um exemplo discutvel o que utilizamos para alterar o valor do atributo InvoicePendingFlag a False. No havia nenhuma regra que o implicara, no envolvia integridade referencial, nem duplicados e podia envolver milhares de registros. Qual seria a alternativa? Prender a propriedade Business Component da transao Invoice, e no procedimento MarkInvoiceAsNotPending definir varivel &invoice com esse tipo de dados e depois: for each where InvoiceDate >= &startDate where InvoiceDate <= &endDate where InvoicePendingFlag &invoice.Load ( InvoiceId) &invoice.InvoicePendingFlag = False &invoice.Save() endfor Mas esta soluo ser mais ineficiente que a atualizao direta utilizando blocking factor, sabendo que milhares de faturas devero ser atualizadas.

292

Uso de Subtipos

293

Definio de subtipos
GeneXus estabelece as relaes atravs de seus nomes. Mediante subtipos se pode estabelecer que dois atributos com nomes diferentes correspondem ao mesmo conceito. Casos de subtipos:
A. Mltiplas referncias B. Especializao de um nvel (relao 1-1) C. Subtipos recursivos

294

A. Mltiplas referncias
Atributos conceitualmente iguais que cumprem regras diferentes (ex.: reservas de passagens).
Reservation PROBLEMA Atributos com o mesmo nome
{ ReservationId* CityId origem CityId destino

City
{

SOLUO
}

CityId * CityName

Reservation
{

City
subtipo subtipo
{ CityId * CityName }

Desaparece o problema!
}

ReservationId* ReservationCityFromId ReservationCityToId

Realidade para representar/desenhar: Em cada reserva tem duas cidades envolvidas, as quais cumprem regras diferentes. O rol de uma das cidades o de ser a cidade de partida (cidade origem) e o rol da outra o de cidade de chegada (cidade destino). O domnio de ambas cidades o mesmo, o da tabela CITY. A forma de representar tanto a origem como o destino so cidades da tabela CITY, desenhando a transao Reservation na forma mencionada inicialmente na transparncia. Todavia, no possvel que na estrutura de uma transao figure o mesmo atributo mais de uma vez, pois no teria maneira de identifica-los. SOLUO: chamar as duas cidades de reserva com diferentes nomes de atributos. Qualquer das seguintes opes vlida. Escolhemos a 3era por maior clareza. Opo 1) ReservationCityFromId cidade origem CityId cidade destino (mesmo nome que a PK de CITY) Opo 2) CityId cidade origem (mesmo nome que a PK de CITY) ReservationCityToId cidade destino Opo 3) ReservationCityFromId cidade origem ReservationCityToId cidade destino O problema que ao colocar por exemplo ReservationCityFromId ao invs de CityId, GeneXus deixa de inferir que ReservationCityFromId corresponde ao cdigo de uma cidade da tabela de CITY. Como fazemos para relacion-los, sendo que tem nomes de atributos diferentes? ver resposta na prxima folha

295

Para estes casos GeneXus fornece os SUBTIPOS, que permitem definir que dois atributos que se chamam diferentes correspondem ao mesmo conceito. Em nosso exemplo, se definimos o atributo ReservationCityFromId como subtipo de CityId, estamos especificando que mesmo ReservationCityFromId e CityId so diferentes atributos (de nomes diferentes), correspondem, ao mesmo conceito (uma cidade da tabela CITY). Ao estabelecer que um atributo subtipo de outro, estamos estabelecendo uma dependncia funcional entre eles. Se ReservationCityFromId subtipo de CityId, ento dizemos que CityId supertipo de ReservationCityFromId. Os atributos que se encontrem numa relao subtipo-supertipo compartilham a mesma definio (tipo de dados). Se realizam os controles de integridade referencial automaticamente. A tabela estendida obtida com a definio do subtipo, a mesma que se obteria utilizando diretamente o supertipo.

296

A. Mltiplas referncias
Com a definio dos subtipos antes mencionados:
Se estabelecem as seguintes relaes:
ReservationCityFromId

RESERVATION
ReservationCityToId

CITY

Os controles de Integridade Referencial (IR) so feitos automaticamente entre ambas tabelas quando utilizam suas correspondentes transaes.

Os atributos secundrios de CITY:


Pertencem a tabela estendida de RESERVATION, mas como existe dupla referncia no se podem utilizar diretamente a partir de RESERVATION (ambigidade de caminhos e com valores de cidades diferentes).

Soluo

definir tambm subtipos para os atributos secundrios de CITY, e inclu-los em cada um dos grupos de subtipos.

IMPORTANTE: Observe que este caso de mltiplas referncias pode acontecer: na tabela base (*) como na tabela estendida (*) o caso do exemplo, na mesma tabela (RESERVATION) tem mais de uma referncia outra tabela (CITY) e com valores diferentes. RESUMINDO: sempre que a partir de uma tabela se acesse a outra que est em sua tabela estendida por mais de um caminho e com valores diferentes, necessrio definir SUBTIPOS, para que os atributos possam ser chamados de forma diferente e realizando todos os controles de integridade referencial. Uma vez definidos os grupos de subtipos que so necessrios, a forma de indicar ao GeneXus qual os caminhos deve tomar para acessar a tabela destino, mencionando os nomes de atributos correspondentes. Ex.: mencionar ReservationCityFromName caso queira nesse momento o nome da cidade origem, o ReservationCityToName caso queira o nome da cidade destino.

297

A. Mltiplas referncias
Nome de cada grupo de subtipos.

Transao Reservation
{ ReservationId* ReservationCityFromId ReservationCityFromName ReservationCityToId ReservationCityToName }

Tabela Reservation
{ ReservationId* ReservationCityFromId ReservationCityToId }

Inferido Inferido

FK FK

Com o grupo estamos indicando que os atributos pertencentes ao mesmo grupo de subtipos, esto relacionados. Por exemplo, no nosso exemplo, GeneXus saber que o atributo ReservationCityToName ser inferido atravs do atributo ReservationCityToId (e no atravs do ReservationCityFromId). Isto por ambos pertencerem ao mesmo grupo (ao nome ReservationCityTo). Quando o usurio digita um valor sobre ReservationCityToId, no somente feito de forma automtica o controle de integridade referencial (que exista uma cidade com esse cdigo na tabela CITY), e sim que vai inferir em ReservationCityToName o nome correspondente a esse cdigo de cidade. IMPORTANTE: Todo grupo de subtipos, deve conter um atributo ou um conjunto de atributos, cujos supertipos, juntos, correspondam a chave primria de uma tabela do modelo. Os demais atributos do grupo deveram ser do tipo Inferred, ou seja, podero ser inferidos atravs da chave. Caso contrrio o grupo estar mal definido.

298

A. Mltiplas referncias a tabela estendida


COUNTRY pertence a tabela estendida de SALE por caminhos diferentes e com cdigos de pas diferentes.
Um caminho a partir de SALE a COUNTRY: atravs do Pas do cliente (CountryId)

CUSTOMER SALE SELLER


Outro caminho a partir de SALE a COUNTRY: atravs do Pas do vendedor (CountryId) Source:
Que pas imprime? Quais dos caminhos toma? Tem uma ambigidade no modelo de dados!

COUNTRY

Layout:

Se desejarmos, por exemplo listar as vendas (SALE), e de cada uma delas mostrar os dados do cliente (nome, pas, etc.) e do vendedor (nome, pas, etc.): necessitamos um For Each com tabela base SALE e acessar atravs de sua extenso as tabelas CUSTOMER, SELLER e COUNTRY para listar os atributos secundrios do cliente, vendedor e pas respectivamente. Problema: Os atributos de nome CountryId, CountryName e todos da tabela estendida COUNTRY pertencem tabela estendida SALE por dois caminhos diferentes: 1) atravs do pas do cliente e 2) atravs do pas do vendedor. Soluo: Devemos diferenci-los, cham-los com diferente nome de atributo, mas querendo que continuem representando todas as relaes e fazendo automaticamente todos os controles de integridade referencial.

299

A. Mltiplas referncias a tabela estendida

Soluo

Quando queremos o pas do cliente da venda: SaleCustomerCountryName


st eCu Sal erId om

CUSTOMER COUNTRY

SALE

Sale Sel le

rId

SELLER
Quando queremos o pas do vendedor da venda: SaleSellerCustomerName

Uma vez definidos os dois grupos de subtipos que se mostram na figura, e fazendo a mudana correspondente na estrutura da transao Sale, resolve a ambigidade no modelo de dados!

300

A. Mltiplas referncias a tabela estendida: Soluo


SaleCustomerCountryId SaleSellerCountryId

Problema resolvido!

Uma vez definidos os subtipos, temos que lembrar de usar o nome do atributo que corresponda ao que queremos acessar. Por exemplo, em todos aqueles objetos GeneXus nos quais gostaramos de acessar ao cdigo do nome do pas do cliente da venda devemos usar atributos SaleCustomerCountryId e SaleCustomerCountryName respectivamente.

301

B. Especializao de atributos
Ex.: Sistema para uma Universidade

PERSON

dados comuns a professores e estudantes

TEACHER
dados prprios dos professores Sistema Teachers

STUDENT
dados prprios dos estudantes Sistema Students

Caso de subtipos Especializao de atributos: Quando se est modelando uma categorizao. Geralmente utilizada, quando um objeto do negcio compartilha todas as caractersticas de outro objeto, mas agrega mais algumas. A diferena pode estar tanto nas propriedades, como no seu comportamento. Exemplo Sistema para uma Universidade: Neste exemplo, o professor e o aluno possuem regras e comportamentos claramente diferenciados. Por exemplo, o professor ter cursos atribudos, remunerao, etc. O aluno estar inscrito num curso, ter pagamentos, assistncia, escolaridade, etc. Estamos em um caso que as regras e o tratamento das entidades da categorizao esto claramente diferenciados. Tanto os estudantes como os docentes compartilham informao em comum (ambos tem um nome, endereo, etc) mas tambm possuem informao diferente, que prpria de cada um. Para representar esta realidade, so criadas trs transaes: Person, Teacher e Student. Na transao Person figura a informao em comum. Para representar que tanto os estudantes como os docentes so pessoas, so utilizados subtipos. Definindo que o identificador de Teacher subtipo do identificador de Person estamos estabelecendo esta relao. Cada vez que inserir um registro na tabela TEACHER atravs de sua transao, a checagem da integridade referencial realizada contra Person. Da mesma forma, ao tentar eliminar um registro de Person, primeiro verificado que no exista nenhum registro na tabela TEACHER (nem em STUDENT) com o mesmo valor na chave primria.

302

B. Especializao de atributos
Person
{ PersonId* PersonName PersonAddress } }

Teacher
{ TeacherId* TeacherName TeacherAddress TeacherSalary

Student
{ StudentId* StudentName StudentAddress StudentAverage }

So criadas 3 tabelas fsicas. So realizadas as checagens de IR contra a tabela PERSON.

A transao Teacher tem associada uma tabela que conter fisicamente somente dois atributos: TeacherId e TeacherSalary. TeacherId o identificador da transao, ser a chave primria da tabela associada. Alem disso, ao ser um subtipo de PersonId, ser uma chave estrangeira da tabela PERSON. Portanto, sero realizadas as checagens de integridade referencial correspondentes. Os atributos TeacherName e TeacherAddress so subtipos de PersonName e de PersonAddress respectivamente e esto agrupados com TeacherId, que sero inferidos da tabela PERSON, atravs da chave estrangeira TeacherId (no esto armazenados na tabela TEACHER).

303

C. Subtipos recursivos
Exemplo: Employee-Manager

Tabela EMPLOYEE { EmployeeId* EmployeeName EmployeeIsManagerFlag EmployeeManagerId Error(Deve ingressar um gerente para o empregado) if not EmployeeIsManagerFlag and EmployeeManagerId.isnull(); }
FK

possvel ter uma tabela subordinada a si mesma utilizando subtipos. Este tipo de subtipos se utiliza para modelar as relaes recursivas. Por exemplo, a relao entre Empregado e Gerente: - cada empregado tem um gerente. Um gerente, a sua vez, um empregado (aqui esta a recursividade). - um gerente pode ter vrios empregados. Alm disso, a realidade a ser representada que somente os empregados que no so gerentes possuem um gerente, ento, ao inserir os dados tem que realizar os seguintes controles: -quando informar os gerentes, tem que permitir deixar nulo o atributo EmployeeManagerId. Para isto, trocamos para Yes a coluna Nulls do atributo EmployeeManagerId, que uma FK na tabela EMPLOYEE. -que todo empregado que no gerente, tenha um gerente. Este controle realizado com a regra error mostrada na figura. O atributo EmployeeManagerName no fica armazenado na tabela EMPLOYEE, inferido aps ingressar um valor em EmployeeManagerId. Por ser EmployeeManagerId subtipo de EmployeeId, so realizadas automaticamente os controles de integridade referencial da tabela com ela prpria. Isto pode ser visto na navegao da transao na pgina seguinte.

304

C. Subtipos recursivos
Listagem de navegao detalhada:

305

Consideraes
Quando se define um subtipo este "herda" a definio do supertipo. Pelo menos um dos supertipos do grupo (ou conjunto de supertipos do grupo) deve(m) corresponder a PK de uma tabela do modelo.

306

PATTERNS

307

Patterns: Cenrio

Filtro sobre os dados

Paginao

Tendo a transao Country e a transao Customer, queremos ter a aplicao mais vistosa, com consultas com vistas mais completas e com algum aumento de produtividade. Por exemplo, trabalhar com os pases de uma forma mais vistosa e amigvel que a que brinda somente a transao. Visualizar num grid os pases existentes, com a possibilidade de filtrar por nome de pas, e fixando a paginao ao grid, de tal forma que mostre um nmero fixo de registros por pgina...

Patterns: Cenrio
New Country

Update Country

Delete Country

T r a n s a c t i o n

...assim como poder ingressar um novo pas (mediante a transao Country), ou selecionar um dos mostrados no grid, para poder modific-lo ou elimin-lo...

Patterns: Cenrio

...ou incluso ver a informao completa desse pas, incluindo os clientes associados...

Patterns
Generalidades Definio Padres que podem ser aplicados a uma KB para implementar automaticamente certa funcionalidade. Padres disponveis: Work With Category

Seletores dentro das Transaes

Uma vez aplicado o padro, todos os objetos gerados ficam como parte da Base de Conhecimento.

natural ao desenvolver, ter que resolver partes muito similares mas no exatamente iguais. Por exemplo, se em uma Base de Conhecimento tem modelados os objetos da realidade Customer e Country, apesar de ditos objetos serem bem diferentes, os Work With Customers e Work With Countries respectivamente, possuem muitas coisas em comum: um grid no form, um conjunto de variveis para utilizar em filtros, opes de ordens da consulta, chamadas transao correspondente para atualizar a base de dados, etc.. Surgem ento os Patterns, oferecendo a possibilidade de aplicar um padro (pattern) s instncias desejadas de uma Base de Conhecimento, e gerar todos os objetos GeneXus necessrios para implementar certa funcionalidade, considerando seus dados especficos. Seguindo com o exemplo mencionado inicialmente, possvel aplicar o padro Work With na Base de Conhecimento, de tal forma que partindo das transaes Customer e Country (e caso se deseja outras), se obtenha todo o desenvolvimento correspondente ao Work With Customers e Work With Countries para ambiente web (telas vistosas que implementam as consultas, com ordens, filtros, chamadas s transaes correspondentes, e mais).

Patterns
Work With
Gera a partir de uma Transao Tela Work With: consulta interativa, mltiplas ordens, filtros, chamada a transao. Etc. Tela View: Registro selecionado, com a informao associada.

Work With

Transao
View

A tela Work With oferece: Consulta interativa Mltiplas ordens Filtros Chamada Transao nos diferentes modos (insert, update, delete, display) Possibilidade de incluir chamadas prprias a objetos Link em cada linha do grid a tela View A tela View mostra: A informao do registro selecionado no grid Work With Um tab control com: Um tab com a informao do registro Um tab para cada tabela subordinada a tabela base do registro no grid Work With.:

Patterns
Aplicao

Abrir a Transao Selecionar o padro a ser aplicado (aparecer a instncia por default) Marcar a opo Apply this pattern on save Salvar a Transao

Para aplicar o pattern sem demoras, basta editar a instncia (selector Work With da transao), marcar o check box e gravar. Pronto! Com isso so criados automaticamente os objetos GeneXus que implementam o pattern (em particular a tela de seleo e filtro e a tela de View que mostramos antes). Assim mesmo se modificar a transao para que agora receba por parmetro o modo (Insert, Update, Delete, Display) e o pas.

Patterns
Work With: objetos gerados
Consequencia: So gerados na KB os objetos que j vimos em execuo. Onde? No Folder View, abaixo da prpria transao:

Uma vez gravada a instncia, no folder view, abaixo o nome da transao, aparece o nome do pattern aplicado a mesma (em nosso exemplo WorkWithCountry) e todos os objetos que GeneXus deve criar para implementar. Em nosso caso sero criados 2 objetos de tipo Web Component, e 2 objetos de tipo Web Panel. So muitos similares. A diferena que um Web Component pode ser includo dentro de outro objeto. No entraremos em detalhes neste momento.

314

Patterns
Exemplo
Aplicao do pattern Work With transao Country.

Ao aplicar o pattern Work With na Transao Country, ser criado: Tela Work With: Ter um grid com os atributos CountryId e CountryName Poder ordenar e filtrar por CountryName, por ser CountryName o atributo descriptor. Poder chamar a transao nos diferentes modos Tela View: Mostrar dois tabs. O primeiro tab ter a informao do pas selecionado, e o segundo ter a informao dos clientes pertencentes a dito pas (porque existe uma relao 1-N entre as transaes Country e Customer). Caso no se queira visualizar o atributo CountryId no grid da tela Work With, basta editar suas propriedades a partir do n Attributes e colocar a propriedade Visible=False. No pode ser eliminada porque a chave primria da transao Country.

Patterns
Comeando a associar janela Work With

Se coloca no pas indicado, ou mostra todos os pases.

So muitas as propriedades oferecidas nas instancias correspondentes ao padro Work With, para personalizar o comportamento dos objetos que sero gerados. Na continuao descrevemos algumas delas. O n Selection oferece as propriedades relacionadas a tela Work With que se gera para a instncia. Seus subns so: Modes (Ins, Upd, Del, Dis) Este n permite definir em quais modos se pode chamar a transao. As possibilidades e seus valores por default so: Insert: True Update: True Delete: True Display: False Na instncia aparece <default> ao lado de cada uma das propriedades anteriores. Onde se configura este valor por default? Veremos numas pginas mais adiante. Para cada modo poder especificar-se uma condio. So fornecidas as seguintes propriedades para esse propsito: Insert Condition, Update Condition, Delete Condition, Display Condition. Se define uma condio associada a um modo, a chamada para esse modo somente ser habilitada a avaliao da condio verdadeira (Exemplo: CountryId=10).

Patterns
Modificando a instncia do Pattern Work With
Agregar, eliminar, ocultar Atributos. Especificar os modos de chamada transao Definir ordens e filtros. Agregar, eliminar, modificar Aes. Agregar, eliminar, modificar Tabs.

Posicionar-se no n correspondente e pressionar o boto direito do mouse.

Attributes Este n permite definir quais atributos desejam mostrar no grid (e para cada atributo, vrias propriedades podem ser personalizadas). Orders possvel oferecer ao usurio final vrias ordens possveis para ver o resultado da consulta (isto , as linhas mostrando os dados no grid). Utilizando o boto direito do mouse pode ser definida uma nova ordem (seu nome e composio). Cada ordem pode estar composta por vrios atributos (podendo indicar para cada um deles se deseja ordem ascendente ou descendente). Um combobox ser apresentado na tela WorkWith oferecendo todas as possveis ordens a serem selecionadas, para que o usurio final escolha e os dados sejam apresentados no grid ordenados pelo mesmo. Filter Este n permite definir condies de filtro, para que no grid sejam mostrados somente os registros que cumpram com as mesmas. Actions O n Actions permite incorporar aes prprias na tela WorkWith. Isto , permite agregar botes (dentro ou fora do grid) que chamem aos objetos indicados, com seus parmetros correspondentes. O n Actions no est visible por default, estando posicionado no n Selection e pressionando o boto direito do mouse, a opo Add Actions oferecida para ser agregada. Uma vez agregado este n, estando posicionado sobre o mesmo e pressionando o boto direito do mouse, se oferecer a opo Add Action que permitir agregar uma ao com seu nome de ao, caption, objeto chamado, etc. O n View por sua vez, oferece as propriedades relacionadas a tela View gerada para a instncia. Mostra toda a informao de um registro, que foi selecionado no grid do WorkWith (a informao do registro mostrada em uma aba de um tab control, e alm disso tem uma aba com um grid para cada tabela diretamente subordinada, para mostrar a informao relacionada).

Patterns
Personalizao- Exemplos
1) Ocultar atributo CountryId do grid.

F4

Por que ocultar ao invs de eliminar?

O atributo CountryId, diferente do CountryName, no pode ser eliminado do grid, isso porque um atributo que se envia a transao Country quando o usurio deseja modificar ou eliminar o pas mostrado numa linha do grid do Work With.

318

Patterns
Personalizao- Exemplos
2) Eliminar modo Delete a partir do grid.

F4

Ao editar as propriedades estando posicionados no n da instncia que se mostra, podemos observar que cada um dos modos que se pode chamar uma transao (para inserir, modificar, eliminar ou incluso mostrar) esto listados como propriedades. Podemos ver tambm que aparece uma propriedade Export que permite exportar os dados a uma planilha excel. Outra vez aqui podemos apreciar que cada uma das propriedades possui o valor <default> que ainda no sabemos de onde pego. Mas se queremos fixar um valor independente de qual seja o default, podemos editar o combo box que apresentar trs valores: <default>, true, ou false. Fixamos o valor da propriedade Delete em false. Podemos ver em execuo a repercusso. No aprece no grid a primeira coluna que contm a imagem que permitia eliminar o pas. Agora no se pode eliminar pases a partir dessa tela. Observe tambm como desapareceu do grid o atributo CountryId. Ocultamos ele na pgina anterior.

319

Patterns
Personalizao- Exemplos
3) Agregar uma ao de chamada a um objeto na tela View Country.
a) Click com o boto direito sobre o n selection, escolha add/actions b) Click com o boto direito sobre a ao criada e escolha add/action.

Patterns
Personalizao - Exemplos
c) Definir a Ao editando suas propriedades (F4).
Nome da ao e objeto que se chama.

Boto fora do grid.

d) Finalmente em execuo, se observa o boto foi do grid.

J havamos definido o objeto BillingProcess para realizar o faturamento do ms de todos os clientes. Aqui estamos agregando um boto fora do grid, que ao pression-lo chama outro objeto GeneXus que havamos criado anteriormente.

321

Patterns
Associando... tela View

O n View por sua parte, oferece as propriedades relacionadas a tela view que se gera para a instncia. Mostra toda a informao de um registro, que foi selecionado no grid do Work With (a informao do registro mostrada em uma aba de um tab control, e alm disso tem uma aba com um grid para cada tabela diretamente subordinada, para mostrar a informao relacionada).

322

Patterns
Personalizao - Exemplos
1) Tirar atributos CustomerGender Customer da tela View Country. e CustomerStatus do tab

a) Posicionar-se sobre o atributo e elimin-lo com a tecla de eliminao do teclado ou boto direito/Delete.

Neste caso se no queremos que os atributos CustomerGender e CustomerStatus sejam vistas no grid em execuo, no necessitamos ocult-los. Podemos diretamente elimin-los.

323

Patterns
Personalizao - Exemplos
2) Agregar um filtro por CustomerName no tab Customer.

a) Click com o boto direito sobre o tab Customer

b) Indicar o atributo sobre o cual filtrar, editando as propiedades (F4).

Uma vez executado o passo a) e escolher Filter aparecer um novo n Filter imediatamente depois do n Attributes, com 2 subns: Attributes e Conditions. Depois, no passo b), dever posicionar-se no subn Attributes e fazer boto direito, onde se oferece a possibilidade de agregar um atributo de filtro. Ao editar as propriedades, voc dever pressionar o combro box vai mostrar uma janela onde se ingressa o atributo (em nosso caso, CustomerName). Com isto se cria automaticamente uma varivel com o mesmo nome que o atributo &CustomerName, que ser o control que aparecer em execuo para que o usurio digite ali o filtro. Vejamos o passo seguinte...

324

Patterns
Personalizao - Exemplos
(Continuao) c) Definir a condio correspondente.

325

Patterns
Valores por default para as propriedades
Propriedades (F4)

O padro WorkWith alm de gerar objetos novos, tambm modifica as transaes, para que sejam chamadas pelos objetos gerados pelo pattern, agregando a regra parm, etc.. Relacionado a isto, cada instncia contm a propriedade UpdateTransaction, que oferece os seguintes valores: Do not update: A transao no ser modificada (web form, regras e eventos sero mantidos). Only rules and events: Somente as regras e eventos sero modificados, o web form no modificado. Apply WW Style: A primeira vez que o padro aplicado, o comportamento ser o mesmo que se houvesse selecionado o valor Create Default. A partir da segunda vez que o padro aplicado, no se modificar a data rea do form da transao (caso tenha sido personalizada com GeneXus e deseja manter), e se modificar o style rea, assim como os eventos e regras. Create default: Regras, eventos e form da transao (tanto data rea como style rea) sero modificados. No que diz respeito ao form, ser como selecionar a opo Create default a partir do GeneXus. O valor por default para esta propriedade Apply WW Style. Enquanto as propriedades AfterInsert, AfterUpdate e AfterDelete, permitem definir o comportamento depois que se insere, modifica ou elimina um registro. Os valores possveis para cada uma delas so: Default Return to caller Go to View Go to Selection

Patterns
Pattern Settings
Configurao das propriedades gerais (para todas as instncias) Preferences \ Patterns

Aqui esto centralizados os <default> para toda instancia. Podemos ver que o n Template oferece algumas propriedades que mencionamos na pgina anterior. O tamanho da pgina dos grids do work with, que nas imagens anterior era de 3 (se mostravam em 3 linhas por pgina do grid) se configura no n Grid. O valor por default desta propriedade Page.Rows. Isto , o valor do domnio enumerado Pages criado por GeneXus automaticamente ao aplicar o pattern na primeira vez. O valor que tem Page 10. Ns tnhamos alterado para 3 para que no fosse mostrado as imagens complestas.

Patterns
Dinamismo entre a Transao e Patterns
Todos os objetos gerados pelos Patterns esto baseados no esquema de Defaults de GeneXus. Cada parte de um objeto gerada como Default.

A implementao baseada em Defaults permite ter dinamismo entre a Transao e o padro


No necessrio reaplicar o padro, as alteraes so vistas ao abrir o objeto novamente

O dinamismo mantido para todas as partes default do objeto Opo Edit / Apply Default do Menu para voltar o default de uma parte ou de todas as partes (All parts)

O dinamismo mencionado se mantm para todas as partes default dos objetos. Todos os objetos gerados por Patterns esto baseados no esquema de Defaults de GeneXus. Cada parte (Form, Regras, Eventos) de cada objeto gerado como Default. Caso alguma parte do objeto tenha sido modificada, esta deixa de ser Default. Por exemplo, se modificar o web form de um WW (no fica como default), e se agrega um novo atributo na TRN, no vai ser atualizado automaticamente o grid WW com esse atributo (ou seja, no ser agregado dito atributo). A implementao baseada em Defaults permite ter dinamismo entre a Transao e o padro Alterar propriedades na definio do padro (Pattern setting) Alteraes na instncia (agregar um novo filtro) Alteraes na Transao (agregar um novo atributo) Se quiser voltar o dinamismo, dever ter novamente as partes como default. Para isto, se deve selecionar a partir do Menu Edit / Apply Default (a parte onde se tem aberto o objeto) ou Apply Default (All parts), voltando o default de todas as partes que haviam sido modificadas.

Patterns
Como eliminar os objetos gerados por Patterns
Selecionar a instncia, pressionar boto direito / opo Delete ou pressionar a tecla DEL. Aparecer a mensagem:

Ao confirmar a mensagem Se eliminaro todos os objetos gerados por Patterns associados na Transao. Se eliminaro todos as regras e eventos agregados por Patterns na Transao. Ser desmarcada a opo Apply this pattern on save da Transao.

Objeto Web Panel

330

Web Panels
Generalidades Definio Objetos GeneXus que permitem ao usurio realizar consultas interativas na base de dados atravs de uma tela em tempo de execuo.
So flexveis, para mltiplos usos.

Elementos que as compem:

Os elementos das web panels so: Web Form: Cada web panel contem um form Web, o qual deve ser desenhado pelo analista agregando variveis, atributos, assim como outros controles, para que o usurio possa interagir com o mesmo. Regras: As regras de uma web panel permitem definir certos comportamentos pontuais de dito objeto. Por exemplo, declarar quais parmetros recebe, definir quais variveis no queremos que sejam aceitas no form mas utilizadas para mostrar informao, etc. Condies: para definir as condies que devem cumprir os dados a ser recuperados (filtros). Subrotinas: So rotinas locais na web panel. Eventos: As web panels empregam a programao orientada a eventos. Este tipo de programao permite definir cdigo ocioso, que se ativa em resposta a certas aes provocadas pelo usurio ou pelo sistema. Nesta seo de uma web panel onde se define o cdigo ocioso associado aos eventos que podem ocorrer durante a execuo da web panel. Propriedades: So caractersticas a serem configuradas para definir certos detalhes referentes ao comportamento geral da web panel. Ajuda: Permite a incluso de texto de ajuda, que os usurios podem consultar em tempo de execuo da web panel. Documentao: Permite a incluso de texto tcnico como documentao para os desenvolvedores.

Web Panels
Para o ingresso de dados

Event Enter

No exemplo, a web panel contem duas variveis &StartDate e &EndDate como se mostra acima. Em tempo de execuo, o usurio pode ingressar valores nas variveis &StartDate e &EndDate visto que nas web panels as variveis por default so de entrada. No evento Enter da web panel (associado ao boto Billing Generation), se obtm e gravam as faturas cujas datas se encontrem na faixa especificada. De modo que a definio desta web panel para que o usurio ingresse a faixa de datas, e ao selecionar o boto Billing Generation, se execute o processamento das faturas.

Web Panels
Para exibir dados de um registro
Customer { CustomerId*

CustomerName CountryId CountryName CustomerAddress CustomerGender CustomerStatus CustomerPhoto }

blob

Tabela base: CUSTOMER

parm(in: CustomerId );

So mostrados os dados do cliente

A web panel mostrada acima foi criada para exibir os dados de um cliente. Precisa ser chamada a partir de outro objeto, passando por parmetro o cdigo do cliente do qual se quer mostrar a informao. Uma web panel um objeto tipicamente utilizado para mostrar informao. Ento, quando GeneXus encontra atributos no form, qual inteno do programador ao ter colocado isso? Pois, o que est pedindo implicitamente que se busque os dados correspondentes a base de dados para mostr-los. Com a web panel anterior, GeneXus vai a tabela CUSTOMER e filtra pelo atributo recebido por parmetro, CustomerId, mostrar a informao do registro encontrado. Que informao? A que reside nos atributos que figuram no form. Mas o atributo CountryName no se encontra na tabela CUSTOMER. Pois acontece o mesmo que com um for each, um grupo de grupo de Data Providers, etc., isto , desde o registro da tabela base, se acessa o registro relacionado da tabela estendida necessria, para obter o valor do atributo requerido (em nosso caso acessa a tabela COUNTRY para recuperar o valor de CountryName). As inferncias que GeneXus realiza so as seguintes: Ao se tratar de uma web panel, os atributos que figurem sero de consulta1. Ento GeneXus deve acessar a base de dados para recuperar seus valores. De quais tabelas? Vai depender se a Web panel possui grids ou no: Web panel plana (sem grid): os atributos esto soltos no form, como no caso que estamos mostrando. Se isso acontece, porque o analista necessita acessar a informao de um registro de uma tabela (e eventualmente dos registros relacionados pela tabela estendida), como o caso do exemplo. Neste caso, a web panel estar bem programada se alm disso se agregar um filtro que determine esse registro a ser mostrado. Em nosso caso, temos a regra parm que ao receber no atributo PK da tabela somente vai recuperar um registro. GeneXus determina uma tabela base da web panel, assim como faz para um for each. Como? Buscando a mnima tabela estendida que contenha os atributos.. Web panel com uno ou mais grids: veremos em seguida, mas j podermos pensar... Qual o sentido de colocar um grid? Mostrar informao repetitiva. No caso geral: cada grid mostra muitos registros de uma tabela (e sua informao associada).

1 Ao contrrio do que acontece com os atributos nas transaes (exceto os inferidos ou os que tem regra noaccept ou propriedade Enabled desabilitada).

Web Panels
Para exibir mltiplos registros: Grids
Exemplo: Mostrar todas as Faturas

CUSTOMER

COUNTRY

Tabela base: CUSTOMER

O que diferencia est web panel da anterior que ela no plana. Quando se incluiu um grid num form, se est indicando que vai mostrar uma quantidade indefinida de dados (neste caso, clientes). Visto que nesta web panel tem envolvidos atributos, GeneXus infere que deseja acessar a base de dados. Simplesmente dizendo quais atributos deseja mostrar, sem necessidade de mais informao. Existe um grid, tem atributos, ento, necessariamente ter tabela base, isto , a tabela da base de dados navegada em busca da informao requerida. Se ao invs de mostra esta informao em tela, quisermos uma listagem, vamos criar um procedimento com um print block customer com os atributos CustomerName e CountryName e no source programaramos: for each print customer endfor

INVOICE

CUSTOMER

Isto a anlogo, somente que o for each est implcito, no tem que especific-lo. Cada linha do grid que se carrega, como o print que se executa em cada iterao do for each da listagem. Das tabelas CUSTOMER e COUNTRY e da relao entre ambas Na1, GeneXus determina a tabela base desta web panel (sendo que a tabela estendida seja a mnima que cumpre que contenha todos os atributos referidos). Observe que este exemplo somente difere do anterior, que os atributos aparecem num grid, e portanto, no precisa filtrar, ficando somente registro de CUSTOMER. Nesta web panel no tem regra parm que estabelea filtro algum. Tambm conseguiremos mais adiante que esta web panel alm de mostrar os clientes da base de dados no grid, tambm permite filtrar os clientes que se quer ver em cada oportunidade, seja por nome do cliente, ou por ambos. Por isso as variveis aparecem no form.

Web Panels
... Load automtico
Customer tabela
CustomerId 1 2 3 4 ... CustomerName Susan Jones Richard Smith Martina Rodrguez Hugo Romero ... CountryId 2 2 1 4 ... . . . . . .

load
l oad l oad l oad

Country table
CountryId 1 2 3 4 ... CountryName Uruguay United States Italy Venezuela ...

For each implcito:


para c/customer buscar nome de pas associado e Load se carrega linha no grid.

Base de dados

Quando GeneXus pode determinar automaticamente uma tabela a percorrer para carregar as linhas do grid, o faz, e nesse caso no ter necessidade dessa informao. por isso que falamos que nesse caso tem um for each implcito. Depois veremos casos em que isso no acontece (grids sem tabela base). Observe o exemplo, que se na tabela existem 4 registros, se carregam uma a um os quatro. Se agora queremos que o usurio possa filtrar os clientes que deseja ver...entra em questo as variveis que definimos na parte fixa do form, como veremos na pgina seguinte.

335

Web Panels
...filtrando
Exemplo: Mostrar os clientes que cumprem condies:

Por default de entrada

Observe como na janela de propriedade do control Grid, aparece un de nome Conditions. Clicando no combo abre um editor para especificar as condies booleanas que devem cumprir os registros para ser carregados como linhas do grid. por essa razo que foi agregado as variveis &CustomerName e &CountryName no form da web panel, para que o usurio possa ingressar ali valores que operem como filtros sobre os dados a mostrar. Em nosso caso, estabelecemos filtros com o operador like. As variveis na parte plana do form de web panels so por default de entrada. Depois veremos que se estiverem em grids so por default de sada. Observe que as condies (separadas com ;) equivalem as que apareciam nas clusulas where de um for each (ou grupo repetitivo de data provider). Da mesma maneira, por questes de otimizao, pode determinar, igual se fazia com um for each, critrio de ordenao da tabela percorrida, como se mostra acima no exemplo. Nota: Assim mesmo, da mesma forma que num procedimento, no somente podem estabelecer condies locais ao grid (for each), mas tambm gerais, mediante o selector Conditions. Isto tem sentido quando tiver mais de um grid (for each), para no ter que repetir cada vez a mesma condio.

336

Client

Web Panels
...com refresh automtico
Re fre sh

Server

Eventos do sistema: Refresh e Load...

Load Load ...


DB

A propriedade Automatic Refresh que se encontra a nvel da Web Panel pode ter os seguintes valores: When variables in conditions change (valor por default): depois de chamar automaticamente o refresh, se dispara o evento Load carregando o grid segundo os novos valores das variveis. No Dependendo do tipo de dados do filtro, e do control web utilizado para filtrar, a condio ser aplicada quando se est digitando ou ao abandonar o campo. No caso de filtros em controles edit, para tipo de dados Character, so aplicados quando o usurio vai digitando. Para tipo de dados Date, DateTime e Numeric, as condies so avaliadas ao sair do campo. No caso de filtros combo boxes ou dynamic combos, as condies so avaliadas quando se abandona o campo. Para Check boxes e Radio buttons, as condies so avaliadas quando o valor alterado. Execuo: o que acontece no cliente e no servidor ao ter a propriedade por default e um grid com tabela base? 1 execuo (variveis vazias): For each CUSTOMER guardar em memria CustomerName acessar o registro de COUNTRY relacionado guardar em memria CountryName carregar (load) linha no grid com ambos valores N-sima execuo (altera o valor da varivel das conditions): Automaticamente no browser do cliente se detecta a mudana refresh no servidor para voltar a carregar o grid com os registros que cumpram as condies (com os novos valores das variveis) load para cada linha. Concluso: Existem dois eventos do sistema que ocorrem no momento da carga do form (Refresh) e da carga de cada linha do grid (Load). Como veremos, estes eventos pode associar cdigo para que se execute nesses momentos especficos...

337

Web Panels
... programando o evento Load

Agregamos ao grid atributo CustomerStatus e a varivel &select booleana...

Inteno: para aqueles clientes com estado On Hold, para poder ativ-los marcando check box e pressionando boto Activate. Antes queremos: 1. Somente habilitar check box para os On Hold:
Quando se carrega cada linha do grid, se o valor do atributo CustomerStatus da tabela CUSTOMER a ser carregado On Hold, habilitar check box...

Ampliaremos a funcionalidade de nossa web panel, permitindo ver o estado de cada cliente, e para aqueles que estiverem On Hold, brindando a possibilidade de os passar para o estado Active. Para fazer isto, agregaremos ao grid o atributo CustomerStatus que mostra o estado, e uma varivel booleana &Select, que permitir ao usurio selecionar aqueles clientes que deseja ativar. Alm disso um boto para efetivamente ativar todos os clientes marcados. Mas isto o faremos num segundo momento. Observe que se o tipo de dados da varivel &select booleano, por default aparece no grid como um check box. Para assegurar que o usurio somente tente ativar clientes On Hold, desejamos que somente aparea habilitado este check box quando corresponde... para ele necessitaremos programar a carga de cada linha, isto , o evento Load...

338

Web Panels
... programando o evento Load

Customer tabela
CustomerId 1 2 3 4 ... CustomerName Susan Jones Richard Smith Martina Rodrguez Hugo Romero ... CustomerStatus A O C A ... ... ... ... ... ...

Se dispara uma vez para cada registro da tabela base a ser carregado... (tendo cdigo programado ou no)

Na seo Events da web panel, programamos o evento Load do grid que vemos acima. No exemplo, customerGrid o nome que demos ao control grid no form. Ao se tratar de uma web panel com um nico grid, tambm poderamos ter programado o evento Load: Event Load if CustomerStatus = Status.OnHold &select.Enabled = 1 else &select.Enabled = 0 endif endevent Isto , no caso de uma web panel com um nico grid, no necessrio qualificar o evento com o nome do grid. Igualmente recomendamos fazer, antecipando a possibilidade futura de agregar outro grid no form da web panel. O evento Load disparado para cada linha que vai carregar no grid, encontrando este comando ou no. O que fazemos no exemplo aproveitar este momento imediatamente anterior a carga, para efetuar uma ao. E esse o cdigo que inclumos no evento. Agora sim, estamos em condies de implementar a activate, para isso precisamos associar ao boto um evento, que poder ser o evento Enter ou um de usurio...

339

Web Panels
... evento Enter
2. Ativar os clientes On Hold selecionados:

Comando For each line... Percorre linhas de um grid

For each line in customerGrid if &select &customer.Load( CustomerId ) &customer.CustomerStatus = Status.Active &customer.Save() Commit endif endfor

&customer

BC Customer

No exemplo, quando o usurio pressiona o boto Confirm, necessitamos percorrer todas as linhas do grid, e para cada uma delas, se o usurio marcou a varivel boleana &Select f (check box), devemos alterar o estado do cliente correspondetne, de On Hold a Active. Ao inserir o boto no form da web panel, e editar suas propriedades, por default se pode observar que o botao esta associado ao evento Enter (ver propiedad OnClickEvent). El Enter ser un evento del sistema, que se ejecuta tanto cuando el usuario hace clic sobre el control asociado, como cuando presiona la tecla Enter. En este ejemplo veremos a la vez: Posibilidad de definir eventos de usuario y asocirselos a controles o de utilizar el evento Enter del sistema. Comando For each line, para recorrer las lneas ya cargadas en un grid. Variables en un grid pasan de ser Read only (de salida) por defecto, a ser de entrada, cuando se utiliza comando for each line en ese grid (tambin cuando se programan eventos OnClickEvent, Click, etc., sobre alguna columna del grid). Obsrvese que el comando For each line slo tiene en comn con el comando For each estudiado antes, el hecho de representar una estructura repetitiva. La diferencia ms importante: mientras el for each recorre registros de una tabla (base) de la base de datos, el for each line recorre las lneas de un grid. En nuestro ejemplo hemos definido una variable &customer, Business Component Customer, mediante la cul cambiaremos a estado Active todas las lneas del grid marcadas por el usuario. Para ello recorremos el grid con el comando for each line.

340

Web Panels
... o evento de usurio
2. Ativar os clientes On Hold selecionados:

For each line in customerGrid if &select &customer.Load( CustomerId ) &customer.CustomerStatus = Status.Active &customer.Save() Commit endif endfor

Outra possibilidade, ao invs de utilizar o evento do sistema Enter, definir um evento de usurio. Isso realizado seguindo os passos que esto acima. Como podemos ver, a maioria dos controles presentes em um form tem a propriedade OnClickEvent associada. Essa propriedade permite especificar um evento a ser disparado quando o usurio faz clique sobre o controle. Poder ser um evento do sistema (Refresh, Enter) ou um evento definido pelo usurio.

341

Web Panels
... Variveis de grid
Por default todas as variveis de um grid so Read-Only For each line [in grid] ou qualquer evento sobre as linhas ou colunas (OnClickEvent, Click, DblClick, IsValid, etc): modifica o valor por default e todas as variveis do grid passam a ser de entrada. Para ter algumas de sada: Propriedade: Read Only

A parte fixa da web panel por default de entrada, como j vimos anteriormente para as variveis utilizadas para filtrar os clientes (customers) mostrados no grid. Como mostrar dados no grid Por default todo atributo e varivel que est dentro de um grid se mostra em execuo como texto, porque unicamente de leitura e por consequencia no pode ser alterado. Como aceitar dados em um grid possvel aceitar dados nas variveis de um grid dependendo da programao dos eventos existentes no objeto: 1. Se dentro de um evento da web panel ter o comando For each line, todas as variveis que esto dentro do grid passam a ser de entrada. possvel indicar neste caso quais so as variveis que no podem ser modificadas atravs da propriedade ReadOnly. 2. Se dentro da fila tem algum controle com um evento click, dblClick, etc.. associado (ou evento de usurio especificado na propriedade OnClickEvent), acontecer o mesmo.

342

Web Panels
...ocultar atributos do grid e permitir seleo de uma linha

Event Select customer CustomerView.Call( CustomerId ) endevent

Continuamos ampliando nosso exemplo; agora queremos que o usurio possa selecionar uma linha do grid (um cliente) e pressionando boto Select customer para chamar a web panel que havamos implementado anteriormente. Neste exemplo vemos duas funcionalidades: A necessidade de colocar uma coluna no grid oculta (no visvel). Permitir que o usurio selecione uma linha do grid para fazer algo com ela. Por que colocar a coluna correspondente a CustomerId e ocult-la, ao invs de no agregar o atributo? Faa a seguinte reflexo: o atributo CustomerId enviado por parmetro ao executar o evento Select customer, de onde extrado? Da base de dados? No, o que est carregado no grid. Mais especificamente, para cada grid existir um arquivo temporrio que contem a quantidade de colunas que o grid possuir, visveis e ocultas. Quando o usurio seleciona no grid a segunda linha, e pressiona o boto Select customer, est posicionado nesse arquivo temporrio, correspondente a essa linha (e nunca na base de dados!). por esta razo que se no colocarmos nenhuma coluna correspondente a CustomerId no grid, no estaramos passando valor algum a CustomerView. Para que o usurio possa selecionar uma linha do grid, suficiente prender a propriedade AllowSelection do grid.

343

Web Panels
Determinao tabela base 1. Atributos soltos no form + 2. Grid: atributos das colunas
(visveis+invisveis) (fora do grid)

propriedade Order propriedade Conditions propriedade Data Selector


Event Activate For each line in customerGrid if &select &customer.Load( CustomerId ) &customer.CustomerStatus = Status.Active &customer.Save() Commit endif endfor endevent Event Select customer CustomerView.Call( CustomerId ) endevent Event customerGrid.Load if CustomerStatus = Status.OnHold &select.Enabled = 1 else &select.Enabled = 0 endif endevent

+ 3. Eventos: atributos soltos


(fora de for eachs)

Como GeneXus determina uma tabela base para percorrer automaticamente para carregar o grid da web panel? Se existir algum atributo em pelo menos um dos 3 lugares mencionados, GeneXus poder encontrar a tabela base. Para determinar a tabela base, ele extrai os atributos encontrados ali (parte fixa do Form, no Grid, tanto nas colunas como nas propriedades Order, Conditions ou using Data Selector, e nos eventos programa programados no selector de Eventos, somente os atributos que estejam soltos dentro do evento, isto , fora de um comando for each de acesso a base de dados), e determina a mnima tabela estendida que os contenha. A tabela base dessa estendida, ser a percorrida automaticamente e carregada com o Load. Observe que somente programamos o evento Load para tomar a deciso para cada lnea que vai ser carregada no grid, que habilitar ou no para a mesma varivel &select que permitir ao usurio marcar o check box. Importante: A forma de determinao da tabela base de um grid depender se existir outro grid na web panel ou se o nico. O resumo apresentado aqui corresponde a um nico grid. Neste caso se diz que a prpria Web panel tem tabela base. a do grid. Quando existir mais de um grid na web panel, isto no vai ter sentido, e cada grid passar a ter cada grid passar a ter ou no tabela base. Veremos a forma de determinao das tabelas bases nesse caso, quando tratemos o caso de mltiplos grids em uma web panel.

344

Web Panels
Para exibir mltiplos registros: Grid (sem tabela base)...

Mostrar o total de faturas por dia (podendo ter um filtro entre as datas informadas)
Cada lnha do grid no corresponde a cada registro da tabela INVOICE, o que faz agrupar todas as faturas de uma data e totalizar se fosse um pdf, seria implementado.
For each order InvoiceDate where ... &InvoiceDate = InvoiceDate &Amount = 0 for each defined by InvoiceDate &Amount += InvoiceAmount endfor print InvoiceInfo endfor

Estamos apresentando aqui outro exemplo, para que possamos observar um caso que surge a necessidade natural de implementar um grid sem tabela base. O caso de implementao natural de um grid com tabela base, quando deseja que seja carregado para cada registro de uma tabela, uma linha do grid (1 registro 1 linha). No caso que se quer carregar uma linha do grid como produto a ser lido de vrios registros da base de dados (N registros 1 linha), como produtos de clculos, etc., mais natural implementar o grid sem tabela base. O caso do exemplo: no queremos carregar para cada fatura uma linha, mas sim queremos agrupar as faturas por data, e para cada grupo, carregar uma linha que some seus valores. Estamos falando de um controle de corte. Se tivssemos que implementar uma listagem PDF ao invs de uma web panel, saberamos como programar (como o fazemos acima) . Vejamos como implementar com uma web panel...

345

Web Panels
anteriores) no tem tabela base

Para exibir mltiplos registros: Grid (sem tabela base)... No tem atributos (em nenhum dos 3 pontos

GeneXus no pode inferir carga automtica: tem que programar evento Load ocorre somente 1vez

Ordem de carga de uma linha no grid (as variveis assumem


valores nesse momento)

O objetivo do comando LOAD agregar um linha num grid. necessrio quando o grid no tem tabela base, visto que nesse caso no ser agregado nenhuma linha de forma automtica. O evento Load vai ocorrer uma vez, e o grid retornar vazio caso no seja programado. Portanto neste caso imprescindvel que seja programado, de acordo com a lgica correspondente. Uma vez que for atribudo a cada varivel seu valor, e se deseja agredar uma linha ao grid, o comando LOAD dever ser programado. O comando LOAD somente pode ser especificado dentro do evento Load do grid de uma web panel. Observe que neste caso a implementao fica por conta do analista. Frente ao caso do grid com tabela base, neste GeneXus realiza menos inferncias.

346

Web Panels
Para exibir mltiplos registros: Grid (sem tabela base)...

Refresh no automtico!

Agregamos boto associado ao evento Enter ou de usurio, sem cdigo, ou diretamente ao Refresh.

No caso de um grid sem tabela base, os filtros dos dados so programados dentro do cdigo implementado para carga (o do Load). Aqui no tem o refresh automtico. Isto , quando o usurio modifica os valores das variveis que interveem nos filtros, GeneXus no sabe que tem que voltar a carregar o grid. Para isso dever, por exemplo, agregar um boto associado ao evento Enter, ou a um evento de usurio, sem cdigo, devido ao fato que somente precisamos dele para que um Refresh seja realizado, ou seja, para que o servidor volte a carregar a web panel. Sobre os eventos disponveis e a ordem em que so disparados, entraremos em seguida.

347

Web Panels
Programao dirigida por Eventos
Evento Start Evento Refresh Evento Load Evento Enter Eventos de Usurio Evento TrackContext (no curso no ser visto)

Associados a controles do form (dependendo do tipo de controle): Evento Click, DblClick, RightClick, IsValid, Drag, Drop, etc.

Nota:
Refresh, Enter, de Usurio: Atravs da propriedade OnClickEvent podem Estar associados a controles do form

Em toda Web panel existem eventos do sistema que podem ser programados. Alguns ocorrem sempre, em cada execuo da web panel (como o Start, Refresh, Load), outros se forem declarados e o usurios realiza as aes necessrias para provoc-los (Enter, definidos pelo usurio, TrackContext). Assim mesmo, quase todos os controles que aparecem no form brindam a possibilidade de disparar um evento quanto o usurio faz clic com o mouse (os hiper-links aparecem em execuo); de duas maneiras diferentes: 1. Editando as propriedades do controle (F4), e definindo um evento de usurio na propriedade OnClickEvent, ou associando o evento Enter ou o Refresh. 2. Dando um nome ao controle e na seo de Eventos programando: Event nomeControl.click Endevent Com esta ltima alternativa no teremos que definir um evento de usurio, mas sim teremos que programar o evento click do controle. O mesmo ocorre com os eventos DblClick, RightClick, IsValid... (quando fizer duplo clique, boto direito, etc.). Sobre os eventos associados as aes sobre os controles (click, dblclick, drag, drop, etc.) no veremos no curso presente. Em nosso wiki tem informao detalhada, assim como no Help de GeneXus. Sobre o evento TrackContext somente mencionaremos que possvel detectar mudanas no valor de um dado controle (grid, varivel, etc.) e nesse caso disparar este evento baseado ao valor modificado, tomar una ao.

348

Web Panels
Evento Start
um evento do sistema, que ocorre automaticamente sempre que se faz Get ou Post e o primeiro evento que se executa. Os valores de atributos no so conhecidos, exceto os recebido por parmetro. Isto se deve que ainda no foi efetuado a consulta. Exemplo: se pode utilizar para que um controle do form no aparea visvel, para carregar um bitmap, para associar um Link a outro controle, etc.: Event Start &var.Visible =0 &Update = LoadBitmap("images/edit.gif") newControl.Link = Tcustomer.link() endevent

Web Panels
Evento Refresh Evento Load
Eventos do sistema, codificveis, associados a carga da Web Panel. Primeiro executado o Refresh e depois sempre o Load. Se o grid tem tabela base
Load executado N vezes: Um para cada linha

Se o grid no tem tabla base


Load executado somente 1 vez: Dentro do evento a carga da linha do grid ter que ser programada, Para carregar, comando Load.

Quando a web panel com tabela base, ao produzir-se o evento Refresh se acessa a base de dados, a essa tabela base (associada a web panel), e se percorre carregando os registros que cumpram as condies (conditions do grid e gerais). Vai ocorrer nesse processo um evento Load para cada registro em que estiver posicionado, imediatamente antes de carreg-lo. Isto nos permite realizar alguma operao que requeira desse registro ( e de sua estendida), antes de efetivamente carreg-lo no grid. Imediatamente depois de executado o cdigo associado ao evento Load, ser carregado a linha do grid e o ponteiro passado ao seguinte registro da tabela base, para realizar o mesmo (evento Load, carga da linha). Este processo se repetir at carregar todas as linhas do grid. Se uma web panel sem tabela base, GeneXus no pode determinar automaticamente uma tabela da base de dados a percorrer para mostrar a informao que se apresenta no form. Neste caso no form somente aparecem variveis (e no atributos) e tambm vo ocorrer os eventos Refresh e Load, somente que o evento Load executado uma nica vez, visto que no estar posicionado em nenhum registro de nenhuma tabela. Dentro desse evento a carga ter que ser codificada, que pode ser que precise acessar a base de dados (ex: comando for each) o no (vamos supor que seq queira carregar o grid com informao obtida ao percorrer um SDT collection, efetuar alguma transformao sobre seus itens ... ou carregar linhas no grid produto de clculos). O controle da carga do grid, fica aqu nas mos do analista, utilizando o comando Load. Este comando somente vlido dentro do evento com o mesmo nome. Note como no caso do grid com tabela base, este comando no necessrio.

350

Web Panels
Refresh automtico
Vlido somente para Grid com tabela base

Para Grid sem tabela base necessariamente tem que associar evento

A propriedade Automatic Refresh que se encontra a nvel da Web Panel pode tomar os seguintes valores: When variveis in conditions change (valor por default): automaticamente provocam o refresh, se dispara o evento Load carregando-se o grid segundo os novos valores das variveis. No: para que o contedo do grid se renove depois de alterar os filtros, o usurio deve realizar uma ao: Se o grid com tabela base: As alteraes nas variveis dos filtros se detectam automaticamente. Ao pressionar a tecla Enter, se dispara o Refresh da pgina (no o cdigo do evento Enter, ainda que esteja programado). Ao fazer click num boto ou numa imagem associados a um evento de usurio, imediatamente depois de alterar o valor de uma varivel das conditions do grid, se executa este evento e atualiza imediatamente depois a pgina. Se o evento for o Enter, este evento NO se executa. Se o grid sem tabela base: As alteraes nas variveis dos filtros NO se detectam automaticamente O usurio deve fazer click no boto ou na imagem associados a um evento Refresh ou a um evento de usurio que chame um Refresh.

351

Web Panels
Eventos Ordem de disparo
GET: Quando a Web Panel aberta.
Start Refresh Load

POST: As outras execues da web panel.


Start Leitura de variveis na tela Evento enter ou de usurio (click, dblclick, etc., que produziu post) Refresh Load

Os eventos disparados e sua ordem depende se a web panel est sendo aberta (Get) ou se j estava aberta e est efetuando uma ao posterior a um boto (Post). Acima mostramos com exemplos o caso geral. 1a. vez: Start + Refresh + Load N-sima vez: Start + Leitura de variveis da tela + Evento que produziu o Post + Refresh + Load. Este o caso geral... existe uma exceo...

352

Web Panels
Eventos Ordem de disparo Exceo:
Alguns eventos de usurio devem ser executado no Server mas outros no so executados somente no Cliente (todos os outros eventos no precisam ser executados no server: Start, Refesh e Load). Evitando roundtrips desnecessrios ao servidor, e reduzindo a quantidade de dados que viajam de um lado a outro. Exemplo: um evento que altera o estado de um controle, no precisa ser executado no server.
Event UserEvent &CustomerId.Visible = 0 endevent

GeneXus tem inteligncia para determinar. Para o programador transparente

Internamente GeneXus determina as entradas e sadas de cada evento. Se em suas entradas, se requerem de aes executas no Server, ento o evento se executar no Server. Por exemplo, se entre as entradas de um evento de usurio X, se encontra alguma das sadas do evento Start (do server), ento o evento de usurio se executar no Server. Se o cdigo do evento no requer que seja executado no servidor, ento por performance, ser executado no cliente, como cdigo javascript. De todas as maneiras o analista GeneXus no deve se preocupar com estes assuntos, visto que em todo caso ser o GeneXus que ter a inteligncia de resolver onde vai executar o evento.

353

Web Panels
Mltiplos grids Grids paralelos

filtrar faturas por dia do cliente

Aqui apresentaremos um exemplo que rene os dois casos que viemos estudando: a web panel mostrada em execuo tem dois grids paralelos: um que mostra informao dos clientes do sistema, e outro que mostra faturas, totalizadas por dia. No nosso caso, queremos alm disso relacionar os dados, de tal maneira que quando o usurio seleciona um cliente, sejam mostradas somente as faturas desse cliente. Incluso ao estabelecer filtros de datas, tambm queremos que v para o cliente selecionado (e no para todos os clientes). Quando uma web panel contem mais de um grid em seu form, GeneXus no determina uma nica tabela base associada para web panel, mas sim uma tabela base associada a cada grid. Atributos que participam na determinao da tabela base de cada grid: Os includos no grid (so levados em considerao os atributos visveis como os no visveis, ocultos/hidden) Os referenciados na Order e Conditions locais do grid A diferena do que acontecia para uma web panel com somente um grid, no caso de mltiplos grids os atributos da parte fixa da web panel no participam na determinao da tabela base de nenhum deles, mas devero pertencer a tabela estendida de algum (para que seja possvel inferir seus valores).Caso isso no seja respeitado, ao especificar a web panel, se mostra na listagem de navegao resultante, um warning advertindo desta situao. Os atributos utilizados nos eventos da web panel tampouco participam na determinao da tabela base de nenhum dos grids. Os atributos que se inclui nos eventos fora de comandos for each, devero pertencer a tabela estendida de algum dos grids (da mesma forma como da parte fixa).

354

Web Panels
Mltiplos grids Grids paralelos
Event Start &CustomerId.Visible = 0 endevent

Event Select customer &CustomerId = CustomerId endevent

GeneXus no relaciona as cargas


Event inoicesGrid.Load for each order InvoiceDate where InvoiceDate >= &startDate when... where InvoiceDate <= &endDate when... where CustomerId = &customerId when not &customerId.IsEmpty() ... endevent

Esta web panel poderia ter sido implementada de diferentes formas e obtendo o mesmo resultado na execuo. Acima podemos ver a implementao mais natural: o primeiro grid tem tabela base e o segundo no tem. Mas poderia ter sido implementada de forma contrria, com variveis no primeiro grid e tendo que realizar a carga dos clientes a mo no Load, e atributos no segundo grid, e algumas coisas a mais para obter o controle de corte, sendo um grid com tabela base. Ou qualquer combinao (ambos grids com tabela base, ou nenhum com tabela base). O importante , uma vez escolhida a implementao mais natural ao caso, realiz-la corretamente. Em qualquer dos casos, ainda que a informao a ser carregada em mais de um grid se encontre relacionada na base de dados, GeneXus no assume nenhuma relao entre os dados na hora de carregar um grid e o outro. anlogo o caso de um par de for eachs paralelos no Source de um procedimento. Acima podemos ver a web panel que temos o grid com os grids, agregamos a parte de visualizao de faturas por data que implementamos na web panel. Mas no basta simplesmente unir as duas web panels... para poder relacionar as cargas dos grids, a lgica deve ser agregada. Em nosso caso desejamos que uma vez que selecionarmos um cliente do primeiro grid, certa lgica precisa ser agregada. Em nosso caso desejamos que uma vez um cliente for selecionado no primeiro grid, as faturas carregadas no segundo grid no sejam de todos os clientes, mas somente do selecionado. Para isso devemos ter duas coisas: agregar uma varivel &CustomerId para armazenar o id do cliente selecionado ao pressionar Select customer, e depois agregar um filtro pelo valor dessa varivel quando se carrega o grid de Invoices. Assim mesmo precisa obrigatoriamente colocar essa varivel no form para que tudo funcione corretamente ... como esperamos... e na anlise abaixo encontraremos a razo.

355

Web Panels
Mltiplos grids Grids paralelos 1. execuo
Start Refresh customerGrid.Refresh customerGrid.Load customerGrid.Load .... oculta &customerId

invoicesGrid.Refresh invoicesGrid.Load

Vamos analisar o que acontece quando a web panel executada pela primeira vez. Primeiro o evento Start executado, em nosso caso a varivel &CustomerId ocultada. Podemos ver na imagem, que um evento Refresh genrico produzido, depois sero produzidos as cargas de todos e cada um dos grids encontrados na web panel, da esquerda para a direita de cima para baixo. Um evento Refresh prprio ocorre e o evento Load (se possuir tabela base so N vezes e se no tiver tabela base somente 1 vez). Observe que nosso caso, o grid de cliente tem condies para serem carregadas, pelas variveis de filtro &customerName e &countryName, no so aplicadas se estiverem vazias (visto que ambas clusulas condicionais tem when not &var.IsEmpty()) O segundo grid sem tabela base, mas como j vimos, o evento Load era executado um for each com clusulas where, sero carregadas somente aquelas linhas que as condies so cumpridas. So trs: where InvoiceDate >= &startDate when not &startDate.IsEmpty() where InvoiceDate <= &endDate when not &endDate.IsEmpty() where CustomerId = &customerId when not &customerId.IsEmpty() Observe que nesta primeira execuo &customerId est vazio, o filtro no aplicado e todas as faturas do dia carregada, de todos os clientes.

356

Web Panels
Mltiplos grids Grids paralelos 2. execuo Selecionar um cliente:
Start oculta &customerId Leitura das variveis na tela Evento que produziu o post
Event Select customer &CustomerId = CustomerId endevent

Refresh customerGrid.Refresh customerGrid.Load customerGrid.Load .... invoicesGrid.Refresh invoicesGrid.Load

O usurio seleciona o cliente do grid o cliente correspondente da linha e pressiona o boto Select customer. Uma ao detectada e ocorre um post ao servidor, quem executa o Start (ocultando a varivel), depois as variveis da tela so lidas (&customerId no momento est vazia, so consideradas no somente as variveis da tela, as que so definidas, mas tambm a informao completa da linha selecionada pelo usurio com o mouse, entre ela, o valor de CustomerId, coluna do grid), depois o cdigo do evento que produziu o post executado, no nosso caso, Select customer. Aqui a varivel &customerId toma o valor do CustomerId da linha escolhida. Depois ocorre o evento Refresh geral que dispara o Refresh e Load de cada grid. Portanto, cada grid executado executando as conditions. O primeiro se carregado como antes, porque nenhuma de suas conditions variou. O segundo, agora se tiver um valor para &customerId, somente ser mostrado as faturas do cliente. Voc poderia se perguntar porque precise colocar a varivel oculta no form. Simplesmente porque no se pode usar como varivel dentro do programa, se no estiver no form e torn-la invisvel. Todavia com esta segunda execuo no podemos responder a pergunta. De fato, se analisarmos, pode ser visto facilmente que teramos o mesmo comportamento se somente fosse atribudo valor a varivel no Select Customer sem coloc-la no form. Vamos ver o motivo com a execuo seguinte....

357

Web Panels
Mltiplos grids Grids paralelos 3. execuo Filtrar as faturas para o cliente selecionado
Start Leitura das variveis na tela
&customerId invisible

Evento que produziu o post (vazio) Refresh customerGrid.Refresh customerGrid.Load customerGrid.Load .... invoicesGrid.Refresh invoicesGrid.Load

Agora o usurio j selecionou o segundo cliente, e o que deseja fazer filtrar suas faturas por data (no quer visualizar todas). Para isso especifica os filtros de data, e pressiona o boto Search, que produzir um post no servidor. Ento o cdigo do Start executado, depois so lidas as variveis da tela: aqui est o motivo de ter colocado &customerId no form. O valor de &customerId lido, permanecendo at que o usurio no selecione outro cliente do grid e pressionar o boto Select customer... esta varivel presente no form, a forma de manter a memria em execues. Lembre que cada vez que se faz um post ao servidor, uma nova execuo da web panel, j que as variveis comeam novamente vazias. Por isso que o segundo passo: Leitura de variveis da tela fundamental. Agora sim, seguindo o exemplo, as variveis da tela so lidas &customerId invisvel (visible=0), junto com as variveis &startDate e &endDate. E depois, como sempre, a carga executada (Refresh genrico + Refresh e Load de cada grid). Alterando as condies do for each que carrega o segundo grid, agora aparece somente as faturas do segundo cliente, entre as datas estipuladas pelo usurio. Se agora o usurio quiser alterar o cliente, para ver suas faturas, ser feito a seleo no grid de clientes e ao pressionar Select Customer, o processo comea novamente como vimos na 2da. execuo. E como fazemos para voltar a trabalhar com as faturas de todos os clientes e no de um? O que acontece se o usurio no selecionar nenhum cliente do grid com o mouse e pressionar Select Customer. O valor da varivel &CustomerId fica vazio, pois CustomerId no vai ter valor. Por este motivo, o boto Select Customer poderamos chamar Select/Unselect.

358

Web Panels
Grid - Propriedades
Paginao automtica: Se a propriedade Rows possuir um valor diferente de 0 GeneXus realiza a paginao automtica

Insere os botes de paginao de forma automtica

Os botes inseridos dependem da quantidade de registros e da quantidade de linhas do grid.

359

Web Panels
Grid Ordem automtica das colunas
No necessrio programar nenhum cdigo adicional para ordenar as colunas: clique sobre o ttulo da coluna.

Esta funcionalidade vlida para grids em transaes e web panels.

A pgina do grid carregado ordenado, mas no compete com o Order programado no grid.

360

Web Panels
Tipos de grids
Grid stardand: Dados repetitivos no formato fixo (filas e colunas)

Grid Free Style: Dados repetitivos em formato livre. Tabela com registros repetitivos As colunas no possuem ttulos Permite ter mais de um tipo de controle numa mesma clula

Dois tipos de grid: Grid padro: que vimos at agora, em Transaes e Web Panels Grid Free Style Estes grids, agregam potncia ao desenho de aplicaes web, permitindo ao desenvolvedor maior liberdade na hora do desenho. O grid Free Style permite ao usurio definir o formato dos dados a serem mostrados de uma forma menos estruturada que o grid padro. O grid Freestyle basicamente uma tabela que podem inserir os atributos/variveis, text blocks, imagens, botes, web components, embedded pages, grids freestyle e/ou grids que sero mostrados posteriormente na tela. Neste caso para poder visualizar as propriedades tem que selecionar a tabela onde se encontram os atributos/variveis. No exemplo apresentado acima queremos mostrar alguma informao dos pases. O atributo CountryFlag foi includo na transao Country para armazenar a foto da bandeira de cada pas ( um atributo de tipo Blob). Mas no queremos mostrar a informao como o faramos em um grid padro, cada elemento de informao em uma coluna diferente do grid. Aqui queremos mostrar a foto e abaixo o identificador e nome do pas. O comportamento das variveis dentro de um grid Free Style anlogo ao apresentado dentro de um grid padro, portanto tambm so de ingresso se existe um For each line ou For each line in <grid> dentro de algum evento, ou se associa um evento a qualquer controle da fila. Novamente este comportamento pode ser modificado, agregando a regra noaccept ou alterando a propriedade Read Only.

361

Web Panels
Mltiplos grids Grids aninhados
Exemplo: Mostrar todos os pases com seus respectivos clientes, e quantidade de clientes.
Trn Country

Grid1: Free Style.

{ CountryId* CountryName CountryFlag

Grid2: standard

Trn Customer Tabela base Grid1: COUNTRY Tabela base Grid2: CUSTOMER
{ CustomerId* CustomerName CustomerAddress CountryId CountryName }

Este caso de grids aninhados igual o de for each aninhados em um procedimento: ou seja, aqui as cargas esto relacionadas, e no Grid2 carregado todos os clientes pertencentes ao pas carregado no Grid1. A ordem de execuo dos eventos estar aninhada: Refresh (genrico) Grid1.Refresh Grid1.Load carga de um pas Grid2.Refresh Grid2.Load carga de cliente do pas Grid2.Load carga de cliente do pas Grid2.Load carga de cliente do pas Grid1.Load carga do pas seguinte Grid2.Refresh Grid2.Load carga de cliente do pas Grid2.Load carga de cliente do pas Grid2.Load carga de cliente do pas .....

362

Web Panels
Grid Free Style
(Exemplo: Continuao)

Propriedades Grid Free Style

363

Web Panels
Tipos
Tipos de Web panels Component Web Page Master Page

Propriedade Type

Os objetos web podem ser definidos com trs tipos diferentes, configurvel na propriedade Type do objeto. Para uma web panel poder ter um dos valores: Component: (transao ou web panel, que a partir daqui poder ser includo em outro web object) Web Page (isto , o objeto ser uma transao ou web panel tal como temos trabalhado at o momento) Master Page Em seguida introduziremos a Web Panel tipo: Component, Master Page e sua utilizao.

364

Web Panel
Web Component
J programamos uma web panel CustomerView que mostrava os dados do cliente vamos reutilizar

Um component uma web panel que executada dentro de outra.

365

Web Panels
Web Component

366

Web Panels
Web Components
Exemplo: Criar um novo tab na instncia do Pattern Work With Countries, mostrando os clientes de cada pas.

1) Definir a Web Panel CustomersPerCountry como


Component

2) Definir o novo tab CustomersPerCountry na


instncia do Pattern Work With Countries

A Web Panel CustomersPerCountry recebe CountryId como parmetro.

367

Web Panels
Web Components

368

Web Panels
Master Pages
As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em um objeto e reutiliz-lo em qualquer objeto, isso sem termos que programar.

Controle onde as pginas sero carregadas

Criadas automaticamente com a KB

Ter um look&feel consistente hoje em dia um dever de toda aplicao Web. Criar e manter cada pgina de uma aplicao Web assegurando a consistncia com o resto do site leva grande tempo de programao. Ao criar uma base de conhecimento GeneXus X criar tambm dois objetos de tipo Mastet Page: ApplMasterPage: Para a aplicao PromptMasterPage: Para os prompts Uma web panel, AppMasterPager categorizado como Master Page ser criada com tudo, ou seja, o Layout e comportamento comum a todas as pginas do site, e no mesmo se deixa um espao para carregar a pgina correspondente (o contedo varivel do site). Corresponde ao controle especial ContentPlaceholder. As pginas web que implementam o contedo varivel, se implementam como Web Panels ou Web Transactions comuns e correntes ( do tipo Web Page, ver pgina anterior), e se associam a Master Page, de maneira que cada vez que se executem, so carregadas com esse contexto. Agora faa o seguinte, abra qualquer objeto GeneXus com form (transao ou web panel) criada na KB, e veja o valor da propriedade Master Page. As Master Pages fornecem uma forma de centralizar o layout e o comportamento comum em somente um objeto e reutiliz-lo em todo outro objeto sem ter que programar. Isto significa que a modificao de alguma parte do layout ou do comportamento comum to fcil como modific-la num nico objeto e pronto!. Em uma mesma base de conhecimento podem ser definidas tantas Master Pages quanto desejar.

369

GXFLOW

GXFLOW
Breve introduo terica

O que um workflow?
Um conjunto de tarefas ordenadas em determinada sequencia, que define um processo no qual as situaes so resolvidas manualmente ou automaticamente.

Exemplo

No exemplo se est mostrando um workflow de uma empresa que vende mercadoria por atacado. Podem ser observados claramente as tarefas consecutivas seguintes para fazer o processo de venda.

GXFLOW
Breve introduo terica

Por que recomendamos incluir tecnologia de workflow dentro de nossas solues GX? Porque todo sistema que quisermos construir para uma empresa, 99% ter processos de negcios para modelar, gerenciar e dar seguimento - conjuntos de tarefas ordenadas - responsveis - cronogramas, alertas, tempos mximos ... e gerenciar e dar seguimento: Gxflow faz

GXFLOW
Breve introduo terica

Gxflow uma ferramenta integrada a GeneXus que nos permite:


Modelar os processos da empresa Definir segurana Definir calendrios, alertas, deadlines Etapas de integradas Modelado e Desenvolvimento da aplicao operacional

Etapa de execuo que brinda pro-atividade Auditoria Clareza para capacitar membros novos e para mostrar aos clientes

Gxflow uma ferramenta integrada ao GeneXus que nos permite e brinda: 1) Modelar os processos da empresa: Diagramar os processos nos da vantagem de poder mudar a ordem de suas tarefas, tirar ou incluir tarefas novas e/ou mudar as condies de sua execuo, sem tocar o cdigo dos mesmos objetos. 2) Definir segurana: Se definem regras e quais podem executar quais tarefas. Isto evita ter que incluir cdigo para a segurana nos objetos. 3) Definir calendrios, alertas, deadlines 4) Etapas de Modelado e Desenvolvimento de aplicao operacional integradas: Em GeneXus X muito prtico e simples relacionar os objetos GeneXus desenvolvidos que implementam a aplicao operacional com os diagramas que modelam os processos. Veremos como se arrastam os objetos aos diagramas e a prtica resultante em ter modelado os processos integrados com o desenvolvimento da aplicao operacional. 5) Etapa de execuo que brinda proatividade: Cada usurio ao executar, de primeira ver as tarefas que precisam ser feitas (no ter que buscar na aplicao o trabalho pendente). 6) Auditoria: GXflow permite ver o que est em cada usurio, quanto tempo leva cada tarefa, etc. 7) Melhor entendimento: para um membro novo da equipe de trabalho, e tambm para fazer mostras aos clientes.

GXFLOW
Breve introduo terica

Passos para trabalhar com GXflow:


Criar objetos GeneXus que descrevem realidade e processos
INTERCALADOS

Criar diagramas de processos de negcios para modelar os processos Associar objetos GeneXus a diagramas de processos de negcios Executar processo

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Como criar um diagrama de processo de negcio? Criando um objeto na KB de tipo Business Process Diagram

Quantos diagramas de processos de negcios definiremos em nossa KB? A quantidade de processos que tenham na empresa

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio passo a passo.. (1)

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio passo a passo.. (2)

TAREFA / ATIVIDADE INTERATIVA

ARRASTANDO ESTES SMBOLOS CONFECCIONADO O DIAGRAMA

TAMBM SE PODE ARRASTAR AO DIAGRAMA TAREfA / ATIVIDADE INTERATIVA A PARTIR FOLDER VIEW

A partir do Folder View se arrasta um objeto transao ou web panel ao diagrama, se estar agregando una tarefa / atividade interativa ao fluxo, e a mesma j ficar com dito objeto associado para a etapa de execuo. Tambm dita tarefa / atividade interativa agregada ao diagrama, ficar automaticamente nominada com o mesmo nome que a transao ou web panel que foi arrastado. Por outro lado se agregar uma tarefa/atividade interativa ao diagrama arrastando o smbolo correspondente a partir do toolbox disponvel para confeccionar diagramas de processos de negcios, depois ser necessrio associar a dita tarefa um objeto transao ou web panel definida na KB. Para isso, simplesmente de ter agregado a tarefa no diagrama e a tendo selecionada, ter que editar suas propriedades (F4 para abrir o dilogo de propriedades) e completar a propriedade Web Application com o objeto que corresponda, assim como a propriedade Name com o nome que se queira dar a tarefa/atividade interativa.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Descrio de smbolos

INCIO DE PROCESSO ATIVIDADE/TAREFA INTERATIVA ATIVIDADE/TAREFA BATCH NESTE PROCESSO QUE SE EST MODELANDO, OUTRO PROCESSO REUTILIZVEL COMO SUBRPROCESSO CONDIO PARA AVALIAR E DEPENDENDO DO RESULTADO, SEGUIR UMA ROTA OU OUTRA VRIAS ROTAS CHEGAM AT ESTE SMBOLO E ASSIM QUE TODAS CHEGUEM A ESTE PONTO, O FLUXO CONTINUA FIM DO PROCESSO

No sero descritos todos os smbolos disponveis na toolbox de workflow, mas sim os smbolos bsicos que no incio devemos conhecer. Smbolo: Condio Quando se est modelando um diagrama de processo e em determinada parte do fluxo de atividades se necessita avaliar uma condio porque dependendo dela ser cumprida ou no, siga com certo fluxo de atividades ou outro, por isso que contamos com o smbolo de condio.

Bastar agregar um smbolo de condio (losango verde) ao diagrama (conectado desde a atividade prvia) e a partir do losango podero sair N rotas (que tero a cor verde tambm). Cada uma destas rotas verdes que partem de um losango de condio, dever ter associada uma condio a ser avaliada (fazendo clique duplo em cada rota verde, um editor aberto para ingressar sua condio associada); e em tempo de execuo do diagrama, como veremos mais adiante, quando se chegue a condio na execuo do processo, dependendo de quais avaliaes for verdadeira continua com a execuo de uma rota e seu fluxo de atividades segue, ou outro. Em breve veremos exemplos de definio de condies (sintaxe e possibilidades).

Smbolo: Batch Activity Permite agregar a um diagrama de processo de negcio, um processo batch (por exemplo um processo macio) que ser executado no servidor. agregado arrastando o smbolo correspondente desde a toolbox, depois ser necessrio associar a dito processo batch um objeto procedimento definido na KB. Para isso, simplesmente depois de ter agregado o smbolo de processo batch no diagrama e tendo selecionado, ter que editar suas propriedades (F4 para abrir o dilogo de propriedades) e completar na propriedade Procedure o nome do procedimento que corresponda. Assim mesmo ter que atribuir um nome em sua propriedade Name. Se por outro lado a partir do Folder View se arrasta um determinado procedimento, estar sendo agregado ao diagrama como processo batch que executar no servidor; e o mesmo j ficar com dito procedimento e nome associado para a etapa de execuo.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio passo a passo.. (3) O diagrama de processo de negcio vai sendo confeccionado, arrastando smbolos de Toolbox e objetos de Folder View .

QUE INFORMAO PODEMOS ENVOLVER NAS CONDIES?

Aqui vemos que temos confeccionado o diagrama de processo que criamos. Temos agregado tarefas interativas e uma condio. Vemos que com um duplo clique nas rotas verdes que partam da condio, se abre o editor de condies para editar cada condio (em caso dela se cumprir uma ou outra se seguir com certo fluxo de atividades ou outro). Em seguida veremos o conceito de Dados Relevantes que fundamental para compreender qual informao podemos envolver nas condies.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Conceito fundamental: Dados Relevantes


O conceito de Dados Relevantes se utiliza para manter uma rea global de dados num processo Este conceito permite administrar a passagem de informao entre as tarefas e que a informao seja conhecida em todo o fluxo As variveis globais podem ser vistas como so no processo

TODO DIAGRAMA DE PROCESSO DE NEGCIO TEM UM TAB PARA A DEFINIO DE SEUS DADOS RELEVANTES

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Conceito fundamental: Dados Relevantes (Cont.) Quando se arrasta a partir do Folder View uma transao a um diagrama de processo, automaticamente se cria um dado relevante com o mesmo nome e mesmo tipo de dado que a chave primria da transao:
NOSSO OBJETO DE TIPO BUSINESS PROCESS MODEL

AO ARRASTAR A TRANSAO INVOICE AO DIAGRAMA, AUTOMATICAMENTE ESTE DADO RELEVANTE FOI CRIADO

Tambm definiremos veremos..

dados

relevantes

explicitamente,

como

Quando so definidos dados relevantes em um diagrama de processo (definidos automaticamente ou definidos explicitamente) algo a ser dito que no so os mesmos atributos definidos na KB. A sintaxe do nome de um dado relevante definido em um diagrama de processo, totalmente anloga a sintaxe do nome de um atributo (e alm disso tem um tipo de dados associado)...mas no um atributo, mas sim um dado global que ser conhecido em todo esse diagrama de processo. Ou seja que ao ver num diagrama de processo um dado relevante de nome InvoiceId, no devemos confundir com o atributo definido na KB. Todavia, para os dados relevantes que so definidos automaticamente com mesmo nome e tipo que as chaves primrias das transaes (como neste exemplo: InvoiceId), tem uma correspondncia automtica entre o dado relevante e o atributo PK, no sentido que quando modelamos o diagrama o dado relevante o dado global conhecido nesse contexto e nos objetos GeneXus que desenvolvemos as atividades do diagrama recebemos no parm o atributo PK (tratando-se da mesma informao ou no contexto do diagrama, ou no contexto do desenvolvimento da funcionalidade respectivamente). Em outras palavras tem um mapa automtico entre o dado relevante com o mesmo nome e tipo que um atributo chave primria com dito atributo chave primria. A maioria de Dados Relevantes num diagrama de processo se correspondem com as chaves primrias, tambm existem casos que surge a necessidade de definir explicitamente outros dados relevantes. Em seguida veremos exemplos, e tambm veremos como definir correspondncia entre dados relevantes que definiremos em um diagrama de processo e variveis que deveremos definir nos objetos GeneXus associados as atividades do diagrama (veremos que utilizaremos tipos de dados workflow, propriedades e mtodos, para que variveis a nvel de objeto correspondam com dados relevantes definidos a nvel do diagrama de processo).

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios InvoiceId = Dado Relevante no diagrama

Quando surge a necessidade de definir dados relevantes?


Trn Invoice

Web

thor l Au Pan e

on izati

Parm(InvoiceId);

COMO CARREGO UM VALOR OU OUTRO NESTES EVENTOS E QUE O VALOR CARREGADO SEJA VISTO NO DIAGRAMA PARA AVALIAR CONDIO POSTERIOR?

Inicialmente explicamos que quando trabalhamos no GeneXus com workflow, realizamos basicamente os seguintes passos: Criar objetos GeneXus Criar diagramas de processos de negcios Associar objetos GeneXus a diagramas de processos de negcios Executar processo Estamos assim confeccionando um diagrama de processo em nossa KB; tnhamos previamente definidos alguns objetos GeneXus que arrastamos ao diagrama, e vamos desenvolvendo outros objetos e incorpor-los ao diagrama tambm. Mais adiante veremos como atribuir regras as diferentes atividades do diagrama. Por enquanto a idia que contamos na KB com uma transao Invoice, a qual foi arrastada ao diagrama como primeira atividade interativa do processo e mais adiante definiremos que esta tarefa interativa poder ser executada pelas vendedoras da empresa. Quando uma vendedora ingresse uma venda (atravs da transao Invoice), entrar o cliente, a mercadoria solicitada, as quantidades, a forma de pagamento solicitada pelo cliente, gravar a venda com um nmero interno (no o nro da fatura formal) e a terminar a primeira atividade. Depois essa venda dever ser avaliada por um supervisor (quem vai avaliar de qual cliente se trata, o montante, a forma de pagamento), e o supervisor dever aceitar ou recusar a venda. Esta segunda atividade interativa do processo foi agregada ao diagrama arrastando a web panel Authorization. Ento, a nvel do diagrama de processo contamos com o dado relevante InvoiceId (com o mesmo nome e tipo de dado que o atributo InvoiceId), o qual significa que dito dado se conhece ao longo de todo o fluxo de atividades. E no que se refere aos objetos GeneXus relacionados ao diagrama, a web panel Authorization implementa a 2da atividade do processo e recebe por parmetro o atributo InvoiceId. No form da web panel Authorization sero visualizados os dados da fatura, o limite de crdito e o saldo do limite de crdito do cliente e possibilita ter o histrico das faturas anteriores do cliente. Esta web panel oferecer ao supervisor 2 botes: Authorize e Refuse.

Vale explicar que quando trabalhamos com workflow em GeneXus, no cdigo dos objetos j no podemos chamar de um objeto a outro. Por outro lado, nos diagramas de processos que confeccionamos j ficam implcitas as chamadas entre atividades consecutivas. Mais adiante veremos que na etapa de execuo vamos executar uma aplicao que nos permite criar instancias dos processo que definimos (por exemplo podero ser criadas N instancias do processo de venda definido). Ao criar uma nova instancia de processo, comea a execuo da primeira atividade (ser mostrada a trn Invoice para isso, e se foram definidas, ser validado que em particular essa atividade seja realizada por uma vendedora, seguir a segunda atividade (para ser efetuada por ele rol que corresponda, que em nosso exemplo um supervisor) e assim sucessivamente e as atividades da instancia do processo vo sendo finalizadas e executando as seguintes atividades at concluir dita instancia do processo. De modo que no codificamos mais calls nos objetos GeneXus, e caso se necessite mudar a ordem de precedncias das atividades em um processo, ou agregar ou tirar atividades, assim como mudar as condies de execuo das atividades, fazemos no diagrama de processo sem tocar o cdigo dos objetos no diagrama de processo. Algo que se deve notar que no definimos calls no cdigo mesmo dos objetos, mas definimos regra parm nos objetos, se definimos a regra parm nos objetos GeneXus que participam num diagrama de processo. Isto porque os objetos so chamados com outro esquema de trabalho do que conhecamos e precisa passar a informao necessria ... Assim que so recebidos por parmetro os atributos chaves primrias que so anlogas aos dados relevantes no diagrama de processo (e que tem uma correspondncia entre esses conceitos). Agora que isso foi explicado, seguiremos estudando passo a passo a implementao da segunda atividade do processo que estamos confeccionando. A web panel Authorization recebe por parmetro o atributo InvoiceId, que mostra em seu form informao para a tomada de deciso da autorizao ou recusa e para isso tem 2 botes Authorize e Refuse respectivamente. Se nosso objetivo carregar uma varivel com valor 1 no evento Authorize e com valor 0 no evento Refuse, e queremos que o valor atribudo seja visto no diagrama de processo, bastar realizar o seguinte: 1) No tab Relevant Data do diagrama de processo, precisa criar um dado relevante (por exemplo de nome: InvoiceAuthorized) de tipo Numeric. 2) Na web panel "Authorization ter que ler o dado relevante e carreg-lo em cada evento da web panel, assim:

Sendo: &wfAuthoriz: uma varivel definida na web panel, de tipo de dados : WorkflowApplicationData &wfProcessInstance: uma varivel definida na web panel, de tipo de dados: WorkflowProcessInstance

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio passo a passo.. (4) Criao explcita de Dado Relevante no Diagrama de Processo e como trabalhar com o mesmo nos objetos

1)

2)

Em wbp Authorization definimos 2 variveis de tipos de dados WorkflowApplicationData e WorkflowProcessInstance para ler e carregar o dado relevante

Vimos que definimos um dado relevante no diagrama de processo (de nome InvoiceAuthorized) e depois na web panel Authorization se l o dado relevante na varivel &wfAuthoriz de tipo WorkflowApplicationData. O tipo de dados WorkflowApplicationData significa dado relevante. Tambm temos definido na web panel uma segunda varivel de tipo WorkflowProcessInstance. O tipo de dados WorkflowProcessInstance significa instancia de processo. Ou seja se analisarmos a primeira linha codificada dos 2 eventos, estamos recuperando na varivel &wfAuthoriz (de tipo dado relevante) o valor do dado relevante de nome InvoiceAuthorized (entre aspas vai o nome do dado relevante tal como foi definido no diagrama de processo) pertencente a instancia do processo que est sendo executado. Depois na segunda linha codificada em ambos eventos, se est atribuindo a varivel &wfAuthoriz (de tipo dado relevante) o valor 0 ou 1 segunda corresponda (utilizando a propriedade Numeric do tipo de dado WorkflowApplicationData, por estar atribuindo um valor numrico). Por ltimo em cada evento se faz return, porque j foi recuperado o valor do dado relevante, se foi carregado o valor desejado e se deseja culminar com a execuo desta atividade. Desta maneira ento lemos e carregamos dados relevantes nos objetos GeneXus associados as atividades de um diagrama de processo (exceto quando se trata de dados relevantes com mesmo nome e tipo que as chaves primrias, j que nesses casos so recebidos por parm os atributos primrios diretamente e pronto).

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio passo a passo.. (5) Avaliao de Dado Relevante em condio de Diagrama de Processo
Em todo o diagrama contamos com o Dado Relevante InvoiceAuthorized... Em rotas que saem da condio Se avalia o valor do dado Relevante InvoiceAuthorized

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

1)

Outra soluo possvel para resolver passos (4) e (5)


Se quiser definir atributo InvoiceAuthorized na trn Invoice e gravar em cada invoice autorizado ou no.. se foi

2)

Na web panel Authorization se chama proc em cada evento, que grava 1 ou 0 no atributo InvoiceAuthorized da invoice autorizada/recusada No Diagrama de Processo o atributo InvoiceAuthorized pode ser inferido (atravs de Dado Relevante InvoiceId que corresponde ao atributo InvoiceId) a avaliamos diretamente dito atributo

3)

AVALIAMOS ATRIBUTO (NO DADO RELEVANTE)

Com esta soluo, no temos necessidade de definir Dado Relevante InvoiceAuthorized, j que temos num atributo a informao se a invoice foi autorizada/recusada e no fluxo podem ser inferidos atributos atravs dos Dados Relevantes correspondentes a chaves primrias, e avaliar diretamente atributos.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Definio de regras
DEFINIO DE REGRAS NA KB

1)

2)

ATRIBUIO DE REGRAS DAS ATIVIDADES NO DIAGRAMA

A definio de regras a nvel da KB na seo de Preferences. Depois selecionando cada atividade do diagrama e pressionando F4, na propriedade Roles poder atribuir a lista de regras que dita atividade poder executar.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Diagrama de Processo completo correspondente ao processo que estamos confeccionando:

Se o supervisor autoriza uma venda, a seguinte atividade no diagrama InvoiceToBePrepared. Esta atividade interativa tem uma web panel associada que recebe por parmetro o atributo InvoiceId, mostra a informao da venda autorizada e tem um boto para que a pessoa do pacote quando terminar de preparar a mercadoria o pressione. O evento associado a esse boto, vai chamar um procedimento que gravar num atributo da invoice, um valor indicador (flag) de que o pacote j foi realizado. A seguinte atividade interativa e tem uma panel associada que recebe por parmetro o atributo InvoiceId, mostra a informao da venda preparada e tem um boto para emitir a fatura. Quando uma vendedora pressionar este boto, o evento associado ao boto chama um procedimento que grava na invoice o nmero de fatura formal e emitir a impresso. A ltima atividade deste fluxo que estamos explicando, corresponde a distribuio da mercadoria. Esta atividade tambm tem uma web panel associada que mostra os dados da venda e pressionando um boto, uma proc grava que a mesma foi entregue. As datas/horrios que foram efetuadas cada uma das atividades, ficaro registradas durante a execuo do workflow.

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Passos para executar: Save All Build All (Sero solicitados dados de Enviroment) Run do Diagrama de Processo

GXFLOW
Conceitos bsicos para criar diagramas de processos de negcios

Execuo:

Tem 2 modalidades de execuo: Prototyper Full Client Na seo de Preferences se configura a desejada:

Logicamente a modalidade Prototyper est orientada a etapa de prototipao. E a modalidade FullClient a etapa de produo. Na etapa de prototipao no nos interessa testar a segurana, motivo pelo qual ao executar a aplicao na modalidade Prototyper inicialmente so limpas todas as instancias de testes anteriores e permitido executar todas as atividades sem controlar regras. Ao executar a aplicao na modalidade Full-Client, no se aborta nada inicialmente e se requer criar usurios (para login) cada um deles com a lista de regras que o corresponda, j que neste caso a segurana controlada.

GERNCIA DE VERSES

Gerncia de Verses
O desenvolvimento de software um trabalho em equipe e certo grau de confuso inevitvel.
O que aconteceu com a regra da semana passada? A aplicao em execuo no compatvel com o cdigo fonte Realmente estamos trabalhando na ltima verso?

No pode reproduzir o error nesta verso!

Este programa ontem funcionava!

Gerncia de Verses
Concluso: O ciclo de desenvolvimento um processo dinmico que requer controle das alteraes realizados aos objetos do projeto. Se necessita: Marcar marcos no desenvolvimento da aplicao Ter linhas de desenvolvimento paralelas Administrar o ciclo de vida da aplicao (SCM)

. . . KB Verso 1 Verso 2 Verso N

Durante o processo de construo da aplicao, necessrio marcar marcos no desenvolvimento da mesma, entendendo como marcos o congelamento do desenvolvimento num determinado momento especial no processo. Isto pode acontecer por exemplo para liberar uma verso na produo, congelar uma verso entregue a um cliente, a necessidade de congelar um determinado estado especial da aplicao, etc. Alm disso tambm vamos querer ter diferentes linhas de desenvolvimento da aplicao, algo muito comum por exemplo quando se quer fazer variaes do projeto para um cliente ou quando se requer que dois grupos de trabalho o faam em paralelo e necessitamos poder realizar uma administrao de todos estes elementos. O que necessitamos basicamente administrar o ciclo de vida da aplicao durante o desenvolvimento. Vrias destas funcionalidades entram no que no mundo do software se conhece como SCM (Software Configuracin Management)

Gerncia de Verses
Soluo: Gerncia de verses da aplicao

1.1.1

1.1.2

APP APP

1.0

1.1

1.2

2.0

2.1

N raiz da rvore de verses

1.0.1

1.0.1

1.0.2

Comea o desenvolvimento seguindo uma linha principal de desenvolvimento (linha do meio Trunk), lugar onde so agregadas as funcionalidades requeridas e so utilizados prottipos para prov-las . Em determinados momentos deste ciclo surge a necessidade de estabelecer um checkpoint no processo, seja pela liberao de uma verso, a entrega de uma verso a um cliente, a necessidade de congelar um determinado estado de uma aplicao, etc. Ento o que fazemos congelar o produto nesse momento criando por exemplo a verso 1.0 que a entregamos a um cliente e continua o processo de desenvolvimento principal. Em determinado momento surge a necessidade de realizar correes sobre a verso entregue ao cliente (1.0) sendo necessrio abrir uma nova linha de desenvolvimento para incluir estas correes sobre o que era a verso 1.0 sem afetar a linha de desenvolvimento principal que continuou crescendo desde o momento que foi congelada a verso 1.0. Ento se cria o que se conhece como Developmen Version ou branch, que simplesmente uma nova linha de desenvolvimento paralela a principal. Depois durante o transcurso do projeto voltam a aparecer requerimentos deste tipo, seja pela determinao de checkpoints como a necessidade de abrir novas linhas de desenvolvimento, ento por exemplo criamos a verso 1.1, ou a 1.0.1 que vem a ser um congelamento da linha de desenvolvimento aberta a partir da verso 1.0 e assim sucessivamente at ter por exemplo a situao estabelecida no diagrama. Estas situaes formam parte da operao normal no desenvolvimento de uma aplicao e necessrio administrar este processo de forma fcil. . Para isso se introduz o conceito de Gerncia de Verses. As verses so classificadas em: Development Versions, representam as linhas de desenvolvimento da aplicao as quais so independentes entre si, existe uma linha principal e vrias paralelas, a principal vem a ser o que se conhece como Trunk e as demais seriam o que em SCM se conhece como Branches Frozen Versions (tambm conhecidas como Labels em SCM), representam as congeladas criados em determinados momentos do processo sobre as DV para determinar certos checkpoints (liberao de verso, entrega ao cliente, congelar estado, etc.)

Gerncia de Verses
Soluo: Gerncia de verses da aplicao
Development Version
1.1.1 1.1.2

APP APP

1.0

1.1

1.2

2.0

2.1

Development Version (Trunk) N raiz da rvore de verses


1.0.1 1.0.1 1.0.2

Development Version Frozen Versions

Gerncia de Verses
Development Version
1.1.1 1.1.2

APP APP

1.0

1.1

1.2

2.0

2.1

Development Version principal (Trunk)


1.0.1 1.0.1 1.0.2

N raiz da rvore de verses = n raiz do Trunk

Development Version

As development version so as linhas de desenvolvimento da aplicao, isto o lugar onde efetivamente criamos e modificamos a aplicao. No ciclo de vida de uma aplicao participa uma linha de desenvolvimento principal, isto , onde comea o processo de desenvolvimento da aplicao e na qual normalmente se vai estar fazendo as modificaes requeridas no avano do projeto. Em SCM esta linha de desenvolvimento conhecida com o nome de Trunk. Alm desta linha principal podero existir uma ou vrias linhas de desenvolvimento secundrias, totalmente independentes da linha principal e independentes entre si. Em SCM estas linhas de desenvolvimento secundrias so conhecidas como Branches e so usadas em geral para realizar correes ou pequenas alteraes sobre verses congeladas ou liberadas da aplicao, ou para liberar uma verso especial para um cliente. O desenvolvimento em cada uma destas development version independente, tendo cada verso seus prprios objetos, sua prpria base de dados, ambientes para gerar a aplicao, etc. Uma Development Version, ento, uma cpia da KB editvel e independente.

Gerncia de Verses
Frozen Version: Verso no modificvel, uma foto da aplicao num dado momento.
1.1.1 1.1.2

APP APP

1.0

1.1

1.2

2.0

2.1

1.0.1

1.0.1

1.0.2

Frozen Versions

Uma Frozen Version permite armazenar de forma esttica momentos especiais da KB. o elemento que utilizamos para marcar distintos marcos no processo, como por exemplo feche uma verso para liber-la aos clientes. Se obtm a partir de uma verso em desenvolvimento (development version), congelando-a para obter uma foto num determinado momento. A verso obtida Read Only, que objetos da mesma no podero ser modificados, nem tampouco suas propriedades. Sendo possvel realizar aes relacionadas com a gerao da aplicao, como por exemplo a criao da base de dados ou a gerao novamente dos programas. Quando congelamos uma verso porque determinamos que a mesma est em um estado consistente e seria conveniente guardar dito estado. Por exemplo, congelamos uma version X para se dar aos clientes, em determinado momento, enquanto o processo de desenvolvimento continua, um novo cliente requer a aplicao, ento o que fazermos gerar a mesma na version X, que sabemos que tem um estado correto e a instalamos ao novo cliente. Se os objetos no poder ser modificados, podem ser abertos para distintas consultas ou para realizar comparaes com outras verses da aplicao.

Gerncia de Verses
Exemplo de verses: Implementao passo a passo
Variaes devido a consertos ou alteraes dos requerimentos Development Version principal (Trunk)

APP APP

..

Ciclo de desenvolvimento principal - Prototipado

Partimos do n raiz da rvore de verses, o qual se cria ao criar a KB. A aplicao vai sofrendo alteraes a medida que transcorre o ciclo de desenvolvimento. A linha de desenvolvimento principal onde se implementam as funcionalidades requeridas e onde se faz a prototipao. Esta linha de desenvolvimento geralmente coincide com o Trunk, ou seja com a ramo principal da rvore de verses. uma Development Version criada por default quando a KB criada. A medida que as modificaes na aplicao so realizadas, a mesma vai se alterando ao longo do tempo.

Gerncia de Verses
Para ver a rvore de verses, abrimos a janela Knowledge Base Versions (View/Versions):

N raiz da rvore de verses = n raiz do Trunk

Gerncia de Verses
Surge a necessidade de congelar verses, para fixar marcos no projeto. Para isso criamos Frozen Versions (cpia somente de leitura da aplicao).
APP APP ..

Development Version principal (Trunk)

1.0 1.0

Frozen Version 1.0

As Frozen Version servem para: Analisar (no modificar) objetos, propriedades, environments, etc. Como fonte de um Reporte de Anlise de Impacto da base de dados Para criar a base de dados Para regerar todos os programas

Gerncia de Verses
Como congelamos uma Development Version, para criar uma Frozen Version?

Boto direito sobre o n raiz do Trunk e selecionamos Freeze

Gerncia de Verses
Agora queremos colocar a aplicao em Produo. Para isso criamos uma Frozen Version 1.1 e a partir dela criamos uma Development Version Release 1.
APP APP ..

Development Version principal (Trunk)

1.0 1.0

1.1 1.1

Release1 Release1

Development Version para Produo

Na verso de Produo vo sendo produzidas variaes devido aos consertos, mas no se agrega funcionalidades novas. As mesmas so agregadas na linha de desenvolvimento principal. As Development Version servem para: - Trabalhar numa linha de desenvolvimento paralela a principal - Como fonte ou destino de uma operation de Revert a partir de uma Frozen Version de Backup

Gerncia de Verses
Criamos a Frozen Version 1.1 como vimos anteriormente

Boto direito sobre o n raiz e click em Freeze

Frozen Version 1.1

Observe que as Frozen Version mais novas, so mostradas mais acima na rvore de verses.

Gerncia de Verses
Depois com boto direito sobre a FV 1.1 e selecionamos New Version.

Development Version Release1

O tempo que se demora em criar uma nova Development Version proporcional ao tamanho da KB.

Gerncia de Verses
Tambm podemos criar novas Frozen Versions tanto no ramo do desenvolvimento principal como no ramo de Produo.
KB1 KB1 ..

Trunk

1.0 1.0

1.1 1.1

1.2 1.2

2.0 2.0

2.1 2.1

Produo

Release1 Release1

1.1.1 1.1.1

1.1.2 1.1.2

Frozen Versions de Produo

Como as linhas de desenvolvimento do Trunk (Desenvolvimento) e de Relase 1 (Produo) so paralelas, as alteraes numa no afeta a outra. Ambas verses so totalmente independentes e podemos requerer congel-las por diferentes motivos. Por exemplo, no caso do ramo de Produo, para fixar um estado depois de certos consertos que tivemos que fazer. De acordo com a metodologia adotada, no ciclo de desenvolvimento principal, onde se agregam novas funcionalidades, consertos, alteraes importantes na aplicao, prototipao e testing. mais frequente que seja necessria fotos nessa etapa viva do desenvolvimento da aplicao. No ramo do Release1, as alteraes so menores, mais certos consertos circunstanciais que no agregam funcionalidade. Neste caso, menos frequente a necessidade de criar Frozen Versions, mas pode ser igualmente necessrio.

Gerncia de Verses
Observe que as Frozen Versions mais novas, so mostradas mais acima na rvores de verses

Gerncia de Verses
Depois de certos consertos na Produo, nos interessa gerar a aplicao. Para isso marcamos a DV Release 1 como ativa.

Boto direito sobre o n Release1 e escolhemos Set Active

GeneXus gera automaticamente os programas e as estruturas da BD, partindo da verso que esteja ativa. Se pode marcar como ativa uma verso em desenvolvimento ou uma verso congelada. Neste ltimo caso, no poderemos fazer nenhuma modificao a mesma, somente utiliz-la para gerar a aplicao ou para realizar um impacto na base de dados, ou para comparar verses. Somente pode ter uma verso ativa por vez.

Gerncia de Verses
A Development Version que estiver ativa, ser utilizada para gerar a aplicao ao fazer um Build (F5)
GeneXus nos indica qual o ramo ativo

Das könnte Ihnen auch gefallen