VBA - 扫描文档的宏和替换宏文本? [英] vba - scan documents for macro and replace macro text?
问题描述
我提出了一个谜。我工作的地方有一个巨大的,所有包含其中包含了一些错误,一个AutoNew eventhandle Word模板量。而这个错误就在于所有的模板中。我不知道是否有可能是扫描目录模板的一种方式,其中包含该宏,并且稍微改变宏代码?
I'm presented with a puzzle. Where I work there are a huge amount of Word templates which all contains an autonew eventhandle which contains some errors. And this error lies within all templates. And I was wondering if there might be a way of scanning a directory for templates which contains this macro and change the macro code slightly?
难道这是可能的吗?
推荐答案
是的,你可以做到这一点。您可以通过访问任何文件的VBA项目:
Yes, you can do that. You can access the VBA project of any document using:
Application.VBE.ActiveVBProject.VBComponents
您的项目必须有一个参考Microsoft Visual Basic的应用程序扩展。
Your project must have a reference to "Microsoft Visual Basic for Applications Extensibility".
要运行代码,您必须启用在Word选项到Visual Basic项目信托访问,使用
To run the code, you must enable the "Trust Access to Visual Basic Project" option in Word, using
工具 - >宏 - >安全(可信
发行商选项卡)
Tools->Macro->Security (Trusted Publishers tab)
VBComponents
集合包含所有标准模块,类模块,形式和项目中包含文件模块。如果你Google一下,你会发现很多关于如何访问/修改它们的帮助
The VBComponents
collection contains all the standard modules, class modules, forms and "document" modules that the project contains. If you Google it, you'll find plenty of help on how to access/modify them.
修改:好了,一些细节。此方法将搜索所有的 VbComponents
寻找具有指定名称的方法的文件,并执行搜索/它找到的第一个内更换。
EDIT: OK, some more detail. This method will search all the VbComponents
of a document looking for a method with the specified name, and perform a search/replace within the first one it finds.
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
请注意,这将只与工作小组
和功能
方法,而不是财产的get / set /令
因为我使用 vbext_pk_Proc
。这是,你需要明确这个皮塔。坦率地说,对于 CodeModule整个API
分量似乎是旨在挫败。例如,而的VBComponent
对象有一个查找
方法(你会觉得是要找到一种方便的方法你要找的)文本,它实际上返回真
或假
(!)。有用的,我不觉得!
Note that this will only work with Sub
and Function
methods, not property Get/Set/Let
because I'm using vbext_pk_Proc
. It's a PITA that you need to be explicit about this. Frankly, the whole API for the CodeModule
component seems almost designed to frustrate. For example, while the VbComponent
object has a Find
method (which you'd think was a convenient way to find the text you're looking for), it actually returns True
or False
(!). Useful, I don't think!
该API的设计者必须有一个非常糟糕的宿醉,他们这样做的时候。
The designers of this API must have had a really bad hangover when they did this.
这篇关于VBA - 扫描文档的宏和替换宏文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!