简介:dbgrideh for D7 是专为 Delphi 7 开发的一款增强型数据库网格组件,面向需要制作进销存、财务、会员管理等数据密集型应用的程序员,解决标准 TDBGrid 在显示和编辑能力上的不足。压缩包共有 129 个文件,大小仅 1.16MB,包含 40 个 Pascal 源文件、34 个编译好的 DCU 单元、12 个窗体定义文件,以及 DPK、DPR、CFG 等工程与配置文件,能够直接安装到 Delphi 7 中,也可作为源码研习。该组件提供了更丰富的列类型与编辑器,支持实时数据验证、分页显示、多字段排序、行与列的冻结和动态调整、打印及导出 Excel/PDF,并具备高级筛选和搜索功能。同时,借助事件机制可以灵活扩展业务逻辑,无论是简单数据表还是复杂父子视图,均能获得流畅操作体验。资源包中的示例与文档可帮助开发者快速完成集成。目前已有 216 人学习浏览,适合希望提升 Delphi 7 数据库应用交互体验和开发效率的中高级开发者。
1. 都 2025 年了,为什么还要折腾 DbGridEh for D7
先说结论:一套跑得好好的老业务系统,没必要因为“组件太老”就推倒重写。DbGridEh 是 Delphi 生态里最经典的增强网格组件库,官方名字叫 Ehlib,它把原本功能单薄的 DBGrid 扩展成了带排序、合计、合并单元格、下拉筛选、树形展示、导入导出等一系列强功能的表格控件。很多中小型企业的进销存、财务、ERP 系统至今还在 Delphi 7 环境下维护,而其中的表格界面十有八九就是 DbGridEh 撑起来的。
本文要聊的就是:怎么在 Delphi 7 里把 DbGridEh 装稳、配好、用起来,并解决安装和运行过程中那些最容易让人卡壳的问题。适合的对象很明确——还在维护老项目的 Delphi 7 工程师、需要在老代码基础上加功能又要保持界面风格一致的二次开发者、以及刚接手这类遗留系统、对着 IDE 一脸茫然的新人。
有一点要先说明白,Delphi 7 是纯 AnsiString 时代的产品,能装上去的 DbGridEh 版本和现在新版 Delphi 能用的完全不是一回事。市面上流传的各种压缩包里,文件名里写着 for D7 的,基本都是 5.x 或者更老的 4.x 版本,它们和后续的 Unicode 版本在接口定义上存在大量差异,下手之前必须先搞清楚自己的开发环境基础。
2. 版本选型是第一步,别看着“能装”就顺手双击
2.1 先识别你手里的 Ehlib 版本
DbGridEh 的安装包解压之后,通常会看到类似Delphi7、D7、Ehlib 5.2这样的目录名。务必确认一点:这个包是不是针对 Delphi 7 单独编译过的。为什么如此强调?因为同一个 Ehlib 版本在不同 Delphi 版本下的包文件名和编译指令可能完全不同。
判断方法很简单,打开包文件.dpk(Delphi Package 文件),看它的Requires部分引用的rtl和vcl版本。如果里面出现System.UITypes、System.Classes这类带命名空间的引用,那基本可以断定它是给 Delphi 2009 以上版本准备的,强行在 D7 里打开只会报一堆Unit not found。真正 for D7 的包,引用关系非常简单,直接写Classes,SysUtils,DB,DBTables。
2.2 为什么新手总在“组件面板找不到控件”上翻车
即使包编译成功了,也经常出现工具面板里找不到 DbGridEh、DBGridEh、DBComboBoxEh 等控件的情况。这时候要检查两件事。
第一件事,你在安装时是不是选错了包类型。Delphi 7 里.dpk分为 Runtime Package 和 Designtime Package 两种,组件的安装必须选择 Designtime Package 即设计期包,在 Package 编辑器中通过Install按钮操作,编译通过之后 IDE 才会把控件注册到组件面板下。如果你只是用Compile命令编译通过,组件根本不会出现在面板上。
第二件事,注册的控件类有没有被 IDE 缓存屏蔽。某些来自网络共享的压缩包自带*.bpl文件,这些文件可能被安全软件清理或拦截,导致 IDE 启动时没有加载成功。在Component > Install Packages里能看到当前加载的包列表,没加载到说明.bpl文件缺失,需要手动把编译生成的.bpl复制到系统System32目录,或者把包文件路径加入全局Library搜索路径。
2.3 老项目改造的版本兼容策略
如果你只是维护老项目,最稳妥的思路是:沿用项目原本已经编译通过的 Ehlib 版本,不要为了所谓“新功能”随便升级。我在实战中就踩过一个坑,接手某个仓库管理系统时,原来用的是 Ehlib 4.1.2,同事“热心”把它升级到 5.2,结果所有DBGridEhColumns的Title.TitleButton属性全部丢失,导致列表排序功能消失,最后花了一整天逐行比对 DFM 文件。老系统能稳定运行就是最大的福报,没有硬性需求不要动基础组件的版本。
3. 安装 DbGridEh for D7 的前期环境准备
3.1 准备一份干净可用的 Delphi 7 环境
安装组件之前,建议先把 Delphi 7 的环境变量和路径理顺。打开Tools > Environment Options > Library,确认:
Library Path里不要包含多余的非必要目录,避免编译器搜索到错误的同名单元。Browsing Path设置为空即可,否则 IDE 会索引过多目录导致启动变慢。- 关闭
Use MSBuild externally这类高版本功能选项,D7 里对应的选项位置不同,但原则是让环境保持“老派”风格。
很多开发者喜欢在一台机器上同时安装多个 Delphi 版本,这本身没问题,但 Ehlib 这类老组件的搜索路径容易串。建议在环境变量的Path中针对不同版本设置独立的 BPL 输出目录,例如:
- D7 使用
C:\Delphi7\Projects\Bpl - D2007 使用
C\Delphi2007\Projects\Bpl
这样在最终发布时,不同的.bpl文件不会互相覆盖。
3.2 下载包的目录结构检查
正规的 Ehlib 压缩包一般包含:
| 目录/文件 | 说明 |
|---|---|
DELPHI7或D7目录 | 包含 D7 可用的.dpk包工程文件 |
SOURCE目录 | 包含全部单元源码,调试时很有用 |
DOC目录 | 帮助文档、版本说明、更新历史 |
BIN目录 | 预编译的.dcu、.bpl文件 |
DEMOS目录 | 大量示例工程 |
拿到包之后,先把所有文件释放到一个不带空格的固定路径,例如D:\Components\Ehlib。Delphi 7 编译器对带空格的路径支持得不好,容易在编译时弹出F1027 Unit not found这类错误。路径确定后,要把SOURCE目录加入Library Path,这样才能在编写代码时使用源码级调试,出错时可以直接跳进组件内部定位。
3.3 检查系统注册表和 IDE 状态
如果这台电脑之前装过其他版本的 Ehlib,建议先卸载干净,否则注册表里残留的TDBGridEh类信息可能导致新版本安装失败。谨慎起见,在HKEY_CURRENT_USER\Software\Borland\Delphi\7.0\Known Packages下找到包含Ehlib或EhLib的键值,手动删除对应的.bpl注册项。这一步不是必须,但能有效防止“安装后组件面板出现两套相同图标”的灵异事件。
4. 完整安装 DbGridEh for D7 的实操过程
4.1 打开包工程并编译
进入D:\Components\Ehlib\DELPHI7目录,找到类似EhLib70.dpk或者dclEhLib70.dpk的工程文件。这里的命名规则通常是:
- 运行时包:
EhLib70.dpk - 设计期包:
dclEhLib70.dpk
在 Delphi 7 中,通过File > Open打开dclEhLib70.dpk。为什么打开的是设计期包?因为设计期包会包含Register过程,组件才能出现在面板中;运行时包只是提供底层实现。
打开后,Package 编辑器会出现一个项目树。右键选择Compile,先编译一次。如果编译过程中报Unit xxx not found,请回到Tools > Environment Options > Library > Library Path,把SOURCE目录加进去,再重新编译。
编译成功后再点击Install按钮。此时 IDE 会提示组件注册成功,并在组件面板中新增一个单独的EhLib页。
4.2 配置 BPL 的输出路径
运行时包编译生成的.bpl文件默认输出到 Delphi 的Projects\Bpl目录,这是系统设定的标准位置。建议不要改动它,因为在发布程序时,如果客户端缺少这个.bpl,程序启动就会报“无法找到动态链接库”。唯一的办法是让这个.bpl的绝对路径保持在稳定可控位置,而后在部署时将这些.bpl一并复制到 exe 同目录下。
我在实际项目中,会把所有第三方组件的.bpl复制到统一的发布目录,例如D:\Release\Runtime\,再通过Tools > Environment Options > Library添加路径指向它。这样一来,开发环境和发布环境使用的.bpl保持一致,杜绝“开发时能跑,打包后闪退”的尴尬。
4.3 手动验证安装成果
安装完组件后,在新建的 Application 工程中拖入一个DBGridEh,如果能在属性面板中看到大量以Eh开头的新增属性,比如ImeMode、ImeName、SumList、FooterRowCount等,说明安装基本成功。
再测试一下DBGridEh能否在设计期正常连接DataSource。很多人这里会遇到一个隐藏问题:如果不小心把DBGridEh从运行时包和设计期包分别编译了两遍,导致DFM文件保存的类名完全相同但资源标识不同,打开窗体时会莫名报错。解决方法是保持源码版本一致,且只安装一次设计期包,运行时包只参与编译不重复安装。
5. 核心功能实操:排序、汇总和合并单元格
5.1 标题按钮排序
DbGridEh 最受欢迎的功能之一,就是点击列标题直接排序。默认情况下Title.TitleButton属性为False,必须手动打开。
在窗体设计期选中DBGridEh,在对象查看器找到Columns属性,点击省略号进入列编辑器。逐个选中需要排序的列,把Title.TitleButton设为True,同时把Title.SortMarker设为smUpEh或smDownEh,这样表头会显示三角箭头,用户点击时自动切换升序降序。
但这只是界面行为,底层排序逻辑必须自己写。标准的做法是在TitleBtnClick事件中判断点击的是哪一列,再动态设置TDataSet的索引字段。如果你用的是TClientDataSet,直接CDS.IndexFieldNames := FieldName就能完成排序;如果用BDE的TQuery,则需要重新拼接ORDER BY并执行Close/Open。这里有个技巧,DbGridEh 提供了一个现成的SortMarkedColumns方法,可以自动标记排序列,但真正执行排序还是要回到数据集层面。
5.2 底部汇总行 Footer
汇总行是财务类系统的刚需。在DBGridEh上右键选择Columns Editor,在列属性中找到Footer分支,把ValueType设为gvtSum,FieldName自动指向当前列的字段,运行时表格底部就会出现合计值。
ValueType可选值非常多:
| ValueType 值 | 含义 |
|---|---|
gvtSum | 求和 |
gvtCount | 统计记录数 |
gvtAvg | 平均值 |
gvtMax | 最大值 |
gvtMin | 最小值 |
gvtStaticText | 静态文本 |
实操中要注意,汇总值的计算默认由 DbGridEh 的SumList完成。如果数据集记录很多且频繁滚动,建议在DBGridEh的DataSource事件中启用SumList.Active := True,否则大数据量下滚动时会有些卡顿。另外汇总行默认显示在表格最下方,如果用户希望固定在底部不随滚动消失,可以把Options里的dgAlwaysShowFooter设为True。
5.3 合并单元格与多表头
做报表时经常需要把“数量”和“单位”两个字段合并到同一列下,或者把“上年”和“本年”合并成一个大表头。DbGridEh 的多表头功能可以做到这一点,前提是必须把DBGridEh的Options中dgMultiTitle设为True。
具体做法是编辑列对象的Title.Caption属性,在标题文字中插入|符号表示纵向拆分为两个层级。比如第一列标题写产品信息|产品名称,第二列写产品信息|产品编号,运行时上方都会显示一个居中的大表头“产品信息”,下面拆成两列。这种定义方式简单粗暴但极其高效,不需要写任何代码。
合并单元格则针对数据区域,把相同值的相邻单元格合并为一块。在列属性中把MergeColumns设为True,前提列的FieldName是连续的相同值。DbGridEh 会自动识别相邻记录的字段内容,内容一致时就合并为一个显示区域,常用于客户名称、订单编号这类重复值较多的列。注意,这个功能只对 DBGridEh 生效,普通 DBGrid 没有。
6. 常见问题与排查技巧实录
6.1 安装时报F2613 Unit 'EhLibMain' not found
这是最常见的问题,原因通常是Library Path没配好。进入Tools > Environment Options > Library,把 Ehlib 的SOURCE目录添加进去。还有个容易忽略的点:如果目录名含中文或空格,严格遵守无空格路径原则,最好把组件包放置到D:\Components\Ehlib\SOURCE这样的路径,同时把Output directory也设置为不带空格的路径。改完路径之后建议关闭 IDE 再重新打开,否则编译器可能使用旧的搜索路径缓存。
6.2 安装成功但拖入 DBGridEh 时提示 “Cannot find unit D7EhLib”
由于不同版本的 Ehlib 包名不同,D7 对应的运行时包一般是EhLib70.dpl或者D7EhLib.dpl。这个报错的本质是你当前使用的设计期包依赖的运行时包没有在当前 IDE 环境被正确加载。解决办法非常直接:在设计期包dclEhLib70.dpk中检查Requires列表,确认运行时包名称,然后在Component > Install Packages中手动添加该.bpl文件。还有一种偷懒但有效的方案是直接把.bpl拷贝到 Delphi 的Bpl目录,并用命令行工具regsvr32注册,但个人建议尽量用 IDE 自带的方式安装。
6.3 程序运行后 DbGridEh 显示空白,连表头都没有
这种问题多发生在旧项目升级 Ehlib 版本之后。检查 DFM 文件中DBGridEh的Align和Parent属性,看是否有被父容器遮挡的情况。更好的做法是在运行期打印DBGridEh.Parent的类名,定位实际被继承到了哪个容器中。
更常见的是,旧项目里使用了DBGridEh的Flat或StyleElements这类在新版本中被移除的属性,导致 DFM 文件反序列化失败,整个窗体被跳过显示。这种情况只能用文本方式打开 DFM 文件,把不认识的属性删除。我通常会用notepad打开 DFM 文件,搜索seFont、seClient等新版本才有的属性,全部删掉。
6.4 排序点击事件不触发或排序结果错乱
先确认Title.TitleButton是否为True,再看数据集类型。如果是TADOQuery,默认排序必须依赖CommandText重新查询,每次排序都是重新取数,速度极慢。推荐的做法是改为TClientDataSet嵌套DataSetProvider,利用它自带的索引排序,速度会快一个量级。DbGridEh 的排序事件本身不会改数据,它只是发通知,实际操作必须写回数据集,否则界面上的箭头标记和实际排序不一致,很容易误导用户。
6.5 老项目发布后 exe 无法启动,提示找不到 BPL
这是所有用了第三方组件项目的通病。DbGridEh 的动态库.bpl没有打进发布包。解决方式有两种。简单粗暴型:把EhLib70.bpl、dclEhLib70.bpl等全部复制到 exe 同目录;推荐型:在项目选项中打开Runtime Packages,勾选Build with runtime packages为 False,也就是静态编译,把组件代码直接链接进 exe,这样客户端就不需要额外装动态库了。静态编译后 exe 体积会变大 1~2 MB,但这在现在的环境下完全可以接受,换来的是部署省心。
6.6 代码中为什么不能访问DBGridEh.DefaultDrawing
这是 Delphi 7 下 Ehlib 版本差异导致的。部分老版本把该属性设在DBGridEh的Options下,而不是直接暴露在顶层。想关闭默认绘制行为,应访问DBGridEh.Options := DBGridEh.Options - [dgDefaultDrawing]。如果你搜到的代码是DBGridEh.DefaultDrawing := False,多半是从高版本例子抄过来的,在老版本里根本不认识这个属性。
7. 调试期使用 DbGridEh 的一些经验心得
DbGridEh for D7 这套组合我前前后后用了接近十年,有一个感受特别深:它的上限完全取决于你对 Delphi 7 老数据集体系的理解。DbGridEh 本身只是界面组件,数据处理能力还是要靠TDataSet的子类来提供。不要把数据库十个字段全塞进一个表格里让用户滚动,配合DBGridEh的列可见性控制,把常用列放在左侧,高级属性放在右侧,用户使用感会好很多。
还有一点偏门但很实用的经验:DbGridEh 的导出功能在老版本上很弱,尤其是导出 Excel 中文会乱码。实际操作中如果需要导出报表,建议自己写一个循环,把DBGridEh的数据逐行写入 CSV 文件,然后交给 Excel 打开。这个方法虽然老土,但稳定不出错,比依赖组件确实可靠得多。
这套老组件组合,只要你理解了它的属性体系和安装机制,能省下的调试时间真不是一点半点。如果你是在维护一套历史悠久的 Delphi 7 业务系统,这个经验能帮你少走很多弯路。
本文还有配套的精品资源,点击获取