【问题标题】:How to use a UserForm to select a worksheet from selected workbook如何使用用户窗体从选定的工作簿中选择工作表
【发布时间】:2017-06-19 21:34:28
【问题描述】:

我正在尝试创建一个宏,该宏允许用户从特定工作簿和工作表更新主工作簿(宏所在的位置)。工作簿和工作表的名称可能会有所不同,因此我从改编自 the ozgrid forum 的代码中调用此 UserForm:

Option Explicit

Private Sub CommandButton1_Click()
    MyFile = Me.ComboBox1.Value
    MySheet = Me.ComboBox2.Value
    Unload Me
End Sub

Private Sub CommandButton2_Click()
    Stopped = True
    Unload Me
End Sub

Private Sub UserForm_Initialize()
    Dim wkb As Workbook
    Dim sht As Worksheet
    Me.Label1.Caption = "Please select one of the following files and Worksheets..."
    With Me.ComboBox1
        For Each wkb In Application.Workbooks
            .AddItem wkb.Name
        Next wkb
    End With
    MyFile = Me.ComboBox1.Value
    With Me.ComboBox2
        For Each sht In Application.Worksheets
            .AddItem sht.Name
        Next sht
    End With
    MySheet = Me.ComboBox2.Value
End Sub

现在问题在于调用用户表单的主工作簿中的模块。我收到此位的类型不匹配错误:Set wb1 = MyFile

这是模块的其余部分:

Option Explicit

Public MyFile As String
Public Stopped As Boolean

Sub Update_Master()
    Stopped = False
    UserForm1.Show
    If Stopped Then Exit Sub
    MsgBox MyFile

' Update_Master Macro
'
' Keyboard Shortcut: Ctrl+m
'
    Dim wb1 As Workbook, wb2 As Workbook
    Dim TargetFile As Variant
    Dim ws1 As Worksheet, ws2 As Worksheet
    Dim ws1LRow As Long, ws2LRow As Long
    Dim i As Long, j As Long
    Dim ws1LCol As Long, ws2LCol As Long
    Dim aCell As Range, bCell As Range
    Dim SearchString As String
    Dim ExitLoop As Boolean, matchFound As Boolean

    '~~> Set EOD Workbook
    Set wb1 = MyFile
    Set ws1 = MySheet
    '~~> Get the last Row and Last Column
    With wb1
        ws1LRow = .Range("E" & .Rows.Count).End(xlUp).Row
        ws1LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    End With

    '~~> Set Master Workbook
    Set wb2 = Workbooks("MoO - Master List - TEST.xlsm")
    Set ws2 = wb2.Sheets("CM List")
    '~~> Get the last Row and Last Column
    With ws2
        ws2LRow = .Range("E" & .Rows.Count).End(xlUp).Row
        ws2LCol = .Cells(1, .Columns.Count).End(xlToLeft).Column
    End With

    '~~> Loop Through Cells of Col E in workbook A and try and find it
    '~~> in Col E of workbook B
    For i = 2 To ws1LRow
        SearchString = ws1.Range("E" & i).Value

        Set aCell = ws2.Columns(5).Find(What:=SearchString, LookIn:=xlValues, _
                    LookAt:=xlWhole, SearchOrder:=xlByRows, SearchDirection:=xlNext, _
                    MatchCase:=False, SearchFormat:=False)

        ExitLoop = False

        '~~> If match found
        If Not aCell Is Nothing Then
            Set bCell = aCell

            matchFound = True

            '~~> Then compare all columns
            For j = 6 To ws1LCol
                If ws1.Cells(i, j).Value <> ws2.Cells(aCell.Row, j).Value Then
                    matchFound = False
                    Exit For
                End If
            Next

            '~~> If all columns matched then write to Col A/B
            If matchFound = False Then
                ws2.Cells(aCell.Row, 12).Value = ws1.Cells(i, 12).Value
                ws2.Cells(aCell.Row, 13).Value = ws1.Cells(i, 13).Value
            End If

            '~~> Find Next Match
            Do While ExitLoop = False
                Set aCell = ws2.Columns(5).FindNext(After:=aCell)

                '~~> If match found
                If Not aCell Is Nothing Then
                    If aCell.Address = bCell.Address Then Exit Do

                    matchFound = True

                    '~~> Then compare all columns
                    For j = 6 To ws1LCol
                        If ws1.Cells(i, j).Value <> ws2.Cells(aCell.Row, j).Value Then
                            matchFound = False
                            Exit For
                        End If
                    Next

                    '~~> If all columns matched then write to Col A/B
                    If matchFound = False Then
                        ws2.Cells(aCell.Row, 12).Value = ws1.Cells(i, 12).Value
                        ws2.Cells(aCell.Row, 13).Value = ws1.Cells(i, 13).Value
                    End If
                Else
                    ExitLoop = True
                End If
            Loop
        End If
    Next
End Sub

任何帮助将不胜感激。我是一个业余爱好者,一直试图从我在这里和其他地方找到的代码的 sn-ps 拼凑起来。

提前致谢!

【问题讨论】:

    标签: excel vba


    【解决方案1】:

    Setwb1 = MyFile替换为Set wb1=Workbooks(myFile)

    【讨论】:

    • 取决于它是否已经打开。但是,是的,不能将字符串分配给工作簿类型。类型不匹配只是告诉你错误,你甚至会得到错误的错误行。首先要做的是检查 = 的两边是否是相同的类型。
    • 感谢 Gordon 的回复,但不幸的是,这仍然不起作用。我确实找到了办法
    • ... `Set wb1 = Workbooks(UserForm1.ComboBox1.Value)' 但现在即使我选择不同的工作簿,它也被设置为主工作簿。当我单步执行代码时,它会返回到用户表单代码但不会显示表单 - 所以我猜它会重新确定每个 ComboBox 的值。我更近了,但仍然很难过。有没有办法从用户窗体中选择的值声明变量,然后将它们传递给模块?可能将它们设置为公共或全局?
    • 更新:我终于通过在用户窗体中使用 Me.Hide 而不是 Unload Me 使用户窗体和模块一起工作,这使我可以将选定的工作簿和工作表设置为模块中的对象。如果有人想看代码,请回复这个帖子。
    猜你喜欢
    • 2015-07-24
    • 1970-01-01
    • 1970-01-01
    • 2015-01-18
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多