VBA-在工作簿中获取模块

VBA-在工作簿中获取模块,vba,excel,Vba,Excel,我正在尝试创建一个用于创建其他.xlsm工作簿的工作簿,但不知道如何获取所需的模块,以便添加它们 我的代码如下(根据此处给出的答案进行修改:) 我需要帮助的地方是ImportModules子模块,在这里的注释“列出模块” 如何获取当前工作簿中的模块数组 Private Sub SVAmaker_Click() Dim file As String file = InputBox("SVA Planner file name", "Name", "Name") Appl

我正在尝试创建一个用于创建其他.xlsm工作簿的工作簿,但不知道如何获取所需的模块,以便添加它们

我的代码如下(根据此处给出的答案进行修改:)

我需要帮助的地方是ImportModules子模块,在这里的注释
“列出模块”

如何获取当前工作簿中的模块数组

Private Sub SVAmaker_Click()

    Dim file As String
    file = InputBox("SVA Planner file name", "Name", "Name")

    Application.DefaultSaveFormat = xlOpenXMLWorkbookMacroEnabled
    Workbooks.Add
    ActiveWorkbook.SaveAs filename:=file

    Dim WB As Workbook
    WB = ActiveWorkbook
    Call ImportModules(VBA.CStr(WB))

End Sub

Sub ImportModules(sWorkbookname As String)

    Dim cmpComponents As VBIDE.VBComponents
    Dim wbkTarget As Excel.Workbook

    Set wbkTarget = Workbooks.Open(sWorkbookname)

    If wbkTarget.VBProject.Protection = 1 Then
        Debug.Print wbkTarget.Name & " has a protected project, cannot import module"
    GoTo Cancelline
    End If

    Set cmpComponents = wbkTarget.VBProject.VBComponents

    Dim vModules As Variant
    'LIST MODULES HERE

    Dim i As Integer
    For i = LBound(vModules) To UBound(vModules)
        cmpComponents.Import vModules(i)
    Next i

Cancelline:

    If wbkTarget.FileFormat = xlOpenXMLWorkbook Then
        wbkTarget.SaveAs wbkTarget.Name, xlOpenXMLWorkbookMacroEnabled
        wbkTarget.Close SaveChanges:=False
    Else
        wbkTarget.Close SaveChanges:=True
    End If

    Set wbkTarget = Nothing

End Sub

你可以像这样学习这些模块。创建一些集合,然后迭代VBProject的VBComponents中的所有对象(模块类型的值为1):


您可以使用easy For Each循环遍历所有模块。 需要引用“Microsoft Visual Basic for Applications Extensibility”

Dim vbcomp As VBComponent

For Each vbcomp In ThisWorkbook.VBProject.VBComponents

    'if normal Module
    If vbcomp.Type = vbext_ct_StdModule Then

        'Do Stuff
    End If
Next vbcomp

使用.Type可以检查模块的类型(表单、普通模块、类模块等)

此代码应该会有所帮助。它会将所有模块导出到桌面,创建一个新工作簿并将它们全部导入其中

Public Sub ExportImportAllModules()

    Dim srcVBA As Variant
    Dim tgtVBA As Variant
    Dim srcModule As Variant
    Dim wrkBk As Workbook
    Dim sDeskTop As String

    On Error GoTo ERROR_HANDLER

    Application.DisplayAlerts = False

    Set srcVBA = ThisWorkbook.VBProject
    sDeskTop = CreateObject("WScript.Shell").specialfolders("Desktop")
    Set wrkBk = Workbooks.Add(xlWBATWorksheet) 'New workbook with 1 sheet.
    Set tgtVBA = wrkBk.VBProject

    For Each srcModule In srcVBA.vbComponents
        'There may be a better way to check it's a module -
        'I'm making it up as I go along.
        If srcModule.Type = 1 Then 'vbext_ct_StdModule
            srcModule.Export sDeskTop & "\" & srcModule.Name
            tgtVBA.vbComponents.Import sDeskTop & "\" & srcModule.Name
            Kill sDeskTop & "\" & srcModule.Name
        End If
    Next srcModule

    Application.DisplayAlerts = True

    On Error GoTo 0
    Exit Sub

ERROR_HANDLER:
    Select Case Err.Number

        Case Else
            MsgBox "Error " & Err.Number & vbCr & _
                " (" & Err.Description & ") in procedure ExportImportAllModules."
            Err.Clear
            Application.EnableEvents = True
    End Select

End Sub

为什么不简单地复制一份从中导入模块的“主”工作簿呢

Option Explicit

Private Sub SVAmaker_Click()

    Dim fso As New FileSystemObject
    Dim myFile As file        
    Dim fileName As String

    fileName = InputBox("SVA Planner file name", "Name", "Name") & ".xlsm"

    Set myFile = fso.GetFile(ActiveWorkbook.FullName)
    fso.CopyFile myFile, myFile.ParentFolder & "\" & fileName

End Sub
从这里开始,您将拥有一个新的工作簿,其中包含所有模块(和工作表)

如果需要删除某些工作表,请突出显示并打开它,然后使用“普通”VBA Excel模型对象代码执行操作


为了使用FileSystemObject API,您需要参考“Microsoft脚本运行时”

JChristen询问这些模块的列表

我将根据gizlmo的建议创建一个集合:

    Dim vbcomp As VBComponent
    Dim modules as Collection

    set modules = new Collection
    For Each vbcomp In ThisWorkbook.VBProject.VBComponents

        'if normal or class module
        If ((vbcomp.Type = vbext_ct_StdModule) _
             Or _
            (VBComp.Type = vbext_ct_ClassModule)) Then 

           modules.add VBcomp.name

        End If
    Next vbcomp
稍后,您可以像这样使用此集合:

    Dim module     as Variant
    for each module in modules
        ' e.g. importing the module 
        import module
    next module

希望它有帮助

,事实上,看看你的代码,你不需要任何集合,只需迭代CMP组件并检查组件类型,如果它等于1,那么它就是模块,你可以导入它。这更像是一个练习,让我在最后一周的工作中保持愉快。谢谢你的回答!
    Dim module     as Variant
    for each module in modules
        ' e.g. importing the module 
        import module
    next module