Combobox no StringGrid - Bug

Delphi

24/06/2008

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

Curtidas 0

Respostas

Roger1976

Roger1976

24/06/2008

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


GOSTEI 0
POSTAR