ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
查看: 1735|回复: 20

[分享] 在VB6中调用Excel/Word/WPS

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-1-12 09:50 | 显示全部楼层 |阅读模式
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助
本帖最后由 vitrel 于 2024-1-12 14:30 编辑

      看了山菊花总版主最近发的一篇贴子《为夕阳添一抹余晖——VB6封装Dll调试方法》,心里热热的。没错,我就是他所说的“在山那边”的人,还在守着VB6的人之一,而且还想在这里多待一会儿,无它,这里的风景实在太美了。

      刚好看到有网友提到,对于在VB6中调用Excel存在疑问。前段时间我刚好也碰到了这个问题,稍为“研究”过,恰好有点心得,不敢私藏,特把我的经验拿出来与大家一同分享一下。先声明一下,对于VBA或VB6,我都只是入门,只是略懂些皮毛,太深的道理我也说不出,以下所分享的问题也仅仅是我的经验所得,如果所说的理论或方法有误,虚心接受网友们的指正。

      言归正传,顾名思义,要在用VB6所编写的程序中,调用Excel(或Word、或PowerPoint、或WPS的文字、表格等,以下就用“Excel一类软件”简单代替,免得每次都写这么长),或是读取其中的内容、或是对其中的内容进行操作等等,理论上并非难事,因为Excel一类软件都支持VBA,与VB6的VB语言可谓是同宗同源。但是,VB6所编译出来的程序与Excel一类软件毕竟是2个不同的软件,要用VB6所编译出来的程序对Excel一类软件进行夸软件操作,必须先建立桥梁,然后再按规范进行操作。其中的方法大致有二。
      其中的“方法一”,兼容性极差,并不推荐使用,但下面仍会用较大的篇幅来介绍,原因之一是网上绝大多数网友介绍的就是这一种方法,介绍它能让你更进一步了解“调用”的原理。而“方法二”的兼容性很好,推荐使用。对于实用党而言,也可以跳过“方法一”,直接看“方法二”。


【调用方法一:先引用,再定义,后调用】因为兼容性差,不推荐
以调用Excel为例,大致步骤为:
1、先引用:
在VB6编辑界面→工程→引用→勾选“Microsoft Excel 16.0 Object Library”。(后面会进一步说明①)

2、然后定义Excel对象:
Dim xlApp As Excel.Application,定义完成后,这个xlApp就指向了Excel程序。

3、再然后打开一个Excel对象:
Set xlApp = GetObject(, "Excel.Application")                '指向当前已经打开的(第一个)Excel对象
Set xlApp = CreateObject("Excel.Application")        '创建一个新打开的(空的)Excel,该Excel对象在后台打开,不可见
上述两语句的区别,后面会进一步说明②。

4、接下来,就可以用这个打开了的Excel程序操作工作簿了。
具体操作方法,后面会进一步说明③。


