单票统计——第三次求解——(250分)(100分)

  • 主题发起人 主题发起人 yifeibbs
  • 开始时间 开始时间
Y

yifeibbs

Unregistered / Unconfirmed
GUEST, unregistred user!
同一问题的第三帖,前两帖如下位置:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1055839
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1116520
前两帖总计150分,现又拿出100分。并附源代码,请解答高手贴出实现问题的主要部分即可:

数据表结构,主表M:
dh(代号),整型
ph(票据号),字符型,5
kh(客户号),字符,5

从表D:
dh(代号),整型 (连接到主表dh),主码
type(类别),字符型,3,主码
n1(数量),整型
n2(数量),整型
n3(数量),整型

价格表J:
type(类别),字符型,3
pri(价格),实数

如果有如下数据:
主表:
dh ph kh
1 001 001
2 002 015
3 003 101

从表:
dh type n1 n2 n3
1 t01 10 10 10
1 t02 5 5 5
1 t10 20 20 3
2 t01 11 12 1
2 t02 1 1 1
2 t03 1 2 1
2 t11 2 20 50
3 t13 20 30 10

价格表:
type pri
t01 10.5
t02 9.01
t03 50.00
t10 10.00
t11 15.1
t13 17.8

程序功能实现如下:
表组件放在数据模块中,在窗体中放置数据控制组件。实现数据的浏览、录入、修改、删除
功能。最主要的是实现票据的数量合计和金额合计。

实现形式如下:
____________________________________________________________
代号 1 票据号:001 客户:001
____________________________________________________________
类别 n01 n02 n03 小计 价格 金额
t01 10 10 10 30 10.5 315.00
t02 5 5 5 15 9.01 135.15
t10 20 20 3 43 10.0 430.00
____________________________________________________________
小计合计:?????? 金额总计:??????



program Project1;

uses
Forms,
Unit1 in 'Unit1.pas' {Form1},
Unit2 in 'Unit2.pas' {DataModule2: TDataModule};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.CreateForm(TDataModule2, DataModule2);
Application.Run;
end.

//单元文件
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DBCtrls, StdCtrls, Mask, Grids, DBGrids, ExtCtrls, DB;

