Fórum Somar campos selecionados DBGrid sem uso do multselect? #362270
08/08/2008
0
O código é este aqui.
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, DBGrids, Db, DBTables, StdCtrls, Mask, JvExMask, JvToolEdit,
JvBaseEdits;
type
TForm1 = class(TForm)
Table1: TTable;
DataSource1: TDataSource;
DBGrid1: TDBGrid;
Table1EmpNo: TIntegerField;
Table1LastName: TStringField;
Table1FirstName: TStringField;
Table1PhoneExt: TStringField;
Table1HireDate: TDateTimeField;
Table1Salary: TFloatField;
Button1: TButton;
JvCalcEdit1: TJvCalcEdit;
procedure DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
procedure DBGrid1CellClick(Column: TColumn);
procedure Button1Click(Sender: TObject);
private fMouseOverRow : integer;
FSelecionados : array of integer;
function GetIndex(Value : Integer) : Integer;
public
{ Public declarations }
end;
var
Form1: TForm1;
implementation
{$R *.DFM}
type
THakGrid = class(TCustomGrid);
function TForm1.GetIndex(Value: Integer): Integer;
var
I : Integer;
begin
for I := 0 to High(FSelecionados) do
begin
if FSelecionados[I] = Value then
//poderia fazer uma busca indexada pra agilizar
//mas vai ficar pra proxima.
begin
Result := I;
Exit;
end;
end;
Result := -1;
end;
procedure TForm1.DBGrid1DrawDataCell(Sender: TObject; const Rect: TRect;
Field: TField; State: TGridDrawState);
begin
if GetIndex(Table1.RecNo) > -1 then
DBGrid1.Canvas.Brush.Color := clSkyBlue;
DBGrid1.DefaultDrawDataCell(Rect, Field, State);
end;
procedure TForm1.DBGrid1CellClick(Column: TColumn);
var
I, I2 : Integer;
begin
I := GetIndex(Table1.RecNo);
if 0 > I then
begin
I := High(FSelecionados) + 1;
SetLength(FSelecionados, I + 1);
FSelecionados[I] := Table1.RecNo;
end else
begin
I2 := High(FSelecionados);
if I2 > I then
Move(FSelecionados[I+1], FSelecionados[I], I2-I);
SetLength(FSelecionados, I2);
end;
THakGrid(DBGrid1).InvalidateRow(THakGrid(DBGrid1).Row);
end;
end.Só que eu aqui uso o Mutselect para somar campos que em marcar no dbgrid assim
procedure TForm1.BtnSomaClick(Sender: TObject); var i: Integer; Valor : Single; begin if DBGrid1.SelectedRows.Count > 0 then begin Valor := 0; with DBGrid1.DataSource.DataSet do begin for i := 0 to DBGrid1.SelectedRows.Count-1 do begin GotoBookmark(Pointer(DBGrid1.SelectedRows.Items[i])); Valor := Valor + Table1.FieldByName(´Salary´).AsFloat; end; end; jvCalcEdit1.Text := FloatToStr(Valor); end end;
Só que ai funciona apenas se eu selecionar os que eu quero somar no dbgrid, gostaria de saber se tem como fazer esta soma usando o código que o colega fez, sem precisar do uso do multselect do dbgrid.
Adriano_servitec
Curtir tópico
+ 0Posts
08/08/2008
Adriano_servitec
procedure TForm1.BtnTotalClick(Sender: TObject); var i: Integer; Valor : Single; begin if High(FSelecionados) > -1 then begin Valor := 0; with DBGrid1.DataSource.DataSet do begin for i := 0 to High(FSelecionados) do begin RecNo := FSelecionados[i]; Valor := Valor + Table1.FieldByName(´Salary´).AsFloat; end; end; jvCalcEdit1.Text := FloatToStr(Valor); end end;
Gostei + 0
09/08/2008
Marco Salles
Este Cogigo tem erro não ???
veja um exemplo
Selecione os Items nesta ordem
table.Recno -->> 10 , 8, 7 , 9 , 13
Agora desmarque o Item Table.RecNo = 8
de modo que fique somente os Items :
table.Recno -->> 10 , 7 , 9 , 13
Ate ai beleza ... Funciona ????
então Minimize o Formulário e veja o que acontece ...
[b:07afb423c2]o Item 13º marcado irá sumir....[/b:07afb423c2]
para corrigir este inconveniente acredito que dá , mas requer um pouco de codificação extra
Gostei + 0
09/08/2008
Adriano_servitec
Valeu amigo.
Gostei + 0
09/08/2008
Adriano_servitec
De qualquer modo, vc tem alguma ideia de como resolver isso amigo?
Gostei + 0
09/08/2008
Marco Salles
não estou aqui com o delphi
A principio olhando o codigo pensei que necessita-sse de codificação extra
mas na fila do mercado (rsss) pensei que talves a simples alteração
de
I2 := High(FSelecionados); if I2 > I then Move(FSelecionados[I+1], FSelecionados[I], I2-I);
para
I2 := High(FSelecionados); if I2 > I then Move(FSelecionados[I2], FSelecionados[I], I2-I);
Deve resolver....
Gostei + 0
09/08/2008
Adriano_servitec
Tomara que seja só isso o bug :D
Obrigado pela ajuda.
Gostei + 0
11/08/2008
Adriano_servitec
Olhe a sitação dele
Então ele me passou outro código, veja
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
Grids, DBGrids, Db, DBTables, StdCtrls, ExtCtrls;
type
TForm1 = class(TForm)
Table1 : TTable;
DataSource1 : TDataSource;
DBGrid1 : TDBGrid;
Panel1 : TPanel;
Label1 : TLabel;
Label2: TLabel;
Button1: TButton;
Table1OrderNo: TFloatField;
Table1CustNo: TFloatField;
Table1SaleDate: TDateTimeField;
Table1ShipDate: TDateTimeField;
Table1EmpNo: TIntegerField;
Table1ShipToContact: TStringField;
Table1ShipToAddr1: TStringField;
Table1ShipToAddr2: TStringField;
Table1ShipToCity: TStringField;
Table1ShipToState: TStringField;
Table1ShipToZip: TStringField;
Table1ShipToCountry: TStringField;
Table1ShipToPhone: TStringField;
Table1ShipVIA: TStringField;
Table1PO: TStringField;
Table1Terms: TStringField;
Table1PaymentMethod: TStringField;
Table1ItemsTotal: TCurrencyField;
Table1TaxRate: TFloatField;
Table1Freight: TCurrencyField;
Table1AmountPaid: TCurrencyField;
procedure DBGrid1DrawDataCell(Sender : TObject; const Rect : TRect;
Field : TField; State : TGridDrawState);
procedure FormCreate(Sender : TObject);
procedure FormDestroy(Sender : TObject);
procedure Button1Click(Sender: TObject);
procedure DBGrid1CellClick(Column: TColumn);
private
MyBookMark : TBookmarkList;
FVlSel : Double;
public
{ Public declarations }
end;
var
Form1 : TForm1;
implementation
{$R *.DFM}
procedure TForm1.DBGrid1DrawDataCell(Sender : TObject; const Rect : TRect;
Field : TField; State : TGridDrawState);
begin
if MyBookMark.CurrentRowSelected then
DBGrid1.Canvas.Brush.Color := clRed;
DBGrid1.DefaultDrawDataCell(Rect, Field, State);
end;
type
HackBookMark = class(TBookmarkList);
procedure TForm1.FormCreate(Sender : TObject);
begin
MyBookMark := TBookmarkList.Create(DBGrid1);
HackBookMark(MyBookMark).LinkActive(True);
FVlSel := 0;
end;
procedure TForm1.FormDestroy(Sender : TObject);
begin
MyBookMark.Free;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyBookMark.Clear;
FVlSel := 0;
Label1.Visible := False;
Label2.Visible := False;
end;
procedure TForm1.DBGrid1CellClick(Column: TColumn);
begin
if MyBookMark.CurrentRowSelected then
begin
MyBookMark.CurrentRowSelected := False;
FVlSel := FVlSel - Table1ItemsTotal.Value;
end else
begin
MyBookMark.CurrentRowSelected := True;
FVlSel := FVlSel + Table1ItemsTotal.Value;
end;
if MyBookMark.Count = 0 then
begin
Label1.Visible := False;
Label2.Visible := False;
end else
begin
Label2.Caption := Format(´¬m´, [FVlSel]);
Label1.Visible := True;
Label2.Visible := True;
end;
end;
end.Gostei + 0
11/08/2008
Marco Salles
permita me descordar ... O que faz a leitura errada na Hora de pintar a Grid é o Valor Errado contido no Array , porque o Codigo inicial esta Errado , atribuindo um Valor errado para FSelecionados
Ao substituir
Move(FSelecionados[I+1], FSelecionados[I], I2-I); por Move(FSelecionados[I2], FSelecionados[I], I2-I);
O conteudo do Array estara de acordo com a sua intenção , que é Ora Marcar Ora Desmarcar a Grid
Ha mas porque so aparece quando se esconde e se abre o Form ??
é pq nesse momento esta se fazendo um ´nova´ Pintura da Grid
Agora se for fazer ´analize´ de Otimização entre os dois codigos é claro que o uso da String TBookmarkList é mais Otimizada . Tb se comparamos
esses métodos com a Propriedade MultiSelect eu previro este Ultimo , ate porque não ganhei nada com os métodos.
Salvo é claro a utilização de classe TcustomGrid :
type
THakGrid = class(TCustomGrid);
....
THakGrid(DBGrid1).InvalidateRow(THakGrid(DBGrid1).Row);
e no Ultimo método a Utlização de TBookmarkList.
é como quem diz : Recordar é Viver
So quero enfatizar que não estou Tentando desmerecer codigo de ninguem , nen tampouco disputa com ninguem .não estou aqui para isso.
Quero parabenizar o autor pela aproveitamento da classe TcustumGrid e da String Opaca
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)