⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unit1.pas

📁 汽车油耗计算工具 计算个人汽车的油耗记录
💻 PAS
📖 第 1 页 / 共 2 页
字号:
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 + -