📄 unit1.pas
字号:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ComCtrls, StdCtrls, ExtCtrls, xmldom, XMLIntf, msxmldom, XMLDoc, ShellApi,
Buttons, ToolWin;
type
{
<serial>1</serial>
<AddOilDate>2006年12月30日</AddOilDate>
<CurKM>1000</CurKM>
<GoKM>400</GoKM>
<OilType>93#汽油</OilType>
<OilPrice>4.98</OilPrice>
<Oil>50</Oil>
<Money>249</Money>
<isFull>0</isFull>
<OilStation>九州港加得士</OilStation>
<AddOilMemo>路况: 市区\r\n空调: 未开</AddOilMemo>
}
TAddOilInfo=record {加油记录}
serial : string; //序号
AddOilDate: string; //加油日期
CurKM: string; //里程表读数
GoKM: string; //行驶里程
OilType: string; //燃油类型
OilPrice: string; //油单价
Oil: string; //加油量
Money: string; //金额
isFull: string; //是否加满
OilStation: string; //加油站
AddOilMemo: string; //备注
end;
TOilStation=record {加油站列表}
itemindex: integer;
name: string;
end;
TForm1 = class(TForm)
ListView1: TListView;
outXMLDoc: TXMLDocument;
CoolBar1: TCoolBar;
BitAdd: TSpeedButton;
BitModify: TSpeedButton;
BtnDelete: TSpeedButton;
BtnGenReport: TSpeedButton;
BtnAbout: TSpeedButton;
BtnExit: TSpeedButton;
CoolBar2: TCoolBar;
InXmlDoc: TXMLDocument;
Label1: TLabel;
Label2: TLabel;
TotalMoney: TLabel;
TotalOil: TLabel;
TotalKM: TLabel;
Label7: TLabel;
Label9: TLabel;
AvgOilMoney: TLabel;
TotalDays: TLabel;
Label11: TLabel;
Label13: TLabel;
Label15: TLabel;
AvgMoney: TLabel;
AvgOil: TLabel;
AvgKM: TLabel;
Label3: TLabel;
procedure BtnExitClick(Sender: TObject);
procedure BtnAddClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure AddListInfo(AddOilInfo: TAddOilInfo);
procedure BtnDeleteClick(Sender: TObject);
procedure Add_OilStationList(oilstname: string);
procedure setShowValue(AddOilInfo: TAddOilInfo; flag: integer);
procedure BtnModifyClick(Sender: TObject);
function MyStrToFloat(str:string; end_cutlen:integer):double;
procedure BtnGenReportClick(Sender: TObject);
procedure savDat2Xml();
procedure BtnAboutClick(Sender: TObject);
procedure showSumInfo();
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure ListView1CustomDrawItem(Sender: TCustomListView;
Item: TListItem; State: TCustomDrawState; var DefaultDraw: Boolean);
private
{ Private declarations }
public
AddOilInfo: TAddOilInfo;
end;
var
Form1: TForm1;
TDays: double;
TKM, TOil, TMoney, v_AvgPrice, v_AvgKM, v_AvgOil, v_AvgMoney: double;
OilStationlist: array [1..50] of TOilStation; //加油站名称信息
OilSNum: integer; //油站名称数目
ModifyID: integer; //传递记录修改条目的ID,正常情况下为-1
OilStnindex: integer; //当前的加油站索引Index
LoadFlag: boolean; //数据装载标志
CurKM_Err: boolean; //里程表读数错误标志
ErrListID: integer; //记录错误的记录ID
const
SYS_NAME='汽车油耗计算工具狮友版';
SYS_VERSION='V1.03';
implementation
uses Unit2, Unit3;
{$R *.dfm}
procedure TForm1.BtnExitClick(Sender: TObject);
begin
savDat2Xml();
Form1.Close();
end;
procedure TForm1.savDat2Xml();
var
i : integer;
Root : IXMLNode; //指向XML根结点
Parent_Node: IXMLNode; //指向学生结点
Child_node : IXMLNode; //指向学生的子结点
begin
//将ListView1的数据写入数据文件
if ListView1.Items.Count>0 then
begin
outXMLDoc.Active:=true; //激活OutXMLDoc,自动初始化空的XML文档
outXMLDoc.Encoding:='GB2312'; //设置字符集
Root:=outXMLDoc.AddChild('OilRec'); //建根结点
for i:=0 to ListView1.Items.Count-1 do
begin
Parent_Node:=Root.AddChild('addOilInfo');
Child_node:=Parent_Node.AddChild('serial');
Child_node.Text:=ListView1.Items[i].Caption;
Child_node:=Parent_Node.AddChild('AddOilDate');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[0];
Child_node:=Parent_Node.AddChild('CurKM');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[1];
Child_node:=Parent_Node.AddChild('GoKM');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[2];
Child_node:=Parent_Node.AddChild('Oil');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[3];
Child_node:=Parent_Node.AddChild('OilType');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[4];
Child_node:=Parent_Node.AddChild('Money');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[5];
Child_node:=Parent_Node.AddChild('isFull');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[6];
Child_node:=Parent_Node.AddChild('OilPKM');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[7];
Child_node:=Parent_Node.AddChild('OilStation');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[8];
Child_node:=Parent_Node.AddChild('OilPrice');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[9];
Child_node:=Parent_Node.AddChild('AddOilMemo');
Child_node.Text:=ListView1.Items[i].SubItems.Strings[10];
end;
OutXMLDoc.SaveToFile('oilRec.xml'); //把组织好的XML文档存于xml文件中
OutXMLDoc.Active := false; //钝化(关闭)OutXMLDoc
end;
end;
procedure TForm1.BtnAddClick(Sender: TObject);
begin
ModifyID:=-1;
setShowValue(AddOilInfo, 0);
Form2.show();
end;
procedure TForm1.FormCreate(Sender: TObject);
var
Root : IXMLNode; //指向XML根结点
Parent_Node: IXMLNode; //指向加油记录结点
Child_node : IXMLNode; //指向加油记录的子结点
begin
TKM:=0;
TDays:=0;
TOil:=0.00;
TMoney:=0.00;
v_AvgPrice:=0.00;
v_AvgKM:=0.00;
v_AvgOil:=0.00;
v_AvgMoney:=0.00;
OilSNum:=0;
ErrListID:=-1;
ModifyID:=-1;
LoadFlag:=true;
CurKM_Err:=false;
Form1.Caption:=SYS_NAME+' '+SYS_VERSION;
//读取xml记录文件,并将数据装载于ListView
if FileExists('oilRec.xml') then
begin
InXmlDoc.LoadFromFile('oilRec.xml');
Root:=InXmlDoc.DocumentElement;
Parent_Node:=Root.ChildNodes.First;
while( Parent_Node<>nil ) do
begin
if ( Parent_Node.NodeName='addOilInfo' ) then
begin
Child_Node:=Parent_Node.ChildNodes.First;
while( Child_Node<>nil ) do
begin
if( Child_Node.NodeName='serial' ) then
AddOilInfo.serial:=Child_Node.Text
else if ( Child_Node.NodeName='AddOilDate' ) then
AddOilInfo.AddOilDate:=Child_Node.Text
else if ( Child_Node.NodeName='CurKM' ) then
AddOilInfo.CurKM:=FloatToStr(myStrToFloat(Child_Node.Text,5))
else if ( Child_Node.NodeName='GoKM' ) then
AddOilInfo.GoKM:=Child_Node.Text
else if ( Child_Node.NodeName='OilType' ) then
AddOilInfo.OilType:=Child_Node.Text
else if ( Child_Node.NodeName='OilPrice' ) then
AddOilInfo.OilPrice:=FloatToStr(myStrToFloat(Child_Node.Text,3))
else if ( Child_Node.NodeName='Oil' ) then
AddOilInfo.Oil:=FloatToStr(myStrToFloat(Child_Node.Text,3))
else if ( Child_Node.NodeName='Money' ) then
AddOilInfo.Money:=FloatToStr(myStrToFloat(Child_Node.Text,3))
else if ( Child_Node.NodeName='isFull' ) then
AddOilInfo.isFull:=Child_Node.Text
else if ( Child_Node.NodeName='OilStation' ) then
AddOilInfo.OilStation:=Child_Node.Text
else if ( Child_Node.NodeName='AddOilMemo' ) then
AddOilInfo.AddOilMemo:=Child_Node.Text;
Child_Node:=Child_Node.NextSibling;
end;
//增加加油站列表选项
Add_OilStationList(AddOilInfo.OilStation);
AddOilInfo.Serial:=IntToStr(ListView1.Items.count);
AddListInfo( AddOilInfo );
end;
Parent_Node:=Parent_Node.NextSibling;
end;
end;
loadflag:=false;
end;
procedure TForm1.AddListInfo(AddOilInfo: TAddOilInfo);
var
i,j,listcnt: integer;
tmpd1,tmpd2: double;
insitem: TListItem;
begin
if LoadFlag=false then
begin
CurKM_Err:=false;
ErrListID:=-1;
end;
//按日期检查排序
tmpd1:=StrToDate(AddOilInfo.AddOilDate);
ListView1.Items.BeginUpdate;
if ModifyID<>-1 then
begin
ListView1.Items.Delete(ModifyID);
end;
for i:=0 to ListView1.Items.Count-1 do
begin
tmpd2:=StrToDate(ListView1.Items[i].SubItems.Strings[0]);
if tmpd1<tmpd2 then
begin
with ListView1 do
insitem:=ListView1.Items.Insert(i);
with insitem do
begin
Caption:=IntToStr(i+1);
SubItems.add(AddOilInfo.AddOilDate);
SubItems.add(AddOilInfo.CurKm+' 公里');
//计算行驶公里数
if i>0 then
begin
tmpd1:=myStrToFloat(ListView1.Items[i-1].SubItems.Strings[1],5);
AddOilInfo.GoKM:=FloatToStr(StrToFloat(AddOilInfo.CurKM)-tmpd1);
SubItems.add(AddOilInfo.GoKM+' 公里');
//当前里程表读数的合法性检查
if StrToFloat(AddOilInfo.GoKM) <= 0.00 then
begin
CurKM_Err:=true;
ErrListID:=i;
end;
end
else
begin
AddOilInfo.GoKM:='未知';
SubItems.add(AddOilInfo.GoKM);
end;
SubItems.add(format('%.2f',[StrToFloat(AddOilInfo.Oil)])+' 升');
SubItems.add(AddOilInfo.OilType);
SubItems.add(format('%.2f',[StrToFloat(AddOilInfo.Money)])+' 元');
SubItems.Add(AddOilInfo.isFull);
if (AddOilInfo.GoKM<>'未知') and (AddOilInfo.GoKM<>'0') and (AddOilInfo.isFull='是') then
begin
v_AvgOil:=StrToFloat(AddOilInfo.Oil)/StrToFloat(AddOilInfo.GoKM)*100;
v_AvgOil:=Trunc(v_AvgOil*100)/100;
SubItems.add(format('%.2f',[v_AvgOil])+' 升/百公里');
end
else
SubItems.add('不可计算');
SubItems.add(AddOilInfo.OilStation);
SubItems.add(AddOilInfo.OilPrice+' 元');
SubItems.add(AddOilInfo.AddOilMemo);
end;
//重新计算对应下一条的行驶公里数
tmpd1:=myStrToFloat(ListView1.Items[i+1].SubItems.Strings[1],5);
ListView1.Items[i+1].SubItems.Strings[2]:=FloatToStr(tmpd1-StrToFloat(AddOilInfo.CurKM))+' 公里';
break;
end;
end;
for j:=i+1 to ListView1.Items.Count-1 do
begin
ListView1.Items[j].Caption:=IntToStr(j+1);
end;
//正常按日期新增记录或者初始化读取文件插入数据
if (ListView1.Items.Count=0) or (i=ListView1.Items.Count) then
begin
listcnt:=ListView1.Items.Count;
//添加进ListView列表
with Form1.ListView1.Items.Add do
begin
Caption:=IntToStr(listcnt+1);
SubItems.add(AddOilInfo.AddOilDate);
SubItems.add(AddOilInfo.CurKm+' 公里');
//计算行驶公里数
if listcnt>0 then
begin
tmpd1:=myStrToFloat(ListView1.Items[listcnt-1].SubItems.Strings[1],5);
AddOilInfo.GoKM:=FloatToStr(StrToFloat(AddOilInfo.CurKM)-tmpd1);
SubItems.add(AddOilInfo.GoKM+' 公里');
//当前里程表读数的合法性检查
if StrToFloat(AddOilInfo.GoKM) <= 0.00 then
begin
CurKM_Err:=true;
ErrListID:=listcnt;
end;
end
else
begin
AddOilInfo.GoKM:='未知';
SubItems.add(AddOilInfo.GoKM);
end;
SubItems.add(format('%.2f',[StrToFloat(AddOilInfo.Oil)])+' 升');
SubItems.add(AddOilInfo.OilType);
SubItems.add(format('%.2f',[StrToFloat(AddOilInfo.Money)])+' 元');
SubItems.Add(AddOilInfo.isFull);
if (AddOilInfo.GoKM<>'未知') and (AddOilInfo.GoKM<>'0') and (AddOilInfo.isFull='是') then
begin
v_AvgOil:=StrToFloat(AddOilInfo.Oil)/StrToFloat(AddOilInfo.GoKM)*100;
v_AvgOil:=Trunc(v_AvgOil*100)/100;
SubItems.add(format('%.2f',[v_AvgOil])+' 升/百公里');
end
else
SubItems.add('不可计算');
SubItems.add(AddOilInfo.OilStation);
SubItems.add(AddOilInfo.OilPrice+' 元');
SubItems.add(AddOilInfo.AddOilMemo);
end;
end;
//计算并显示汇总信息
showSumInfo();
ListView1.Items.EndUpdate;
//选中当前错误记录
if ( loadflag=false ) and ( CurKM_Err=true ) and ( ErrListID>=0 )then
begin
ListView1.SetFocus;
ListView1.Items[ErrListID].Selected := True;
Application.MessageBox('请检查里程表读数是否正确! ',SYS_NAME,MB_OK+MB_ICONINFORMATION);
end;
//增加加油站列表选项
Add_OilStationList(AddOilInfo.OilStation);
end;
//计算并显示汇总信息
procedure TForm1.showSumInfo();
var
listcnt, i, j, begno : integer;
tmpd1, tmpd2 : double;
isF: Boolean;
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -