ERP维护经验总结

5 篇文章 0 订阅

1、隐藏dxDBGrid显示的英文字段可以在窗口OnShow事件里通过把数据集字段隐藏:Search_AdoDataSet.FieldByName('ConsumeSubId').Visible := false;

2、dxDBGrid的KeyField属性一定要设置,没设置数据不显示

3、抽象编辑单元AbstractEditUnit读写数据(对应AbstractInfoUnit[信息显示单元]也可与SingleTableClass[单表查询抽象单元])

写数据方法DOWriteDate

读数据方法ReadData

保存前检查DoCheck

4、查询模块抽象类

5、单表查询抽象类

6、主从表抽象类

7、数据表字段bit,数据集字段应设为boolean类型,数据集FieldByName('XX').value='1'相当于

FieldByName('XX').value=true,

数据集FieldByName('XX').value='0'相当于

FieldByName('XX').value=false

8、DataSet FieldName exceeds 31 chars提示,FieldName设置不能超过31个字符
9、简单映射Map功能可应用TStringList  StringItem='Key=Value'   取值:Values[Key]

10、通过数据集更新数据库

Commdb.UpdateDataBatchTrans([hDataSqlBefore,AdoQuery_Master])

11、日期格式互转

procedure TForm1.Button1Click(Sender: TObject);
var
  D:TDateTime;
  s:string;
begin
  D:=VarToDateTime('05-10-14 04:35PM');
  S:=FormatDatetime('YYYY/MM/DD HH:MM:SS',D);
  showmessage(s);
end;

12、delphi FTP报错“no FTP list parsers have been registered”

要使用idftp_Client.DirectoryListing属性,必须uses IdAllFTPListParsers;否则会有no idftplistparse classes have been registered的错误

uses IdAllFTPListParser

 

13、objFieldName是某个对象的字段名

procedure FieldToItemObj(Items: TStrings; FieldName, ObjFieldName, TableName, Condition: string; IsAddEmpty: Boolean);

14.ThDataSet 过滤功能

(1)禁用过滤功能

ADOQuery_Single.Filter := '';
ADOQuery_Single.Filtered := False;

(2)店用过滤功能

ADOQuery_Single.Filter := 'IssueUser=' + #39 + LoginRecord.EmployeeNo + #39;
ADOQuery_Single.Filtered := True;

15.删除Delphi编译中间文件

del *.~pas /F /S /Q 
del *.~ddp  /F /S /Q 
del *.ddp  /F /S /Q 
del *.~dfm   /F /S /Q 
del *.dcu /F /S /Q 
del *.~dsk /F /S /Q 
del *.~dpr /F /S /Q 
del *.~pa /F /S /Q 

新一批处理文件,把上面的文本放到里面运行即可

16.idhttp升级到10.6版本,打开项目运行提示Undelcare  FileSizeByName  

解决方法要引用IdGlobalProtocols,原来是在idGlobal

17.从第二个字符Copy后面的字符串

s2 := copy(s2, 2, length(s2));

18.ThDataSet判断字段是否存在用IndexOf,若不存结果为-1

if AdoQuery_Master.FieldList.IndexOf('VoucherId') <> -1

19.警告: 现有列的 ANSI_PADDING 设置为 “off”。将以 ANSI_PADDING 为 “on” 的设置创建新列

数据库表添加列的时候提示  警告: 现有列的 ANSI_PADDING 设置为 “off”。将以 ANSI_PADDING 为 “on” 的设置创建新列。

 

执行 SET ANSI_PADDING ON 即可

 

 

 

设置为on ,长度不足的自动补充空格。

 

以后的版本逐渐使用onoff将会导致错误

 

以下为示例。 

 

PRINT 'Testing with ANSI_PADDING ON'

SET ANSI_PADDING ON;

GO

 

CREATE TABLE #t1 (

   charcol CHAR(16) NULL

   varcharcol VARCHAR(16) NULL

   varbinarycol VARBINARY(8)

);

GO

INSERT INTO #t1 VALUES ('No blanks''No blanks', 0x00ee);

INSERT INTO #t1 VALUES ('Trailing blank ''Trailing blank ', 0x00ee00);

 

SELECT 'CHAR' '>' + charcol + '<''VARCHAR'='>' + varcharcol + '<',

   varbinarycol