※对于“方法一”,以下要说明几点问题:
{ 说明一:GetObject(, "Excel.Application") 与 CreateObject("Excel.Application") 的区别② }
      (此问题解释起来有点复杂,但挺重要的,我尽量说得通俗些,建议看完)
      要想弄懂,GetObject与CreateObject(这里用简称代表)的区别,首先须理解,Excel就像一个个“容器”,每个“容器”都可以“装下”多个工作簿。
      进一步解释就是,同一时间,系统允许打开多个Excel对象(就像微信多开一样),而每个Excel对象又可以打开多个工作簿。
      同一个工作簿文件甚至可被同一台电脑的多个Excel对象同时打开,区别只在于首先打开的那份可正常读写,随后打开的却是只读。如此一来,同一工作簿的多个副本同存在于任务栏上。
      对于用户来说,只能直观地看见任务栏上一个个被打开的工作簿,并不知道哪些工作簿是由哪个Excel对象打开的。
      通过人工打开一个或多个工作簿,同属于一个Excel对象;每次使用CreateObject又会创建一个新的Excel对象。这些Excel对象虽地位相同,但有先后之分。
      使用GetObject可指向最先出现(队列中第一)的Excel对象,从而操作该Excel对象(包含其中的任一工作簿、以及工作簿中的所有对象)。
      使用CreateObject创建新的Excel对象时也可指向该(新建的)Excel对象,从而操作其中的任一工作簿中的所有对象。
      不同Excel对象之间是相互独立的,互不能访问,更不能操作(←这个是重点,所以要用这么多的篇幅来解释GetObject与CreateObject的区别)。
      正因如此,在使用上,我的建议是,若系统中已有Excel打开的话,就用GetObject指向它;若系统中尚未有Excel打开的话,就用CreateObject来新打开一个。
      具体到代码上,我们优先使用GetObject,若出错,则证明当前环境并不存在已打开的Excel对象,此时才CreateObject。代码举例如下:
  1. On Error Resume Next
  2. Set xlApp = GetObject(, "Excel.Application")  '指向当前已经打开的(第一个)Excel对象
  3. If Err Then  '若出错,则表示当前并没有打开的Excel对象
  4.     Set xlApp = CreateObject("Excel.Application")  '创建一个新打开的(空的)Excel,该Excel对象在后台打开,不可见
  5.     xlApp.Visible = True  '使Excel对象可见,非必要
  6. End If
  7. On Error GoTo 0
复制代码

{ 说明二:操作Excel、操作工作簿的常用方法③ }
Dim xlBook As Excel.Workbook
Dim xlSheet As Excel.Worksheet
Set xlBook = xlApp.Workbooks.Add                        '新建Excel工件簿文件
Set xlBook = xlApp.Workbooks.Open("工作簿名")        '打开已经存在的Excel工件簿文件
Set xlSheet = xlBook.Worksheets("工作表名")        '设置活动工作表
xlSheet.Activate                                                        '激活工作表
MsgBox xlApp.ActiveWorkbook.Name                        '当前工作簿
MsgBox xlApp.ActiveSheet.Name                                '当前工作表
xlSheet.Cells(Row, col) = 值                                '给单元格(row, col)赋值
xlSheet.PrintOut                                                        '打印工作表
xlBook.SaveAs Filename:="E:\ABC.xlsx"                '保存/另存
xlBook.Close (True)                                                '关闭工作簿
xlApp.Quit                                                                '结束Excel对象,即关闭Excel

{ 说明三:工程引用① }
      上面提到过,要在VB6中调用Excel,首要一步就是要在VB6的工程中引用“Microsoft Excel 16.0 Object Library”。
      聪明的网友们一看这里出现了一个“16.0”的版本号,就该想到事情没那么简单。
      以下是常见Office的版本号:
    Office 2003        11.0
    Office 2007        12.0
    Office 2010        14.0
    Office 2013        15.0
    Office 2016        16.0
    Office 2019        16.0
    Office 2021        16.0(为何Office 2016~2021的版本号都是16.0?我也不知道,好像Office 2024的版本号也是16.0)
      对于安装了Office2016(或2019、2021)的系统,VB6的引用列表仅提供“Microsoft Excel 16.0 Object Library”供引用;对于安装了Office2013的系统,VB6中仅提供“Microsoft Excel 15.0 Object Library”供引用;如此类推。
      因此,引用“Microsoft Excel 16.0 Object Library”后,仅可调用Excel2016、2019、2021;引用“Microsoft Excel 15.0 Object Library”后,仅可调用Excel2013;也是如此类推。
      好了,问题来的,如果您的电脑安装的是Office 2013,在VB6中编写代码时,只能引用“Microsoft Excel 15.0 Object Library”。编译后的程序,若在本电脑是运行,调用Excel 2013肯定是没问题的。但假如把该程序放到别的电脑上运行,而别的电脑安装的是Office 2013以外的版本呢?调用就会出错。
      如此差的兼容性,就是我不推荐使用“方法一”的原因之一。

