 |
ActiveDelphi .: O site do programador Delphi! :.
|
| Exibir mensagem anterior :: Exibir próxima mensagem |
| Autor |
Mensagem |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Qui Jul 17, 2014 11:28 am Assunto: Campo Adicional ClientDataSet [Resolvido] |
|
|
Olá pessoal,
É possível criar um campo no CDS sem que o mesmo exista numa tabela do banco?
Para facilitar o entendimento, vou dar alguns detalhes:
Tenho um "sqlDataSet" com a seguinte instrução SQL:
| Código: |
select id_cliente, nome, cidade from cliente
|
Também existe um "dataSetProvider" ligado ao "sqlDataSet", e finalmente um "clientDataSet" ligado ao "dataSetProvider".
O que eu preciso, é criar no "clientDataSet" um campo a mais, porém que não está trazendo no select. Seria o campo "check" do tipo boolean.
Se eu tentar pesquisar, da um erro dizendo que o campo "check" não foi encontrado. Aí está minha dúvida, existe alguma propriedade que eu configuro no "clientDataSet" para ignorar esse campo?
Porque estou tentando criar um checkbox na DBGrid, e preciso de um campo pra eu verificar através de uma função, se o mesmo esta marcado ou não na grid, pra eu poder pintar a linha referente.
Esse problema seria resolvido, se eu criar um CDS temporário, mas, quero saber se consigo fazer isso sem precisar criar um temporário.
Qualquer dúvida, eu explico com mais detalhes.
Grato. _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles)
Editado pela última vez por wjuniordias em Ter Jul 22, 2014 1:52 pm, num total de 1 vez |
|
| Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Qui Jul 17, 2014 12:02 pm Assunto: |
|
|
Bom dia,
Para esse caso acho que você pode criar um campo do tipo InternalCalc no ClientDataSet.
Espero que ajude.
Editado pela última vez por imex em Dom Out 01, 2023 3:34 pm, num total de 1 vez |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Qui Jul 17, 2014 3:05 pm Assunto: |
|
|
Ok, vou fazer isso, logo posto se deu certo ou não. Obrigado pela dica. _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Qui Jul 17, 2014 4:00 pm Assunto: |
|
|
Deu certo. Só que agora o "DBCheckBox" não aparece na DBGrid, no lugar aparece "True" ou "False". rs
Será que tem a ver com o tipo do campo, que antes era "fkData" e agora "fkInternalCalc"?
Acredito que não, mas por descargo de consciência resolvi perguntar.
Grato. _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Qui Jul 17, 2014 5:22 pm Assunto: |
|
|
| Acho que teria você teria que analisar o seu código. Pode ser que esteja em um bloco que só é executado quando o campo é um fkData... |
|
| Voltar ao Topo |
|
 |
johnny-walker Moderador


