ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

EhLib 11.1.015在Delphi 12.3中的安装配置与DBGridEh报表实战

EhLib 11.1.015在Delphi 12.3中的安装配置与DBGridEh报表实战 简介Delphi 12.3专用的EhLib 11.1.015控件库压缩包面向使用Object Pascal开发Windows应用的工程师尤其适合需要在项目中快速实现复杂表头、分组汇总、数据排序过滤及灵活数据库交互的开发者。压缩包共2000个文件以dfm窗体和pas单元为界面与逻辑核心配以dpk/dproj工程文件、res/ico/png资源以及chm帮助文档完整呈现了控件库的工程组织方式。资源包整体约32.7MB已有55人学习下载。包内附英文与俄文双版本介绍文档详细讲解控件功能、安装方法、使用示例与编程技巧history文件记录了各版本新增特性与修复内容license与readme则分别提供合规使用指引和配置快速入门并额外包含最新版本下载说明。借助这套资料开发者能够系统掌握EhLib的架构设计、版本演进和实际用法减少探索成本高效集成到Delphi 12.3环境中。1. EhLib 11.1.015 在 Delphi 12.3 环境里的真实定位做 Win32 桌面报表的老项目最怕什么不是写不出 SQL而是客户临时要求“表头加两层、分组带小计、点列头就排序”。用标准 TDBGrid 硬拼这几个需求叠加起来代码能膨胀到没法维护。EhLib 11.1.015 的定位就是把这些高频交互变成控件属性我在 Delphi 12.3 里装上之后第一件事是把一个 3000 行的报表单元删到 1200 行。这个压缩包不是单纯一份控件源码里面带完整帮助文档、版本历史和俄英双语手册适合两类人一类是拿 Delphi 12.3 做企业 MIS 的另一类是维护老项目、被 DBGrid 交互折磨到想重构的。需要说明的是网上流传的“Delphi 12.3 绿色版下载”大多不包含商业控件EhLib 的 IDE 包必须自己安装编译本文就按这个前提展开。2. 安装前置读懂包内文件与 Delphi 12.3 的安装顺序2.1 包内文件到底哪些是安装必需的解压后看到的文件列表里最容易迷惑人的是Project1.bpr、Project2.cfg和delphixe.bmp。.bpr是 CBuilder 的工程文件.cfg是编译配置这两个文件对 Delphi 12.3 用户来说几乎无用可以直接忽略它们的存在只是说明资源包同时在为 C Builder 侧保留构建入口。真正有用的分组是文件 / 目录名作用安装阶段EhLibHelp.chm、EHLIB.CNT离线帮助与目录索引安装后查阅About EhLib.VCL 11.1 Eng/Rus.docx双语介绍、架构说明、快速上手路径安装前阅读history-eng.html、history-rus.html逐版本变更记录、缺陷修复对照升级评估时使用license.rus、license.txt许可证条款分俄文和英文安装前确认readme.rus、readme.txt安装配置指南与常见问题安装中对照最新版本下载.txt官方后续版本获取说明需要升级时参考有一个关键点容易被忽略EHLIB.CNT是帮助文档的目录文件在 Windows 10/11 上如果 CHM 打不开右键选择“解除锁定”即可不需要改注册表。我一般先把中文文档读一遍重点是确认它支持的 IDE 版本范围——11.1.015 明确为 Delphi 12.x 设计但这里有个坑如果你的 IDE 是社区版Delphi Community Edition而非商业版安装包仍然可以编译只是需要手动指定 BPL 输出目录。2.2 标准安装步骤与参数说明常见的安装流程是打开 Delphi 12.3依次执行Component - Install Packages - Add然后选择EhLib 11.1.015对应的.bpl文件。但刚解压完没有现成的 BPL必须先编译 RUN 和 DESIGN 两个包。下面是把命令行编译作为备选方案的做法适合在没有 IDE 图形界面的 CI 机器上预编译cd /d C:\EhLib\11.1.015\Delphi\12 msbuild /t:Rebuild /p:ConfigRelease /p:PlatformWin32 EhLib.dproj msbuild /t:Rebuild /p:ConfigRelease /p:PlatformWin32 EhLibDesign.dproj参数含义拆开说ConfigRelease指生成非调试版本运行时不需要携带 RTTI 调试符号PlatformWin32是因为大多数存量业务系统仍是 32 位若目标程序是 64 位两个包要分别切换平台重新编译。/t:Rebuild强制全量重建避免增量编译留下的过期 DCU 干扰 IDE 注册过程。编译结束后把生成的EhLib*.bpl放到 Delphi 的bin目录或者单独建一个D:\Libs\BPL目录并在 IDE 的Tools - Options - Environment Variables里添加路径。2.3 安装验证别装完就跑readme.txt虽然提供了 Quick Start但没有强调验证动作。安装完成后新建一个 VCL 工程在窗体上放一个TDBGridEh如果控件面板出现EhLib 11.1.015分组且拖拽无异常这只是第一步。真正的验证是编译一个用到TMemTableEh的 Demo 工程——因为 TDBGridEh 只是外壳排序和合计依赖TMemTableEh内部实现如果这个数据集控件没有正确注册设计期会报“类未注册”。我习惯用一个最小工程验证with TMemTableEh.Create(nil) do begin FieldDefs.Add(Name, ftString, 20, False); FieldDefs.Add(Score, ftInteger, 0, False); CreateDataSet; AppendRecord([ZhangSan, 88]); AppendRecord([LiSi, 95]); First; ShowMessage(FieldByName(Name).AsString); Free; end;逻辑很简单FieldDefs 声明两列CreateDataSet 时把元数据物化为数据集AppendRecord 写入两行最后读取第一行姓名。如果这段代码能编译并弹窗说明核心包已完整注册。若报E1048 Unknown identifier: TMemTableEh优先检查 DCU 输出目录是否加入了 Library 搜索路径而不是重新安装——这个错误九成是 IDE 找不到编译单元不是控件坏了。振动提示在第 2.1 节的基础上从history-eng.html里搜12.3能看到该版本对 IDE 版本适配的明确记录比在论坛问“支不支持”可靠得多。3. DBGridEh 核心配置多层表头、分组合计与列宽策略3.1 三层表头如何在设计期一次配好EhLib 在报表领域的口碑主要来自DBGridEh的标题分级能力。标准 TDBGrid 想实现“主表头下面再拆两个子表头”只能靠多行 DrawGrid 事件手工绘制而 DBGridEh 内置了TitleLines和Columns[].TitleLines结构。实际操作上我在设计器里把网格的TitleLines设为 2然后逐列在Columns编辑器里拖动列位置属于同一组的列会在第 1 层显示为合并单元格——这是自动合并的前提是OptionsEh里的dghAutoSortMarking不干扰标题绘制。放一张实际参数对照表方便直接抄作业目标效果属性路径推荐值备注表头显示两行TitleLines2第 1 行为分组名禁用列表格线OptionsEh.dghClearSelectionFalse保持选中状态可读性奇偶行底色区分OddRowColor/EvenRowColor例如clBtnFace/clWindow需同时启用UseOddRowColor列头点击排序SortLocalTrue依赖数据集支持本地排序行高自适应RowHeight.AutoFitTrue自动按字体和内容计算还有一种是 I 级标题跨列合并比如“2024 年销售数据”横跨 1~3 列。做法是Columns[0].TitleLines : 2; Columns[0].Title写分组名再把Columns[0].Title.ToolTips关掉否则鼠标悬停会弹黑框。列宽这一步最容易翻车直接用Columns[].Width写死像素值在高 DPI 屏幕上会错位。我一般是Width : 120作为基准然后配合OnGetColumnTitleParams调整最小宽度。注意dghAutoFitColWidths这个选项只对普通列有效对合并标题下的子列不起作用需要自己写循环按字符数估算。3.2 分组合计的三种实现路径DBGridEh的统计行来自FooterRowCount和FooterRows[0].Value。最常见的三种合计需求每组小计、全局总计、以及按页面分页统计。全局总计最简单在设计器里把FooterRowCount设为 1任意列选中FooterRows[0].FieldName然后设Value值为SUM。但“每组小计”不能靠这个得用DBGridEh的GroupPanel拖拽分组字段此时FooterRows[0].ValueType需要设为gvtSum。procedure TForm1.DBGridEh1GroupDataHint( Sender: TObject; Column: TColumnEh; GroupField: TField; var Value: Variant); begin if Column.FieldName Amount then Value : GroupField.DataSet. AggregateField(Amount).Value; end;这段代码解释一下GroupField是当前分组依据字段AggregateField(Amount)在TMemTableEh内部按组聚合。引用Value走的是 Varaint返回浮点数时注意壳类型否则Value : ...会出现 EConvertError。这里有个小坑如果数据集是TADOQueryAggregateField不可用需要在 SQL 里先按分组字段排序再配合DBGridEh的GroupFieldView属性把分组渲染交给前端——本质上仍是局部排序 前端捞每条记录做累计。分页统计是另一个场景。当网格数据量大、开了PageSize时FooterRows[].Value默认统计的是当前页不是整表。想统计全表需要把DBGridEh.DataSource.DataSet.AggregateField放到自己维护的合计字段上并显式设置FooterRows[].FieldName : TotalAll把总合计放到FooterRows[1]第二行再写页合计。值类型建议看history-eng.html里对TFooterValueType从 8.x 到 11.x 的变更描述——旧的gvtCount在 11.1.015 里被拆成了gvtCount与gvtCountDistinct前者统计行数后者统计去重数语义不小。3.3 列宽自适应与高 DPI 拖动容差高 DPI 下有个细粒度的体验问题手动拖列宽时鼠标在列边界位置偏移超过 4 个像素就拖不了。这是 EhLib 的dghColumnResize选项配合系统 DPI 缩放造成的容差偏差。我建议在FormCreate里做一次全局初始化DBGridEh1.OptionsEh : DBGridEh1.OptionsEh [dghColumnResize, dghExtendVertLines]; DBGridEh1.ColumnDefValues.EndEllipsis : True; DBGridEh1.ColumnDefValues.Title.ToolTips : False;dghExtendVertLines让竖线延伸到底部避免最后一行下边框缺失EndEllipsis让超长文本以省略号展示而不是撑宽列Title.ToolTips关闭后列头长文本不再弹出提示防止和分组列的拖拽提示冲突。如果你发现DBGridEh1.Columns[0].Width在设计器里怎么改都会被还原检查是否勾选了AutoFitColWidths这个属性在数据源变更时会重算列宽优先级别高于你手工设置的值。排序标记那块TitleSortMarker在 11.x 里能显示“升/降/组内”三种图标但对SortMarkerStyle的合法值EhLibHelp.chm里列出的是smDefault、smArrow、smArrowAndUpDown其中smArrowAndUpDown在中文系统下配合微软雅黑 9pt 会有 1 像素截断建议字体调到 10pt 或改用smArrow。4. TMemTableEh 实战内存数据集排序过滤与 Excel 导出4.1 为什么报表场景优先选 TMemTableEh业务数据量大时很多人在TFDQuery上直接开Indexes排序但报表多级过滤会反复触发 SQL压力全在后端。EhLib 的TMemTableEh是一个客户端内存数据集排序、过滤、分组都不再回库。它的定位接近轻量级 ClientDataset但内部针对 DBGridEh 做了优化Aggregates增量更新、Filter字符串语法直接复用 DBGridEh 的过滤表达式、DataSet属性可以直接包一层 TDataSet 做整表载入。MemTableEh1.LoadFromDataSet(ADOQuery1, lmCopy, lmCopy, True);参数说明第一个lmCopy是结构复制模式指复制字段元数据第二个lmCopy是数据复制模式第三个布尔值True表示载入后游标停留在首行。注意LoadFromDataSet默认关闭索引所以载入后需要手动AddIndex。排序通常用SortOrder替代旧版的IndexNameMemTableEh1.SortOrder : Score DESC; Name ASC;SortOrder与IndexName的差别在于前者是内存快速排序临时生效不维护永久索引文件后者适合频繁随机查询。报表临时排序用SortOrder不要建索引——建索引会带来维护开销在 10 万行内存表上每次插入都会变慢。4.2 过滤表达式与编码坑位TMemTableEh的过滤语法兼容 DBGridEh 的筛选器比如Score 90 and Name like 张%。但有个老生常谈的麻烦SQLite 里的数据源常常出现乱码这不是 EhLib 的问题而是源数据集把 UTF-8 字节流直接装进 AnsiString 字段。方向盘在数据集层解决而不是在控件层。稳妥做法是载入前把字段类型显式指认为ftWideStringwith MemTableEh1.FieldDefs.AddFieldDef do begin DataType : ftWideString; Size : 200; Name : NameW; end;这样赋值时使用宽字符过滤条件里的中文字符串不再发生字节错位。字段长度Size我这里写 200是按“常见姓名备注”估的如果标题列更多按最大字节数除以 2 再留余量。ftWideString在 DBGridEh 显示时如果用默认字体可能拉高行高所以数据量大时配合RowHeight.AutoFit : False锁定行高渲染性能更稳。4.3 导出 Excel从网格到表格文件EhLib 自带导出器DBGridEh上挂一个TDBGridEhExportAsText或TDBGridEhExportAsUnicodeText就能导出但格式控制最细的还是ExportToExcel。这个接口在 11.x 里支持xlExcel8兼容旧 Excel和xlExcelXML两种格式XML 格式对中文兼容更好uses EhLibMTE, DBGridEhImpExp; DBGridEh1.ExportToExcel(C:\Temp\Report.xml, Sheet1, xlExcelXML, True, False);xlExcelXML写出来是 XML 电子表格Excel 可以原生打开不会弹兼容警告。参数True表示导出列头False表示不导出标题重复的合计行。这里有个坑导出前必须保证DBGridEh1.FooterRowCount 1否则合计行会被当成数据导出合计值错位。如果客户只要固定列临时隐藏多余列再导出——用Column.Visible : False然后在finally里恢复。导出数据超过 5 万行时Excel XML 文件体积会膨胀到几十 MB此时可以考虑导出 CSV 加 UTF-8 BOMExcel 双击也能直接打开但公式和样式全部丢失。我一般遵循这样的原则5 万行以内用 XML 保留格式超过 5 万行导出 CSV 并在文件名标注数据范围。控制行数还有一种做法MemTableEh1.RecordCount超过阈值时弹出对话框让用户选择按月份拆分为多个文件下面是一个简化版本。if MemTableEh1.RecordCount 50000 then begin dlgSave1.Filter : CSV|*.csv; if dlgSave1.Execute then DBGridEh1.SaveToCSV(dlgSave1.FileName, True, True); end;SaveToCSV的三个参数分别是逗号分隔符、引号转义、是否带列名。默认的逗号分隔在 Excel 中文系统里表现良好但如果你导出后发给欧美同事注意本地系统区域设置里的列表分隔符——部分欧系语言区域是分号需要手动切换文件类型。5. 历史记录读法从 history-eng.html 判断升级风险5.1 三个文件配合使用的方法压缩包里的历史记录文件不是摆设在决定是否引入这个版本到存量项目时它们是唯二的事实依据之一。方法是先把history-eng.html打开定位到 11.1 系列然后和readme.txt对照安装基线。真正值得警惕的是破坏性变更比如某个控件的属性从“默认开启”变成“默认关闭”这类信息通常藏在“Improvements”段落里而不是“Bug fixes”里因为官方觉得改进不破坏兼容但对老项目来说可能就是坑。一个实用的判断指标在历史记录里搜索Added和Changed的次数再加Fixed的次数三者的比例关系能反映版本稳定性。如果某个子版本Fixed数量远大于Added说明它在修上一个大版本引入的回归优先选择这一类。比如 11.1.015 的变更更密集地集中在TDBGridEh的排序标记与TMemTableEh的过滤后端说明 11.1 系列的核心逻辑处在一个稳定收敛期。5.2 许可证文件与团队合规检查license.txt和license.rus拿来直接读不需要逐行翻译重点看三点是否允许修改源码、是否允许分发 BPL、是否允许在商业闭源软件中收费集成。如果团队有人把编译出的EhLib*.bpl直接随安装包拷给客户就要确认“再分发”条款。这个包的许可文本英文版对“应用本身可以闭源”没有阻挠但对象链接库文件本身不允许拆出去单独售卖。许可证关注点英文版常见表述团队落地检查清单修改源码后是否保留版权声明Yes在源码头部保留原注释是否可随商业软件分发通常允许不要分发.dpk源码包是否禁止反向工程明确禁止不进行任何形式的调试监听是否提供升级续费说明见“最新版本下载.txt”评估当前版本是否满足项目期这一章结合实际项目经验比如目标程序需要部署到客户内网环境license.txt还有一条容易踩的约束部分版本禁止在非 VCL 框架比如 FMX中使用。开发人员如果顺手把DBGridEh拖到 FMX 窗体上编译能过但运行报缺少 VCL 主题授权那就是这个限制的表现。所以不要在uses里混用 VCL 和 FMX 单元。5.3 升级评估的具体手势给老项目升级前先拿history-eng.html与当前版本的差异清单出一份风险表。实操上可以这么做打开当前项目的.dproj记下所有引用的 EhLib 相关包名再对照最新版本下载.txt里指明的官方发布渠道判断升级路径是否跳跃。如果项目当前用的是 8.x直接跳到 11.1.015建议先做一次 “空白工程 核心报表页” 的原型验证时间预算 2 天——因为 8.x 到 11.x 之间有属性名重命名例如ShowFooter改为FooterRowCount编译期错误不难修运行期表现差异才是重点。具体验证动作把DBGridEh1.FooterRowCount : 1写到 FormCreate 里然后用TButton触发一次分组排序和导出再执行Application.MessageBox看是否有异常。这样能一次性覆盖三个核心路径。6. 运行期行为校准几个影响交付质量的技巧这一章写给已经装好控件、正在收尾的人。EhLib 的功能开关多到可以当教学案例但交付时真正决定“客户觉得好不好用”的往往是几个边缘属性。第一个技巧是列头排序图标和数据刷新的一致性。DBGridEh的排序标记在SortLocal : True时会显示但当你调用了MemTableEh1.Refresh重新载入数据后DBGridEh1.SortMarkedColumns可能残留旧状态。解决办法是在刷新后显式清掉排序描述DBGridEh1.RestoreColumnsLayout( TDBGridEh.InitLayout( DBGridEh1, nil, nil, nil, nil), true, false);RestoreColumnsLayout会重置列状态InitLayout这个第二参到第五参分别对应筛选、排序、合计、分组全传nil表示按默认值清空。这是重置不是重载数据不受影响。第二个技巧是报表合计行的千分位显示。FooterRows[].Value里的数字在 DBGridEh 默认按字段类型显示不带千分位。想统一格式处理OnGetFooterParams事件procedure TForm1.DBGridEh1GetFooterParams( Sender: TObject; DataIndex: Integer; var Value: Variant); begin if DataIndex 0 then Value : FormatFloat(#,##0.00, StrToFloatDef(VarToStr(Value), 0)); end;DataIndex对应列索引Value在进入事件前已经是合计运算结果这里做一次格式转换。StrToFloatDef兜底防止空值触发异常。这个事件每行合计都会触发数据量大时耗时可忽略但如果Value本身是字符串型合计比如计数FormatFloat会抛异常所以只在DataIndex 0这个确定列做格式化别全局套用。第三个技巧是关于DBGridEh的快速滚动。数据量到十万行时把DBGridEh1.RowHeight.AutoFit设为 False同时启用dghAutoFitColWidths的替代方案——按比例计算列宽而不是逐列精测。开启Timer延迟重绘也能减少滚动时闪烁。具体手式DBGridEh1.OptionsEh : DBGridEh1.OptionsEh - [dghAutoFitColWidths]; DBGridEh1.OptionsDBGrid : DBGridEh1.OptionsDBGrid [dghColumnResize];这里把dghAutoFitColWidths从选项里移除换取滚动帧率稳定保留列宽手动调整权限这份取舍适合交互优先的管理端报表页面。如果你在写 Delphi 12.3 下的新项目还可以研究一下EhLibHelp.chm里TCustomDBGridEh的ReadOnly属性在 11.1.015 中的行为变化——它从单列级推进到了单元格级这对只读报表的数据防误改是一个更有力的保证。本文还有配套的精品资源点击获取
返回列表