{ 说明四:调用WPS }
      随着WPS在国内的崛起,国内安装WPS的人越来越多,这是不争的事实。
      那么,VB6能调用WPS吗?答案是肯定的,但比调用Excel难得多(仅指方法一)。
      首先,据内行的网友所说,金山公司极少对外公开调用方法(其实网上根本找不到,但不敢把话说列,所以才保守地用了“极少”一词),网上流传的方法都是网友们非系统性测试总结所得,因此并不统一。
      其次,以现在最流行的WPS 2019专业版实测,本人曾安装过几个不同的版本(Guo家电网专业版、邮Zheng企业专业版、武Han市政务专业版等)来测试。结果发现,要想调用WPS表格(对应Office中的Excel),在VB6的工程引用列表中,有些版本提供的选项为“WPS Spreadsheets 2.0 Object Library”,有些版本提供的选项则为“Upgrade WPS Spreadsheets 3.0 Object Library”,选项的名称差别较大,并不统一。又因金山不提供技术支持,因此只能自己摸索。
      就算顺利通过了“引用”这一关,后续的“调用”也不轻松。上面调用Excel时用到的Dim xlApp As Excel.Application、GetObject(, "Excel.Application") 、 CreateObject("Excel.Application"),里面都用到“Excel.Application”,指的就是Excel这个程序。轮到WPS表格,则存在两个版本。对于WPS正式版,对应的是“Et.Application”;对于WPS开发版/抢先版,对应的则是“Ket.Application”。
    例如:Dim xlApp As Excel.Application,若是WPS正式版,须改为Dim xlApp As Et.Application,若是WPS开发版/抢先版,则须改为Dim xlApp As Ket.Application。
    例如:GetObject(, "Excel.Application") ,若是WPS正式版,须改为GetObject(, "Et.Application") ,若是WPS开发版/抢先版,则须改为GetObject(, "Ket.Application") 。
    例如:CreateObject("Excel.Application"),若是WPS正式版,须改为CreateObject("Et.Application"),若是WPS开发版/抢先版,则须改为CreateObject("Ket.Application")。
      听说,自己安装的WPS究竟是正式版还是开发版/抢先版,自己是不知道,也查不出来的,你说气人不气人。
      如此差的兼容性,就是我不推荐使用“方法一”的原因之二。


      说了这么多情况,相信大家也看得出来,使用“方法一”在VB6所编译出来的程序,在本机上调用本机所安装的Excel或WPS表格,当然是没问题的。但若放到别的电脑上运行呢?那可是恶梦,除非刚好另一台电脑所安装的Excel或WPS表格的版本与您的刚好相同。您常见得这样“刚好”的机会大吗?
      既然“方法一”的兼容性那么差,那么有没有一种能兼容“所有”版本的Excel或WPS表格的方法呢?答案是肯定的,就是下面要介绍的“方法二”。

(由于贴子的字数限制,后续的内容在3楼。)

评分

8

查看全部评分

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-12 12:37 | 显示全部楼层
本帖最后由 vitrel 于 2024-1-12 14:21 编辑


【调用方法二:不引用,先定义,后调用】(兼容性好,推荐)
      “方法一”之所以兼容性差,跟它第一步的“引用”脱不了关系。按“方法一”的思路,要想在VB6编译后的程序中调用Excel或WPS表格,必须在VB6中正确地引用,这一步骤不仅要区分软件(要么Excel,要么WPS表格)、更要区分软件的版本号。而且VB6的引用列表不能“任意多选”,即不可以一次性选择n个不同版本的Excel和n个不同版本的WPS表格,只能是系统安装了哪个就只能勾选哪个(只有相关软件在系统上安装完毕后,引用列表才会出现相应的选项供勾选)。毫不夸张地说,这个“引用”就是不兼容的根源。而“方法二”的最大特点就是直接跳过了“方法一”的“引用”,直接进入“定义”步骤,从而解决掉兼容性的问题。