Registrado: Sábado, 4 de Outubro de 2003 Mensagens: 10653 Localização: Contagem/MG - BRAZIL
|
Enviada: Sex Jul 18, 2014 11:31 am Assunto: |
|
|
Amigo é possível sim criar tal campo, mas não pode fazer parte nem da cláusula WHERE e nem da UPDATE, pois lhe causaria erro.
Bem se vc estiver com dificuldade em criar o checkbox, eis um código que utilizo:
| Código: | procedure TForm1.FormCreate(Sender: TObject);
begin
DBCheckBox1.DataSource := DataSource1;
DBCheckBox1.DataField := 'DIRETOR';
DBCheckBox1.Visible := False;
DBCheckBox1.Color := DBGrid1.Color;
DBCheckBox1.Caption := '';
DBCheckBox1.AllowGrayed:= False;
//explained later in the article
DBCheckBox1.ValueChecked := 'T';
DBCheckBox1.ValueUnChecked := 'F';
end;
procedure TForm1.DBGrid1ColExit(Sender: TObject);
begin
if DBGrid1.SelectedField <> nil then
if DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField then
DBCheckBox1.Visible := False
end;
procedure TForm1.DBGrid1KeyPress(Sender: TObject; var Key: Char);
begin
if (Key = Chr(9)) then
Exit;
if (DBGrid1.SelectedField.FieldName = DBCheckBox1.DataField) then
begin
DBCheckBox1.SetFocus;
SendMessage(DBCheckBox1.Handle, WM_Char, word(Key), 0);
end;
end;
procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const IsChecked : array[Boolean] of Integer =
(DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or DFCS_CHECKED);
var
DrawState: Integer;
DrawRect: TRect;
begin
if gdSelected in State then
begin
Canvas.FillRect(Rect);
Canvas.Brush.Color := clHighLight;//clBackground; // Cor de seleção
Canvas.Font.Color := clHighLightText;//clWhite;//$00FFF2D9;//clYellow;
end
else
inherited;
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
if (gdFocused in State) then
begin
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
DBCheckBox1.Top := Rect.Top + DBGrid1.top + 2;
DBCheckBox1.Width := Rect.Right - Rect.Left;
DBCheckBox1.Height := Rect.Bottom - Rect.Top;
DBCheckBox1.Visible := True;
end
end
else
begin
if Column.Field <> nil then
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DrawRect:=Rect;
InflateRect(DrawRect,-1,-1);
DrawState := ISChecked[Column.Field.AsBoolean];
DBGrid1.Canvas.FillRect(Rect);
DrawFrameControl(DBGrid1.Canvas.Handle, DrawRect,
DFC_BUTTON, DrawState);
end;
end;
end;
end.
|
bye _________________ P.O.W.E.R B.Y D.E.L.P.H.I |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Sex Jul 18, 2014 2:00 pm Assunto: |
|
|
Legal, neste caso, eu teria que configurar o providerFlags deste campo né? _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Seg Jul 21, 2014 5:29 pm Assunto: |
|
|
Então pessoal, se eu criar um CDS temporário com os mesmos campos do CDS original, e no temporário criar um campo "Check" do tipo Boolean (fkData), e seguir os passos do link abaixo, o DBCheckBox aparece na DBGrid.
http://delphi.about.com/od/usedbvcl/l/aa082003a.htm
Acontece que eu tenho que fazer um procedimento para popular o temporário, ou seja, que le todos os dados do CDS original e popula o temporário.
Isso me toma muito o tempo, por isso que estou tentando procurar uma solução que me permita ter o mesmo efeito, só que com o CDS original.
Se eu crio um campo no dataset da erro de "Field Not Found" ao executar o SQL, mesmo configurando o "ProviderFlags".
Se eu alterar o campo para "InternalCalc", elimina o erro citado, contudo, o DBCheckBox não aparece na DBGrid. Mostra apenas "True" ou "False".
Claro que existem componentes de terceiros que resolveriam meu problema, mas procuro não utilizá-los, porque já tive problema quando precisei mudar de versão no Delphi e certos componentes não terem suporte, aí tive que sair alterando tudo.
Se não tiver como, tudo bem, eu crio o temporário mesmo, mas, vai que alguém conhece alguma forma que simplifica isso tudo, exatamente por isso que resolvi postar aqui.
Desde já, agradeço as dicas de todos.  _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Ter Jul 22, 2014 10:45 am Assunto: |
|
|
Acho que o fkInternalCalc deveria funcionar da mesma forma que o fkData.
Você adicionou algum código no evento OnCalcFields do Cds?
Você verificou se os blocos de código que estão abaixo do If que segue são executados?
| Código: | | if (Column.Field.FieldName = DBCheckBox1.DataField) then |
Talvez seja melhor você postar o seu código do OnCalcFields e do OnDrawColumnCell.
Outra alternativa, que sinceramente acho desnecessária, seria criar um campo na query para utiliza-lo no Cds como fkData, desabilitando no caso todas as ProviderFlags. Ex:
| Código: | | select *, 'T' as CampoCheck from Tabela |
Espero que ajude. |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Ter Jul 22, 2014 1:49 pm Assunto: |
|
|
Então, estranho, porque se eu usar InternalCalc, o DBCheckBox não aparece na DBGrid. Não tenho nenhuma implementação no evento "OnCalcFields".
Se eu volto para "fkData" da erro de "Field Not Found", e se eu crio em um ClientDataSet temporário, dá certo, isso sem alterar nada no código. rsrs
Muito estranho, mas, se fizer criando o campo no sql igual vc (imex) mostrou, da certo também, sem ter que criar um temporário e popular. Resolveu meu problema. Muito obrigado.
Segue abaixo o código que eu uso no evento "OnDrawColumnCell":
| Código: |
procedure TfrmPesquisa.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;
DataCol: Integer; Column: TColumn; State: TGridDrawState);
const
IsChecked: array [Boolean] of Integer = (DFCS_BUTTONCHECK, DFCS_BUTTONCHECK or
DFCS_CHECKED);
var
DrawState: Integer;
DrawRect: TRect;
begin
if (DM.cdsAuxSELECT.AsBoolean) then
begin
if gdSelected in State then
DBGrid1.Canvas.Brush.Color := clSkyBlue
else
DBGrid1.Canvas.Brush.Color := clSkyBlue;
DBGrid1.Canvas.Font.Style := [fsBold];
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end;
if (gdFocused in State) then
begin
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DBCheckBox1.Left := Rect.Left + DBGrid1.Left + 2;
DBCheckBox1.Top := Rect.Top + DBGrid1.Top + 2;
DBCheckBox1.Width := Rect.Right - Rect.Left;
DBCheckBox1.Height := Rect.Bottom - Rect.Top;
DBCheckBox1.Visible := True;
end
end
else
begin
if (Column.Field.FieldName = DBCheckBox1.DataField) then
begin
DrawRect := Rect;
InflateRect(DrawRect, -1, -1);
DrawState := IsChecked[Column.Field.AsBoolean];
DBGrid1.Canvas.FillRect(Rect);
DrawFrameControl(DBGrid1.Canvas.Handle, DrawRect, DFC_BUTTON, DrawState);
end;
end;
end;
|
Se encontrarem alguma coisa que deve ser alterado, posta aí, senão, sem problema, a dica do campo no SQL já resolveu tb. Obrigado imex, e obrigado a todos. Abraço. _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Ter Jul 22, 2014 3:45 pm Assunto: |
|
|
| Só para tentar entender melhor, qual é o nome do campo do tipo fkInternalCalc, e como está preenchida a propriedade DataField do DBCheckBox1? |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Ter Jul 22, 2014 4:13 pm Assunto: |
|
|
| imex escreveu: | | Só para tentar entender melhor, qual é o nome do campo do tipo fkInternalCalc, e como está preenchida a propriedade DataField do DBCheckBox1? |
Campo fkInternalCalc: Select
DataField do DBCheckBox1: Select
Era "check" depois resolvi alterar para "Select". _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
imex Moderador

Registrado: Sexta-Feira, 7 de Janeiro de 2011 Mensagens: 11666
|
Enviada: Ter Jul 22, 2014 4:23 pm Assunto: |
|
|
Não testei, pode ser que não tenha relação com o problema, mas experimente comentar o trecho abaixo:
| Código: | if (DM.cdsAuxSELECT.AsBoolean) then
begin
if gdSelected in State then
DBGrid1.Canvas.Brush.Color := clSkyBlue
else
DBGrid1.Canvas.Brush.Color := clSkyBlue;
DBGrid1.Canvas.Font.Style := [fsBold];
DBGrid1.Canvas.FillRect(Rect);
DBGrid1.DefaultDrawColumnCell(Rect, DataCol, Column, State);
end; |
Espero que ajude. |
|
| Voltar ao Topo |
|
 |
wjuniordias Profissional


Registrado: Sexta-Feira, 16 de Março de 2012 Mensagens: 667
|
Enviada: Ter Jul 22, 2014 4:25 pm Assunto: |
|
|
imex, realmente o campo InternalCalc dá certo sim, foi falta de atenção minha na implementação em algum momento, porque resolvi começar um projeto novo e ir fazendo parte por parte e agora deu certo.
Obrigado novamente e desculpe pela minha falta de atenção. _________________ "O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles) |
|
| Voltar ao Topo |
|
 |
|
|
Enviar Mensagens Novas: Proibido. Responder Tópicos Proibido Editar Mensagens: Proibido. Excluir Mensagens: Proibido. Votar em Enquetes: Proibido.
|
|