乐于分享
好东西不私藏

手把手教你做VBA系统:自定义64位Office环境下的网格控件

手把手教你做VBA系统:自定义64位Office环境下的网格控件

立即添加星标

每天学好教程

前文以报税记账系统为例,详细介绍基于Excel + vba+mysql的系统搭建和开发方法以及权限控制的实现逻辑、新增模块的集成和实现方法以及将加载宏打包成exe安装包的方法、VBA程序“脱离”Excel运行的核心逻辑和方法,本文介绍64位Office环境下的网格控件自制方法。

猜您喜欢
往期精选▼

手把手教你做一套Excel VBA系统

继续手把手教你做Excel VBA系统

手把手教你做Excel VBA系统:新增模块

手把手教你做Excel VBA系统:打包成EXE

手把手教你做Excel VBA系统:VBA能否“脱离”Excel运行?

20年VBA开发经验总结47条万字原创长文,刷新你对Excel的认知!

一、背景

很多vba开发者都有这样的烦恼:在64位office环境下,耳熟能详的类似datagrid的网格控件几乎全部不兼容,且没有替代控件,listbox、listview等以展示为主的控件并不能满足大多数时候都需要进行数据编辑的需要,笔者做的ERP等大型系统这种需求更是比比皆是,于是有了基于Excel表格进行网格控件封装的强烈动机,最终在两套ERP系统中进行了应用与验证,在此介绍详细介绍实现方法。
二、基本原理
其实,Excel工作表是最好的网格应用,功能强大到令人叹为观止,将工作表作为网格的基础是在自然不过的了,否则就有舍近求远之嫌了。
窗体是系统级应用的标配或者说是显著标志,相对于直接在Excel文档中操作,窗体显得更独立,且在系统迁移或传播时不容易走样变形,从而能够进行更好的流程控制和幂等性操作,这才使得将网格封入窗体的事情变成了刚需。
没错,“将网格封入窗体”是本文的底层基础,这首先要面临着解决如下几个问题:(公众号:左手excel右手vba)
1、隐藏ribbon功能区,工作表标签,状态栏,编辑栏。
2、尺寸要随宿主窗体动态调整,且要与宿主同生共死。
3、窗体切换时要确保不改变宿主。
三、核心逻辑
1、关键词:隐藏
无论是ribbon功能区还是编辑栏、状态栏,这些工作表中的必备要素在网格中并不需要,好在Excel设计思想支持将相关要素进行隐藏控制。
在《VBA能否脱离Excel运行》一文中详细介绍了Excel.applicaiton,即实例的概念,在一个实例下可以创建多个文档,隐藏操作的对象是实例而不是文档,所以在创建实例的同时就可以隐藏任何你不需要的模块和要素。
创建实例后可添加工作表作为封装后的主编辑区域2️⃣,newWS作为全局工作表对象,在后续操作中可以通过它来调用工作表的任何属性和方法,比如耳熟能详的条件格式、数据验证以及各种常用函数。
在创建的同时马上获取其句柄PID3️⃣并存起来,为后续的肃清工作做铺垫,避免误杀。(公众号:左手excel右手vba)
另外需要给实例的caption指定一个唯一值,为后续获取其句柄pid做准备。
为确保Ribbon能够成功隐藏,才用两种方式(Excel自身的方法和windows系统的内置API)互为兜底儿。
对标题栏仅仅隐藏是不够的,因为稳定性不足,所以直接通过系统底层的api进行修改。
注意,在调用这些底层api之前需要在模块顶部先引用。
2、关键词:嵌入
嵌入是封装的核心,实现方式却是做简单的,直接调用系统的SetParent内置函数:
SetParent xlHWnd, frmHWnd
两个参数分别为被嵌入的Excel实例对象以及要嵌入的窗体对象。所以在进行嵌入之前需要先定位这两个对象,即获取其句柄PID值。
根据caption获取excel实例对象xlHWnd
根据窗体caption获取窗体对象frmHWnd
至此已经完成了将新创建的excel实例嵌入到了指定的窗体之中。
3、关键词:调整
记得有位著名诗人写过两句诗:“屎上雕花终觉浅,屁中寻得一缕香”,仔细想想却是如此,你每天的工作不就是屎上雕花,屁中寻香吗?
接下来的要做的主要工作就是尺寸调整。
excel窗体设计我认为比较拉垮之处是尺寸单位不一致,官方给出的转换关系并不能得到想要的结果,所以上述方法中的几个数字其实是不断尝试出来的,虽然可以通过传入ctrl等几个主窗体控件的尺寸来间接控制Excel实例的尺寸,但有时候实际情况并没有想象中的那般美好,不过也不是毫无效果,总之要尽可能的通过标准化控制而不是写死几个数值,只有这样才能够提升兼容性和降低迁移成本。(公众号:左手excel右手vba)
另外,尺寸的调整不仅仅只是和窗体本身有关,还涉及到分辨率和系统的缩放比,只有把这些因素也考虑进去,才会调整到比较理想的效果。
如笔者的电脑使用的是150%的缩放比,在调整前要将其转换为基准系数1,即需要把获取到的系统缩放比除以1.5。
4、关键词:销毁
任何对象都有生命周期,因为excel实例是随宿主窗体的出现而创建的,也应该随窗体的消失而销毁,否则就会不断的累积新的实例对象,系统资源被过度占用,系统卡顿将肉眼可见。
所以,需要在关闭窗体的事件中增加销毁实例的操作。
通过创建实例时获取并保存的pid来定位进程,并借用系统shell这把刀进行精准击杀,从而保证了窗体与实例不仅同年同月同日生,而且同年同月同日死。(公众号:左手excel右手vba)
四、高阶技能
一旦实例工作表创建起来,理论上,excel所有的方法、属性和操作都可以使用了,但有一个问题,新建的实例2️⃣和窗体所在的实例1️⃣并不是同一个,也就是说实例1️⃣中的代码无法操作实例2️⃣,这就涉及到了跨实例操作的问题。
以在新实例中生成数据验证的下拉菜单为例,首先在生成新实例2️⃣的同时在老实例1️⃣中通过VBComponents的CodeModule将代码写入到新实例2️⃣,假如方法名为setDownList,然后通过老实例1️⃣跨实例远程调用写入到新实例2️⃣的setDownList,这样就好在新实例中以数据验证的形式生成下拉菜单。
具体不再详述,后续发文细讲,先上个图。
五、写在最后
留个作业:AI编程的大佬可以试试能否实现文中想要的效果,提示词几乎已经彻底暴露在文中了,请让你的小龙虾开始表演。
还是那句老话:无论设计得多完美的系统、思考得多周到的设计,都会有不足之处。
当你通过这样一个简易的系统把前中后端打通,那么你就是一个真正的系统开发者而不是表格制作者了。
猜您喜欢
往期精选▼

VBA工具合集,复杂工作一键搞定,让同事目瞪口呆的Excel自动化

一键搞定!VBA自动化工具合集

一键全自动!基于Excel VBA的智能工具集,90%工作秒级完成

精选VBA工具合集,从此告别手工操作

数据为刃,玉麟擒牛—玉麒麟智选系统详细介绍

单据模板库:一键拿来,3秒搞定所有格式!

长按

关注

立即添加星标

每天学好教程

相关学习资料