FROM #t1;

GO

 

PRINT 'Testing with ANSI_PADDING OFF';

SET ANSI_PADDING OFF;

GO

 

CREATE TABLE #t2 (

   charcol CHAR(16) NULL

   varcharcol VARCHAR(16) NULL

   varbinarycol VARBINARY(8)

);

GO

INSERT INTO #t2 VALUES ('No blanks''No blanks', 0x00ee);

INSERT INTO #t2 VALUES ('Trailing blank ''Trailing blank ', 0x00ee00);

 

SELECT 'CHAR' '>' + charcol + '<''VARCHAR'='>' + varcharcol + '<',

   varbinarycol

FROM #t2;

GO

 

DROP TABLE #t1

DROP TABLE #t2

20.事件和方法区别就是当事件没赋值时就不会触发

 

21、拷贝消息

procedure DoSendSMSCopyData(var MsgCopyData: TWMCopyData); Message WM_COPYDATA;  //处理发送短信

procedure TMainForm.DoSendSMSCopyData(var MsgCopyData: TWMCopyData);
var
  sMsgId:string;
begin
  if MsgCopyData.CopyDataStruct^.dwData=110 then
  begin
    sMsgId:=StrPas(MsgCopyData.CopyDataStruct^.lpData);
    TNowSendSMSThread.Create(False,sMsgId);
  end;
end;

procedure SendMsgToMain(AMsgid:string);/

procedure TSendSmsClass.SendMsgToMain(AMsgid: string);
var
  DS: TCopyDataStruct;
  sMsgId:string;
begin
  sMsgId := AMsgid;
  DS.dwData :=110;
  Ds.cbData := Length(sMsgId) + 1;
  GetMem(Ds.lpData, Ds.cbData);
  StrCopy(ds.lpData, PChar(sMsgId));
  SendMessage(MainFormHandle, WM_COPYDATA, 0, Cardinal(@ds));
  FreeMem(Ds.lpData);
end;

22、短信发送接口修改

修改接口链接

SmsUrl:string ='https://smssh1.253.com/msg/send/json';

修改DoSendCLSms、SendCLSmsExt过程

function TSendSmsClass.DoSendCLSms(AMobile, AMsg: string): Integer; //创蓝短信
var
  params:TStringList;
  Tmphttp:TIdHttp;
  sResult:string;
  SplitAry: TSplitArray;
  s:string;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  stream, restream: TStringStream;
  jsonStr: string;
begin
  result := -1;
//  params := TStringList.Create();
  Tmphttp:=TIdHttp.Create(nil);
  try
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      LHandler.SSLOptions.Method:=sslvSSLv23;
      Tmphttp.Request.UserAgent:='Mozilla/5.0 (Windows NT 5.1; rv:46.0) ';
      Tmphttp.HandleRedirects := True;
      Tmphttp.ReadTimeout := 5000;
      Tmphttp.Request.ContentType := 'application/json';
      Tmphttp.Request.CharSet := 'utf-8';
      Tmphttp.IOHandler := LHandler;
//      params.Add('account='+FUserName);
//      params.Add('password='+FPassword);
//      params.Add('phone='+AMobile);
//      params.Add('msg='+AnsiToUTF8(AMsg));
//      params.Add('report=true');
      jsonStr := '{"account":"' + FUserName + '","password":"' + FPassword + '","phone":"'
        + AMobile + '","msg":"' + AnsiToUTF8(AMsg) + '","report":"true"}';
      stream := TStringStream.Create(jsonStr);
      restream := TStringStream.Create('');
      Tmphttp.Post(SmsUrl,stream,restream);
      sResult :=utf8toansi(restream.DataString);

//      SplitString(sResult,#$A,SplitAry);
      if Pos('"code":"0"',sResult) > 0 then
      begin
//        s := Trim(SplitAry[0]);
//        Result := strtoInt(Copy(s,Pos(',',s)+1,Length(s)));
        Result := strtoInt(BetweenString(sResult,'"code":"','",'));
//        SetLength(SplitAry, 0);
      end;
    finally
      LHandler.free;
      restream.Free;
      stream.Free;
    end;
  finally
    FreeAndNil(Tmphttp);
//    params.Free();
  end;
end;

class function TSendSmsClass.SendCLSmsExt(ASmsContent: TSmsContent): Integer;//直接发送创蓝短信  //直接发送创蓝短信--必须提供帐号和密码 线程在调用
var
  Tmphttp:TIdHttp;
  sResult:string;
  SplitAry: TSplitArray;
  s:string;
  LHandler: TIdSSLIOHandlerSocketOpenSSL;
  stream, restream: TStringStream;
  jsonStr: string;
begin;
  result := -1;
  Tmphttp:=TIdHttp.Create(nil);
  try
    LHandler := TIdSSLIOHandlerSocketOpenSSL.Create(nil);
    try
      LHandler.SSLOptions.Method:=sslvSSLv23;
      Tmphttp.Request.UserAgent:='Mozilla/5.0 (Windows NT 5.1; rv:46.0) ';
      Tmphttp.HandleRedirects := True;
      Tmphttp.ReadTimeout := 5000;
      Tmphttp.Request.ContentType := 'application/json';
      Tmphttp.Request.CharSet := 'utf-8';
      Tmphttp.IOHandler := LHandler;
      jsonStr := '{"account":"' + ASmsContent.UserName + '","password":"' + ASmsContent.Password + '","phone":"'
        + ASmsContent.Mobile + '","msg":"' + AnsiToUTF8(ASmsContent.Msg) + '","report":"true"}';
      stream := TStringStream.Create(jsonStr);
      restream := TStringStream.Create('');
      Tmphttp.Post(SmsUrl,stream,restream);
      sResult :=utf8toansi(restream.DataString);

    if Pos('"code":"0"',sResult) > 0 then
      begin
        Result := strtoInt(BetweenString(sResult,'"code":"','",'));
      end;
    finally
      LHandler.free;
      restream.Free;
      stream.Free;
    end;
  finally
    FreeAndNil(Tmphttp);
  end;
end;

23、子窗口创建步骤

1)新建一个窗口继承自某子窗口父类

2)Destroy方法里要释放自己

3)在Project Option-Forms里禁止窗口在运行时创建

24、分析一张报表主要看用户需要报表的信息而非SQL语句,然后再跟据报表的信息去思考SQL语句该是什么样子

25、*=和=*表示左连接和右连接等于

26、dataset唯一性检查

function TAbstractEditForm.RepeatCheck(ACheckValue, ACheckFieldName: string;
  AADODataSet: ThDataSet): Boolean;
var
  Clone: ThDataSet;
  ID: string;
begin
  Result := True;
  ID := AADODataSet.FieldByName('ID').asstring;
  Clone := ThDataSet.Create(nil);
  try
   // Clone.Clone(AADODataSet);
      Clone.Data := AADODataSet.Data;
    if FOpState = OPAdd then //增加记录
    begin
      if Clone.Locate(Trim(ACheckFieldName), Trim(ACheckValue), []) then
        Result := False;
    end
    else if FOpState = OPEdit then //编辑记录
    begin
      if Clone.Locate(Trim(ACheckFieldName), Trim(ACheckValue), []) then
      begin
        if Clone.FieldByName('ID').asstring <> ID then
          Result := False;
      end;
    end;
  finally
    Clone.Free;
    Clone := nil;
  end;
end;

27、BLOB定义

BLOB (binary large object)----二进制大对象,是一个可以存储二进制文件的容器。
  在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。
  BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。
  根据Eric Raymond的说法,处理BLOB的主要思想就是让文件处理器(如数据库管理器)不去理会文件是什么,而是关心如何去处理它。
  但也有专家强调,这种处理大数据对象的方法是把双刃剑,它有可能引发一些问题,如存储的二进制文件过大,会使数据库的性能下降。
在数据库中存放体积较大的多媒体对象就是应用程序处理BLOB的典型例子。

28、 dxDBGrid+字段名禁用编辑器:dxDBGrid2UseCard.DisableEditor:=True;

29、dxDBGrid设置焦点字段:dxDBGrid2.FocusedField := ADOQuery_SS_ConsumeProjectDetail.FieldByName('price');

30、ThDataSet.ExecSQL默认使用全局的函数

constructor ThDataSet.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);

  FUseGlobalFuncs := True; // 默认使用全局函数
  FzInitFieldValueOnNewRecord := True;
