VBA宏,它可以动态地从字符串中写入新的宏

时间:2017-04-04 09:07:01

标签: string vba excel-vba module excel

是否可以从字符串变量创建Excel VBA宏?

假设我们有FirstMacro:

Sub FirstMacro()
    Dim MyString
    MyString = "Sub SecondMacro()" & Chr(13) & Chr(10) & "MsgBox " & Chr(34) & "Hello" & Chr(34) & Chr(13) & Chr(10) & "End Sub"
    Debug.Print MyString
    'Here be code that magicly creates SecondMacro
End Sub

运行宏,我想创建存储在VBA字符串变量中的SecondMacro。可以在同一模块下面或新模块中创建第二个宏。

所以字符串中的第二个宏看起来像这样:

Sub SecondMacro()
MsgBox "Hello"
End Sub

2 个答案:

答案 0 :(得分:1)

当然可以。请注意,您无法在正在运行代码的模块中添加/删除。

这会将代码附加到模块的末尾。如果你可以避免这种情况,我只会用它来添加我编程的按钮代码。

With Workbooks(ThisWorkbook.Name).VBProject.VBComponents("MyModuleHere").CodeModule
    .InsertLines .CountOfLines + 1, "Sub... End Sub"
End With

所以要添加到" MyModuleHere"代码模块(假设你有一个名为的模块),请将其放入:

Sub addcode()
    Dim subtext As String
    subtext = "Sub PrintStuff" & vbCrLf & "msgbox ""Hello World""" & vbCrLf & "End Sub"
    With Workbooks(ThisWorkbook.Name).VBProject.VBComponents("MyModuleHere").CodeModule
        .InsertLines .CountOfLines + 1, subtext
    End With
End Sub

与往常一样,CPearson增加了一些非常有用的见解:

http://www.cpearson.com/excel/vbe.aspx

关于删除我认为你在评论中暗示的代码,我使用下面的函数来查找子名称,然后将其删除(这假设我将知道sub的长度) :

Function ClearModule(strShapeName As String)
Dim start As Long
Dim Lines As Long
Dim i As Variant, a As Variant

    With Workbooks(ThisWorkbook.Name).VBProject.VBComponents("MyModuleHere").CodeModule
        For i = .CountOfLines To 1 Step -1
            If Left(.Lines(i, 1), 8 + Len(strShapeName)) = "Sub " & strShapeName & "_Cli" Then
                .DeleteLines i, 6
            End If
        Next
    End With
End Function

答案 1 :(得分:1)

在这里你或多或少都有所有变化,希望能解决你的问题。要测试此代码,请将其全部复制到普通代码模块中(默认情况下为“Module1”)将其重命名为“Remin”,并在激活的工作表的单元格A1中写入“FirstMacro”,即单元格A2中的数字。然后直接从VBE窗口运行以下第一个过程。

Sub SelectMacroToRun()
    ' 04 Apr 2017

    Dim MacroName As String
    Dim Arg1 As String
    Dim Outcome As Long

    With ActiveSheet
        MacroName = .Cells(1, 1).Value
        Arg1 = .Cells(2, 1).Value
    End With

    On Error Resume Next
    Outcome = Application.Run(ActiveSheet.name & "." & MacroName, Arg1)
    If Err Then
        MsgBox "The macro """ & MacroName & """ wasn't found", _
               vbInformation, "Error message"
    Else
        If Outcome <> xlNone Then MsgBox "Outcome = " & Outcome
    End If
End Sub

Private Function FirstMacro(Optional ByVal Dummy As String) As Long

    MsgBox "First Macro"
    FirstMacro = xlNone
End Function

Private Function SecondMacro(Arg1 As Long) As Long

    MsgBox "Second Macro" & vbCr & _
           "Argument is " & Arg1

    SecondMacro = Arg1 * 111
End Function

代码将运行FirstMacro,从工作表中读取名称。将该名称更改为“SecondMacro”以改为调用第二个宏。第二个宏需要一个参数,第一个只接受它并且不做任何事情。你不需要传递任何参数,但是这段代码显示了如何传递(尽可能多地以逗号分隔)并且它还显示了如何忽略它 - 参数传递给FirstMacro中的虚拟变量,并且功能也没有返回。

Application.Run "Remin" & MacroName, Arg1

只运行宏(它可能是一个子)。如果您不想传递参数,请省略参数。 “Remin”是被调用宏所在的代码表的名称。此名称可以扩展为包含另一个工作簿的名称。但是,如果被调用的宏与调用者不在同一个模块中,则它不能是私有的。