Você está na página 1de 19

Curso de POWERBUILDER 7.

CONSTRUINDO UMA JANELA DE DADOS


(DataWindow Object)
Parte 5

A DataWindow
Uma DataWindow (Janela de Dados) é um objeto usado para manipular, atualizar e
apresentar dados. Os dados podem estar armazenados em um banco de dados relacional ou
podem vir de outra fonte (arquivos texto, planilhas excel, etc).
Você define o objeto DataWindow usando o DataWindow Painter (Pintor de Janela de
Dados) e o coloca em janelas utilizando o controle DataWindow.

Objeto Banco de
DataWindow Dados

Controle
DataWindow

Janela

O Objeto DataWindow
Objetos DataWindow são o coração de uma aplicação PowerBuilder. Saber utilizar
bem as funções pré-definidas deste objeto significa escrever menos e usufruir melhor de seus
recursos.
Quando você cria um objeto DataWindow, você define de onde o dado virá (a fonte de
dados) e como este dado será apresentado (estilo de apresentação). O objeto DataWindow é
armazenado em uma biblioteca PB.

Utilização da DataWindow
Como objetos DataWindow "sabem" a fonte de dados e determinam seus estilos de
apresentação, eles servem a um duplo propósito:
 como uma interface para o sistema de gerenciamento de banco de dados e;
 como uma interface para o usuário

Para a interface com o usuário associamos um objeto DataWindow a um controle


DataWindow em uma janela. O controle DataWindow atua como outros controles que você
pode usar em uma janela, como CommandButtons (Botões de Comando), ou SingleLineEdits
(Linhas Únicas de Edição). Uma Window pode conter várias DataWindows e uma DataWindow
pode estar contida em várias Windows.

22/11/21 Pag.: 80
Curso de POWERBUILDER 7.0

Objeto Banco de
DataWindow Dados

Controle
DataWindow

Janela

Criando o Objeto DataWindow


Como vimos anteriormente, para criarmos QUALQUER objeto novo no PB, podemos
utilizar o ícone New, da PowerBar ou através do item File, sub-item New do menu. A caixa de
diálogo New será apresentada e devemos escolher na pasta DataWindow, o estilo de
apresentação da mesma, conforme figura abaixo.

Podemos construir uma DataWindow em uma variedade de estilos de apresentação.


Os mais comuns são Tabular (na forma de tabelas), freeform (formulário livre) e grid (em
grade, semelhante a uma planilha).
Outras opções incluem Group (para consultas ou relatórios que possuam quebra de
grupo), Label (para etiquetas), N-up (semelhante à tabular, só que com possível repetição de
colunas na mesma página - as colunas são preenchidas antes da quebra de página), Graph
(gráfico) e Crosstab (tabela de referência cruzada, para consultas que envolvam
consolidações de três variáveis, tal como núm. de funcionários x cargo x sexo), Composite
permite conectar várias DataWindows já existentes no sistema para emitir um relatório
composto.

22/11/21 Pag.: 81
Curso de POWERBUILDER 7.0

Nas próximas unidades e exercícios veremos com mais detalhes cada um deles.
Para nosso exemplo vamos utilizar o modo de apresentação FreeForm. A próxima janela de
diálogo que aparecerá será a de escolha da fonte de dados.

Esta janela determina como você define a fonte de dados (Data Sources) para a
DataWindow e como a mesma obtém os dados que ela mostrará. As opções existentes serão
descritas no quadro a seguir:

Quick Select Quando você quer construir um comando SQL SELECT com um simples critério
de recuperação, usando colunas de uma tabela do banco de dados ou de
tabelas relacionadas com chaves estrangeiras..
SQL Select Quando você quer que a DataWindow emita um comando SQL SELECT para
uma ou mais tabelas e você quer usar critérios mais extensivos de recuperação,
possivelmente incluindo parâmetros de substituições. Se você usa parâmetros
de substituições, você deve suprir valores para estes cada vez que você emite
uma requisição de Retrieve (requisição para recuperação) para a DataWindow.
Query Quando o comando SQL SELECT foi previamente codificado e armazenado em
uma biblioteca PowerBuilder (.PBL) como uma Query. (Não estudaremos)
External Para indicar que a DataWindow não submeterá um comando SQL para
provisão da fonte dos dados, mas que você irá supri-los através de comandos
PowerScript
Stored Procedure Quando você quiser que a DataWindow execute uma Stored Procedure
armazenada no banco de dados e exiba os dados do conjunto de resultados.
(Não estudaremos)