procedure ThDataSet.ExecSQL;
var
  TempExecSQL: TNotifyEvent;
begin
  RemoteServer := nil;
  ProviderName := '';

  if FUseGlobalFuncs then
    TempExecSQL := GlobalExecSQL
  else
    TempExecSQL := FGlobalExecSQL;

  if Assigned(TempExecSQL) and (zFlagAppID <> -1) then
  begin
    TempExecSQL(Self);
  end
  else
    raise Exception.Create(Format('%s 没有设置:GlobalExecSQL 或 zFlagAppID !', [name]));
end;

(1)ExecSQL不支持事务执行

(2)当FUseGlobalFuncs为False时,即ExecSQL不使用全局的函数时,要给FGlobalExecSQL赋一个通知事件执行SQL,要不会报异常

31、dxDBGrid自定义单元格的颜色

procedure TMasterDetailClassForm1.dxDBGrid2DiYongQuanCustomDrawCell(
  Sender: TObject; ACanvas: TCanvas; ARect: TRect; ANode: TdxTreeListNode;
  AColumn: TdxTreeListColumn; ASelected, AFocused, ANewItemRow: Boolean;
  var AText: string; var AColor: TColor; AFont: TFont;
  var AAlignment: TAlignment; var ADone: Boolean);
begin
  if (CheckBox1.Checked) and (ADOQuery_SS_ConsumeProjectDetail.FieldByName('DiYongQuan').AsFloat > 0) then
  begin
    AColor := clRed;
    AFont.Color := clBlue;
  end
  else
  begin
    AColor := clWhite;
    AFont.Color := clWindowText;
  end;
end;

32、判断RemObject是否连接

if not CommDB.ROSuperTcpChannel.Connected then
     Exit;

33、抽象树表浏览窗口类:AbstractTreeUnit

34、抽象输入窗口类:AbstractEditUnit

35、SQL Server判断数据库是否存在:if exists(select * from syscolumns where id=object_id(''TFYZC'')) DROP TABLE TFYZC

36、ThDataset事务提交失败后要一般要调用CancelUpdates取消更改

37、delphi adoquery的post和UpdateBatch

Post是确认当前的修改,而UpdateBatch是把已经确认但是没有存盘的数据写入数据库
当ADOQuery的CursorType是ctKeySet或者ctStatic,并且LockType是ltBatchOptimistic的时候,数据DataSet是用批量更新的更新方式。这时,每条记录修改之后,用Post确认当前修改,但是确认后的数据却并没有立即写入数据库,而是保存于缓存之中。
当调用UpdateBatch的时候,这些缓存中的修改才写入数据库。
如果不是使用批量更新的方式的时候,Post的时候,确认的修改直接写入数据库。

38、调用UpdateBatch报错

这是你的数据表中的数据有重复造成的,可以通过后补一个id自增字段来解决 

39、delphi ADOQUery中错误解决方法"无法为更新定位行

delphi ADOQUery中错误解决方法"无法为更新定位行。一些值可能已在最后...

使用delphi中的ADOQuery控件中自带的,insert ,edit,delete此操作时,有时会出现下面的错误提示,提示错误信息:"无法为更新定位行。一些值可能已在最后一次读取后已更改。" 此解决方案:

出现的原因:

 

1.可能是修改的时候在其它地方已经重新修改过此数据集中的某些字段信息,例如我在上传文件时,修改了某表中的文件名称和文件路径,由于没有注意到,所以在修改数据,并再一次选择上传文件时,就会报出此错误;

 

2.数据库中的表没有主键;

3.在数据库设计时,为某些字段设置了默认值,在修改进行提交以后,数据库会自动修改对应字段的所有行的默认值,从而导致了数据库与数据集中数据的不一致,使ADOQuery无法对数据集进行定位。"

 

解决方法:

 

1.把数据集重新关闭,再打开,如ADOQuery.close;ADOQuery.open;然后再执行Adoquery.post,完成后,也可以执行 ADOApply.Refresh或 ADOApply.Requery; 视情况而定;

2.修改数据库设计,不再设置默认值,为数据库表定义主键,保证其唯一性。

3.在执行完ADOQuery.Post之后,执行ADOQuery.Refresh,对于设置默认值的情况可以解决。

好的代码像粥一样,都是用时间熬出来的

40、聚合不应出现在 WHERE 子句中,除非该聚合位于 HAVING 子句或选择列表所包含的子查询中,并且要对其进行聚合的列是外部引用。

41、speedbutton 设置图标:Glyph:设置图片   layout:设置图片排列对齐

42、sql server报这个错误:子查询返回的值不止一个。当子查询跟随在 =、!=、<、<=、>、>= 之后,或子查询用作表达式时,这种情况是不允许的。

一般是子查询查询结果多条对应主查询结果一条造成的

43、 having和where的异同:

相同:
  都是对数据过滤,只保留有效的数据;
  where和having一样,  都不允许出现字段的别名;
  只允许出现最原始的字段的名字。

不同:
   where是对原始的记录过滤having是对分组之后的记录过滤;
   where必须的写在having的前面,顺序不可颠倒否则运行出错。

44、判断表是否存在,存在删除表

if object_id(''TTShops1'') is not null

drop table TTShops1

45、判断临时表是否存

if exists (select * from tempdb.dbo.sysobjects where id = object_id(N'tempdb..#TEMP_TBL') and type='U')
PRINT '存在'
ELSE
PRINT'不存在'

46、ADOQuery.sql.add(sqlstat)递归执行时,内层会丢失,所以ADOQuery内层和外层必须独立执行

procedure TMainForm.GetFileListEx(mainmenu: TMenuItem; LTypename: string);
var
  k: Integer;
  menuStr: string;
  LModuleName, Lname, LDescription: string;
begin
  if mainmenu.Count > 0 then
  begin
    for k := 0 to mainmenu.Count - 1 do
    begin
      if (mainmenu.Items[k].Caption <> '-') and (mainmenu.Items[k].Visible = true) then
        if mainmenu.Items[k].Count > 0 then
        begin
          GetFileListEx(mainmenu.items[k], LTypename);
        end
        else
        begin
          if pos('(', mainmenu.Items[k].Caption) > 0 then
          begin
            LModuleName := trim(copy(mainmenu.Items[k].Caption, 1, pos('(', mainmenu.Items[k].Caption) - 1));
            Lname := trim(copy(mainmenu.Items[k].Name, 1, pos('(', mainmenu.Items[k].Name) - 1));
          end
          else
          begin
            LModuleName := trim(mainmenu.Items[k].Caption);
            Lname := trim(mainmenu.Items[k].Name);
          end;
          LDescription := trim(mainmenu.Items[k].Caption);
          menuStr := 'insert into sm_power(type,ModuleName,Description,Fname) values(' + '''' + LTypename + '''' + ',' + '''' + LModuleName + '''' + ',' + '''' + LDescription + '''' + ',' + '''' + Lname + '''' + ')';
          AdoQuery1.sql.Add(menuStr);
        end;
    end;
  end;
end;

 

外层调用

begin
    if MainMenu1.Items[i].Visible = True then
    begin
      if pos('(', MainMenu1.Items[i].Caption) > 0 then
        Ltype := trim(copy(MainMenu1.Items[i].Caption, 1, pos('(', MainMenu1.Items[i].Caption) - 1))
      else
        Ltype := trim(MainMenu1.Items[i].Caption);
      GetFileListEx(MainMenu1.Items[i], Ltype);
    end;

  end;
  sqlStr := 'insert into sm_power(type,ModuleName,Description) values(''物流管理'',''到货确认'',''到货确认'') ' + #13#10 +          //  'insert into sm_power(type,ModuleName,Description) values(''系统管理'',''查看完整手机号码'',''查看完整手机号码'') '+#13#10+
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''修改顾问'',''修改顾问'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''卡升级'',''卡升级'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''退卡'',''退卡'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''退款'',''退款'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''选择员工'',''选择员工'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''退疗程卡项目'',''退疗程卡项目'') ' + #13#10 +    
    'insert into sm_power(type,ModuleName,Description) values(''系统管理'',''导出EXCEL'',''导出EXCEL'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''营运管理'',''卡扣卡权限'',''卡扣卡权限'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''物流管理'',''进价权限'',''进价权限'') ' + #13#10 +
    'insert into sm_power(type,ModuleName,Description) values(''系统管理'',''会员停用'',''会员停用'') ';
  AdoQuery1.sql.Add(sqlStr);