type
TForm1 = class(TForm)
DBNavigator1: TDBNavigator;
DBGrid1: TDBGrid;
DBEdit1: TDBEdit;
DBEdit2: TDBEdit;
DBEdit3: TDBEdit;
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
Label4: TLabel;
Label5: TLabel;
DBText1: TDBText;
DBText2: TDBText;
DataSource1: TDataSource;
DataSource2: TDataSource;
Shape1: TShape;
Shape2: TShape;
procedure FormShow(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
datamodule2.Table2.MasterSource:=datasource1;
datamodule2.Table2.MasterFields:='dh';
end;

end.

//窗体
object Form1: TForm1
Left = 192
Top = 107
Width = 495
Height = 389
Caption = 'Form1'
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = #23435#20307
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 12
object Label1: TLabel
Left = 16
Top = 36
Width = 24
Height = 12
Caption = #24207#21495
end
object Label2: TLabel
Left = 176
Top = 36
Width = 24
Height = 12
Caption = #31080#21495
end
object Label3: TLabel
Left = 336
Top = 36
Width = 24
Height = 12
Caption = #23458#25143
end
object Label4: TLabel
Left = 21
Top = 328
Width = 60
Height = 12
Caption = #23567#35745#21512#35745#65306
Font.Charset = GB2312_CHARSET
Font.Color = clRed
Font.Height = -12
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
end
object Label5: TLabel
Left = 173
Top = 328
Width = 60
Height = 12
Caption = #37329#39069#24635#35745#65306
Font.Charset = GB2312_CHARSET
Font.Color = clRed
Font.Height = -12
Font.Name = #23435#20307
Font.Style = []
ParentFont = False
end
object DBText1: TDBText
Left = 85
Top = 326
Width = 65
Height = 17
end
object DBText2: TDBText
Left = 237
Top = 326
Width = 65
Height = 17
end
object Shape1: TShape
Left = 80
Top = 344
Width = 65
Height = 2
end
object Shape2: TShape
Left = 232
Top = 344
Width = 65
Height = 2
end
object DBNavigator1: TDBNavigator
Left = 0
Top = 0
Width = 487
Height = 25
DataSource = DataSource1
Align = alTop
TabOrder = 0
end
object DBGrid1: TDBGrid
Left = 0
Top = 64
Width = 485
Height = 248
DataSource = DataSource2
TabOrder = 1
TitleFont.Charset = GB2312_CHARSET
TitleFont.Color = clWindowText
TitleFont.Height = -12
TitleFont.Name = #23435#20307
TitleFont.Style = []
end
object DBEdit1: TDBEdit
Left = 56
Top = 32
Width = 70
Height = 20
DataField = 'Dh'
DataSource = DataSource1
TabOrder = 2
end
object DBEdit2: TDBEdit
Left = 216
Top = 32
Width = 70
Height = 20
DataField = 'Ph'
DataSource = DataSource1
TabOrder = 3
end
object DBEdit3: TDBEdit
Left = 368
Top = 32
Width = 70
Height = 20
DataField = 'Kh'
DataSource = DataSource1
TabOrder = 4
end
object DataSource1: TDataSource
DataSet = DataModule2.Table1
Left = 144
Top = 32
end
object DataSource2: TDataSource
DataSet = DataModule2.Table2
Left = 384
Top = 312
end
end


//单元文件
unit Unit2;

interface

uses
SysUtils, Classes, DB, DBTables;

type
TDataModule2 = class(TDataModule)
Table1: TTable;
Table2: TTable;
Table3: TTable;
Table1Dh: TIntegerField;
Table1Ph: TStringField;
Table1Kh: TStringField;
Table3Type: TStringField;
Table3Pri: TFloatField;
Table2Dh: TIntegerField;
Table2Type: TStringField;
Table2N1: TIntegerField;
Table2N2: TIntegerField;
Table2N3: TIntegerField;
Table2xj: TIntegerField;
Table2je: TFloatField;
Table2pri: TFloatField;
procedure Table2CalcFields(DataSet: TDataSet);
private
{ Private declarations }
public
{ Public declarations }
end;

var
DataModule2: TDataModule2;

implementation

{$R *.dfm}

procedure TDataModule2.Table2CalcFields(DataSet: TDataSet);
begin
table2xj.Value:=table2n1.Value+table2n2.Value+table2n3.Value;
table2je.Value:=table2xj.Value+table2pri.Value;
end;

end.
//窗体
object DataModule2: TDataModule2
OldCreateOrder = False
Left = 222
Top = 156
Height = 274
Width = 394
object Table1: TTable
Active = True
FieldDefs = <
item
Name = 'Dh'
DataType = ftInteger
end
item
Name = 'Ph'
DataType = ftString
Size = 5
end
item
Name = 'Kh'
DataType = ftString
Size = 5
end>
StoreDefs = True
TableName = 'M.db'
Left = 32
Top = 32
object Table1Dh: TIntegerField
FieldName = 'Dh'
end
object Table1Ph: TStringField
FieldName = 'Ph'
Size = 5
end
object Table1Kh: TStringField
FieldName = 'Kh'
Size = 5
end
end
object Table2: TTable
Active = True
OnCalcFields = Table2CalcFields
FieldDefs = <
item
Name = 'Dh'
DataType = ftInteger
end
item
Name = 'Type'
DataType = ftString
Size = 3
end
item
Name = 'N1'
DataType = ftInteger
end
item
Name = 'N2'
DataType = ftInteger
end
item
Name = 'N3'
DataType = ftInteger
end>
StoreDefs = True
TableName = 'D.db'
Left = 88
Top = 40
object Table2Dh: TIntegerField
DisplayLabel = #20195#21495
FieldName = 'Dh'
Visible = False
end
object Table2Type: TStringField
DisplayLabel = #31867#21035
FieldName = 'Type'
Size = 3
end
object Table2N1: TIntegerField
FieldName = 'N1'
end
object Table2N2: TIntegerField
FieldName = 'N2'
end
object Table2N3: TIntegerField
FieldName = 'N3'
end
object Table2xj: TIntegerField
DisplayLabel = #23567#35745
FieldKind = fkCalculated
FieldName = 'xj'
Calculated = True
end
object Table2je: TFloatField
DisplayLabel = #37329#39069
FieldKind = fkCalculated
FieldName = 'je'
Calculated = True
end
object Table2pri: TFloatField
DisplayLabel = #21333#20215
FieldKind = fkLookup
FieldName = 'pri'
LookupDataSet = Table3
LookupKeyFields = 'Type'
LookupResultField = 'Pri'
KeyFields = 'Type'
Lookup = True
end
end
object Table3: TTable
Active = True
FieldDefs = <
item
Name = 'Type'
DataType = ftString
Size = 3
end
item
Name = 'Pri'
DataType = ftFloat
end>
StoreDefs = True
TableName = 'J.db'
Left = 152
Top = 40
object Table3Type: TStringField
FieldName = 'Type'
Size = 3
end
object Table3Pri: TFloatField
FieldName = 'Pri'
end
end
end
 
试试这个:
select M.*,D.*,D.n01+d.n02+D.n03 as 小计,j.pri as 价格,
j.pri*(D.n01+d.n02+D.n03) as 金额
from M,d,J where M.id=d.id and D.type=j.type and M.id=:id;
传入一个参数就行。
合计可以用一个循环得到:
Var
Count:integer;
sum:float;
begin
if adodataset.isempty then
exit;
adodataset.first;
while not adodataset.eof do
begin
count:=Count+adodataset.fieldbyname('小计').asinteger;
sum:=sum+adodataset.fieldbyname('金额').asfloat;
adodataset.next;
end;

end;

当然用sql语句也可以得到,
select id,sum(小计) as count,sum(金额) as sum
from
(select M.*,D.*,D.n01+d.n02+D.n03 as 小计,j.pri as 价格,
j.pri*(D.n01+d.n02+D.n03) as 金额
from M,d,J where M.id=d.id and D.type=j.type and M.id=:id) T1
group by id
 
book523朋友的方法不大可能实现。

我按一种笨办法考虑,分析该问题,可以分为两部分:
1。数据计算(在后部数据模块内)
2。数据显示(在窗体中)

(我感觉合适的实现方法应该是:
1。在窗体中放置数据敏感组件;
2。在后端计算该合计数据。)

按以上笨办法的思路,数据计算分为两部分:
1。浏览数据时数据计算;
2。数据编辑时数据计算。


数据显示有以下几部分需要实现:
1。窗口打开时,显示合计数据;
2。浏览主表数据时,显示合计数据;
3。编辑数据时,合计数据随数据的修改、添加、删除操作而变化。

在数据浏览状态可以实现数据的合计功能,在编辑状态无法实现该功能。

实现方法如下,在数据模块中声明一个全局变量,用来计算小计合计值,
在主表oncalcfields中将全局变量置0,在从表oncalcfields中声明一个局部变量;
实现如下:
procedure TDataModule2.Table2CalcFields(DataSet: TDataSet);
var 局部变量:integer;
begin
table2xj.Value:=table2n1.Value+table2n2.Value+table2n3.Value;
table2je.Value:=table2xj.Value+table2pri.Value;
局部变量:=table2xj.value;
全局变量:=全局变量+局部变量;
end;

在数据窗体的onshow,dbnavigator1的onclick事件中设置显示功能;比如:
begin
label1.capion:=inttostr(全局变量);
end;
金额合计值的显示方法同上。
 
你可以先做一个查询,将所有数据全集中到一个表中
SELECT M.DH, M.PH, M.KH, D.TYPE, D.N1, D.N2, D.N3, (D.N1+D.N2+D.N3) AS N4,
J.PRI,(D.N1+D.N2+D.N3)*J.PRI AS PRI_TOTAL
FROM M,D,J
WHERE (M.DH=D.DH) AND (D.TYPE=J.TYPE)
然后,如果你要打印的话,就可以直接对这个查询进行分组统计(推荐reportbuilder)
如果要用表格显示的话,可以用Express控件组中的dxDBgrid,它可完全胜任你的工作
 
粗略看一下,和我以前实现目的一样,但最后我放弃了编程,而直接使用控件。
TO::yifeibbs兄:
按以上笨办法的思路,数据计算分为两部分:
1。浏览数据时数据计算;
2。数据编辑时数据计算。
实际运行中,这样资源会浪费吗?
 
如果很麻烦 就建中间表或者临时表
 
nplang老兄:
我非常愿意用控件来显示数据,可是什么控件才能实现这个功能哪?
 
这个问题终于解决了。

本来我期望着可以弄懂这个问题的根本,无奈,资质所限,只好用个控件来搪塞。
而且好象大家也不屑于回答这个问题,我所承诺的250也只好降为100了。
大家的解答虽然很贴题,但是看的出都没有实验过。

在这里我表示对“enlib”控件包作者的感激。
因为我使用了一个“ehlib”控件包之后解决了问题。
————————
我在这里恭喜大家,你们得到了该题的分数100。
 

Similar threads

I
回复
0
查看
662
import
I
I
回复
0
查看
516
import
I
I
回复
0
查看
734
import
I
I
回复
0
查看
654
import
I
后退
顶部