2016年4月

首页2016年4月
24
Apr
0

取整函数round、trunc、ceil和floor

在Delphi的开发过程中,用到div、/、mod的时候并不是很多,除非要进行数据处理的时候才有可能用到它们了,下面介绍一下他们之间的用法与区别:
1、div
div是用于取两数相除的商的,c = a div b,得到的c的值就是a除b的商。
2、/
/ 是用于取两数相除的结果的。c = a / b,如果c是i数据类型的,这个语法会进行四舍五入的。
3、mod
mod 是用于取两数相除的余数,c = a mod b,得到的c的值的就是a除b的余数。

1.Round(四舍六入五留双)

功能说明:对一个实数进行四舍五入。(按照银行家算法)

例:

var

i, j: Integer;

begin

i := Round(1.5); // i等于2

j := Round(2.5); // j等于2

end;

在Delphi中使用Round函数得到的答案有时与我们所预期的会不太一样:采用的是四舍六入五留双。即当舍或入位大于或小于五时按四舍五入来处理

,而当舍或入位等于五时,就要看前面一位是什么,根据奇进偶不进,它总是返回一个偶数值。

例:

i:= Round(11.5)//i等于12

i:= Round(10.5)//i等于10

这种Round其实是按照银行家算法,统计学上一般都用这种算法,比传统的"四舍五入"要科学。

如果要使用传统的"四舍五入"方法,可以使用下面函数:

function RoundClassic(R: Real)

2.trunc(取得X的整数部分)

如:trunc(-123.55)=-123, floor(123.55)=123

3.ceil(取得大于等于X的最小的整数)

如:ceil(-123.55)=-123, ceil(123.15)=124

4.floor(取得小于等于X的最大的整数)

如:floor(-123.55)=-124,floor(123.55)=123

注:floor和ceil是math unit里的函数,使用前要先Uses Math

15
Apr
0

clientdataset和文本在内存在互转

function XMLToDataSet(aStr: string): TClientDataSet;
var
strStream:TStringStream;
begin
strStream := TStringStream.Create;
try

strStream.Clear;
strStream.WriteString(aStr);
strStream.Position := 0;
Result :=  TClientDataSet.Create(nil);
Result.Close;
Result.LoadFromStream(strStream);
Result.Open;

finally

FreeAndNil(strStream);

end;
end;

function CreateXMLByDataSet(
aClientDataSet: TClientDataSet): string;
var
strStream:TStringStream;
begin
aClientDataSet.MergeChangeLog;
strStream := TStringStream.Create;
try

aClientDataSet.SaveToStream(strStream,dfXML);
strStream.Position := 0;
Result := strStream.ReadString(strStream.Size);

finally

FreeAndNil(strStream);

end;
end;

14
Apr
0

常量数组定义的两种方法

const
cDayReport_IgnoreField_TakingReport:array of string = ['F_ID','操作员','F_MinID'];

cFieldList : array[1..4] of string = ('haha', 'hehe', 'hoho', 'kuku');

14
Apr
0

合并多天JSON格式的数据到ClientDataSet

function MergeData(aData: OleVariant;
aIgnoreFields: array of string;aKeyFields:array of string): OleVariant;
var
cdsData,
cdsSource,
cdsDest:TClientDataSet;
function CopyTableStructure(acdsSource,acdsDest:TClientDataSet):Boolean;
var

List:TList;
Field:TField;
i:Integer;
Fields:string;

begin

Result := False;
if acdsDest.Active then
  Exit;
for i := 0 to acdsSource.Fields.Count - 1 do
  Fields := Fields + acdsSource.Fields[i].FieldName + ';';
List := TList.Create;
try
  acdsSource.GetFieldList(List,Fields);
  for i := 0 to List.Count - 1 do
  begin
    Field := List[i];
    acdsDest.FieldDefs.Add(Field.fullName,Field.DataType,Field.Size);
  end;
  acdsDest.CreateDataSet;
  acdsDest.Open;
finally
  FreeAndNil(List);
end;
Result := True;