//  ClipLog(Adoquery1.SQL.text);
  AdoQuery1.ExecSQL;

如上面所示的递归内层添加的SQL语句到外层时会丢失,故不能执行相应的语句,应改为:

procedure TMainForm.GetFileListEx(mainmenu:TMenuItem; LTypename:string;SqlStrings:TStrings);
var
  k:Integer;
  menuStr:string;
  LModuleName,Lname, LDescription: string;
begin
  if mainmenu.Count>0 then
  begin
    for k:=0 to mainmenu.Count-1 do
    begin
      if (mainmenu.Items[k].Caption<>'-') and (mainmenu.Items[k].Visible =true) then
      if mainmenu.Items[k].Count>0 then
        begin
          GetFileListEx(mainmenu.items[k],LTypename);
        end
      else
      begin
        if pos('(', mainmenu.Items[k].Caption) > 0 then
        begin
          LModuleName := trim(copy(mainmenu.Items[k].Caption, 1, pos('(', mainmenu.Items[k].Caption) - 1));
          Lname := trim(copy(mainmenu.Items[k].Name, 1, pos('(', mainmenu.Items[k].Name) - 1));
        end
        else
        begin
          LModuleName := trim(mainmenu.Items[k].Caption);
          Lname := trim(mainmenu.Items[k].Name);
        end;  
        LDescription := trim(mainmenu.Items[k].Caption);
        menuStr := 'insert into sm_power(type,ModuleName,Description,Fname) values(' +
                '''' + LTypename + '''' + ',' +
                '''' + LModuleName + '''' + ',' +
                '''' + LDescription + '''' + ',' +
                '''' + Lname + '''' +
                ')';

        SqlStrings.Add(menuStr);
      end;
    end;
  end;
end;

 

47、TStringList键值对的应用

sList.Add('BuyCardDept=' + FPrintBuyCardQianKuan);
    sList.Add('GoodsDept=' + PGoodsQianKuan);
    sList.Add('ProjectDept=' + PProjectQianKuan);

// 调用
if (AParamList <> nil) and (AParamList.Count > 0) then
    begin
      for i := 0 to AParamList.Count - 1 do
      begin
        if Trim(AParamList.Names[i]) <> '' then
          RMReport.Dictionary.Variables.AsString[AParamList.Names[i]] := AParamList.ValueFromIndex[i];
      end;
    end;

48、Application.CreateForm(TSS_ConsumeBomForm, SS_ConsumeBomForm)创建窗体会触发OnFormShow事件(还未找到原因)

49、dxDBTreeList一般设置一下KeyField和OptionsView.ParentField

50、dataset查找定位一盘用locate

if trim(Edit_Name_PinYin.Text) <> '' then
    ADOQuery1.Locate('name', Edit_Name_PinYin.Text, [])
  else
    ADOQuery1.Locate('mobile', Edit_Mobile.Text, []);

51、设置编辑文本对齐(右对齐)

SetWindowLong(Edit.Handle, GWL_STYLE, GetWindowLong(Edit.Handle, GWL_STYLE) or ES_Right);

52、DBEdit设置光标的位置

DBEdit9.SelStart := Length(DBEdit9.Text);

53、ThDataset书签应用

p := ADODataSet_Info.GetBookmark;
if ADODataSet_Info.BookmarkValid(p) then
       ADODataSet_Info.GotoBookmark(p);
    ADODataSet_Info.FreeBookmark(p);

54、ThDataset获取字段方法:FindField

ADODataSet_Info.FindField('id').ProviderFlags := [pfInUpdate,pfInWhere,pfInKey];
  ADODataSet_Info.FindField('CustomerNo').ProviderFlags := [];
  ADODataSet_Info.FindField('Mobile').ProviderFlags := [];
  ADODataSet_Info.FindField('shopname').ProviderFlags := [];
  ADODataSet_Info.FindField('MemberGrade').ProviderFlags := [];

55、还原数据库前先执行以下语句,否则会报错

ALTER DATABASE p飘洒老店 SET OFFLINE WITH ROLLBACK IMMEDIATE

56、dxDBGrid设置多选

OptionsBehavior :=[edgoMultiSelect]

