c# - vba - 扫描文档中的宏并替换宏文本?

标签 c# vb.net vba

有人给我一个谜题。在我工作的地方有大量的 Word 模板,它们都包含一个包含一些错误的自动更新事件句柄。这个错误存在于所有模板中。我想知道是否有一种方法可以扫描包含此宏的模板目录并稍微更改宏代码?

这可能吗?

最佳答案

是的,你可以做到。您可以使用以下方式访问任何文档的 VBA 项目:

Application.VBE.ActiveVBProject.VBComponents

您的项目必须引用“Microsoft Visual Basic for Applications Extensibility”。

要运行代码,您必须在 Word 中启用“信任对 Visual Basic 项目的访问”选项,使用

Tools->Macro->Security (Trusted Publishers tab)

VBComponents 集合包含项目包含的所有标准模块、类模块、窗体和“文档”模块。如果你用谷歌搜索,你会找到很多关于如何访问/修改它们的帮助。

编辑:好的,更多细节。此方法将搜索文档的所有 VbComponents 以查找具有指定名称的方法,并在找到的第一个方法中执行搜索/替换。

Public Sub ReplaceInProject(ByVal oDocument As Document, ByVal strMethodName As String, ByVal strFindText As String, ByVal strReplaceWithText As String)

    ' For each module (of any type - could use oVbComponent.Type to restrict
    ' this to certain types of module)

    Dim oVbComponent As VBComponent
    For Each oVbComponent In oDocument.VBProject.VBComponents

        Dim oCodeModule As CodeModule
        Set oCodeModule = oVbComponent.CodeModule

        ' See if we can find the method in this module

        Dim ixStartLine As Long
        ixStartLine = FindMethodStartLine(oCodeModule, strMethodName)

        If ixStartLine > 0 Then

            ' Get all the text of the method

            Dim numLines As Long
            numLines = oCodeModule.ProcCountLines(strMethodName, vbext_pk_Proc)

            Dim strLines As String
            strLines = oCodeModule.Lines(ixStartLine, numLines)

            ' Do the find/replace

            strLines = Replace(strLines, strFindText, strReplaceWithText)

            ' Replace the method text.

            oCodeModule.DeleteLines ixStartLine, numLines

            oCodeModule.InsertLines ixStartLine, strLines

        End If

    Next oVbComponent

End Sub

Private Function FindMethodStartLine(ByVal oCodeModule As CodeModule, ByVal strMethodName As String) As Long

    FindMethodStartLine = 0

    ' ProcStartLine will raise an error if the method is not found;
    ' we'll just ignore the error and return -1

    On Error Resume Next
    FindMethodStartLine = oCodeModule.ProcStartLine(strMethodName, vbext_pk_Proc)

End Function

请注意,这仅适用于 SubFunction 方法,不适用于 Get/Set/Let 属性,因为我使用的是 vbext_pk_Proc。这是一个 PITA,您需要明确说明这一点。坦率地说,CodeModule 组件的整个 API 似乎都被设计成令人沮丧的。例如,虽然 VbComponent 对象有一个 Find 方法(您认为这是一种查找所需文本的便捷方法),但它实际上返回 TrueFalse(!)。有用,我不认为!

这个 API 的设计者在这样做时一定宿醉得很厉害。

关于c# - vba - 扫描文档中的宏并替换宏文本?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1742044/

相关文章:

c# - 以编程方式获取文件夹位置

sql - 在将记录添加到数据库之前检查记录是否存在

excel - 在表单事件后面将 Access 数据传输到 Excel 模板表中

c# - Java TCP 客户端和 C# 服务器;客户端仅在服务器关闭后才收到消息

c# - 如何检查文件是否被隐藏?

vb.net - VB.NET 私​​有字段的命名约定

javascript - 从 Node.js 调用 VBScript

c# - System.Security.Cryptography 与 Windows.Security.Cryptography

c# - 我可以在保存更改之前验证实体吗?

c# - 在 C# 中翻译 COM 错误代码