Combobox no StringGrid - Bug

24/06/2008

0

Saudações!!!

Caros(as) amigos(as), eu pesquisei na net e encontrei uma solução publicada aqui e em outros sites da implementação de um combobox no stringgrid. Tenho uma aplicação onde há um campo com itens, aí eu criei uma procedure básica para preencher o combo com os itens cadastrados pelo usuário. Logo em seguida, é feito o processo da inclusão do combo em cada linha que contiver registros. O combo só ficará visível e editável somente quando o modo de dataset estiver como dsinsert. Ótimo, só não é perfeito por um pequeno detalhe: tenho 1 campo chamado data e outro área, que é o que contém o combo. Se eu selecionar um item do combo ou digitar diretamente nele, quando clico na célula pra digitar a data, simplesmente recebe o conteúdo do combo, e ainda pior, se eu cancelar o registro, limpa a linha inteira, porém quando é feito um refresh para atualizar o grid, a primeira célula (da data) fica em branco, e aí vira uma salada só. Gostaria de saber o por que que o conteúdo do combo é copiado para outra célula que será editada, e se há uma solução, por favor publique e ficarei imensamente grato.

Código (apenas as partes principais):

procedure TfrmPaciEqMult.FormShow(Sender: TObject);
begin
edtrghc.Text := frmIdentifica.edtRGHC.text;
edtPaciente.Text := frmIdentifica.edtNome.text + ´ ´ + frmidentifica.edtSobrenome.text;
sgData.ColWidths[0] := 10;
sgData.ColWidths[1] := 0;
sgData.ColWidths[2] := 60;
sgData.ColWidths[3] := 145;
sgData.RowCount := 0;
PreencheAreaCombo;
MontaEquipeMulti;
end;

// Preenche o combo
procedure TfrmPaciEqMult.PreencheAreaCombo;
begin
with dm.cdsAux2 do
begin
close;
commandtext := ´´;
commandtext := ´ SELECT PC_EQ_MULT_AREA FROM PACI_EQUIP_MULT ´ +
´ ORDER BY PC_EQ_MULT_AREA´;
open;
if not IsEmpty then
begin
while not eof do
begin
cbbxArea.Items.Add(FieldByName(´PC_EQ_MULT_AREA´).AsString);
next;
end;
end;
end;
end;

// Carrega os dados no grid
procedure TfrmPaciEqMult.MontaEquipeMulti;
var
i : integer;
begin
// Seleciona os dados para serem preenchidos no grid e nos campos profissional e observação
with dm.cdsEqMultDisc do
begin
close;
commandtext := ´ SELECT * FROM PACI_EQUIP_MULT ´ +
´ WHERE PACI_COD = ´ + QuotedStr(dm.vPaci_cod) + ´ ´ +
´ ORDER BY PC_EQ_MULT_DAT DESC´;
open;

if not eof then
begin
sgData.RowCount := Recordcount + 1;
for i := 1 to Recordcount do
begin
sgData.Cells[1,i] := FieldByName(´PC_EQ_MULT_COD´).AsString;
sgData.Cells[2,i] := FieldByName(´PC_EQ_MULT_DAT´).AsString;
sgData.Cells[3,i] := FieldByName(´PC_EQ_MULT_AREA´).AsString;
next;
end;
first;
HabilitaDesabilitaBotoes(dsEdit);
end
else
begin
edtProfissional.Enabled := false;
mmObs.Enabled := false;
HabilitaDesabilitaBotoes(dsBrowse);
sgData.Cells[2, sgData.RowCount - 1] := ´´;
sgData.Cells[3, sgData.RowCount - 1] := ´´;
sgData.RowCount := 2;
end;

edtProfissional.Text := FieldByName(´PC_EQ_MULT_PROF´).AsString;
mmObs.Text := FieldByName(´PC_EQ_MULT_TEX´).AsString;
sgData.Col := 2;
sgData.Row := 1;
sgData.Cells[2,0] := ´Data´;
sgData.Cells[3,0] := ´Área´;
sgData.FixedRows := 1;
end;
end;

//// Montagem do combobox no stringgrid
procedure TfrmPaciEqMult.FormCreate(Sender: TObject);
begin
sgData.DefaultRowHeight := cbbxArea.Height;
end;

procedure TfrmPaciEqMult.cbbxAreaChange(Sender: TObject);
begin
sgData.Cells[sgData.Col, sgData.Row] := cbbxArea.Items[cbbxArea.ItemIndex];
cbbxArea.Visible := false;
//sgData.SetFocus;
end;

no onexit do combo, segue o mesmo código acima

procedure TfrmPaciEqMult.sgDataSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
vR : TRect;
begin
// Desenha o combobox no grid
if (ACol = 3) and (ARow <> 0) then
begin
vR := sgData.CellRect(ACol, ARow);
vR.Left := vR.Left + sgData.Left;
vR.Right := vR.Right + sgData.Left;
vR.Top := vR.Top + sgData.Top;
vR.Bottom := vR.Bottom + sgData.Top;
cbbxArea.Left := vR.Left + 1;
cbbxArea.Top := vR.Top + 1;
cbbxArea.Width := (vR.Right + 1) - vR.Left;
cbbxArea.Height := (vR.Bottom + 1) - vR.Top;
end;
//CanSelect := true;

