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

📄 ucommon.pas

📁 水电管理系统,你们不妨看看怎么样?我再继续给你们别的
💻 PAS
字号:
{ 功能:1:常用函数
        2:费用计算
  编码: Wanghq
  时间:2003-10-4
}

unit UCommon;

interface
Uses Windows, Classes, Forms, Sysutils, ADODB, ShellAPI;

type
  PMeterInfo = ^MeterInfo;
  MeterInfo = record       //静态字段
    MeterNO: String;         //1:表编号
    cPrice: Currency;        //2:单价
    cQuotaPrice: Currency;   //3:超出部分单价
    BaseNumber: Integer;     //4:安装基数
    iMaxBound: Integer;      //5:最大的计数范围
    cQuota: Currency;        //6:费用限额
    iSubjoin: Integer;       //7:附加数
    //MeterSort: Integer;      //8:分类
    iMultiple: Integer;      //9:倍率
    WorkShopID: Integer;     //10:所属车间
    SubWorkShopID: Integer;  //11:所属班组
    MaxMayUsedNumber: Integer;   //17:最大的可以使用的数(度或吨)
  end;

  PCalMeterInfo = ^CalMeterInfo;
  CalMeterInfo = Record        //需要计算的字段
    //TakeMeterInfo: PMeterInfo;   //表固有的信息
    iTakeMeterCount: Integer;    //12:已抄表次数
    cAllQuota: Currency;         //13:已使用的限额合计数
    cAllQuotaCharge: Currency;   //14:已使用的超额费用
    iAreadlyUsedSum: Integer;    //15:已使用的数之和(度或吨)
    iAllSubJionNumber: Integer;  //16:已使用的附加数之和(度或吨)

    iPrioiTakeMeterNumber: Integer; //18:上次抄表数
    iTakeMeteNumber: Integer;       //19:本次抄表数
    iCurrentUsedNumber: Integer;    //20:本次使用数

    dateTakeMeter: TDateTime;       //21:本次抄表时间
  end;

  //存储本次计算的费用值
  PStoreCurValue = ^StoreCurValue;
  StoreCurValue = record
    CurValue: Integer;         //本次使用的数量(吨或度)
    CurCharge: Currency;       //本次计划内费用
    CurQuotaCharge: Currency;  //本次的超出的费用
  end;

  
  TSDMg = class(TPersistent)
    FQuery: TADOQuery;
  private
    FCurValue: Integer;
    FCurCharge: Currency;
    FCurQuotaCharge: Currency;
    FPrioiTakeMeterNumber: Integer;
    Procedure ExceMySQLResultSet(strSQL: String);

    Function FormatString(strSource, StrValue: String): String;  //格式化字符串
    Function GetAppPath: String;                             //取应用程序所在的路径

    Function GetCurUnitName: String;
    Function GetYearMonth(TakeMeterDate: TDateTime): String;
    procedure SetCurValue(const Value: Integer);
    procedure SetCurCharge(const Value: Currency);
    procedure SetCurQuotaCharge(const Value: Currency);
    procedure SetPrioiTakeMeterNumber(const Value: Integer); //取年月

  Public
    constructor Create;
    destructor Destroy; override;

    Property AppPath: String read GetAppPath;
    Property CurUnitName: String read GetCurUnitName;
    Property CurValue: Integer read FCurValue write SetCurValue;   //当前使用值
    Property CurCharge: Currency read FCurCharge write SetCurCharge;
    Property CurQuotaCharge: Currency read FCurQuotaCharge write SetCurQuotaCharge;
    Property PrioiTakeMeterNumber: Integer read FPrioiTakeMeterNumber write SetPrioiTakeMeterNumber;

    //Procedure InitMeterInfo(MeterNo: String; TakeTime: TDateTime; iCurTakeMeterNum: Integer); //初始化记录
    Function InitMeterInfo(MeterNo: String; TakeTime: TDateTime; iCurTakeMeterNum: Integer): Boolean;
    Function IsMeterExist(MeterNo: String): TADOQuery;       //表是不是存在?
    Function MeterNOAlreadyInput(MeterNo: String;
      TakeMeterDate: TDateTime): Boolean;                    //当天表费用是否已经录入

    Procedure ShowErrMsg(StrErr: String);
    Procedure SetConnectString(TmpAdoQUery: TADOQuery);  //设置连接字符串

    Procedure CalCharge(MeterNo: String; TakeMeterDate: TDateTime);
  end;