A seguir uma explicação mais detalhada de cada uma das opções de fonte de dados.

A fonte de dados Quick Select


Utilizamos esta fonte de dados quando desejamos selecionar colunas a partir de uma
tabela simples ou a partir de varias tabelas desde que exista relacionamentos através de
chaves estrangeiras nas mesmas. Apesar de estar colocado, por questões práticas, como um
ícone separado da opção SQL Select, a opção Quick Select também gera um comando SQL.
Este tipo de fonte de dados apresenta algumas limitações, por isso, quando
escolhemos a mesma não podemos:
 Especificar grupos para o SQL;
 Incluir colunas computadas;
 Especificar argumentos de recuperação.

22/11/21 Pag.: 82
Curso de POWERBUILDER 7.0

Quando você seleciona Quick Select a partir da janela New DataWindow, a janela
Quick Select aparece, conforme figura abaixo.

Através desta janela, vamos construir um comando SQL, para isto seguiremos os seguintes
passos:
1. Selecione a tabela a partir da caixa de listagem de Tabelas (Tables). As colunas na tabela
aparecem na caixa de listagem de Colunas (Columns).
2. Selecione as colunas individuais ou, se você precisa selecionar todas as colunas, click o
botão Add All. As colunas são mostradas na base da janela. No nosso exemplo, vamos utilizar
a tabela de agencias e selecionar todas as colunas.

22/11/21 Pag.: 83
Curso de POWERBUILDER 7.0

3. Se as colunas aparecerem em uma seqüência diferente da esquerda para direita, arraste as


colunas para a posição apropriada.

4. Se necessário, especifique o critério de ordenação para uma ou mais colunas. (Sort)

5. Se necessário, especifique o critério de recuperação para cada coluna. (Criteria)


· Se você entrar o critério de seleção em mais de uma coluna em uma linha, o
PB assume o operador lógico AND (E) entre os critérios de recuperação, ou seja, uma
linha do banco de dados será selecionada se todos critérios na linha forem obedecidos.
· Se você entrar o critério de seleção em duas ou mais linhas, o PB assume o
operador lógico OR (OU), ou seja, uma linha do banco de dados será selecionada se
o(s) critério(s) de recuperação de qualquer linha for(em) obedecido(s).

Você pode utilizar os seguintes operadores relacionais SQL para critério de


recuperação:

Operador Significado
= É igual a (operador default)
> É maior que
< É menor que
<> É diferente de
>= É maior que ou igual a
<= É menor que ou igual a
LIKE De acordo com
NOT LIKE Em desacordo com
IN Está neste conjunto de valores
NOT IN Não está neste conjunto de valores

Para o nosso exemplo não teremos critério de recuperação, nem ordenação. A seguir
alguns exemplos de definição de critérios de recuperação:

Exemplo 1. A expressão na grid recupera informação dos empregados cujos salários


são menores que $50.000:

A instrução SQL que o PB cria é:


SELECT emp_id, dept_id, salary FROM employee WHERE salary < 50000

Exemplo 2. A expressão na grid recupera informação dos empregados que pertencem


ao departamento 100:

A instrução SQL que o PB cria é:

22/11/21 Pag.: 84
Curso de POWERBUILDER 7.0

SELECT emp_id, dept_id, salary FROM employee WHERE dept_id = 100

Exemplo 3. A expressão na grid recupera informação dos empregados cuja


identificação seja maior que 300 e cujo salário seja menor que R$50.000:

A instrução SQL que o PB cria é:


SELECT emp_id, dept_id, salary FROM employee WHERE emp_id > 300 AND salary <
50000

Exemplo 4. A expressão na grid recupera informação dos empregados que tanto


pertencem ao departamento 100 e possuem salário menor que R$50000 ou os quais o
departamento seja maior que 300, independente dos salários.

A instrução SQL que o PB cria é:


SELECT emp_id, dept_id, salary FROM employee WHERE (dept_id = 100 AND salary
< 50000) OR dept_id > 300

Exemplo 5. A expressão na grid recupera informação dos empregados que pertencem


ao departamento 100 ou 200 ou 500:

