Somar campos selecionados DBGrid sem uso do multselect?
Ola pessoal um colega postou em outro forum um jeito de marcar dados no dbgrid sem uso do multselect, gostei e estou querendo usar aqui no meu projeto.
O código é este aqui.
Só que eu aqui uso o Mutselect para somar campos que em marcar no dbgrid assim
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.
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
Curtidas 0
Respostas
Adriano_servitec
08/08/2008
Resolvido
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
Marco Salles
08/08/2008
Quem lhe passou este código ???
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
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
Adriano_servitec
08/08/2008
Verdade, vou passar pro autor do código o erro.
Valeu amigo.
Valeu amigo.
GOSTEI 0
Adriano_servitec
08/08/2008
para corrigir este inconveniente acredito que dá , mas requer um pouco de codificação extra
De qualquer modo, vc tem alguma ideia de como resolver isso amigo?
GOSTEI 0
Marco Salles
08/08/2008
Acho que sim...
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
para
Deve resolver....
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
Adriano_servitec
08/08/2008
Olá amigo, bom a principio parece que resolveu o problema.
Tomara que seja só isso o bug :D
Obrigado pela ajuda.
Tomara que seja só isso o bug :D
Obrigado pela ajuda.
GOSTEI 0
Adriano_servitec
08/08/2008
Olá, segundo o autor do código a solução não é esta.
Olhe a sitação dele
Então ele me passou outro código, veja
Olhe a sitação dele
o prob ai é q ao pintar a grade, ele move o ponteiro do dataset internamente, porem sem mover os controles, o q causa uma leitura incorreta do RecNo.
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
Marco Salles
08/08/2008
Olá, segundo o autor do código a solução não é esta.
Olhe a sitação dele
Citação:
[quote:19eb0b04a7]o prob ai é q ao pintar a grade, ele move o ponteiro do dataset internamente, porem sem mover os controles, o q causa uma leitura incorreta do RecNo
. [/quote:19eb0b04a7]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