Relatorios QReport com relacionamento entre tabelas MySQL

Delphi

29/12/2008

Olá a todos.


Estou com a seguinte dúvida:

Tenho uma tabela de clientes e uma de telefones dos clientes.

Na tabela de telefones, tenho o ID do cliente a quem este telefone pertence.

Bem... no relatório deve constar todos os dados do cliente, bem como, todos os seus telefones cadastrados.

Coloquei através de QRText´s os dados do cliente num Detail, mas não consigo fazer com que apareçam todos os telefones cadastrados. O máximo que consegui foi fazer aparecer apenas o primeiro telefone que estava cadastrado.

Estou usando MySQL e os componentes para acesso ZEOS.


Será que alguém, por favor, poderia me ajudar?


Obrigado desde já,

Sérgio Gobbo


Sérgio Gobbo

Sérgio Gobbo

Curtidas 0

Respostas

Micheus

Micheus

29/12/2008

[b:1425e1739b]Sérgio Gobbo[/b:1425e1739b], você poderia usar o evento BeforePrint da banda, onde imprime os dados do cliente, para fazer a concatenação das informações contidas no dataset do telefone e utilizar um QRLabel para mostrar o resultado da concatenação.


GOSTEI 0
Sérgio Gobbo

Sérgio Gobbo

29/12/2008

Obrigado pela ajuda micheus, mas num entendi direito.

Eu gostaria que no preview do relatório fosse exibido os dados de duas tabelas, que se relacionam através do código do cliente.

Por exemplo:

Vai aparecer todos os dados da tabela tbClientes, ou seja, todo o cadastro daquele cliente, e vai listar todos os registros contidos na tabela tbTelefones, que tenham o id daquela cliente.

O problema é que só aparece um registro da tbTelefone, sendo que tem uns 10, por exemplo. Eu devo estar fazendo alguma relação incorreta nos componentes, mas não sei o que deve ser configurado, entende?

Se alguém que saiba fazer relatórios através do qreport puder me passar os passos ou algum exemplo em que se pegue informações de mais de uma tabela no mesmo relatório, me ajudaria muito.


Muito obrigado pela ajuda de todos.


GOSTEI 0
Micheus

Micheus

29/12/2008

[quote:99be7a23ec=´Sérgio Gobbo´]O problema é que só aparece um registro da tbTelefone, sendo que tem uns 10, por exemplo. Eu devo estar fazendo alguma relação incorreta nos componentes, mas não sei o que deve ser configurado, entende?[/quote:99be7a23ec]Eu entendi o que vc quer fazer, apenas tentei dizer como vc poderia fazê-lo.

A questão é que não está claro como vc quer mostrar estes números de telefone.
Por ex., se eles forem apresentados entre os dados do cadastro do cliente, ou seja, na mesma banda que vc usou para mostra estas informações (imagino que seja uma banda to tipo [i:99be7a23ec]rbDetail[/i:99be7a23ec]), então uma opção seria a que citei: concatenar os vários números em uma string e mostrá-la usando um componente [i:99be7a23ec]TQRLabel[/i:99be7a23ec];
Caso estes números possam ocupar mais que uma linha, seria conveniente utilizar bandas filhas para pôr este componente (TQRChildBand - através da habilitação da propriedade [i:99be7a23ec]HasChild[/i:99be7a23ec] da [i:99be7a23ec]rbDetail[/i:99be7a23ec]) e manter a propriedade [i:99be7a23ec]AutoSize=False[/i:99be7a23ec], [i:99be7a23ec]AutoStretch=True[/i:99be7a23ec] e configurar a propriedade [i:99be7a23ec]Width[/i:99be7a23ec] com a largura de praticamente toda a banda.
Outra opção, utilizar um componente [i:99be7a23ec]TQRMemo[/i:99be7a23ec], também colocado em uma banda filha, para que possa ocupar várias linhas no relatório e ao invés de concatenar, simplesmente adiciona cada número a uma nova linha na propriedade [i:99be7a23ec]Lines[/i:99be7a23ec] do componente;

