摘 要 介绍了一个实际的IC卡售水业务中购水量及水费计算的处理过程。
关键词 TDBEdit,计算字段,键值控制
一、概述
数据库应用系统中存在许多数据录入窗体,它是人机对话的基础。例如,系统登录窗口就是一个简单的录入界面,它接收输入的帐号和密码,并判断和处理输入的合法性。在实际应用中各种业务表单的录入和保存操作也很普遍,处理好表单录入操作是开发数据库应用系统的一个重要环节。一般数据录入窗体界面设计是按照功能模块要求设计需要输入数据项和保存数据的,录入的数据项可以是本表单的字段,也可能是关联表单的字段。数据的处理上,主要是基本数据的保存和计算类型字段的处理。下面根据实际应用的客户购水业务(IC卡)来分析录入窗体的设计和数据处理功能的实现。
二、录入界面设计
1.模块要求
(1) 显示购水客户的水表信息,水表号、安装位置、用水性质、用水单价。
(2) 录入每块水表的购水量、自动计算购水费用、自动合计购水量及购水费用。
(3) 将购水信息保存到购水记录表中。
在设计这个窗体前,已建好的数据表单有客户的基本信息、客户水表信息、用水性质、用水价格表,要保存的数据表单是客户的购水记录表。
客户信息表:客户编号、客户名称、客户住址、联系电话
客户水表信息:客户编号、水表编号、用水性质编号、水表型号
用水性质:用水性质编号、用水性质名称
用水价格:用水性质编号、用水价格
购水记录表:客户编号、水表编号、购水量、购水费用、购水时间
2.业务流程

图1 购水流程
业务流程描述:
读卡上客户编号,从客户购水信息表中查询该客户是否已购水,未购水客户依据客户编号查询该客户;根据客户编号,从客户水表信息表中查询水表安装位置和用水性质编号;在用水性质表中,查询客户用水性质编号对应的用水性质名称;在用水价格表中,查询指定用水性质编号的购水单价;购水界面上显示查询结果,客户编号、客户名称、水表编号、安装位置、用水性质名称、购水单价;输入购水量,计算水费并合计购水量和购水费用;将每块表的购水记录保存到客户购水记录表中。
3.界面设计
按要显示的数据项内容,将查询出的字段内容使用TEdit显示文本,将输入购水量、单价、水费和合计部分使用TDBEdit数据感知组件来处理。由于需要对两块水表处理,在界面上放置两个数据集(TADOQuery)组件和数据源(TDataSource)。分别是adq1、dsqty1和adq2、dsqty2,界面如图2所示。

