pvParentKey:=FCdsGongChengPZJL_TV.FieldByName('FKey').AsString;
    lvTmpCds := TClientDataSet.Create(nil);
    lvTmpCds.CloneCursor(FCdsGongChengPZJL_TV, false);
    lvTmpCds.First;
    raise Exception.Create(
          'Clone:' + lvTmpCds.FieldByName('FKey').AsString
          + sLineBreak + 'After Clone:' + FCdsGongChengPZJL_TV.FieldByName('FKey').AsString
          + sLineBreak + 'Before Clone:' + pvParentKey

image

 

raise Exception.Create(
      'Clone Filter[' + lvTmpCds.Filter + '] RecordCount:' + IntToStr(lvTmpCds.RecordCount)
      + sLineBreak + 'Source Filter[' + FCdsGongChengPZJL_TV.Filter + '] RecordCount:' + IntToStr(FCdsGongChengPZJL_TV.RecordCount)
      );

image

posted @ 2008-08-16 12:37 D10.天地弦 阅读(16) | 评论 (0)编辑

UUCall知道是什么东西吧?不知道吧,火星人了吧...其实我也是刚知道的,以前总听说有网上免费电话,就是,然后下载了。免费体验拿了10分钟。打了个电话回家, 呵呵, 感觉还可以,

大家要是经常打长途的话可以尝试一下,

点下面这个注册吧, 这样如果你也免费体验我有积分拿, 呵呵, 谢谢先!

 http://account.uucall.com/c/34925953.html

posted @ 2008-08-13 09:22 D10.天地弦 阅读(26) | 评论 (0)编辑

01

02 我点击这个部位,他执行的是新建的动作.

03 在这个位置点就是正常的

 

04 这个位置点,弹出这个

 

经过几个小时的折腾, 也没有找出什么原因来

我上面都的按扭都是连的是action. 居然点按钮的前半部分不正常. 点后半部分才正常. 写这么多年程序, 头一次见到...,

我把他换成dxBar是正常的.

后来再换回来, 把属性ShowCaption设为false再设为true, 把什么AutoSize重设了几下, 居然可以了

难怪真的这几个小时我的RP真的有问题? 

至今没有想明白是什么问题. 如果哪位知道, 请告诉我一下. 谢谢

posted @ 2008-08-06 23:49 D10.天地弦 阅读(33) | 评论 (1)编辑

 

procedure TfrmOrderMgr.grdVMainStylesGetContentStyle(
  Sender: TcxCustomGridTableView; ARecord: TcxCustomGridRecord;
  AItem: TcxCustomGridTableItem; out AStyle: TcxStyle);
var
  AIndex: Integer;
  AVar: Variant;
  ABoolean: Boolean;
  lvItem: TcxGridDBColumn;
begin
  lvItem := TcxGridDBColumn(AItem);

  if grdVMainFCompleted.GroupIndex <> -1 then Exit; //分组时不分颜色

  AIndex := grdVMainFCompleted.Index;
  AVar := ARecord.Values[AIndex];
  if VarIsOrdinal(AVar) then ABoolean := AVar else ABoolean := false; //是否为bool值

  if ABoolean then  //已完成
    AStyle := dmMain.cxStyleRecCompleted else AStyle := dmMain.cxStyleRecNormal;

  if lvItem.VisibleIndex = 0 then //第一列
  begin
    AIndex := grdVMainFClosed.Index;
    AVar := ARecord.Values[AIndex];
    if VarIsOrdinal(AVar) then ABoolean := AVar else ABoolean := false; //是否为bool值
    if ABoolean then  //已取消
      AStyle := dmMain.cxStyleRecClosed;
  end;
end;

posted @ 2008-07-28 10:52 D10.天地弦 阅读(37) | 评论 (0)编辑

UPDATE hrm_EmpKaoQin SET FJiaQinLX=0 WHERE FJiaQinLX IS NULL

 

----未建立约束

if object_id('DF_hrm_EmpKaoQin_FJiaQinLX') IS NULL 
  ALTER TABLE hrm_EmpKaoQin ADD CONSTRAINT
    DF_hrm_EmpKaoQin_FJiaQinLX DEFAULT (0) FOR FJiaQinLX

 

---更改字段类型

ALTER TABLE hrm_EmpKaoQin ALTER COLUMN FBeiZhu VARCHAR(1600)

 

--更改字段不允许为空

ALTER TABLE sto_MCOH_InKey ALTER COLUMN FPiHao VARCHAR(30) NOT NULL

posted @ 2008-07-25 01:14 D10.天地弦 阅读(34) | 评论 (0)编辑

--从人事库中查出在职的,薪卡号重复的记录

select FGongKaHao from bas_Employee
   where  FZaiZhi=0
   group by FGongKaHao having count(FGongKaHao)>1

 

--找出进仓从表的出仓数量和出仓记录中的出仓数量总合不一样的记录

SELECT * FROM
(
    select
       ISNULL(
         (
            --计算出仓记录里的出仓数量总合
            SELECT SUM(FShuLiang)
               FROM sto_ChuCangJL f_ccjl
               WHERE f_d.FKey=f_ccjl.FJinCangKey
            )
           ,0) AS FChuCangSLEX, f_d.FChuCangSL AS FChuCangSL2, f_d.*
    FROM
      (
      select f_m.FFormDate, f_m.FBianHao,
             f_d.*
          from sto_inStore_d f_d
          INNER JOIN sto_InStore_m f_m on f_m.FFormKey = f_d.FFormKey
      )f_d
)__v

where FChuCangSL<>FChuCangSLEX
order by FBianHao

 

--进仓从表的出仓数量和出仓记录中的出仓数量总合不一样的记录,更新一至
UPDATE f_d
  SET f_d.FChuCangSL=__v.FChuCangSLEX
  FROM sto_inStore_d f_d
  INNER JOIN
    (
        select
           ISNULL(
             (
                --计算出仓记录里的出仓数量总合
                SELECT SUM(FShuLiang)
                   FROM sto_ChuCangJL f_ccjl
                   WHERE f_d.FKey=f_ccjl.FJinCangKey
                )
               ,0) AS FChuCangSLEX, f_d.FChuCangSL AS FChuCangSL2, f_d.*
        FROM
          (
          select f_m.FFormDate, f_m.FBianHao,
                 f_d.*
              from sto_inStore_d f_d
              INNER JOIN sto_InStore_m f_m on f_m.FFormKey = f_d.FFormKey
          )f_d
    )__v ON f_d.FKey=__v.FKey
   where __v.FChuCangSL<>__v.FChuCangSLEX

 

--使用联连的方式来更新一个表

--更新禁止使用的模块
UPDATE #tmpModules SET IsEnable=0
  FROM #tmpModules f_tb INNER JOIN sys_cm_ModuleFuncs f_slv ON f_tb.FModuleFuncIndex=f_slv.FIndex
  WHERE f_slv.FDisable=1

 

--更新班次

SELECT @ExeStr=
'UPDATE f_tb
   SET FBanCiBH=
        (SELECT ['+@SDay+'] FROM hrm_EmpBanCi
           WHERE FNianYue='''+@NianYue+''' AND FZhiYuanKey=f_tb.FZhiYuanKey)
   FROM hrm_EmpKaoQin f_tb
   WHERE  f_tb.FApproved<>1
          AND f_tb.FKaoQinRQ='''+cast(@mm_Date as varchar(24))+''''
EXEC (@ExeStr)

posted @ 2008-07-25 01:12 D10.天地弦 阅读(36) | 评论 (0)编辑

FormDestroy和Destroy都是执行Free时执行的两个函数

FormDestroy是事件, Destroy是析构函数.FormDestroy是在Destroy中执行的事件,是为了方便程序员写释放资源的代码.

在程序中要么用直接用Destroy释放,要么用FormDestroy事件,不要混合使用.

都知道写Destroy的一般都是

destructor Destroy()

begin

   CdsMain.Free;

   inherited destroy;//保证基类的资源释放, FormDestroy是在TCustomForm中的事件

end;

所以FormDestroy是发生在Destroy的最后一部份,如果你在Destroy中使用了CdsMain.Free

而你再想在FormDestroy中写上CdsMain.Cancel,必然就会发生AV错误.

 

写给初学者.....

D10.Mofen

posted @ 2008-07-08 11:04 D10.天地弦 阅读(43) | 评论 (0)编辑

今天花了我将近一个小时的时间来才找到了这个原因,真是郁闷.

我将查询的设计流ChangeName将QueryCreator改成QueryCreatorView后发现主的QueryCreator创建老是有问题,有一些组件不显示了.后来才发现是在ChangeName的时候,设计流保存了修改记录,恢复Detail的设计流时,把Main的QueryCreator的组件进行改名,

解决:

在数据字典设计流改名后,重新DesignAnayzer.Star一下.这样就好了.

posted @ 2008-05-29 17:48 D10.天地弦 阅读(57) | 评论 (0)编辑

一步步教你优化Delphi字串查找

2005-06-13 11:46 作者: 朱晓峰 出处: csdn开发高手 责任编辑:方舟

  本人在编写离线浏览器WebSeizer的过程中,用到大量字符串处理函数,这是很耗CPU的一个处理过程,为了编写出高效率的网页解析引擎,对优化代码作了一番研究。
  1 、高精度的计时函数
代码优化时需要用到精确的计时器。常用的有GetTickCount函数,可以达到毫秒级的精度。但还是很不够的,这时可以采用提高循环次数的办法。另外,还有一个精度更高的定时——“高分辨率性能计数器”(high-resolution performance counter),它提供了两个API函数,取得计数器频率的QueryPerformanceFrequency和取得计数器数值的QueryPerformanceCounter。实现原理是利用计算机中的8253,8254可编程时间间隔定时器芯片实现的。在计算机内部有三个独立的16位计数器。
  计数器可以以二进制或二—十进制(BDC)计数。计数器每秒产生1193180次脉冲,每次脉冲使计数器的数字减一,产生频率是可变的,用QueryPerformanceFrequency可以得到,一般情况下都是1193180。QueryPerformance Counter可以得到当前的计数器值。所以只要你的计算机
够快,理论上精度可以达到1/1193180秒。
  2 、代码优化实例
  下面以一个自定义的字符串函数的为例,说明代码优化过程。
  Delphi提供的字符串函数里有一个Pos函数,它的定义是:

function Pos(Substr: string; S: string): Integer;

  它的作用是在字符串S中查找字符串Substr,返回值是Substr在S中第一次出现的位置,如果没有找到,返回值为0。
  在本人编写WebSeizer软件(天空软件站有下载)过程中,Pos已经不能满足要求。一方面:在处理网页中的字符串时,要求对大小写不敏感,即< h t m l > 和<HTML>代表的含义完全一样。另一方面:我们还要求有一个函数,返回值是Substr在S中最后一次出现的位置,而不是第一次出现的位置。下面是这个函数的未经优化的代码。

function RightPos(const Substr,S: string): Integer;
var
 iPos: Integer;
 TmpStr:string;
begin
 TmpStr:=s;
 iPos := Pos(Substr,TmpStr); Result:=0;
 //查找Substr第一次出现位置
 while iPos<>0 do
 begin
  Delete(TmpStr,1,iPos+length(Substr)-1);
  //删除已经查找过的字符
  Result:=Result+iPos;
  iPos := Pos(Substr,TmpStr); //查找Substr出现位置
  if iPos=0 then break;
  Result:=Result+length(Substr)-1;
 end;
end;

  这个函数里,用到了Delete函数,我们再来看一看System.pas文件里Delete函数的实现过程,请看下面代码:

procedure _LStrDelete{ var s : AnsiString; index, count : Integer };
asm
{ EAX Pointer to s }
{ EDX index }
{ ECX count }
PUSH EBX
PUSH ESI
PUSH EDI
MOV EBX,EAX
MOV ESI,EDX
MOV EDI,ECX
CALL UniqueString
MOV EDX,[EBX]
TEST EDX,EDX { source already empty:
nothing to do }
JE @@exit
MOV ECX,[EDX-skew].StrRec.length
{ make index 0-based, if not in [0 .. Length(s)-1]
do nothing }
DEC ESI
JL @@exit
CMP ESI,ECX
JGE @@exit
{ limit count to [0 .. Length(s) - index] }
TEST EDI,EDI
JLE @@exit
SUB ECX,ESI { ECX = Length(s) - index
}
CMP EDI,ECX
JLE @@1
MOV EDI,ECX
@@1:
{ move length - index - count characters from
s+index+count to s+index }
SUB ECX,EDI { ECX = Length(s) - index
- count }
ADD EDX,ESI { EDX = s+index }
LEA EAX,[EDX+EDI] { EAX = s+index+count }
CALL Move
{ set length(s) to length(s) - count }
MOV EDX,[EBX]
MOV EAX,EBX
MOV EDX,[EDX-skew].StrRec.length
SUB EDX,EDI
CALL _LStrSetLength
@@exit:
POP EDI
POP ESI
POP EBX
end;

  Delete 函数中,有这两句:CALL Move和CALL_LstrSetLength。其中Move函数是将一个内存块拷贝到另一个地址,LstrSetLength函数将改变字符串的长度,其中也有对内存进行分配的代码。这些对内存进行操作的函数都是极其消耗CPU运行时间的,所以Delete函数也是一个极其消耗CPU运行时间的函数。为了尽量避免使用这些函数,我对自定义函数RightPos进行了改写。
  修改后不再使用Delete及Pos函数,直接通过指针对内存操作,提高了效率。

function RightPosEx(const Substr,S: string): Integer;
var
  iPos: Integer;
  TmpStr: string;
  i, j, lvlen: Integer;
  PCharS, PCharSub: PChar;
begin
  PCharS := PChar(s); //将字符串转化为PChar格式
  PCharSub := PChar(Substr);
  Result := 0;
  lvlen := length(Substr);
  for i := 0 to length(S) - 1 do
  begin
    for j := 0 to lvlen - 1 do
    begin
      if PCharS[i + j] <> PCharSub[j] then break;
    end;
    if j = lvlen then Result := i + 1;
  end;
end;

  请看第一句PCharS:=PChar(s),它的作用是将Delphi字符串强制转化为PChar 格式(PChar 是Windows中使用的标准字符串,不包含长度信息,使用0为结束标志),并得到指向PChar字符串的指针PcharS。
  下面就要对自定义函数的运行时间进行测量,为了提高测量的精度,减小随机性,我们计算重复10000次所需的时间。代码如下:

var
i,len,iPos: Integer;
PerformanceCount1,PerformanceCount2,Count:int64;
begin
len:=10000; //重复次数
QueryPerformanceCounter(PerformanceCount1);//开始计数
for i:=0 to len-1 do
begin
 iPos:=RightPos(’12’,Edit1.Text); //被测试的函数
end;
QueryPerformanceCounter(PerformanceCount2); //结束计数
Count:=(PerformanceCount2-PerformanceCount1);
Label1.Caption:=inttostr(iPos)+’ time=’+inttostr(Count);
End;

  我的配置是Duron700,256M内存,测试中RightPos函数重复了10000遍,RightPos使用的参数为:Substr=12,S=Edit12ewew12tet。得到的测量结果是Count=217000,又对其他几个函数作了对比,结果如下:

函数名
重复次数
QueryPerformanceCounter 计数值

Pos
10000
150000

RightPos
10000
217000

RightPosEx
10000
160000

  可以看出测试的结果是比较满意的,改进过的RightPosEx函数效率比RightPos高很多,考虑到测试用的字符串比较短,使用长字符串效果更明显。如果直接使用Delphi的字符串格式而不用转为PChar格式,则效率又可提高一步。但字符串格式是Delphi语言自定义的,存在兼容性问题。所以这一版本的字串搜索函数就不列出来了,读者在前面代码的基础上很容易就可写出来的。代码优化到底要执行到哪一步,是仁者见仁,智者见智的问题。有的人偏重于提高效率,有的人偏重于保证兼容性,这需要在实际使用过程中作取舍。

 

----

实际测试,

{*

//长字符串(大概1M左右)

1000次


BDS 2007 见Demos
(Delete) time: 323301
(CopyStr) time: 953036

(LastPosEx)Pos: 144881
 time: 3665003
(Pos)Pos: 58745
 time: 314023
(FastPosEx)Pos: 58745
 time: 11383136
(fstAt)Pos: 58745
 time: 354948
(SmartPos)Pos: 58745
 time: 206409

*}

 

const
  COUNT_NUM = 10000;


procedure TForm1.btnDeleteAndCopyStrClick(Sender: TObject);
var
  i, lvlen, iPos: Integer;
  PerformanceCount1, PerformanceCount2, Count: int64;
  lvSubString, lvSourceString: string;
begin
  lvlen := COUNT_NUM; //重复次数

  lvSourceString := edtSourceString.Text;
  if chkUseMemoSource.Checked then
  begin
    lvSourceString := mmoSourceString.Text;
    lvlen := lvlen div 10;
  end;

 

  QueryPerformanceCounter(PerformanceCount1); //开始计数
  lvSubString := lvSourceString;
  for i := 0 to lvlen - 1 do
  begin
    Delete(lvSubString, 1, 1);
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(Delete) time: ' + inttostr(Count));

  QueryPerformanceCounter(PerformanceCount1); //开始计数
  lvSubString := lvSourceString;
  for i := 0 to lvlen - 1 do
  begin
    lvSubString := CopyStr(lvSubString, 2, Length(lvSubString));
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(CopyStr) time: ' + inttostr(Count));


end;

procedure TForm1.btnPosTestClick(Sender: TObject);
var
  i, lvlen, iPos: Integer;
  PerformanceCount1, PerformanceCount2, Count: int64;
  lvSubString, lvSourceString: string;
begin


  lvlen := COUNT_NUM; //重复次数

  lvSourceString := edtSourceString.Text;
    lvSubString := edtPosTest.Text;
  if chkUseMemoSource.Checked then
  begin
    lvSourceString := mmoSourceString.Text;
    lvlen := lvlen div 10;
  end;


  QueryPerformanceCounter(PerformanceCount1); //开始计数
  for i := 0 to lvlen - 1 do
  begin
    iPos := LastPosEx(lvSubString, lvSourceString); //被测试的函数
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(LastPosEx)Pos: ' + inttostr(iPos) + sLineBreak + ' time: ' + inttostr(Count));


  QueryPerformanceCounter(PerformanceCount1); //开始计数
  for i := 0 to lvlen - 1 do
  begin
    iPos := Pos(lvSubString, lvSourceString); //被测试的函数
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(Pos)Pos: ' + inttostr(iPos) + sLineBreak + ' time: ' + inttostr(Count));


  QueryPerformanceCounter(PerformanceCount1); //开始计数
  for i := 0 to lvlen - 1 do
  begin
    iPos := FastPosEx(PChar(lvSourceString), Length(lvSourceString), PChar(lvSubString), Length(lvSubString)); //被测试的函数
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(FastPosEx)Pos: ' + inttostr(iPos) + sLineBreak + ' time: ' + inttostr(Count));

  QueryPerformanceCounter(PerformanceCount1); //开始计数
  for i := 0 to lvlen - 1 do
  begin
    iPos := fstAt(lvSubString, lvSourceString); //被测试的函数
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(fstAt)Pos: ' + inttostr(iPos) + sLineBreak + ' time: ' + inttostr(Count));

  QueryPerformanceCounter(PerformanceCount1); //开始计数
  for i := 0 to lvlen - 1 do
  begin
    iPos := SmartPos(lvSubString, lvSourceString); //被测试的函数
  end;
  QueryPerformanceCounter(PerformanceCount2); //结束计数
  Count := (PerformanceCount2 - PerformanceCount1);
  mmoMessage.Lines.Add('(SmartPos)Pos: ' + inttostr(iPos) + sLineBreak + ' time: ' + inttostr(Count));
end;

posted @ 2008-05-25 21:52 D10.天地弦 阅读(68) | 评论 (0)编辑

浪费了我将近三个小时的查错,郁闷.

以前增加TmfEditFormCmptMgr.OnDstMainSetFieldData事件,但是在Destroy的时候忘记了还原事件.导致Cds.OnSetFieldData为无效内存块.

以后写程序时一定要紧记,内存块问题.不要使还存在的对象指象一块无效的内存.

posted @ 2008-05-19 12:22 D10.天地弦 阅读(48) | 评论 (0)编辑