【问题标题】:How to get result of a Word VBA function in c#?如何在 C# 中获取 Word VBA 函数的结果?
【发布时间】:2015-11-01 08:34:59
【问题描述】:

我需要打开一个 Microsoft Office Word 文档并获取该文档中某个模块的功能结果:

VBA 模块(MainModule):

Option Explicit

Public Function GetResult() As String
    GetResult = "My Expected Result"
End Function

我尝试了一些代码,最新的是:[Reference]

using System.Reflection;
using System.Runtime.InteropServices;
using MsWord = Microsoft.Office.Interop.Word;
using Microsoft.Office.Core;

...

var wordApp = new MsWord.Application();
wordApp.DisplayAlerts = MsWord.WdAlertLevel.wdAlertsNone;
wordApp.Visible = true;
wordApp.AutomationSecurity = MsoAutomationSecurity.msoAutomationSecurityForceDisable;

MsWord._Document wordDoc = wordApp.Documents.Open(ref fileNameObject,  ref falseValue, ref trueValue, ref falseValue,
    ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue,
    ref missingValue, ref missingValue, ref falseValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue);    

object n;
n = wordApp.Run("GetResult");
// or
n = wordApp.Run("MainModule.GetResult");
// or 
n = RunMacro(wordApp, new Object[] {"MainModule.GetResult"});
// or
n = RunMacro(wordApp, new Object[] {"GetResult"});
// or
n = wordApp.Run("MainModule.GetResult", ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue, ref missingValue);

...

private static object RunMacro(object oApp, object[] oRunArgs)
{
    return oApp.GetType()
        .InvokeMember("Run", BindingFlags.Default | BindingFlags.InvokeMethod, null, oApp, oRunArgs);
}

RunMacro 行的错误是:

调用的目标已抛出异常。
[Inner-Exception]:无法运行指定的宏

堆栈跟踪是:

at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters)
at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
at ConsoleApplicationTest.Program.RunMacro(Object oApp, Object[] oRunArgs) in c:\..\Visual Studio 2013\Projects\ConsoleApplicationTest\ConsoleApplicationTest\Program.cs:line 57
at ConsoleApplicationTest.Program.Main(String[] args) in c:\..\Visual Studio 2013\Projects\ConsoleApplicationTest\ConsoleApplicationTest\Program.cs:line 32

注意:
Office 2013 将我的 Word 文档另存为 Office 97-2003 文档。
宏设置启用所有宏
并且对 VBA 项目对象模型的信任访问也被选中。

任何帮助将不胜感激。

【问题讨论】:

  • AFAIK,您可以使用 Application.Run ""macroName" 运行 VBA 宏(就像​​您一样),但它必须是没有返回值的 Sub。您需要找到一些解决方法才能返回返回值。
  • @A.S.H 谢谢,这是我的第一次尝试;)。
  • n = wordApp.Run("MainModule.GetResult"); 不起作用吗?函数是否带参数?
  • @Mat'sMug 确实如此。我的意思是 run 方法确实有一个返回值。我的第一条评论是错误的。我只是从来没有这样用过,抱歉(刚刚用excel测试过,我想应该和word差不多)。
  • 是的。但其他 Office 应用程序对有效呼叫有其他规范。 Excel 也允许您限定项目名称,而 Outlook 只是没有 Run 方法到其 Application 类。

标签: c# vba ms-word office-interop


【解决方案1】:

以下在 vb.net 中完美运行。我相信您可以轻松地将其翻译成 C#:

VB.Net:

Public Class Form1
    Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
        Dim wdApp As New Microsoft.Office.Interop.Word.Application()
        Dim wdDoc As Microsoft.Office.Interop.Word.Document
        wdDoc = wdApp.Documents.Open("C:\SO\Abc.docm")
        Dim s As String = wdApp.Run("myFunc", "Hello World!")
        MsgBox(s)
        wdDoc.Close(False) : wdApp.Quit()
    End Sub
End Class

VBA 字:

Function myFunc(str As String) As String
    myFunc = str
End Function

ps:VS2015、Word2007、Office12

编辑 令人惊讶的是,当我将您添加的安全设置(即... = msoAutomationSecurityForceDisable)添加到我的代码中时,我失败了。然后我去了MSDN的页面,发现:

MsoAutomationSecurityLow 开启所有宏并且是默认值 当你启动程序时。 MsoAutomationSecurityForceDisable 禁用 以编程方式打开的所有文件中的所有宏,没有 显示任何安全警告。

据我了解,它必须是MsoAutomationSecurityLow。这一个在这里再次起作用。

【讨论】:

  • 感谢您的宝贵时间,但任何类型的翻译都存在问题并且都失败了。
  • @shA.t 我明白这一点,但想分享它对我来说很顺利。由于 C# 和 VB 是等价的,这表明您必须检查环境问题(安全性、办公版本、项目引用等),而不是在编程部分。
  • 在我的 c# 代码中,wordApp.Run("Test"); 的简单代码会引发同样的错误 ;)。
  • 请看我的编辑。我认为msoAutomationSecurityForceDisable 禁用了单词 app 中的 VBA。它可能无法完全解决 pb,但可以肯定它不允许宏运行。 @shA.t
  • msoAutomationSecurityLowAutomationSecurity 的默认值,无论有没有该设置,错误都会再次出现。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-03
  • 1970-01-01
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多