|
@@ -7,14 +7,15 @@ uses
|
|
|
sdDB, VCLZip, VCLUnZip, Dialogs, Forms, ShlObj, Classes, StrUtils, Math, ADODB,
|
|
|
IdGlobal;
|
|
|
|
|
|
-type
|
|
|
+type
|
|
|
+ TRoundMode = (rmNearest, rmUp, rmDown);
|
|
|
TBookmarkRefreshEvent = procedure (AExpandFrame: Boolean) of object;
|
|
|
|
|
|
{RoundTo}
|
|
|
function QuantityRoundTo(AValue: Double): Double;
|
|
|
function PriceRoundTo(AValue: Double): Double;
|
|
|
function TotalPriceRoundTo(AValue: Double): Double;
|
|
|
- function CommonRoundTo(AValue: Double; ADigit: Integer): Double;
|
|
|
+ function CommonRoundTo(AValue: Double; ADigit: Integer; RoundMode: TRoundMode = rmNearest): Double;
|
|
|
|
|
|
{Interface Control}
|
|
|
procedure AlignControl(AControl, AParent: TWinControl; AAlign: TAlign);
|
|
@@ -117,40 +118,90 @@ type
|
|
|
implementation
|
|
|
|
|
|
uses
|
|
|
- SysUtils, dxBar, MainFrm, ConstUnit, Globals, StdCtrls, ShellAPI,
|
|
|
- ScUtils;
|
|
|
+ SysUtils, dxBar, MainFrm, ConstUnit, Globals, StdCtrls, ShellAPI;
|
|
|
|
|
|
var
|
|
|
SysProgressDisabled: Boolean;
|
|
|
|
|
|
{RoundTo}
|
|
|
+function InnerRoundTo(const AValue: Extended; const ADigit: Integer; RoundMode: TRoundMode): Extended;
|
|
|
+var
|
|
|
+ LFactor, Offset: Extended;
|
|
|
+ HFactor: Integer;
|
|
|
+begin
|
|
|
+ LFactor := IntPower(10, ADigit);
|
|
|
+ HFactor := Trunc(IntPower(10, abs(ADigit)));
|
|
|
+ Result := AValue;
|
|
|
+ case RoundMode of
|
|
|
+ rmNearest:
|
|
|
+ begin
|
|
|
+ if AValue >= 0 then
|
|
|
+ Offset := 0.5
|
|
|
+ else
|
|
|
+ Offset := -0.5;
|
|
|
+ Result := Trunc((AValue * HFactor) + Offset) * LFactor;
|
|
|
+ end;
|
|
|
+ rmUP:
|
|
|
+ begin
|
|
|
+ if Frac(AValue / LFactor) > 0 then
|
|
|
+ Result := Trunc(AValue * HFactor + 1) * LFactor
|
|
|
+ else
|
|
|
+ Result := Trunc(AValue * HFactor) * LFactor;
|
|
|
+ end;
|
|
|
+ rmDown:
|
|
|
+ begin
|
|
|
+ Result := Trunc(AValue * HFactor) * LFactor;
|
|
|
+ end;
|
|
|
+ end;
|
|
|
+end;
|
|
|
+
|
|
|
function QuantityRoundTo(AValue: Double): Double;
|
|
|
begin
|
|
|
if Assigned(OpenProjectManager.CurProjectData) then
|
|
|
- Result := ScRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.QuantityDigit)
|
|
|
+ Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.QuantityDigit)
|
|
|
else
|
|
|
- Result := ScRoundTo(AValue, iQuantityDigit);
|
|
|
+ Result := CommonRoundTo(AValue, iQuantityDigit);
|
|
|
end;
|
|
|
|
|
|
function PriceRoundTo(AValue: Double): Double;
|
|
|
begin
|
|
|
if Assigned(OpenProjectManager.CurProjectData) then
|
|
|
- Result := ScRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.PriceDigit)
|
|
|
+ Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.PriceDigit)
|
|
|
else
|
|
|
- Result := ScRoundTo(AValue, iPriceDigit);
|
|
|
+ Result := CommonRoundTo(AValue, iPriceDigit);
|
|
|
end;
|
|
|
|
|
|
function TotalPriceRoundTo(AValue: Double): Double;
|
|
|
begin
|
|
|
if Assigned(OpenProjectManager.CurProjectData) then
|
|
|
- Result := ScRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.TotalPriceDigit)
|
|
|
+ Result := CommonRoundTo(AValue, -OpenProjectManager.CurProjectData.ProjProperties.TotalPriceDigit)
|
|
|
else
|
|
|
- Result := ScRoundTo(AValue, iTotalPriceDigit);
|
|
|
+ Result := CommonRoundTo(AValue, iTotalPriceDigit);
|
|
|
end;
|
|
|
|
|
|
-function CommonRoundTo(AValue: Double; ADigit: Integer): Double;
|
|
|
-begin
|
|
|
- Result := ScRoundTo(AValue, ADigit);
|
|
|
+function CommonRoundTo(AValue: Double; ADigit: Integer; RoundMode: TRoundMode = rmNearest): Double;
|
|
|
+var
|
|
|
+ X: Double;
|
|
|
+ P: Pointer;
|
|
|
+ I: Integer;
|
|
|
+ Buf: array [0..7] of Byte;
|
|
|
+begin
|
|
|
+ P := @AValue;
|
|
|
+ CopyMemory(@Buf[0], P, SizeOf(AValue));
|
|
|
+ // 进位处理,从后往前,如果当前byte为$FF,则往前一byte进1
|
|
|
+ // 注意到尾数开始的位置停止
|
|
|
+ // 这里说的前后是二进制串,实际存储前后相反
|
|
|
+ for I := 0 to 6 do
|
|
|
+ if (I < 6) and (Buf[I] = $FF) then
|
|
|
+ Buf[I] := 0
|
|
|
+ else
|
|
|
+ begin
|
|
|
+ Buf[I] := Buf[I] + 1;
|
|
|
+ Break;
|
|
|
+ end;
|
|
|
+ P := @X;
|
|
|
+ CopyMemory(P, @Buf[0], SizeOf(X));
|
|
|
+ Result := InnerRoundTo(X, ADigit, RoundMode);
|
|
|
end;
|
|
|
|
|
|
{Interface Control}
|