Curso GeneXus - Comunicação entre Objetos Em situações anteriores encontramos a necessidade de chamar um objeto a partir de outro. Por exemplo, no evento Enter da web panel EnterPercentage2, estamos chamando o procedimento IncreaseFlightPrices
com o método call : A sintaxe na chamada permite que possa se omitir o call e o funcionamento será exatamente o mesmo, já que GeneXus tem a inteligência para determinar que estamos chamando um objeto; assim que
eliminemos o ponto e o call. Lembre-se, que quando chamamos um objeto podemos passar dados que temos no objeto chamador, para que o objeto chamado os conheça e possa usá-los. Neste exemplo, estamos passando ao procedimento o valor do percentual informado pelo usuário na web panel, armazenado na variável &percentage. Neste caso temos o valor numa variável. Se tivéssemos o dado num atributo, incluiríamos dentro dos parênteses o atributo que corresponda, ou no caso de ter que passar dois ou mais valores, enviaríamos vários atributos e/ou variáveis separados por vírgula. Como já vimos no objeto chamado, declaramos os dados recebidos na regra parm.
Vemos nesta regra, a variável &percentage entre parênteses.
Neste objeto nós definimos a variável com o mesmo nome e tipo de dados conhecido na web panel. O nome poderia ser diferente, mas o tipo de dados tem que ser o mesmo. Recorde-se que a variável recebida com o valor da porcentagem, utilizamos no source do procedimento. Se ao chamar um objeto, se não forem envidados dados, no objeto chamado não tem que declarar a regra parm. E se mais de um item for enviado, eles tem que ser recebidos dentro da regra parm na mesma ordem, separados por vírgulas. Vejamos um exemplo. Vamos definir uma web panel para que o usuário informe um intervalo inicial e final de nomes de atrações que deseja listar. E a partir da web panel se chama um procedimento, para que liste todas as atrações cujos nomes estejam incluídos neste intervalo. New/Object, selecionamos web panel, e damos o nome: EnterAttractionNameRange
Pressionamos Create Vamos a seção de variables para criar as 2 variáveis que precisamos.. Definimos o nome da variável: AttractionNameFrom e nos é sugerido basear a definição da variável na definição do atributo AttractionName.
Isto significa que a definição da variável está relacionada com a definição do atributo e se no futuro alterar o tipo de dados do atributo, o tipo de dados da variável também muda, automaticamente. Vamos definir mais uma variável, de nome: AttractionNameTo, do mesmo tipo: E vamos agora ao form. A partir do ToolBox inserimos uma tabela e deixamos o tamanho por default.
Quando desenhamos na web, é importante usar tabelas para que o que se escreva ou se insira na tela, fique devidamente alinhado. Digitamos Attraction name from: nesta célula, e Attraction name to: nesta outra
e inserimos as variáveis que acabamos de definir Também inserir um botão e deixe por uma momento a web panel dessa forma, para resolvermos o procedimento que vamos chamar no evento associado ao botão. Na janela Folder View localizamos o procedimento AttractionsReport
pressionamos botão direito do mouse, escolhemos Save As damos o nome AttractionsReport2 e obtemos uma copia, a qual faremos algumas mudanças. Apagaremos o order e o where. Desta forma, a listagem imprime todas as atrações. Vamos ver o layout
contém 3 printblocks este imprime o título do relatório este imprime os títulos das colunas
e este é o único que contém atributos e é o que é impresso dentro do For each. Vamos novamente ao source, e vemos que o For each contém somente a chamada ao printblock Attractions Definiremos agora, que este procedimento receba o intervalo inicial e final de nomes de atrações e usaremos os dados recebidos para fazer o filtro no For each. Vamos à seção de variables do procedimento e definimos 2 variáveis: - NameFrom, baseado no atributo AttractionName - E NameTo, também baseado no atributo AttractionName Observe que demos as variáveis, nomes diferentes aos nomes das variáveis que definimos na web panel.
O importante é que os tipos de dados enviados e recebidos coincidam!! Agora, vamos à seção Rules do procedimento e escrevemos: parm(&namefrom,&nameto); Estas variáveis que recebemos no procedimento, vamos utilizá-las para filtrar no For each. Assim que voltemos ao source e escrevemos where AttractionName>=&NameFrom.. enter... e where AttractionName>=&NameTo Como este procedimento foi salvo a partir de outro, as propriedades e a regra necessária para que seja impresso no formato PDF já estão configuradas. Este procedimento está pronto e só nos resta chamá-lo a partir da web panel. Vamos à web panel e damos um clipe duplo no botão para ver o evento associado.
Insira o nome do procedimento AttractionsReport2 e ao final do nome do procedimento, adicione um par de parênteses, dentro dos quais vamos informar os dados que queremos enviar, separados por vírgula.
Aqui as variáveis são chamadas &AttractionNameFrom e &AttractionNameTo Assim as enviaremos com estes nomes. Dentro dos parênteses se digita & (ecomercial) e escolha &AttractionNameFrom digitamos uma vírgula, & (ecomercial) novamente e escolha &AttractionNameTo. A chamada ao procedimento fica completa, ao qual enviamos um intervalo de nomes de atrações que o usuário digitou no form nestas 2 variáveis. Se formos ao procedimento, a regra parm, recebe duas variáveis:
O dado enviado em primeiro lugar vem também em primeiro lugar ao receber e assim sucessivamente chegam os dados ao objeto chamado, na ordem enviada.
Ressaltamos que não importa o nome das variáveis, mas a ordem delas. Deve sempre usar nomes relacionados como fizemos aqui, para entender melhor o código (que ele seja mais legível).
O valor recebido nas variáveis foram utilizadas para filtrar no For Each. Observemos que usamos os nomes das variáveis definidas neste procedimento e não os nomes usados no objeto chamador. Vejamos funcionando tudo o que vimos e explicado até aqui. Pressionamos F5 Executamos a web panel EnterAttractionNameRange.
Queremos ver a as atrações cujos nomes começam entre A e Z pressionamos o botão e vemos listadas todas as atrações
Agora vamos delimitar um pouco mais o intervalo. Entre A e F e vemos que somente saiu a Torre Eiffel e as pirâmides do Egito.
Vimos em execução, uma chamada a outro passando 2 parâmetros ao objeto chamado. Os dados recebidos
Usaram para filtrar no comando For Each Passaremos agora a conhecer, outra maneira possível de chamar, particularmente, objetos procedimentos ou data providers.
Neste exemplo, estamos chamando um procedimento de nome GetDiscount. Observemos que antes da chamada ao procedimento tem uma variável e um sinal de igualdade.. Isto é porque o objeto chamado devolve um valor. A esquerda do sinal de igualdade
Pode ter uma variável que recebe o valor e dependendo do objeto e a seção do mesmo, pode ter um atributo recebendo o valor. Neste caso, não nos interessa entrar em detalhes do que faz o procedimento GetDiscount. Para o nome do procedimento que devolve um valor e o nome da variável que recebe o valor retornado pelo procedimento
podemos deduzir que: - o procedimento nos devolverá um desconto - enviados ao procedimento 2 dados: identificador do cliente e um identificador de voo - e que o procedimento utilizará estes dados, avaliará e calculará o que o corresponda e retornará um desconto. - Agora, é importante vermos como se declara no objeto chamado, a regra parm, quando na sintaxe da chamada, o objeto devolve um valor. Na seção de regras do procedimento GetDiscount declaramos esta regra parm
com 3 parâmetros. O termo parâmetros se usa para referir a dados que se enviam e recebem entre 2 objetos que um chama o outro.
Assim se pode falar em forma genérica independentemente de se enviam ou recebam variáveis, atributos ou valores fixos. Vemos agora como funciona: Os dois parâmetros enviados, Recebe-se nessa ordem. E o terceiro parâmetro definido na regra parm
corresponde ao que armazena o valor retornado, na variável &discount da chamada. Mas: No source do objeto GetDiscount, em algum lugar do conjunto de instruções O valor tem de ser atribuído a variável &discount,
para que dito valor possa ser devolvido e atribuído a variável que se encontra a esquerda do sinal de igualdade. Anteriormente já chamamos um objeto Data Provider desta maneira. Esta sentença
sendo atribuído a variável &Customers, definida como uma coleção de clientes, o que devolve o DataProviderCustomers. Neste caso não se enviam parâmetros ao objeto chamado Já que não tem nada dentro dos parênteses. Portanto o Data Provider chamado não tem uma regra parm declarada.
Lembre-se que quando arrastamos ao source deste Data Provider o SDT que queríamos carregar, automaticamente se completou a propriedade Output do Data Provider
Com o nome do SDT que arrastamos. Tal como o nome da propriedade Output o descreve, ficou configurado assim no objeto, o que o mesmo retorna, ou em outras palavras: a saída do Data Provider. Por este motivo, em objetos Data Provider tem que receber na regra parm, a mesma quantidade de parâmetros que foram enviados na chamada. sem agregar um parâmetro extra de retorno ao final
já que a saída fica definida pela propriedade Output do data provider
Para finalizar, vamos observar una última coisa. Neste exemplo, alguns parâmetros são variáveis e outros, atributos. Como escolhemos o que mandar e o que receber? Na hora de enviar dados a um objeto chamado, não se gera dúvidas: Se os dados estão num atributo
se inclui como parâmetro o atributo; e se estiver numa variável, se utiliza a variável. Um exemplo de termos os dados em atributos, seria o caso da chamada ao procedimento GetDiscount estiver definida numa regra da transação na qual o usuário tem ingressado um identificador do cliente e o identificador de voo
e se tem os valores a serem enviados ao procedimento, em atributos. Outro exemplo de uso de atributos pode ser se a mesma chamada estiver definida dentro de um For each, o qual navega em certa tabela base, e se a tabela estendida tem alcance da mesma e dispõe desses atributos. Um exemplo de quando tivemos os dados em variáveis, foi na web panel EnterAttractionNameRange
Onde informávamos um intervalo de atrações e ao confirmar chamamos um procedimento passando dito intervalo que os tínhamos em 2 variáveis
Lembre-se que aqui podemos omitir o call.
Com relação à declaração da regra parm no objeto chamado, podemos decidir para cada parâmetro recebido, declarar um atributo ou uma variável, independentemente de como foi enviado. Qual é a diferença entre usar uma variável ou um atributo na regra parm do objeto chamado? Se receber o valor numa variável, a mesma pode ser utilizada livremente na programação: poderá ser utilizado como condição de filtro por igualdade, maior, maior ou igual, menor, menor ou igual... pode ser utilizada para uma operação aritmética, ou o que necessite realizar com a mesma. Se ao invés disso o valor for recebido num atributo,
automaticamente o mesmo atuará como filtro por igualdade no objeto. Veremos isto. Vamos gravar uma cópia deste procedimento com outro nome. Damos o nome: AttractionsReport3.
Neste novo objeto, ao invés de receber duas variáveis que contém um valor inicial e final de nomes de atrações vamos receber somente uma variável com um identificador de atração, cujos dados se desejam ser listados. Ou seja, a ideia aqui é listar os dados de uma única atração. Vamos à regra parm, tiramos estas 2 variáveis e escrevemos &AttractionId. Estando aqui, modificamos o nome do arquivo pdf a: AttractionsReport3. Agora vamos à seção de variáveis e definimos a variável &AttractionId. E vamos modificar no source os filtros do For Each
É claro que com esta definição, estamos listando os dados de uma atração recebida por parâmetro. Agora vamos ver o que ocorre se ao invés de receber o identificador de atração em uma variável, o receber em seu atributo. Quando recebemos o valor de um atributo na regra,
GeneXus filtra por igualdade, ou seja, somente vai acessar os registros que tenham esse valor de identificador de atração, em todos os acessos a base de dados que são feitas no source do objeto. Assim, não é necessário este where já que o efeito de filtro é realizado ao receber o atributo na regra parm. Eliminamos então esta linha Se olharmos a navegação deste objeto
vemos que o filtro está sendo realizado
Ainda que o where não esteja escrito. Se escrever, não obtemos um erro, mas não é necessário o escrever. Vimos duas maneiras de filtrar a informação acessada por igualdade. Se nosso objetivo não é utilizar um filtro de valor recebido por igualdade, então a única solução é receber os valores em variáveis e usá-los livremente.