通过宏查找并将代码添加到模块中

时间:2019-07-17 15:24:03

标签: excel vba

我正在尝试在VBA中创建代码,该代码将通过模块进行搜索,找到特定的文本,然后在该文本之前在同一行中添加一个字符串。例如,每次在模块中说“ yo”时,我都希望将其改为“ Add This yo”。

下面的代码成功地找到了在模块中说“ yo”的实例,但是没有在我想要的地方添加文本。而是在模块的最顶部(甚至不在子内部)添加文本。我如何在“ yo”之前添加此文本?

Public Sub Edit()

Dim vb As VBComponent
Dim i As Long
Dim intFoundLine As Integer
Dim strSearchPhrase As String
Set vb = ThisWorkbook.VBProject.VBComponents("Module2")
strSearchPhrase = "yo"
intLinesNr = vb.CodeModule.CountOfLines

For i = 1 To intLinesNr
    If vb.CodeModule.Find(strSearchPhrase, i, 1, -1, -1) Then
        intFoundLine = i
        MsgBox "Found at " & intFoundLine
        vb.CodeModule.AddFromString ("Add This")
    End If
Next

End Sub

2 个答案:

答案 0 :(得分:3)

用新文本替换行:

vb.CodeModule.ReplaceLine i, "Add This" & vb.CodeModule.Lines(i, 1)

根据Mathieu Guindon的回答,这是我将如何处理搜索短语的所有实例:

Do While vb.CodeModule.Find(strSearchPhrase, i, 1, -1, -1)
    vb.CodeModule.ReplaceLine i, "Add This" & vb.CodeModule.Lines(i, 1)
    i = i + 1
Loop
'

答案 1 :(得分:2)

迭代模块的所有行似乎对Find方法的使用不佳,该方法能够在模块中的任何位置查找文本,并接受ByRef自变量,如果函数返回{{1} },其中将包含找到的文本的确切位置-对于用户定义的True,这是一个很好的用例:

Type

现在您拥有要重写的编辑器内的行号,请使用Option Explicit Private Type CodeStringLocation StartLine As Long EndLine As Long StartColumn As Long EndColumn As Long End Type Sub test() Dim module As CodeModule Set module = ThisWorkbook.VBProject.VBComponents("Module1").CodeModule Dim foundAt As CodeStringLocation If module.Find("test", foundAt.StartLine, foundAt.StartColumn, foundAt.EndLine, foundAt.EndColumn) Then 'L9C5-L9C9 Debug.Print "L" & foundAt.StartLine & "C" & foundAt.StartColumn & "-L" & foundAt.EndLine & "C" & foundAt.EndColumn End If End Sub 进行重写-例如,用以下内容替换上面的CodeModule.ReplaceLine语句:

Debug.Print

如果您需要替换模块中所有出现的搜索文本,只需运行搜索,直到Dim newLine As String newLine = Replace(module.Lines(foundAt.StartLine, 1), "test", "Renamed") module.ReplaceLine foundAt.StartLine, newLine 返回CodeModule.Find-像这样:

False

关键是除搜索文本外,所有内容均为 output 参数;通过对这些参数中的任何一个进行硬编码,您将失去对它们返回值的引用。如果要将搜索限制为特定范围或行范围,则正确的方法是在运行搜索之前配置Dim foundAt As CodeStringLocation Do While module.Find("test", foundAt.StartLine, foundAt.StartColumn, foundAt.EndLine, foundAt.EndColumn) Dim newLine As String newLine = Replace(module.Lines(foundAt.StartLine, 1), "test", "Renamed") module.ReplaceLine foundAt.StartLine, newLine Loop 值。

foundAt

这样,您就可以利用参数的实际双向特性,而不会丢失对输出值的引用-并且无需在不需要时迭代多达1万行代码。

请注意,这完全是基于文本的搜索,并且绝对采用零语法考虑:API不会在意是否在标识符,注释,字符串文字或关键字中找到搜索字符串。