Да, вы можете сделать это. Вы можете получить доступ к проекту VBA любого документа, используя:
Application.VBE.ActiveVBProject.VBComponents
Ваш проект должен иметь ссылку на «Microsoft Visual Basic для расширяемости приложений».
Чтобы запустить код, вы должны включить опцию «Доверительный доступ к проекту Visual Basic» в Word, используя
Инструменты-> Макрос-> Безопасность (Доверенные
Вкладка "Издатели")
Коллекция VBComponents
содержит все стандартные модули, модули классов, формы и модули «документ», содержащиеся в проекте. Если вы зайдете в Google, вы найдете множество справок о том, как получить к ним доступ или изменить их.
РЕДАКТИРОВАТЬ : ОК, более подробно. Этот метод будет искать во всем 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
Обратите внимание, что это будет работать только с методами Sub
и Function
, а не со свойством Get/Set/Let
, потому что я использую vbext_pk_Proc
. Это PITA, что вы должны быть откровенными об этом. Честно говоря, весь API для компонента CodeModule
, похоже, почти расстроен. Например, хотя объект VbComponent
имеет метод Find
(который, как вы думаете, был бы удобным способом поиска искомого текста), он фактически возвращает True
или False
(!). Полезно, я не думаю!
У разработчиков этого API должно было быть очень плохое похмелье, когда они это делали.