A instrução SQL que o PB cria é:


SELECT emp_id, dept_id, salary FROM employee WHERE dept_id IN (100, 200, 500)

6. Quando você tiver terminado a especificação na janela Quick Select, click OK.

Para o nosso exemplo não definiremos ordenação nem critério de recuperação, então
ao clicarmos OK, surgira a janela de escolha de cores e tipos de borda:

22/11/21 Pag.: 85
Curso de POWERBUILDER 7.0

Nesta janela podemos definir:


 Cor de fundo da DataWindow (Background Color): define a cor de fundo da DataWindow;
 Cor do Texto (Text - Color): define a cor que será apresentado o texto que identifica a
coluna;
 Borda do Texto (Text - Border): define o tipo de borda do texto que identifica a coluna;
 Cor da Coluna (Columns - Color): define a cor que será apresentado o texto da coluna em
si;
 Borda da Coluna (Columns - Border): define o tipo de borda da coluna;
 Altura da Moldura (Wrap Height): define a altura da moldura dos textos e das colunas;
 Salvar como padrão (Save as default): salva as definições para que nas próximas
datawindows criadas, as opções selecionadas apareçam automaticamente.

Apesar de configurarmos estes itens nesta janela, podemos depois, no próprio


DataWindow Painter modificá-los o quanto quisermos. Para o nosso exemplo, definiremos:

Cor de Fundo Silver


Cor do Texto Black
Borda do Texto None
Cor da Coluna Blue
Borda da Coluna 3 D Lowered
Altura da Moldura 0.5 inches

Apos a configuração destes itens, vamos clicar no botão “Next”, o que abrira uma
janela de resumo das informações fornecidas até o momento para o desenvolvimento da nova
DataWindow:

22/11/21 Pag.: 86
Curso de POWERBUILDER 7.0

Esta janela apresenta as informações fornecidas e avisa que está pronta para criar a
nova DataWindow. Então, clicando-se em Finish, a área de trabalho do DataWindow Painter
mostra o estilo da DataWindow que você definiu.

O datawindow painter é apresentado. Vamos apenas salvar nossa datawindow (d_agencias), pois
mais adiante, após a definição dos demais tipos de fontes de dados, apresentaremos detalhadamente a área
de trabalho do datawindow painter.

NOTA.
Se você precisa alterar o critério ou mesmo incluir mais tabelas e cláusulas no comando SQL
SELECT, click o botão Modify SQL select syntax na toolbar ou selecione Edit >Data Source. a
partir do menu Design.

22/11/21 Pag.: 87
Curso de POWERBUILDER 7.0

A fonte de dados SQL Select


Utilizamos esta fonte de dados quando desejamos especificar sentencas/instrucões SQL
complexas, portanto temos mais opcões do que a fonte de dados Quick Select. Neste tipo de fonte de
dados podemos definir:
 Mais de uma tabela;
 Critérios de Seleção (Cláusula WHERE);
 Critérios de Ordenação (Cláusula ORDER BY);
 Critérios de Agrupamento (Cláusulas GROUP BY e HAVING);
 Colunas Computadas;
 Um ou mais argumentos a serem fornecidos durante a execução;

Quando você escolhe SQL Select para a fonte de dados da nova DataWindow e clica
OK, o PB abre o SQL Painter, um pintor de auxilio para a definição/desenvolvimento de
instruções SQL. Este pintor é bastante semelhante ao existente para a definição de views ou
de auxílio à confecção de SQL Embedded, item este que será visto adiante.
Inicialmente, a janela Select Tables aparece.

Para selecionar as tabelas podemos:


 Clicar no nome de cada tabela ou visão que desejasse utilizar. Cada tabela escolhida fica
marcada (highlighted) e, para desmarcar uma determinada tabela, somente necessitamos
clicá-la novamente. Apos a seleção de todas as tabelas utilizadas na seleção (SELECT)
podemos clicar no botão “Open” para fechar a janela de diálogo “Select Tables”.
 Duplo-clicar no nome de cada tabela ou visão que desejasse utilizar. Cada objeto é aberto
imediatamente atrás da caixa de diálogo “Select Tables”. Para fechar a caixa de diálogo
utilizamos o botão “Cancel”.

Apos isto, as tabelas e/ou visões selecionadas serão apresentadas no SQL Painter, o
qual será apresentado a seguir.