end;
function getFilerStr():string;
var

i:Integer;

begin

for i := 0 to Length(aKeyFields) - 1 do
begin
  Result := Result + aKeyFields[i] + ';';
end;

end;
function getFilerValue(acdsSource:TClientDataSet):Variant;
var

i:Integer;

begin

Result := VarArrayCreate([0, High(aKeyFields)], varVariant);
for i := 0 to Length(aKeyFields) - 1 do
begin
  if acdsSource.FieldByName(aKeyFields[i]).IsNull then
  begin
    Result[i] := null;
  end
  else
  begin
    Result[i] := acdsSource.FieldByName(aKeyFields[i]).AsString;
  end;
end;

end;
function IsIgnoreField(aFieldName:string):Boolean;
var

i:Integer;

begin

Result := False;
for i := 0 to Length(aKeyFields) - 1 do
begin
  if aKeyFields[i] = aFieldName then
  begin
    Result := True;
    Exit;
  end;
end;
for i := 0 to Length(aIgnoreFields) - 1 do
begin
  if aIgnoreFields[i] = aFieldName then
  begin
    Result := True;
    Exit;
  end;
end;

end;
function CalSum(acdsSource,acdsDest:TClientDataSet;isNewRecord:Boolean):Boolean;
var

i:Integer;
Field:TField;
FieldName:string;
curValue,dstValue:Currency;

begin

if isNewRecord then
begin
  acdsDest.Append;
  for i := 0 to acdsSource.FieldCount - 1 do
  begin
    Field := acdsDest.FindField(acdsSource.Fields[i].FieldName);
    if Field <> nil then
      Field.AsVariant := acdsSource.Fields[i].AsVariant;
  end;
  acdsDest.Post;
end
else
begin
  acdsDest.Edit;
  for i := 0 to acdsSource.FieldCount - 1 do
  begin
    FieldName := acdsSource.Fields[i].FieldName;
    if IsIgnoreField(FieldName) then
    begin
      Continue;
    end;
    Field := acdsDest.FindField(FieldName);
    if Field <> nil then
    begin
      if not TryStrToCurr(acdsSource.Fields[i].AsString,curValue) then
        curValue := 0;
      if not TryStrToCurr(Field.AsString,dstValue) then
        dstValue := 0;
      dstValue := dstValue + curValue;
      Field.AsVariant := CurrToStr(dstValue);
    end;
  end;
  acdsDest.Post;
end;

end;
begin
cdsData := TClientDataSet.Create(nil);
try

cdsSource := TClientDataSet.Create(nil);
try
  cdsDest := TClientDataSet.Create(nil);
  try
    cdsData.Close;
    cdsData.Data := aData;
    cdsData.Open;
    if cdsData.RecordCount < 1 then
      Exit;
    cdsData.First;
    while not cdsData.Eof do
    begin
      cdsSource.Close;
      cdsSource.CleanupInstance;
      TJSONDB.JsonToClientDataSet(cdsData.FieldByName('F_VALUE').AsString,cdsSource);
      if not cdsSource.Active then
        cdsSource.Open;
      CopyTableStructure(cdsSource,cdsDest);
      if cdsDest.Locate(getFilerStr,getFilerValue(cdsSource),[]) then
      begin
        CalSum(cdsSource,cdsDest,False);
      end
      else
      begin
        //不能确定字段数目一定相同 所以不能用 cdsDest.CloneCursor(cdsSource,true)
        CalSum(cdsSource,cdsDest,True);
      end;
      cdsData.Next;
    end;
  finally
    FreeAndNil(cdsDest);
  end;
finally
  FreeAndNil(cdsSource);
end;

finally

FreeAndNil(cdsData);

end;
end;

14
Apr
0

VarArrayOf函数

声明:
VarArrayOf(const Values: array of Variant): Variant

实际内部:
Result := VarArrayCreate([0, High(Values)], varVariant);
for I := 0 to High(Values) do

Result[I] := Values[I];

反之:
VarIsArray(KeyValues)

取回数据
KeyValues[i]