var
  Sdgl: TSDMg;

implementation

uses uConst;

var
  pMyMeterInfo: PMeterInfo;
  pMyCalMeterInfo: PCalMeterInfo;


{ TSDMg }
{$l+}

procedure TSDMg.CalCharge(MeterNo: String; TakeMeterDate: TDateTime);
var
  LeavQuotaNum: Currency;   //所剩限额
  AllSubJoin: Integer;   //
  pMyStoreCurValue: PStoreCurValue;
begin
  //todo  计算费用
  try
    New(pMyStoreCurValue);
  except
    Exception.Create('内存分配错误!');
  end;
  
  pMyStoreCurValue.CurValue := pMyCalMeterInfo.iCurrentUsedNumber;

  //没有限额时
  if pMyMeterInfo.cQuota <= 0 then begin
    pMyStoreCurValue.CurValue := pMyCalMeterInfo.iCurrentUsedNumber;
    pMyStoreCurValue.CurCharge := pMyMeterInfo.cPrice * (pMyCalMeterInfo.iCurrentUsedNumber
                                  + pMyMeterInfo.iSubjoin);
    pMyStoreCurValue.CurQuotaCharge := 0;
  end
  else begin   //有限额时
    if pMyMeterInfo.MaxMayUsedNumber > (pMyCalMeterInfo.iAreadlyUsedSum +
             pMyCalMeterInfo.iAllSubJionNumber) then
    begin
      LeavQuotaNum := pMyMeterInfo.MaxMayUsedNumber - (pMyCalMeterInfo.iAreadlyUsedSum +
             pMyCalMeterInfo.iAllSubJionNumber);   //可以按普通单价计算的部分

      if LeavQuotaNum < (pMyCalMeterInfo.iCurrentUsedNumber + pMyMeterInfo.iSubjoin) then
      begin
        pMyStoreCurValue.CurValue := pMyCalMeterInfo.iCurrentUsedNumber;
        pMyStoreCurValue.CurCharge := LeavQuotaNum * pMyMeterInfo.cPrice;
        if pMyMeterInfo.cQuotaPrice > 0 then
          pMyStoreCurValue.CurQuotaCharge := ((pMyCalMeterInfo.iCurrentUsedNumber +
                    pMyMeterInfo.iSubjoin)- LeavQuotaNum) * pMyMeterInfo.cQuotaPrice
        else
          pMyStoreCurValue.CurQuotaCharge := ((pMyCalMeterInfo.iCurrentUsedNumber +
                    pMyMeterInfo.iSubjoin)- LeavQuotaNum) * pMyMeterInfo.cPrice;
      end
      else begin
        pMyStoreCurValue.CurCharge := (pMyCalMeterInfo.iCurrentUsedNumber + pMyMeterInfo.iSubjoin)
                                       * pMyMeterInfo.cPrice;
        pMyStoreCurValue.CurQuotaCharge := 0;
      end;
    end
    else begin
      pMyStoreCurValue.CurValue := pMyCalMeterInfo.iCurrentUsedNumber;
      pMyStoreCurValue.CurCharge := 0;
      if pMyMeterInfo.cQuotaPrice > 0 then
        pMyStoreCurValue.CurQuotaCharge := pMyStoreCurValue.CurValue * pMyMeterInfo.cQuotaPrice
      else
        pMyStoreCurValue.CurQuotaCharge := pMyStoreCurValue.CurValue * pMyMeterInfo.cPrice;
    end;

  end;

  SetCurValue(pMyStoreCurValue.CurValue);
  SetCurCharge(pMyStoreCurValue.CurCharge);
  SetCurQuotaCharge(pMyStoreCurValue.CurQuotaCharge);
  SetPrioiTakeMeterNumber(pMyCalMeterInfo.iPrioiTakeMeterNumber);

  try
    Dispose(pMyCalMeterInfo);
    Dispose(pMyMeterInfo);
    Dispose(pMyStoreCurValue);
    pMyStoreCurValue := NIL;
  except
    Exception.Create('内存是放异常!');
  end;
end;

constructor TSDMg.Create;
begin
  FQuery := TADOQuery.Create(nil);
  SetConnectString(FQuery);
end;