22/11/21 Pag.: 88
Curso de POWERBUILDER 7.0

Layout
das
tabelas
Seleçã
o
(Where
Ordenaçã ) Seleção
o (Sort) Agrupament (Having)
o (Group)

Colunas
Calculadas
(Compute)
Sintaxe
(Syntax)

Podemos observar sete áreas bem distintas:


 Layout das tabelas: Onde podemos visualizar as tabelas e visões escolhidas. Para cada
tabela ou visão, visualizamos os campos e definições dos mesmos. Além disto, podemos
adicionar ou excluir tabelas;
 Seleção (Where): Definimos o critério de seleção da consulta;
 Ordenação (Sort): Definimos ordenação para a consulta;
 Agrupamento (Group): Definimos grupo(s) para a consulta;
 Seleção (Having): Definimos a seleção dentro do resultado obtido na consulta;
 Colunas Calculadas (Compute): Definimos campos calculados;
 Sintaxe (Syntax): Verificamos a sintaxe do comando SQL que está sendo gerado.

Por default, estas áreas são apresentadas no SQL Painter. Mas, através do menu
View, podemos exibir ou não cada área descrita acima. Dentre outras opções, podemos:
· Escolher colunas específicas para serem mostradas na nova DataWindow;
· Fazer junção de tabelas;
· Agrupar colunas;
· Especificar critérios de recuperação de dados;
· Ordenar dados.

Neste momento devemos estar bem familiarizados pelo menos no que diz respeito aos
comandos SQL, pois na verdade, o PB está apenas apresentando os comandos/instruções
SQL de uma forma gráfica. No caso acima, um comando SELECT. Vamos verificar a seguir
como manipular/utilizar as opções do SQL Painter.

Adicionando e removendo tabelas e/ou visões


A qualquer momento podemos tanto adicionar quanto remover tabelas e/ou visoes para
a area de Layout de Tabelas:

Para Fazer Isto Faca Isto


Adicionar tabelas ou visoes
Clicar no botão Tables na painter bar e
selecionar tabelas ou visoes para
adicionar
Remover uma tabela ou Com o botão direito sobre o nome da
visão tabela ou visão, selecionar a opção

22/11/21 Pag.: 89
Curso de POWERBUILDER 7.0

Close do menu popup


Remover todas tabelas e Selecionar a opção do menu Design >
visoes Undo All

Selecionando e Definindo Colunas


Você pode clicar em cada coluna que se deseja incluir a partir das representações das
tabelas na área de Layout de Tabelas. O PB selecionara as colunas e as mesmas serão
colocadas na “Lista de Seleção”, localizada no topo do Select Painter.
Para reordenar as colunas selecionadas basta arrastar a coluna desejada com o
mouse até a posição desejada na lista:

Além das colunas provenientes das tabelas, podemos também definir colunas
calculadas. Para isto, devemos selecionar a pasta Compute. Nesta pasta, cada linha
apresentada pode ser utilizada para a definição:
 da expressão da coluna computada, por exemplo: salário / 12;
 de uma função suportada pelo SGBD utilizado, como por exemplo:
substr("employee"."emp_fname",1,2).

Podemos também utilizar um menu popup na pasta de Colunas Computadas para


selecionar e colar colunas, funções e argumentos (se houve a criação dos mesmos).

Visualizando a Sentença SQL


À medida que vamos definindo os dados para o objeto datawindow, o PB na verdade
está gerando a sentença SQL SELECT. Será esta instrução SQL que será enviada ao DBMS
quando utilizarmos a datawindow. Você pode dar uma olhada no SQL que está sendo gerado
enquanto está definindo o seu novo objeto datawindow.
Para visualizar a sentença SQL devemos selecionar a pasta Syntax (ou selecionar
View>Syntax se a mesma não estiver aparecendo correntemente). Esta instrução é atualizada
cada vez que ocorre alguma modificação.

Editando a Sentença SQL Sintaticamente


Ao invés de modificar os dados da datawindow graficamente, você pode editar
diretamente a instrução SELECT no Select painter. Para editar a sentença SELECT:
1. Selecionar o menu Design > Convert to Syntax. O PB apresentará o select em uma
janela de texto;
2. Editar a instrução SQL;
3. Selecionar o menu Design > Convert to Graphics.