图2 数据录入界面
第一块表:购水量、用水单价数据感知组件属性、数据集和数据源的设置
adq1.sql := ‘select * from pay_water where customer_id=:custid and submeter_id=:subid’;
dsqty1.Dataset := ‘adq1’;
dbedtqty1.DataField := ‘quantity’;
dbedtqty1.DataSource := ‘dsqty1’
dbedtprice1. DataField := ‘sumprice’;
dbedtprice1. DataSource := ‘dsqty1’
在adq1数据集上新增计算类型字段,双击adq1显示字段编辑器,右键可以新增一个字段,并设置字段类型为计算类型。
购水费(summoney)、水量合计(sumqty)、水费合计(summoney1)
dbpaymoney1. DataField := ‘summoney;
dbpaymoney1. DataSource := ‘dsqty1’
dbsumqty. DataField := ‘sumqty;
dbsumqty. DataSource := ‘dsqty1’
dbsummoney. DataField := ‘summoney1;
dbsummoney. DataSource := ‘dsqty1’
同理,第二表的设置方式和第一块表相同,只是数据集和数据源名称不同(adq2、dsqty2)。
三、界面数据处理
录入界面上的数据感知控件放置好后,并完成对应的数据源及数据字段的属性设置。这样就可以按业务流程来实现数据显示部分和数据录入部分的功能。
1.处理流程
(1) 在显示数据录入窗体前,需要查询客户编号及客户名称,客户购水水表的基本信息,包括安装位置、用水性质、用水单价。
(2) 操作员需要输入购买量,并自动计算水费、合计购买量、合计购买费用。自动计算字段:水费=购水量 * 用水单价;购买量合计=第一块表购水量+第二块表购水量;费用合计=第一块表水费+第二块表水费。
(3) 对录入数据进行合法性校验并将购水数据保存到购水记录表。
2.程序实现
利用两个数据集的Append方法追加水表的购水记录,这样就可以对购水量数据项进行录入操作了。实际开发中经常会使用TDBEdit组件来完成数据项的输入,它可以直接对追加记录的指定字段进行编辑。
(1) 录入界面主窗体的OnShow()事件。
procedure Tqsellwaterfrm.FormShow(Sender: TObject);
var
strtype,strtypename,straddr: string;
i: integer;
begin
metercount := 0;
with adqvalue0 do
begin
close;
sql.Clear;
sql.Text := 'select * from cust_water_meter where customer_id=:cust_id';
parameters.ParamByName('cust_id').Value := sell_water_custid;
open;
if recordcount>0 then
begin
metercount := recordcount;
for i := 0 to recordcount-1 do
begin
case i of
0:begin
//第一块表追加购水记录
adq1.Parameters.ParamByName('custid').Value := sell_water_custid;
adq1.Parameters.ParamByName('subid').Value := 1;
adq1.Open;
adq1.Append;
end;
1:begin
//第二块表追加购水记录
adq2.Parameters.ParamByName('custid').Value := sell_water_custid;
adq2.Parameters.ParamByName('subid').Value := 2;
adq2.Open;
adq2.Append;
end;
end;
//取水表的安装地址
straddr := fieldbyname('install_addr').AsString;
case i+1 of
1:edtmeteraddr1.Text := straddr;
2:edtmeteraddr2.Text := straddr;
end;
strtype := fieldbyname('water_type').AsString;
awater_type[i] := strtype;
//查询用水性质名称
strtypename := searchtypename(strtype,i);
case i+1 of
1:begin
edttype1.Text := strtypename;
edtallowqty1.Text := floattostr(qty_max_purch[0]);
dbedtqty1.Enabled := true;
dbedtqty1.ReadOnly := false;
dbedtqty1.Color := clWindow;
end;
2:begin
edttype2.Text := strtypename;
edtallowqty2.Text := floattostr(qty_max_purch[1]);
dbedtqty2.ReadOnly := false;
dbedtqty2.Enabled := true;
dbedtqty2.Color := clWindow;
end;
end;
//查询水表的用水价格
searchprice(strtype,i+1);
next;
end;
dbedtqty1.SetFocus;
end;
close;
end;
······
end;
(2) 查询用水单价的过程,读取水表的购水单价。
procedure Tqsellwaterfrm.searchprice(typeid: string; recordnum: integer);
begin
with adqvalue1 do
begin
close;
sql.Clear;
sql.Text := 'select * from water_price where water_type=:type';
parameters.ParamByName('type').Value := typeid;
open;
if recordcount>0 then
begin
case recordnum of
1:begin
adq1.fieldbyname('price_water').AsString:=fieldbyname('price_water').AsString;
end;
2: begin
adq2.fieldbyname('price_water').AsString:=fieldbyname('price_water').AsString;
end;
end;
end; {case}
end;
end;
end;
(3) 计算字段的处理,完成购水费用、购水量合计、购水费合计。OnClacFields()事件代码如下:
procedure Tqsellwaterfrm.adq1CalcFields(DataSet: TDataSet);
begin
adq1.FieldByName('sumqty').AsFloat := adq1.FieldByName('quantity').AsFloat;
adq1.FieldByName('summoney').AsFloat :=
(adq1.FieldByName('quantity').AsFloat*adq1.FieldByName('sumprice').AsFloat);
if adq1.Active then begin
adq1.FieldByName('sumqty').AsFloat := adq1.FieldByName('quantity').AsFloat;
adq1.FieldByName('summoney1').AsFloat:= (adq1.FieldByName('quantity').AsFloat*adq1.FieldByName('sumprice').AsFloat);
end;
if adq2.Active then begin
adq1.FieldByName('sumqty').AsFloat:= adq1.FieldByName('quantity').AsFloat+adq2.FieldByName('quantity').AsFloat;
adq1.FieldByName('summoney1').AsFloat:= (adq1.FieldByName('quantity').AsFloat*adq1.FieldByName('sumprice').AsFloat) +(adq2.FieldByName('quantity').AsFloat*adq2.FieldByName('sumprice').AsFloat);
end;
end;
(4) 输入购水量时,为了控制非法数据的输入,只允许输入Float型数据。可以在dbedtqty1、dbedtqty2 的OnKeyPress()事件加入对键值的控制。允许输入0-9的数字、小数点。OnKeyPress()事件代码如下:
procedure Tqsellwaterfrm.dbedtqty1KeyPress(Sender: TObject; var Key: Char);
begin
if not (key in ['0'..'9','.',#8]) then
begin
key:=#0;
exit;
end;
end;
(5) 数据处理最后环节是将录入的数据保存至购水记录表中,下面给出第一块水表保存数据的代码段,其中包括SQL Server保存数据出错的处理。通过TADOConnect属性Errors获得SQL Server错误集代码,并显示错误代码的描述。
……
try
adq1.FieldByName('customer_id').AsString := sell_water_custid;
adq1.FieldByName('submeter_id').AsInteger := 1;
adq1.FieldByName('time_pay').AsDateTime := pay_time ;
adq1.FieldByName('total_money').AsCurrency:=adq1.FieldByName('summoney').AsCurrency;
adq1.Post;
except
case DMServer.ADCServer.Errors.Item[0].NativeError of
2627:
Begin
messagebox(handle,'数据已存在!','警告',MB_OK+MB_ICONWARNING);
End
Else
Begin
mss := '保存数据错误。’+#13+’错误代码:
’+inttostr(DMServer.ADCServer.Errors.Item[0].NativeError)+#13+'代码描述’ +
DMServer.ADCServer.Errors.Item[0].Description;
MessageBox(handle,pchar(mss),'警告',MB_OK+MB_ICONWARNING);
End
End
Exit;
end;
……
3.界面显示

图3 售水界面
四、结语
本文根据实际的购水业务模块,详细介绍了数据录入界面设计及功能实现,包括数据输入、数据处理和数据保存功能。数据录入窗体在数据库应用系统中大量使用,在各种实际业务中应用范围较广。因此,掌握数据录入窗体设计及功能处理的技巧和方法是开发数据库应用系统的基础。该功能也可以扩展到其他业务模块中,例如各种收费录入界面、销售管理模块等,都涉及到数据量的录入、计算、保存的功能。通过灵活应用数据感知控件和数据集中计算字段事件的处理,使录入和操作数据更简单、更方便。
|