方法二的大致步骤为:
1、定义对象。
      在“方法一”中,定义的语句是Dim xlApp As Excel.Application,由于“方法二”没有引用,因此VB6无法识别“Excel.Application”变量类型,如果直接使用原句便会报错,那该怎么办呢?放心,VB6/VBA里有一个几乎“万能”的变量类型“Object”,就像变量类型“Variant”一样好使,懂的都懂。
      于是乎,在没有引用的情况下,正确的定义语句为:Dim xlApp As Object。
      经过Dim xlApp As Object定义后,xlApp既可以是Excel,也可以是WPS表格(下面会进一步说明)。

2、然后打开一个对象:
Set xlApp = GetObject(, "Excel.Application")           '指向当前已经打开的(第一个)Excel对象(或WPS表格对象)
Set xlApp = CreateObject("Excel.Application")  '创建一个新打开的(空的)Excel(或WPS表格),该Excel对象(或WPS表格对象)在后台打开,不可见
      关于GetObject(, "Excel.Application") 与 CreateObject("Excel.Application") 的区别,上面已经详细解释过,这里不再重复。
      看到这里,网友们可以会疑问,语句中明明写的是“Excel.Application”,名字里含有一个“Excel”,因此,它能指向Excel,大家都能理解。但上面的注释里,为何它还能指向WPS表格对象呢?您还别说,真是这样。
      这么说的,这里的“Excel.Application”(不用改为“Et.Application”或“Ket.Application”)指向/调用的是当前系统xls、xlsx、xlsm等文件的默认打开软件,并不特指Excel这个软件(这应该是WPS作为后来者,为了兼容Office而作出的特殊处理吧)。
      所以,不管当前系统里安装的是哪个版本的Office,或哪个版本的WPS,或者既安装了Office又安装了WPS,总得有一个是xls、xlsx、xlsm等文件的默认打开程序吧,这里的“Excel.Application”就指向/调用它。
      这样一来,兼容性的问题就被瞬间解决了。

3、接下来,就可以用这个打开了的Excel(或WPS表格)程序操作工作簿了。
      具体操作方法与上面“说明二”的大致相同。
      但是,还是那个原因,由于“方法二”没有引用,因此VB6无法识别“Excel.Workbook”、“Excel.Worksheet”等变量类型。
      所以,“方法二”中,定义这些工作簿、工作表等对象时,统统要改为Object。
    Dim xlBook As Excel.Workbook        须改为        Dim xlBook As Object
    Dim xlSheet As Excel.Worksheet        须改为        Dim xlSheet As Object
      除此以外,“方法二”和“方法一”在操作Excel、WPS表格、工作簿、工作表……等等的方法几乎是一模一样的④。


※对于“方法二”,以下要说明几点问题:

{ 说明一:方法一和二在操作方法上的差异④ }
      细心的网友可能已经看出,我上面所说的“操作方法几乎一模一样”,意思就是并非完全一模一样。
      毕竟“方法二”在VB6中缺少了引用Excel或WPS表格的步骤,因此,有些Excel的专有常量(如xlUp、xlMaximized等)便不能被VB6所识别,直接使用会出错,要将其改为常数(如将xlUp改为-4162、将xlMaximized改为-4137等等)。
      其次的就是,在不引用的情况下,VB6是不认识Rows、Columns、Cells等元素的,因此不能单独地使用,必须在这些元素前添加父对象(如xlApp.)。
      上述情况都不是本贴的重点,就不占用太多篇幅去说了。

{ 说明二:对于既安装了Office又安装了WPS的系统,能否指定调用对象呢? }
      使用“方法二”,VB6对Excel/WPS表格的调用不能随心所欲,“Excel.Application”只能指向/调用的是当前系统xls、xlsx、xlsm等文件的默认打开软件,而不能自由选择Excel或WPS表格。


