TDBGridEh安装与实战:基于Ehlib 5.2.84在Delphi中的配置与使用
简介这是为 Delphi 与 CBuilder 开发者准备的数据库网格增强组件 Ehlib 5.2.84 完整发布包内含 dbgrideh 核心组件及相关类库官方支持 Delphi 5 至 RAD Studio 2010 等众多版本可有效提升表格展示、打印预览、数据导出等常见功能的灵活度和开发效率。资源包共 448 个文件RAR 压缩后约 3MB主要由 94 个 pas 源码文件、74 个 dfm 窗体定义、42 个 dpk 包文件组成同时带有 bdsproj/dpr 工程文件、bmp/res 图标资源和少量 CBuilder 示例便于在目标 IDE 中安装、编译与按需裁剪。目前已有 261 人学习下载。借助源码和设计期/运行期包开发者既可将组件快速接入不同版本的 Delphi 环境也能深入研读 dbgrideh 的类层次、事件驱动和绘制机制从而根据业务需求定制表格列、排序、合计、导出等行为显著节省组件选型和二次开发时间。 用Delphi写桌面数据库应用的朋友十有八九绕不开Ehlib这套组件库而TDBGridEh更是其中出镜率最高的“当红炸子鸡”。这次拿到的是Ehlib v5.2.84一个在当年非常经典、至今仍被不少老项目锁定的版本号。我花了两天时间在自己的Delphi 2007环境里把它完整装起来顺手验证了一批高频功能包括多选、合计行、排序、导出Excel中间也踩了几个值得记录的坑。这篇就当作一份实操笔记给正在用这个版本、或者打算在老工程里集成TDBGridEh的同学提供参考。如果你正准备给项目添加一个“能打”的表格控件或者你在维护一套用了很多年的Delphi老系统搞不清Ehlib到底该怎么装、用到哪一步为止这篇内容应该能帮你省下不少折腾时间。1. Ehlib是什么以及为什么老Delphi开发者离不开它1.1 从DBGrid到TDBGridEh一件能打的网格组件Delphi自带的标准TDBGrid说起来很基础数据源一连字段一拖表格就能跑。可真到了做业务系统的阶段你会发现它到处“差口气”不支持复选框列多选要自己写合计行要自己算列宽自适应要自己处理导出到Excel更是没有原生的好办法。TDBGridEh就是来解决这些“差口气”的。它是Ehlib组件库里的核心网格控件在保留TDBGrid全部能力的基础上扩展了大量面向实际业务场景的功能。比如内置的统计行FooterRow可以直接对数值字段求和、计数、平均不需要你写任何查询语句比如下拉列表、日期控件可以直接嵌进单元格编辑体验比肉眼可见的原生TDBGrid强得多。我个人的感受是Ehlib不是那种“用了会显得很酷”的库而是“用了之后写业务代码会少掉一大批工作”的库。对于MIS、ERP、进销存这类字段多、表格多、报表需求复杂的项目TDBGridEh几乎是标配。1.2 v5.2.84一个“不上不下”却极度稳定的版本Ehlib的版本线拉得比较长早年从2.x一路走到现在的11.x。这个v5.2.84大概对应Delphi 2005到2007那一时期算是一个偏老但非常稳的版本。很多老项目在升级到高版本Delphi之后依然沿用Ehlib 5.x因为业务代码里对TDBGridEh的封装已经太多贸然升级组件库反而容易出现兼容性问题。v5.2.84这个版本号的记忆点有几个它支持DBGridEh和DBGridEhExportAsText、ExportAsRTF、ExportAsHTML这些导出单元支持TPrintDBGridEh打印预览支持TMemTableEh内存表同时也带了一套比较完整的字段编辑器。从功能完成度来看日常开发里能用到的网格需求基本都能覆盖。这套东西在社区里的口碑以“稳”为主没有太多花哨功能但凡是它声明支持的能力用起来基本不会给你“掉链子”。所以这个版本到今天还在被大量项目沿用一点也不意外。2. TDBGridEh的核心能力拆解2.1 显示层从多选、复选列到页脚汇总TDBGridEh让我最先感受到“值了”的功能是它的选择列和合计行。标准DBGrid你要做一个整行多选得自己管理选中集合代码量不小。TDBGridEh只需要打开几个选项// 启用多选 DBGridEh1.Options : DBGridEh1.Options [dgMultiSelect]; // 遍历选中行 var i: Integer; begin for i : 0 to DBGridEh1.SelectedRows.Count - 1 do begin DBGridEh1.DataSource.DataSet.Bookmark : DBGridEh1.SelectedRows[i]; // 处理当前选中行 end; end;合计行更省心。在设计期把DBGridEh的FooterRowCount设为1然后在字段的Footer字段里配置SumList运行起来后数值列底部会自动出现合计值不需要写任何汇总SQL。这个功能在做单据列表、库存台账的时候特别好用。显示层的另一个高频需求是列宽自适应。原生DBGrid要做到“最后一列把剩余空间填满”或者“列宽跟随内容伸缩”处理起来比较啰嗦TDBGridEh提供了DBGridEh1.ColumnDefValues.AutoFitColWidth之类的机制也可以在设计期对每一列做精细化配置标题、对齐、文字颜色、行高列宽都可以直接可视化调整。2.2 编辑层单元格下拉、日期选择与Inplace编辑业务系统的表格交互很大一部分是“编辑”。TDBGridEh对单元格内编辑做得很完善你可以直接在列定义里挂一个TDBComboBoxEh或者TDBDateTimeEditEh这样用户点击单元格时就会出现下拉列表或日期控件。这个设计带来的直接好处是你的录入表单可以做得更简单。以前需要弹出一个编辑对话框实现的“选择客户”“选择商品”现在直接在网格里点一下就能搞定。编辑层还有一个容易被忽略但实际很有用的地方TDBGridEh支持单元格级别的ReadOnly控制。你可以根据业务逻辑在GetCellParams里动态决定某个单元格是否可编辑procedure TForm1.DBGridEh1GetCellParams(Sender: TObject; Column: TColumnEh; AFont: TFont; var Background: TColor; State: TGridDrawState); begin if Column.FieldName Amount then AFont.Color : clBlue; end;这种灵活度是标准DBGrid给不了的。2.3 数据衔接与ClientDataSet协作的常见套路TDBGridEh和TClientDataSet是一对非常常见的组合。ClientDataSet承担内存数据管理、过滤、排序、增量更新TDBGridEh负责可视化和编辑交互两者配合几乎没有磨合成本。这里有个经验当你用ClientDataSet做数据源时TDBGridEh的排序功能可以直接利用CDS的IndexName或者内部排序机制来跑而不需要每次都对数据库发SQL。客户端网格排序、服务端数据库查询各司其职响应速度会明显更快。如果你的项目里用的是TClientDataSet还经常和TDBGridEh配合做数据展示还有一个细节值得关注CloneCursor。这个函数的作用是创建一个共享数据但独立的游标让两个数据集指针彼此独立。常见使用场景是在同一个数据源上开两个网格视图一个做汇总展示、一个做明细操作互不干扰。在Ehlib网格里配合多选或跳转时这个特性相当实用也解开了不少人对“为什么同一个CDS可以同时在两个网格里用”的疑惑。2.4 场景联想管控类工具里的网格界面搜索热词里有一个“delphi 禁用u盘”这类工具在实现时通常会有一个设备列表界面把当前接入的USB设备列出来让管理员选择禁用或启用。这种需求用TDBGridEh来做非常顺手复选列勾选设备、状态列显示“已禁用/正常”、FooterRow统计当前设备数量一套下来界面既清晰又专业。Ehlib本身虽然和U盘管控没有直接关系但说它是这类企业管控工具里最常见的“门面组件”一点也不夸张。3. 实操安装与IDE配置3.1 拿到安装包后先做这些从压缩包解压后先别急着双击任何DPK文件。先看目录结构Ehlib的安装包一般会区分Lib、Design、Docs、Source几个部分。v5.2.84的源码目录里运行时包的源码和设计期包的源码是明确分开的这决定了后续编译顺序。我习惯先把源码目录整个拷到固定位置比如D:\Components\EhLib5.2.84不要放在桌面或临时目录。因为Delphi的Library路径是持久化的以后每次打开IDE都会去这个路径找单元如果放在临时目录哪天清理系统就把组件弄丢了。然后检查一下有没有对应的Readme或Install说明。Ehlib的安装脚本在后续版本里做得比较智能但在5.x上我更推荐手工方式因为你能清楚看到每一步在干什么出问题也好定位。3.2 编译顺序与路径配置在Delphi 2007下手工安装Ehlib 5.2.84的步骤如下打开IDE进入Tools Options Environment Options Delphi Options Library - Win32把D:\Components\EhLib5.2.84\Lib和D:\Components\EhLib5.2.84\Design加入Library Path。先编译运行时包。打开Ehlib5.dpk包名以实际文件为准部分版本可能叫Ehlib5DB.dpk在Project Manager里右键选择Compile。打开设计时包通常叫Ehlib5Design.dpk或类似名称右键选择Install。这一步会把TDBGridEh等控件注册到IDE组件面板上。如果项目需要打印功能把TPrintDBGridEh所在的设计时包也一并编译安装。安装完成后打开组件面板在EhLib页签下能看到一排以“Eh”结尾的组件这就说明装成功了。这里特别提醒一点编译顺序一定要先运行时包、再设计期包。设计期包依赖运行时包导出单元如果先装了设计期包IDE会报“Cannot load package”的错容易误导你去查环境配置实际上是顺序不对。3.3 版本适配经验Ehlib 5.2.84在设计时是针对旧版Delphi编译的放在新版本IDE里直接打开DPK大概率会失败因为编译器版本变了。如果你正在用Delphi 10.4或更新的版本不要强行安装Ehlib 5.x建议选用对应新版IDE的Ehlib 6.x、7.x甚至更高版本。这里有一个版本对照思路不是官方表但按这个思路排查会快很多开发IDE版本建议Ehlib版本说明Delphi 7Ehlib 4.x / 5.x老项目主流组合稳定Delphi 2007Ehlib 5.x与v5.2.84搭配很顺Delphi XE ~ XE8Ehlib 6.x过渡期常用Delphi 10.xEhlib 9.x / 10.x涉及Unicode、高DPI适配Delphi 11/12Ehlib 11.x当前最新版支持较全实际上你在网上搜“delphi 10.4 sm4.pas”“delphi 13.0 florence”这些关键词就能感受到社区在持续把老组件往新IDE上迁移的热情。但迁移归迁移生产环境里“稳定压倒一切”才是首要原则。如果一个老项目在Delphi 2007 Ehlib 5.2.84下跑了好几年没出问题真不建议为了上新版本而把整条链路换掉。4. 高频坑点与排查技巧4.1 编译期报错怎么破我在安装过程中遇到过一个很典型的错误F2046: Unit EhLib5DB not found。新手碰到这个第一反应是去网上找这个DCU文件实际上问题根源是Library Path没配好或者运行时包还没编译成功。Ehlib的单元之间依赖关系很紧密源码文件都在只要路径正确、依赖包已编译这个错就会消失。另一个很常见的坑是设计期包安装时提示“Resource dcu not found”或者“Cannot load package ... .bpl”十有八九是运行包还没有Install到IDE里。Ehlib 5.x的运行时包虽然以dpk形式存在但IDE需要在设计期包注册时能解析到运行期包的BCP文件所以两个包必须放在IDE能搜到的路径里。4.2 运行期表现异常的定位思路安装成功之后我遇到过几个运行期的怪问题这里挑两个典型的说一下。第一个是“合计行不刷新”。SumList虽然配置了但数据源里的记录增删改之后合计值一直不变。排查后发现是因为代码里动态修改了数据集数据但没有让SumList重新计算。解决办法是在数据更新后调用DBGridEh1.SumList.Active : False; DBGridEh1.SumList.Active : True;来强制刷新一次。第二个是“列宽保存与恢复”。网格列排版是用户调整过的程序重启后回到默认状态客户不满意。TDBGridEh提供了SaveGridLayout和RestoreGridLayout把列宽、排序状态保存到文件或注册表。这段逻辑虽然不难但如果你不在程序退出时保存、启动时恢复就体验不到这个功能的价值。还有一点值得注意用TDBGridEh做行排序时如果开了dgMultiSelect和SortMarkedColumns同时工作容易搞混用户预期。我的建议是多选模式下慎用点击标题栏自动排序否则刚勾好的几行被排序一打乱用户很容易懵。4.3 性能优化与导出Excel的细节数据量大之后网格性能会明显下降这是任何网格控件都不可避免的。TDBGridEh在5.x版本里有一些优化项可以尝试用DBGridEh1.Options : DBGridEh1.Options - [dgEditing]关闭编辑功能纯展示模式能省不少刷新开销。大数据量下关闭DBGridEh1.OptionsEh里的某些实时绘制选项例如dghAutoFitColWidths滚动起来会更跟手。如果行数极其夸张建议在数据库层分页或者用DataSet的PacketRecords机制限制每次取多少条而不是一次性把几十万行塞进网格。导出Excel是TDBGridEh被问得最多的话题之一。v5.2.84自带的导出单元主要是DBGridEhExportAsText、DBGridEhExportAsRTF、DBGridEhExportAsHTML在时代背景下已经够用。如果你需要导出为真正的Excel文件常用的方案是借助Excel OLE对象循环写入或者通过文本CSV再交给Excel打开。Ehlib后来的版本里有DBGridEhExportAsXLS但5.x这个版本我印象里还没有需要用外部库配合。我给一个比较稳的通用做法uses DBGridEhExportAsText; // 保存为CSV格式文件Excel可直接打开 DBGridEh1.SaveToXLS(export.csv);具体到不同版本的API名称可能有些差异但思路是注意编码和分隔符。中文环境下建议用UTF-8 with BOM避免Excel打开CSV时中文乱码。这里提一句如果你正好在找“delphi 读取excel”的方案思路是反过来的不要试图让TDBGridEh去读Excel而是用OLE或第三方库把Excel数据导入到DataSet再由TDBGridEh展示各层各司其职才不容易出问题。5. 版本升级与维护策略5.1 什么时候该升什么时候不该升Ehlib 5.2.84这种老版本最大的价值是稳定性和兼容性。一个在企业里跑了好几年的系统最怕的是“为了升级而升级”。如果现有功能完全满足需求新增需求也可以通过小改代码实现我不建议动组件库。但也有非升不可的场景换新Delphi版本、需要支持64位编译、需要对接新数据库驱动、需要在高DPI屏幕上跑界面。这些情况下老组件大概率会成为瓶颈。比如你用Delphi 10.4做Win64发布Ehlib 5.x的DCU是绝对不可能直接用的必须找配套版本。我的做法是升级之前先在虚拟机里搭一套干净的Delphi环境把项目完整编译一遍记录所有报错点再决定升级路径。千万别在原项目里直接换组件包。5.2 维护老项目时的一些习惯对于还在维护Ehlib 5.x老项目的朋友我建议养成几个习惯源码包单独备份不要只留DCUIDE环境里记录一份Library Path快照组件的版本号写进项目的Readme。这样即使换了电脑、换了人接手环境重建也能在半小时内完成而不是靠记忆。另外如果团队里还在用老版本Delphi做开发最好在代码里限制TDBGridEh的使用范围封装成统一的公共函数或基类不要每个窗口各写一套网格配置。这样将来不管升Ehlib还是换IDE改动都可以收敛在一个文件里风险会小很多。最后再分享一点个人体会像Ehlib这种历经多年的组件库它的价值不在于某个版本有多新而在于你在真实业务里对它有多熟悉。TDBGridEh的很多细节功能比如GetCellParams、SumList、SelectedRows、布局保存恢复都是老开发者一点一点用出来的。与其纠结要不要追最新版本不如先把手头这个版本的特性吃透。我在项目里用v5.2.84做一套进销存的单据列表从安装到功能验证不到半天就全部跑通这就是老组件该有的效率。本文还有配套的精品资源点击获取