destructor TSDMg.Destroy;
begin
  FQuery.Free;
  //Dispose(pMyMeterInfo);
  inherited Destroy;
end;

procedure TSDMg.ExceMySQLResultSet(strSQL: String);
begin
  SetConnectString(FQuery);
  
  with FQuery do
  begin
    Close;
    SQL.Clear;
    SQL.Text := strSQL;
    Try
      Open;
    Except
      ShowErrMsg(ErrorInfo);
    end;
  end;

end;

function TSDMg.FormatString(strSource, StrValue: String): String;
begin
  Result := Format(strSource, [StrValue]);
end;

function TSDMg.GetAppPath: String;
begin
  Result := ExtractFilePath(Application.ExeName);
end;

function TSDMg.GetCurUnitName: String;
var
  strSQL: String;
begin
  Result := '';
  //strSQL := 'Select UseUnitName from CnfgPara';
  strSQL := 'Select WrokShopName from WorkShop Where WorkShopLevel = 0 and ResideWorkShopID = 0';
  ExceMySQLResultSet(strSQL);
  Result := FQuery.Fields[0].AsString;
end;

function TSDMg.GetYearMonth(TakeMeterDate: TDateTime): String;
begin
  Result := FormatDateTime('yyyy-mm', TakeMeterDate);
end;

Function TSDMg.InitMeterInfo(MeterNo: String; TakeTime: TDateTime; iCurTakeMeterNum: Integer): Boolean;
var
  strAll: String;
  strDateStart,
  strDateEnd: String;
  strSelectMeterInfo: String;
begin
  Result := True;
  strDateStart := GetYearMonth(TakeTime) + '-1';
  strDateEnd   := FormatDateTime('yyyy-mm-yy', TakeTime);

  New(pMyMeterInfo);
  New(pMyCalMeterInfo);
  
  strSelectMeterInfo := 'Select m.MeterNO, p.PriceNumber, p.ExceedPrice, m.BaseNumber, ' +
                        ' m.MaxBound, m.Quota,  m.SubjoinNumber, m.Multiple, m.WorkShopID,  ' +
                        ' m.SubWorkShopID  from Meter m, Price p where m.PriceID = P.PriceID ' +
                        ' and m.MeterNO = ''%s''';

  ExceMySQLResultSet(Format(strSelectMeterInfo, [MeterNO]));
  with FQuery do begin
    if RecordCount = 1 then begin
      pMyMeterInfo.MeterNO         := Fields[0].AsString;
      pMyMeterInfo.cPrice          := Fields[1].AsCurrency;
      pMyMeterInfo.cQuotaPrice     := Fields[2].AsCurrency;
      pMyMeterInfo.BaseNumber      := Fields[3].AsInteger;
      pMyMeterInfo.iMaxBound       := Fields[4].AsInteger;
      pMyMeterInfo.cQuota          := Fields[5].AsCurrency;
      pMyMeterInfo.iSubjoin        := Fields[6].AsInteger;
      //pMyMeterInfo.MeterSort       := Fields[7].AsInteger;
      pMyMeterInfo.iMultiple       := Fields[7].AsInteger;
      pMyMeterInfo.WorkShopID      := Fields[8].AsInteger;
      pMyMeterInfo.SubWorkShopID   := Fields[9].AsInteger;
      if pMyMeterInfo.cPrice <> 0 then
        pMyMeterInfo.MaxMayUsedNumber:= Trunc(pMyMeterInfo.cQuota / pMyMeterInfo.cPrice);
    end
    else begin
      //ShowErrMsg('有多于一条的相同的表记录!');
      Exit;
    end;
  end;

  strAll := 'Select Count(1), Sum(Charge), Sum(QuotaCharge), Sum(CurValue), ' +
            ' Max(TakeNumber) from TakeMeter where TakeTime >= #%s# ' +
            ' and TakeTime < #%s# and MeterID = ''%s''';
            
  Sdgl.ExceMySQLResultSet(Format(strAll, [strDateStart, strDateEnd, MeterNO]));
  with FQuery do begin
    //pMyCalMeterInfo.TakeMeterInfo := pMyMeterInfo;
    pMyCalMeterInfo.iTakeMeterCount := Fields[0].AsInteger;
    pMyCalMeterInfo.cAllQuota       := Fields[1].AsCurrency;
    pMyCalMeterInfo.cAllQuotaCharge := Fields[2].AsCurrency;
    pMyCalMeterInfo.iAreadlyUsedSum := Fields[3].AsInteger;

    if Fields[4].AsInteger <> 0 then      //当月是否已抄表?
      pMyCalMeterInfo.iPrioiTakeMeterNumber := Fields[4].AsInteger
    else
    begin                                 //取上月抄表数
      Sdgl.ExceMySQLResultSet(Format('Select Max(TakeNumber) from TakeMeter where MeterID = ''%s''', [MeterNO]));
      pMyCalMeterInfo.iPrioiTakeMeterNumber := Fields[0].AsInteger;
      if pMyCalMeterInfo.iPrioiTakeMeterNumber = 0 then
        pMyCalMeterInfo.iPrioiTakeMeterNumber := pMyMeterInfo.BaseNumber;
    end;

    pMyCalMeterInfo.iAllSubJionNumber := pMyCalMeterInfo.iTakeMeterCount *  pMyMeterInfo.iSubjoin;
    pMyCalMeterInfo.iTakeMeteNumber := iCurTakeMeterNum;
    pMyCalMeterInfo.dateTakeMeter := TakeTime;

    //判断抄表数是不是合法
    if pMyCalMeterInfo.iTakeMeteNumber > pMyMeterInfo.iMaxBound then
    begin
      ShowErrMsg('抄表数大于表的最大计数范围:' + IntToStr(pMyMeterInfo.iMaxBound));
      Result := False;
      //Exit;
    end;

    //计算实际使用数
    if pMyCalMeterInfo.iTakeMeteNumber < pMyCalMeterInfo.iPrioiTakeMeterNumber then
      pMyCalMeterInfo.iCurrentUsedNumber := (pMyMeterInfo.iMaxBound - pMyCalMeterInfo.iPrioiTakeMeterNumber +
                       pMyCalMeterInfo.iTakeMeteNumber) * pMyMeterInfo.iMultiple
    else
      pMyCalMeterInfo.iCurrentUsedNumber := (pMyCalMeterInfo.iTakeMeteNumber -
                       pMyCalMeterInfo.iPrioiTakeMeterNumber) * pMyMeterInfo.iMultiple;
  end;
  