// Deixa o grid em edição quando o usuário estiver incluindo um registro
if vModoDataSet = dsInsert then
begin
if arow = sgdata.RowCount - 1 then
begin
cbbxArea.Visible := true;
cbbxArea.SetFocus;
sgdata.Options := sgdata.options + [goEditing];
end
else
begin
cbbxArea.Visible := false;
sgdata.Options := sgdata.options - [goEditing];
end;
end
else
begin
// Mostra o conteúdo da observação da data selecionada
if sgData.Cells[2, Arow] <> ´´ then
PreencheCampos(ARow)
else
begin
edtProfissional.Clear;
mmObs.Clear;
end;
//cbbxArea.Visible := false;
end;
end;

Estou utilizando Delphi 2005 + DBxpress + SqlServer 2000.
Os dados que são preenchidos do combo vem de um campo chamado PC_EQ_MULT_AREA



[]s


Roger1976

Roger1976

Responder

Posts

25/06/2008

Roger1976

Caros(as) amigos(as), após trocas de idéias com meu amigo de trabalho, fizemos algumas modificações e agora está funcionando corretamente, lembrando que a solução que postarei aqui pode ser discutida por quem estiver lendo o tópico, e para o momento é a melhor. Ignorem o código que postei anteriormente e considerem o que colocarei abaixo.

[b:6d786b8c5a]No ONCREATE do form:[/b:6d786b8c5a]
procedure TfrmPaciEqMult.FormCreate(Sender: TObject);
begin
sgData.DefaultRowHeight := cbbxArea.Height - 2;
end;

[b:6d786b8c5a]No ONSHOW do form:[/b:6d786b8c5a]procedure TfrmPaciEqMult.FormShow(Sender: TObject);
begin
...
PreencheAreaCombo; // [b:6d786b8c5a]carrega os dados do campo PC_EQ_MULT_AREA no combo[/b:6d786b8c5a]
...
end;

[b:6d786b8c5a]No botão NOVA DATA (para fazer a inclusão do registro):[/b:6d786b8c5a]
procedure TfrmPaciEqMult.btnNovoClick(Sender: TObject);
begin
...
cbbxArea.itemindex := -1;
vStatusCombo := 0;
...
end;

[b:6d786b8c5a]No ONDRAWCELL do stringgrid, para desenhar o combobox na célula:[/b:6d786b8c5a]procedure TfrmPaciEqMult.sgDataDrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
begin
if (gdSelected in state) and (vStatusCombo = 0) then
begin
if (ACol = 3) and (ARow = sgData.RowCount - 1) and (vModoDataSet = dsInsert) then
begin
cbbxArea.Top := rect.Top + sgData.top ;
cbbxArea.Left := rect.Left + sgData.left + 3;
cbbxArea.Visible := true;
cbbxArea.SetFocus;
vStatusCombo := 1;
end
else
cbbxArea.Visible := false;
end;
end;

[b:6d786b8c5a]No ONSELECTCELL do stringgrid:[/b:6d786b8c5a]
procedure TfrmPaciEqMult.sgDataSelectCell(Sender: TObject; ACol, ARow: Integer;
var CanSelect: Boolean);
var
vR : TRect;
begin
cbbxArea.Text := sgdata.Cells[Acol,Arow];
// Deixa o grid em edição quando o usuário estiver incluindo um registro
if vModoDataSet = dsInsert then
begin
if arow = sgdata.RowCount - 1 then
begin
sgdata.Options := sgdata.options + [goEditing];
end
else
begin
sgdata.Options := sgdata.options - [goEditing];
end;
end
else
begin
// Mostra o conteúdo da observação da data selecionada
if sgData.Cells[2, Arow] <> ´´ then
PreencheCampos(ARow)
else
begin
edtProfissional.Clear;
mmObs.Clear;
end;
cbbxArea.Visible := false;
end;
vStatusCombo := 0;
end;

[b:6d786b8c5a]No ONEXIT do combobox:[/b:6d786b8c5a]
procedure TfrmPaciEqMult.cbbxAreaExit(Sender: TObject);
begin
if not (sender is TBitBtn) then
begin
sgData.Cells[3, sgData.Row] := cbbxArea.Items[cbbxArea.ItemIndex];
cbbxArea.Visible := false;
end;
sgData.Cells[3, sgData.RowCount -1] := cbbxArea.Text;
end;

[b:6d786b8c5a]No ONEXIT do memo onde é digitada a observação:[/b:6d786b8c5a]
procedure TfrmPaciEqMult.mmObsEnter(Sender: TObject);
begin
...
PreencheAreaCombo; // Atualiza os dados do combobox
end;

É só.

Desde já agradeço a atenção de todos, e estejam à vontade para exporem suas opiniões e dar uma outra solução, que pode ser melhor do que a minha.

[]s


Responder

Que tal ter acesso a um e-book gratuito que vai te ajudar muito nesse momento decisivo?

Ver ebook

Recomendado pra quem ainda não iniciou o estudos.

Eu quero
Ver ebook

Recomendado para quem está passando por dificuldades nessa etapa inicial

Eu quero

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar