ActiveDelphi - Índice do Fórum ActiveDelphi
.: O site do programador Delphi! :.
 
 FAQFAQ   PesquisarPesquisar   MembrosMembros   GruposGrupos   RegistrarRegistrar 
 PerfilPerfil   Entrar e ver Mensagens ParticularesEntrar e ver Mensagens Particulares   EntrarEntrar 

Campo Adicional ClientDataSet [Resolvido]

 
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi
Exibir mensagem anterior :: Exibir próxima mensagem  
Autor Mensagem
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Qui Jul 17, 2014 11:28 am    Assunto: Campo Adicional ClientDataSet [Resolvido] Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qui Jul 17, 2014 12:02 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Qui Jul 17, 2014 3:05 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Qui Jul 17, 2014 4:00 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Qui Jul 17, 2014 5:22 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular
johnny-walker
Moderador
Moderador


Registrado: Sábado, 4 de Outubro de 2003
Mensagens: 10653
Localização: Contagem/MG - BRAZIL

MensagemEnviada: Sex Jul 18, 2014 11:31 am    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular MSN Messenger
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Sex Jul 18, 2014 2:00 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Seg Jul 21, 2014 5:29 pm    Assunto: Responder com Citação

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. Smile

Desde já, agradeço as dicas de todos. Wink
_________________
"O sábio nunca diz tudo o que pensa, mas pensa sempre tudo o que diz." (Aristóteles)
Voltar ao Topo
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Ter Jul 22, 2014 10:45 am    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Ter Jul 22, 2014 1:49 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Ter Jul 22, 2014 3:45 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Ter Jul 22, 2014 4:13 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
imex
Moderador
Moderador


Registrado: Sexta-Feira, 7 de Janeiro de 2011
Mensagens: 11666

MensagemEnviada: Ter Jul 22, 2014 4:23 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular
wjuniordias
Profissional
Profissional


Registrado: Sexta-Feira, 16 de Março de 2012
Mensagens: 667

MensagemEnviada: Ter Jul 22, 2014 4:25 pm    Assunto: Responder com Citação

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
Ver o perfil de Usuários Enviar Mensagem Particular Visitar a homepage do Usuário MSN Messenger
Mostrar os tópicos anteriores:   
Novo Tópico   Responder Mensagem    ActiveDelphi - Índice do Fórum -> Delphi Todos os horários são GMT - 3 Horas
Página 1 de 1

 
Ir para:  
Enviar Mensagens Novas: Proibido.
Responder Tópicos Proibido
Editar Mensagens: Proibido.
Excluir Mensagens: Proibido.
Votar em Enquetes: Proibido.


Powered by phpBB © 2001, 2005 phpBB Group
Traduzido por: Suporte phpBB