end;

function TSDMg.IsMeterExist(MeterNo: String): TADOQuery;
var
  str: String;
begin
  str := FormatString(cIsMeterExist, MeterNo + '%');
  ExceMySQLResultSet(str);
  Result := FQuery;
end;

function TSDMg.MeterNOAlreadyInput(MeterNo: String;
  TakeMeterDate: TDateTime): Boolean;
var
  strMeterNoAlreadyInput: String;
begin
  If MeterNo = '' Then
    Result := False;

  strMeterNoAlreadyInput := 'Select * from TakeMeter where TakeTime = ' +
           '#' + DateToStr(TakeMeterDate) + '#' + ' and MeterID = ' + #39 + MeterNo + #39;

  ExceMySQLResultSet(strMeterNoAlreadyInput);
  If FQuery.Recordset.RecordCount > 0 Then
    Result := True
  Else
    Result := False;

end;

procedure TSDMg.SetConnectString(TmpAdoQUery: TADOQuery);
begin
  TmpAdoQUery.ConnectionString := Format(strConnectString, [AppPath]);

  if not FileExists(AppPath + '\MDB\SDManager.mdb') then
  Begin
    ShowErrMsg(ErrorConnectDataBase);
    Application.Terminate;
  end
  else begin
    Try
      TmpAdoQUery.Connection;
    except
      ShowErrMsg(ErrorConnectDataBase);
      Application.Terminate;
    end;
  end;
end;

procedure TSDMg.SetCurCharge(const Value: Currency);
begin
  FCurCharge := Value;
end;

procedure TSDMg.SetCurQuotaCharge(const Value: Currency);
begin
  FCurQuotaCharge := Value;
end;

procedure TSDMg.SetCurValue(const Value: Integer);
begin
  FCurValue := Value;
end;

procedure TSDMg.SetPrioiTakeMeterNumber(const Value: Integer);
begin
  FPrioiTakeMeterNumber := Value;
end;

procedure TSDMg.ShowErrMsg(StrErr: String);
begin
  MessageBox(Application.Handle, Pchar(StrErr), '错误提示', MB_ICONINFORMATION or MB_OK);
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -