[delphi]老代码维护 -- [zt]TClientDataSet[8]: 关于索引与排序
clq
浏览(453) -
2019-05-27 12:52:31 发表
编辑
关键字: delphi
[2019-05-27 12:52:49 最后更新]
[delphi]老代码维护 -- [zt]TClientDataSet[8]: 关于索引与排序
索引的目的有三: 快速定位、排序、建立主从表. 下面是相关属性与方法: IndexDefs; { } IndexFieldCount; { } IndexFieldNames; { } IndexFields[]; { } IndexName; { } AddIndex(); { } DeleteIndex(); { } GetIndexInfo(); { } GetIndexNames(); { } 添加索引的方法有二: 1、用 IndexFieldNames 通过字段名(多个字段用 ; 隔开)指定临时索引; 2、通过 IndexDefs.AddIndexDef 或 AddIndex 建立索引, 然后用 IndexName 指定为当前索引. 两种方法都可以在设计时完成; 后者会有更多功能, 譬如倒排序; 两种方法是互斥的, 指定一个会自动取消另一个. TClientDataSet 会自动生成两个默认索引: DEFAULT_ORDER、CHANGEINDEX; 它们都不允许用户删改. CHANGEINDEX 是用于 Delta(日志)的. DEFAULT_ORDER 可用于恢复默认排序; 它可能已经和某些字段关联, 如(xml 源码): <PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" ... /> 或 <PARAMS DEFAULT_ORDER="1 2" PRIMARY_KEY="1 2" ... /> 关于临时索引最常用的代码是在 DBGrid 的 OnTitleClick 事件中更换索引, 如: { 根据当前字段排序 } procedure TForm1.DBGrid1TitleClick(Column: TColumn); begin if not Column.Field.IsBlob then { 不能给大二进制字段建立索引或排序 } ClientDataSet1.IndexFieldNames := Column.FieldName; end; { 恢复默认排序 } procedure TForm1.Button1Click(Sender: TObject); begin ClientDataSet1.IndexName := 'DEFAULT_ORDER'; end; 使用 IndexFieldNames 可指定多个字段, 如: ClientDataSet1.IndexFieldNames := '字段x; 字段y; 字段z'; 此时顺序很重要, 这里会先按 "字段x" 排序; 在 "字段x" 的值相同时会按 "字段y" 排序; 在 "字段y" 的相同时... IndexFieldNames 没有更多了, 更复杂的排序就需要建立排序对象(TIndexDef)了. 实现倒排序的例子: { 下面是在 holdings.xml 的基础上建立的两个索引; ACCT_NBR、SYMBOL 是其中的两个字段 } procedure TForm1.FormCreate(Sender: TObject); begin ClientDataSet1.AddIndex('Index_1', 'ACCT_NBR; SYMBOL', []); { 正序 } ClientDataSet1.AddIndex('Index_2', 'ACCT_NBR; SYMBOL', [ixDescending]); { 倒序 } ClientDataSet1.IndexName := 'Index_1'; end; { 切换上面建立的两个索引 } procedure TForm1.Button1Click(Sender: TObject); begin if ClientDataSet1.IndexName = 'Index_1' then ClientDataSet1.IndexName := 'Index_2' else ClientDataSet1.IndexName := 'Index_1'; ClientDataSet1.First; end; { 上面的 TForm1.FormCreate 过程也可以写作(另一种建立方法) } procedure TForm1.FormCreate(Sender: TObject); begin with ClientDataSet1.IndexDefs.AddIndexDef do begin Name := 'Index_1'; Fields := 'ACCT_NBR; SYMBOL'; end; with ClientDataSet1.IndexDefs.AddIndexDef do begin Name := 'Index_2'; Fields := 'ACCT_NBR; SYMBOL'; Options := [ixDescending]; end; ClientDataSet1.IndexName := 'Index_1'; end; 关于 AddIndex: AddIndex( const Name: string; { 索引名称; 不能重名 } const Fields: string; { 索引字段; 多个字段用分号隔开; 默认升序排列 } Options: TIndexOptions; { 选项 } const DescFields, { 按降序排列的字段; 须先在 Fields 中列出 } const CaseInsFields: string; { 不区分大小写的字段; 须先在 Fields 中列出 } const GroupingLevel: Integer { 分组级别, 用于分组统计的 } ); //Options: IxPrimary { 主索引 } IxUnique { 字段值无重复 } ixDescending { 降序 } ixCaseInsensitive { 不区分大小写 } ixExpression { 无用 } ixNonMaintained { 无用 } { 可选空值 [], 最多不能多于两个选项 } { 若是两个选项, 其中之一须是: ixDescending 或 ixCaseInsensitive } AddIndex 的一些用法(都是先 F1 后 F2): //F1、F2 降序, 两种写法一样: AddIndex('Index_1', 'F1; F2', [ixDescending]); AddIndex('Index_2', 'F1; F2', [], 'F1; F2'); //F1、F2 不区分大小写排序(不指定降序则默认升序): AddIndex('Index_1', 'F1; F2', [ixCaseInsensitive]); AddIndex('Index_2', 'F1; F2', [], '', 'F1; F2'); //F1 升序, F2 降序: AddIndex('Index_1', 'F1; F2', [], 'F2'); AddIndex('Index_2', 'F1; F2', [ixDescending], 'F2'); { 此时 [ixDescending] 被忽略 } //F1 降序, F2 升序: AddIndex('Index_1', 'F1; F2', [], 'F1'); AddIndex('Index_2', 'F1; F2', [ixDescending], 'F1');AddIndex 能做到的, 用 IndexDefs.AddIndexDef 也可以, 并且也都能在设计时完成.
clq
2019-05-27 12:52:49 发表
编辑
来自 https://www.cnblogs.com/del/archive/2010/01/28/1658118.html
NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.