【调用Word/WPS文字】
      在VB6中既然能调用Excel/WPS表格,那么用相似的方法也能调用Word/WPS文字,上述的“方法一”和“方法二”都可以。具体的语法稍有差别,以下简单地择录一下:
{ 引用部分 }
Microsoft Excel xx.0 Object Library                改为:Microsoft Word xx.0 Object Library
WPS Spreadsheets 2.0 Object Library                改为:Kingsoft WPS 2.0 Object Library
Upgrade WPS Spreadsheets 3.0 Object Library        改为:Upgrade Kingsoft WPS 3.0 Object Library
{ 定义部分 }
Dim xlApp As Excel.Application                改为:Dim wdApp As Word.Application
Dim xlApp As ET.Application                改为:Dim wdApp As Wps.Application
Dim xlApp As Ket.Application                改为:Dim xlApp As Kwps.Application
{ 创建对象部分 }
Set xlApp = GetObject(, "Excel.Application")        改为:Set wdApp = GetObject(, "Word.Application")
Set xlApp = CreateObject("Excel.Application")        改为:Set wdApp = CreateObject("Word.Application")
Set xlApp = GetObject(, "Et.Application")                改为:Set wdApp = GetObject(, "Wps.Application")
Set xlApp = CreateObject("Et.Application")        改为:Set wdApp = CreateObject("Wps.Application")
Set xlApp = GetObject(, "Ket.Application")                改为:Set wdApp = GetObject(, "Kwps.Application")
Set xlApp = CreateObject("Ket.Application")        改为:Set wdApp = CreateObject("Kwps.Application")


【VB6程序实例】
      说一千道一万,说再多的理论也比不上直接来个代码直接测试一下。
      这里提供一个使用“方法二”创建的VB6实例(附原码),它里面包含两项测试:
        ~测试一:能调用本系统安装的Word(或WPS文字)来打开测试用的文档,并读取其中的内容,读取完毕后,关闭文档,退出Word(或WPS文字)。
        ~测试二:能调用本系统安装的Excel(或WPS表格)来打开测试用的工作簿,并读取其中的内容,读取完毕后,关闭工作簿,退出Excel(或WPS表格)。
图.png
      该实例我是特意为本贴所编写的,暂时只分别在Win10+Office 2019以及Win10+WPS 2019专业版的两台电脑上测试通过,而我之前用同样方法(“方法二”)所编写和VB6程序,已在多台不同的电脑上正常运行,“方法二”已充证实是可行的。这些电脑环境多种多样,有Win7、Win10、Win11,所安装的Office或WPS版本也是多种多样,更有些是既安装了Office又安装了WPS的,全部都能测试通过。
      当然,丑话须说在前,毕竟我的测试环境有限,而Office与WPS的版本更是多种多样,例如仍有电脑使用WinXP,而Office 2003至今仍在服役,还有,非专业版的WPS是不支持VBA的,所以,说到底,这个使用“方法二”所创建的测试实例到底有多广的兼容性,相信根本没人能够说得清楚,只能由网友们实际测试后反馈结果,我们才能逐一了解了。(完)

调用Office、WPS测试.rar

31.59 KB, 下载次数: 80

评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-1-12 11:29 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-1-12 13:20 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
占位,待更新。写了很多次vb,到别人电脑,就是createobject时出错

TA的精华主题

TA的得分主题

发表于 2024-1-12 13:46 | 显示全部楼层
VB6受到了限制,只能用于32位Office,改为VB.NET就不受限了。

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-1-12 14:27 | 显示全部楼层
shenjianrong163 发表于 2024-1-12 13:46
VB6受到了限制,只能用于32位Office,改为VB.NET就不受限了。

感谢您的提醒。
由于64位的Office对VBA支持不好,所以我一直没有接触64位的Office(既没下载,也没安装过),
而我能接触到的电脑(应该)也没有安装64位的Office,
所以,VB6所写的程序究竟能否调用64位的Office,真的要麻烦一下网友们帮忙测试一下了。

TA的精华主题

TA的得分主题

发表于 2024-1-12 17:06 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-1-12 21:51 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-1-13 09:55 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2024-1-13 21:10 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
感谢分享!楼主威武。
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-4-30 18:58 , Processed in 0.052618 second(s), 14 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表