如何在Excel VBA中访问Word公共变量

9

我正在尝试自动化一些报告生成工作,其中Excel VBA正在完成所有工作。我的雇主有一套标准模板,所有文档都应从中生成。我需要从Excel VBA中填充其中一个模板。Word模板广泛使用VBA。

这是(部分)我的Excel VBA代码:

Sub GenerateReport() ' (Tables, InputDataObj)
  ' code generating the WordApp object (works!)

  WordApp.Documents.Add Template:="Brev.dot"

  ' Getting user information from Utilities.Userinfo macro in Document
  Call WordApp.Run("Autoexec") ' generating a public variable
  Call WordApp.Run("Utilities.UserInfo")
  ' more code
End sub

在Word VBA的Autoexec模块中定义并声明了一个名为user的公共变量。来自Utilities模块的Userinfo子过程填充user。这两个程序在VBA中都能成功运行。我想在我的Excel VBA中访问user变量,但是我得到了以下错误:

编译错误:此上下文中尚未创建变量。

我该如何在Excel VBA中访问Word VBA变量?我认为它们基本上是相同的?
编辑:user变量是用户定义的具有仅String属性的Type。复制填充user变量的Word VBA函数绝对是可行的,但比我认为的更费力……

UserInfo 转换为一个函数,并赋予它一个可分配给 Excel 变量的返回值。 - SierraOscar
@MacroMan UserInfo 是内置在模板中的,我无法篡改它... - Holene
@ScottHoltzman 是的,可以复制 Word VBA 中的函数。我只是认为在一个或另一个 VBA 实例中访问公共变量应该很容易。 - Holene
2
@Holene 如果你可以修改设置全局变量的应用程序代码(或在开始时设置它),那么这很容易,但在这种情况下,你似乎无法这样做。 - Scott Holtzman
1
"UserInfo已经嵌入到模板中,我无法篡改...在这种情况下,您无法访问Word中生成的信息。然而,“代码需要在其他计算机上运行,而模板是为工作中的所有用户设置的”不必阻止您。有方法可以解决这个问题,而不会影响使用代码的其他人,例如写入文档变量(这是文档内的字符串存储,没有人可以看到它,也不会影响任何东西)。" - Cindy Meister
显示剩余2条评论
2个回答

4
在Word模块中:
Public Function GetUserVariable() As String '// or whatever data type
    GetUserVariable = user
End Function

在 Excel 模块中:

myUser = WordApp.Run("GetUserVariable")

或者,您可以复制变量值 - 因为它被称为user,我猜它返回有关文档用户或作者的某些信息。如果是这种情况,以下之一可能是您想要的:

'// Username assigned to the application
MsgBox WordApp.UserName

'// Username defined by the system
MsgBox Environ$("USERNAME")

'// Name of the author of the file specified
MsgBox CreateObject("Shell.Application").Namespace("C:\Users\Documents").GetDetailsOf("MyDocument.doc", 9)

这个能通过Excel VBA实现吗?就像Excel VBA添加模块到Word文档,执行并返回user变量一样? - Holene
1
除非您可以访问受保护的VBProject对象模型(出于安全原因,默认情况下已禁用),否则不可能实现该操作。 - SierraOscar
我怀疑这些模板是几年前制作的,可能是在2000年左右。我该如何确认它不会工作? - Holene
1
尝试从Excel运行以下代码:Set wApp = GetObject(, "Word.Application"): Set wDoc = wApp.Documents(1): Set vPrj = wDoc.VBProject你很可能会收到一个错误,提示程序访问未受信任。 - SierraOscar
如评论中所述 - 如果您告诉我们变量user返回的内容,我们可以提供Excel中可用的替代解决方案。 - SierraOscar

3

另一个选项 - 如果您只能向Utilities.UserInfo子程序添加一行代码(在设置公共变量之后):

ActiveDocument.Variables("var_user") = user

那么您之后就可以轻松地在Excel中访问它:

Sub GenerateReport() ' (Tables, InputDataObj)
  ' code generating the WordApp object (works!)

  'I am assuming your WordApp object is public, as you don't declare it.
  'Capture the new document object    
  Dim newdoc as Object
  set newdoc = WordApp.Documents.Add(Template:="Brev.dot")

  ' Getting user information from Utilities.Userinfo macro in Document
  Call WordApp.Run("Autoexec") ' generating a public variable
  Call WordApp.Run("Utilities.UserInfo")

  'Get and show the value of "user"
  Dim user as String
  user = newdoc.Variables("var_user")
  msgbox, user
End Sub

假设user是一个字符串。

编辑:由于要求仅在Excel VBA上工作,如果可能的话,我肯定会尝试Scott和MacroMan建议的方法 - 在Excel中复制Word宏的相同功能。

我假设您已经排除了使用原始模板的编辑副本,设置为公共文件夹的可能性...

为了完整起见,还有另一种可能性:实际上可以通过“暴力”方式向Word文档中注入VBA代码,而不使用VBProject对象模型。如果将Word文档重命名为.zip文件并打开它,您将注意到其中有一个\word\vbaProject.bin文件。此文件包含文档的VBA项目,并且原则上,可以通过修改或替换它来添加或更改VBA代码。

我进行了一些测试,通过简单地复制vbaProject.bin文件从一个文档移植代码到另一个文档,这个概念是可行的。如果您对了解更多关于此文件的信息感兴趣,此主题可能会有所帮助。

但请注意,要使用这种技术做你想要的事情会有一些复杂(首先需要更新Excel VBA中的压缩文件),并且需要大量实验来减轻意外损坏文件的风险。如果您正在寻找简单的解决方案,则绝对不建议使用此方法-但是这是可能的。


请注意,使用这种技术,如果保存了文档,则文档变量“var_user”的值也会被保存,并且可以在之后访问,而无需重新运行宏(只需打开文档并检查其Document.Variables集合即可)。 - dnep
还要注意的是,Word很难将DocVariables设置为空值;如果它们可能出现,您必须使用特殊的字符序列来指示它们。 - Carl Colijn
使用这种方法肯定很好,但我不能触碰Word VBA。代码需要在其他计算机上运行,并且模板已为所有工作用户设置... - Holene
但是Word VBA密码受保护吗?或者你至少可以读取它吗? - dnep
编辑了答案,以进一步阐述此事的想法。 - dnep
我能看懂。这非常有趣!我会先尝试将填充“user”(及其依赖项)的VBA函数复制到我的Excel VBA中,但这绝对是一个可行的方法!感谢您的想法! - Holene

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接