Unindo Tabelas (Join)


Se o objeto datawindow contiver dados de mais de uma tabela, você deve unir as
mesmas de acordo com suas colunas comuns.
Se você selecionou mais de uma tabela, o PB:
 unira as colunas baseando-se nos relacionamentos preexistentes no banco de
dados;
 se não existir relacionamento entre as colunas, o PB tentara “adivinhar” o
relacionamento e unira as tabelas baseando-se nos nomes e tipos de colunas em
comum.

O PB mostra um link entre as tabelas que estão apresentando relacionamento na área


de Layout de Tabelas.
A união que o PB faz pode ser diferente dependendo da ordem na qual as tabelas
foram selecionadas, e algumas vezes o “adivinhar” da união pode estar incorreto. Então, você
pode sentir a necessidade de excluir uma união (join) e defini-la manualmente.

22/11/21 Pag.: 90
Curso de POWERBUILDER 7.0

Para excluir uma união:


1. Clicar no operador de união que conecta as tabelas;
2. A caixa de diálogo “join” aparecera;
3. Clicar em “Delete”.

Para definir uma união:

1. Clicar no botão de união ( );


2. Escolher as colunas as quais deseja-se criar o join das tabelas.
3. Para criar joins diferentes do join de igualdade, selecione o operador de join na
área de Layout das Tabelas. A caixa de diálogo “Join” surgira:

4. Selecione o operador join que você deseja e selecione OK.

Clausula Where
Você pode especificar critérios de recuperação para o comando SELECT na área de
Seleção (Where), localizada abaixo das tabelas na janela de definição de objetos datawindow:

22/11/21 Pag.: 91
Curso de POWERBUILDER 7.0

Para especificar o(s) critério(s) de recuperação dos dados, você pode entrar valores
clicando:

· Um nome de tabela/coluna na DropDownListBox no campo Column.


· Um operador a partir da DropDownListBox no campo Operator.
· Uma função no campo Value, clicando o botão direito do mouse e selecionando
Functions.
· Clicando o botão direito do mouse e selecionando a opção SELECT que abre o
Select Painter de novo permitindo a você criar uma cláusula SELECT aninhada.
· Operadores lógicos AND e OR (e ou) a partir da DropDownListBox no campo Logical
(uma nova linha será exibida).

Utilizando Argumentos de Recuperação


Se você sabe exatamente quais linhas serão recuperadas para o objeto datawindow
durante sua execução, isto é, se você pode especificar totalmente a sentença SELECT sem
que haja a necessidade de fornecer uma variável, você não precisa especificar argumentos de
recuperação.

Adicionando Argumentos de Recuperação


Você pode também especificar um comando SQL SELECT que solicite ao usuário ou a
aplicação que forneça um ou mais valores específicos. Por exemplo, o usuário pode precisar
especificar uma identificação de agencia, para que a DataWindow possa recuperar uma lista de
todos os correntistas daquela determinada agencia.
Para especificar argumentos de recuperação:
1. Selecione Retrieve Arguments... a partir do menu Design. A janela Specify
Retrieval Arguments aparecerá:

22/11/21 Pag.: 92
Curso de POWERBUILDER 7.0

2. Especifique o nome e o tipo para cada argumento de recuperação da datawindow e


click OK.
3. Você normalmente usa os argumentos de recuperação nas cláusulas WHERE
(onde) e HAVING (tendo). Para especificar o critério de recuperação de dados, no
HAVING entre com as expressões e operadores nos campos utilizando o mesmo método
já visto para a cláusula WHERE.

Ordenando os Resultados (SORT)


Você pode também especificar que os dados de um comando SQL SELECT sejam
ordenados. Para isto devemos:
1. Selecione a pasta de Ordenação (Sort);
2. Selecione a coluna desejada na área da esquerda e arraste-a para a área da
direita;

22/11/21 Pag.: 93
Curso de POWERBUILDER 7.0

Para mudar a ordem para descendente, click no chekbox próximo ao nome da coluna
selecionada.

Definindo Grupos (Group By)


