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
,长度不足的自动补充空格。
以后的版本逐渐使用
on
,
off
将会导致错误
以下为示例。
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提示:数据已被更新,请刷新数据后重新操作
原因一般是其他地方对数据集做了更改