Já se os números forem adicionados ao final dos dados do cliente, então vc poderia utilizar uma banda do tipo [i:99be7a23ec]TQRSubDetail[/i:99be7a23ec], com a propriedade [i:99be7a23ec]DataSet[/i:99be7a23ec] setada para o dataset telefones. Este seria um caso em que vc simplesmente configuraria o componente TQRDBText para mostrar o campo telefone, e seria mostrada, abaixo dos dados do cliente, uma linha para cada telefone relacionado a ele.

Para todas as opções, o relacionamento entre os datasets tem que existir. Voce não informou qual componentes usa para o acesso (se TZTable, TZQuery), conforme o caso o relacionamento é feito de um modo.
Mas, para tentar lhe dar uma luz, vamos a várias suposições:
- que vc tenha usado TZQuery;
- que o nome das suas tabelas sejam Clientes e Telefones;
- que o nome dos datasets sejam QClientes e QTelefones;
- que o nome do campo de identificação seja ID em ambas as tabelas;
- que as propriedades SQL, sejam:
QClientes: select * from Clientes
QTelefones: select * from Telefones where ID = :ID

Assim, o relacionamento entre os datasets seria realizado de QTelefones para QClientes, e para isto será necessário adicionar um componente TDataSource (chamarei [i:99be7a23ec]DSClientes[/i:99be7a23ec]), com a propriedade [i:99be7a23ec]DataSet[/i:99be7a23ec] apontando para [i:99be7a23ec]QClientes[/i:99be7a23ec]. Deste modo, será possível selecionar [i:99be7a23ec]DSClientes[/i:99be7a23ec] na propriedade [i:99be7a23ec]MasterSource[/i:99be7a23ec] do dataset [i:99be7a23ec]QTelefones[/i:99be7a23ec].

Com esta configuração, antes de apresentar o relatório vc abre o dataset [i:99be7a23ec]QClientes[/i:99be7a23ec] e em seguida [i:99be7a23ec]QTelefones[/i:99be7a23ec]. Com este procedimento, o valor para o parâmetro [i:99be7a23ec]ID[/i:99be7a23ec] definido no SQL de QTelefones será obtido do dataset [i:99be7a23ec]QClientes[/i:99be7a23ec] (via [i:99be7a23ec]MasterSource[/i:99be7a23ec]). Resumindo, estará feito o filtro dos telefones de cada cliente sendo processado.

Então, se vc usar a opção da banda sub-detail, não terá mais nada a fazer. Caso use as outras abordagens, como disse no post anterior, vc terá que fazer isto na mão, via evento BeforePrint da banda onde o componente mostrará os dados:
// versão para QRLabel
procedure TRelCliente.QRBand1BeforePrint(Sender: TQRCustomBand;  var PrintBand: Boolean);
var
  Fones :string;
begin
  Fones := ´´;
  QTelefones.First;
  while not QTelefones.EOF do
  begin
    Fones := Fones +´, ´ +QTelefones.FieldByName(´NumFone´).AsString;
    QTelefones.Next;
  end;
  Delete(Fones, 1, 2); // remove ´, ´ iniciais - ocorre na 1ª concatenação
  QRLabelFone.Caption := Fones;
end;

// versão para QRMemo
procedure TRelCliente.QRBand1BeforePrint(Sender: TQRCustomBand;  var PrintBand: Boolean);
begin
  QTelefones.First;
  while not QTelefones.EOF do
  begin
    QRMemo1.Lines.Add(QTelefones.FieldByName(´NumFone´).AsString);
    QTelefones.Next;
  end;
end;

Como vê, uma resposta correta/definitiva depende das informações que vc passa. Poderia dar outras opções...

Acredito que vc consiga avançar um pouco, lendo com paciência e tentando captar o espírito da coisa.

Abraços


GOSTEI 0
POSTAR