Você pode agrupar as linhas recuperadas através da especificação de grupos, os quais
correspondem a clausula GROUP BY na sentença SQL SELECT. Este agrupamento ocorre
antes dos dados serem apresentados no datawindow object. Cada group é retornado como
uma linha de dados para o datawindow object.
Como exemplo, vamos definir um grupo para a tabela de Cliente por numero da
agencia, ou seja, vamos obter uma linha de dados do banco de dados para cada agencia
existente na tabela de cliente. Vamos também especificar algumas colunas
calculadas/computadas, como a media de saldo dos clientes, além do maior e menor saldos.
Abaixo o sentença SELECT correspondente:

SELECT "cliente"."num_ag", sum(saldo), min(saldo), max(saldo)


FROM "cliente"
GROUP BY "cliente"."num_ag" ;

Um exemplo de retorno de acordo com meu banco de dados atual seria:

Para definir novo(s) grupo(s):


1. Selecione a pasta de Agrupamento (Group);
2. Selecione a coluna desejada na área da esquerda e arraste-a para a área da
direita;

O exemplo a seguir o datawindow object será agrupado por numero de agencia:

22/11/21 Pag.: 94
Curso de POWERBUILDER 7.0

Além disto, as colunas são agrupadas na ordem em que estão aparecendo no lado
direito da área de agrupamento.
Para excluir um determinado grupo, basta retorná-lo ao lado esquerdo da referida área.
Para alterar a ordem de agrupamento, arraste as colunas da área da direita para as
posições desejadas.

Clausula Having
Se você definiu grupos, você pode então utilizar a clausula HAVING. Esta clausula tem
como objetivo restringir estes grupos. Continuando nosso exemplo, como definimos um grupo
por numero de agencia, vamos restringir o mesmo de tal forma que somente retornem as
agencias que possuam saldo menor que R$ 60.000,00. Tal restrição corresponde a:

SELECT "cliente"."num_ag", sum(saldo), min(saldo), max(saldo)


FROM "cliente"
GROUP BY "cliente"."num_ag"
HAVING sum(saldo) < 60000.00 ;

Um exemplo de retorno de acordo com meu banco de dados atual seria:

Para definir nova(s) clausula(s) HAVING utilizamos o mesmo processo visto


anteriormente para a definição da clausula WHERE.
O nosso exemplo apresentaria a área de seleção (Having) da seguinte forma:

22/11/21 Pag.: 95
Curso de POWERBUILDER 7.0

A fonte de dados EXTERNAL


Sempre que o objeto DataWindow que você está criando não for ser associado a uma
tabela de banco de dados, especifique External (externo) como a fonte de dados. A
DataWindow não emitirá um comando SQL SELECT; ela espera que você forneça os dados
executando comandos PowerScript. Para isto devemos:

1. Apos escolher o modo de apresentação da nova datawindow, a caixa de diálogo Choose


Data Source for XXXXX DataWindow surge. Escolha External e click OK, a caixa de diálogo
Define Result Set (defina o conjunto de resultados) aparece:

2. Já que a DataWindow não terá uma estrutura de alguma tabela do banco de dados como
referência, você deve descrever explicitamente esta estrutura. Entre com as definições de cada
coluna nas caixas e click OK. A área de trabalho do DataWindow Painter mostra o estilo de
DataWindow que você especificou.

22/11/21 Pag.: 96
Curso de POWERBUILDER 7.0

NOTA.
As DataWindows Externals são utilizadas por exemplo quando os dados serão importados de uma
aplicação DDE, exemplo Excel.

22/11/21 Pag.: 97
Curso de POWERBUILDER 7.0

INFORMAÇÕES SOBRE O CURSO E A APOSTILA

Para o desenvolvimento desta apostila, utilizei como referência o


livro abaixo, o qual recomendo para pessoas não iniciantes. Grande parte
foi elaborada pôr mim mesmo, pela experiência nos sistemas que
participei como desenvolvedor, nos cursos que realizei e alguns que
ministrei.
Qualquer informação sobre cursos, tanto básico como avançado,
favor entrar em contato através do meu e-mail.
Trabalho com PB desde 1994 e tenho empresa aberta para poder
emitir notas fiscais dos cursos.

Bibliografia de referência:
Advanced PowerBuilder 7 Techniques
Editora: Wiley
Autores: Ramesh Chandak e Purshottam Chandak

Desenvolvida pôr: Rodrigo Domiciano de Souza


e-mail(s): rdomiciano@hotmail.com, domiciano@finasa.com.br
Consultor PowerBuilder

22/11/21 Pag.: 98

Você também pode gostar