for  i:= 0  to dxDBGrid_Single.SelectedCount-1 do
        begin
          sCusomerId := Trim(dxDBGrid_Single.SelectedNodes[i].Strings[iIndex]);

57、窗口查找控件函数FindComponent

if (FindComponent('CheckBox' + inttostr(i + 201)) as TCheckBox).Checked = true then
      begin
        lfieldlist := 'Employeeid,GoodsKindId';
        lfieldvalue := QuotedStr(ADOQuery.fieldbyname('id').AsString) + ',' + QuotedStr((FindComponent('CheckBox' + inttostr(i + 201)) as TCheckBox).Hint);
        tmpataSet.SQL.Add(SaveDataSql('bd_GoodsKindRelate', lfieldlist, lfieldvalue));
      end;

58、数据集ADOQueryAfterScroll事件可代替记录单击事件

59、报表基类:SearchClass

60、显示报表明细基类:fmDetailBase(员工薪资业绩报表、门店客流状况分析表)

procedure TSS_YuanGongWeiHuKeForm.dxDBGrid1DblClick(Sender: TObject);
begin
  inherited;
  ShowClickDetail(dxDBGrid1.FocusedField.FieldName);
end;

var
  sShopID: string;
  frmDetail: TfrmDetailBase;
  dsTemp: ThDataSet;
  sSql: string;
begin
  sShopID := Search_AdoDataSet.fieldbyname('ID').AsString;
  dsTemp := nil;
  try
    dsTemp := ThDataSet.Create(Self);
    if SameText('NewCustomerNum', AFieldName) then
    begin
      sSql := FNewCustomerSql + ' and a.shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '新客数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('NewCustomerTableNum', AFieldName) then
    begin
      sSql := FNewCustomerTradeSql + ' and b.shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.KeyFieldIDName := 'Customerid';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '新客成单数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('NewCusNoSucc', AFieldName) then
    begin
      sSql := FNewCustomerNoTradeSql + ' and a.shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      //frmDetail.KeyFieldIDName := 'Customerid';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '新客未成单数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('Quantity', AFieldName) then
    begin
      sSql := FCusotmerKCIDetailSql + ' and c.ShopID = ' + QuotedStr(sShopID) + ' order by saledate ';
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.KeyFieldIDName := 'FuWuCustomerId';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '客次';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('Num', AFieldName) then
    begin
      sSql := FCusotmerNumDetailSql + ' and c.ShopID = ' + QuotedStr(sShopID) + ' order by c.FType ';
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.KeyFieldIDName := 'FuWuCustomerId';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '客数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('LostCustomerNum', AFieldName) then
    begin
      //sSql := FLostCustomerDetailSql + ' and a.Shop = ' + QuotedStr(sShopID);
      sSql := FLostCustomerDetailSql + ' and c.Shop = ' + QuotedStr(sShopID);
//      ClipLog(sSql);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      //frmDetail.KeyFieldIDName := 'FuWuCustomerId';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '流失会员';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('ThisNewCustomerTableNum', AFieldName) then
    begin
      sSql := FthisCustomerTradeSql + ' and b.Shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.KeyFieldIDName := 'customerid';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '当月成单数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('historyNewCustomerTableNum', AFieldName) then
    begin
      sSql := FhistoryCustomerTradeSql + ' and b.Shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      frmDetail.KeyFieldIDName := 'customerid';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '历史成单数';
      frmDetail.ShowModal;
      frmDetail.Free;
    end
    else if SameText('LostCustomerInNum', AFieldName) then
    begin
      sSql := FLostCustomerInDetailSql + ' and e.Shop = ' + QuotedStr(sShopID);
      OpenSql(dsTemp, sSql);
      frmDetail := TfrmDetailBase.Create(Self);
      //frmDetail.KeyFieldIDName := 'FuWuCustomerId';
      frmDetail.FDSData := dsTemp;
      frmDetail.Caption := '流失跟进';
      frmDetail.ShowModal;
      frmDetail.Free;
    end;

  finally
    dsTemp.Free;
  end;
end;

// 查询时同时获取相应明细SQL: FNewCustomerSql 
// 新客明细 
GetNewCustomerSql(AStartDate, AEndDate);

61、ADOQuery提示:数据已被更新,请刷新数据后重新操作

原因一般是其他地方对数据集做了更改 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值