遍历所有打开的工作簿时,代码会在一个工作簿后退出循环

时间:2019-05-20 05:29:18

标签: excel vba

我想遍历所有打开的Excel工作簿,以确定要对哪个工作簿执行操作。问题是,无论我打开了多少个工作簿,该代码都会在活动工作簿之后退出for循环并返回“ Nothing”。

我需要每周运行一次此例程,以将工作时间从下载的Excel工作簿转移到备用工作簿。文件名每周更改一次,但始终以“时间表”开头

从一月到四月,我每周都使用此例程,没有任何问题。我今天尝试使用它,这个问题冒出来了。我已经在具有不同操作系统(Windows 7,Windows 10)的多台不同计算机上使用了该例程。

我已经保存,关闭并重新打开了要激活的工作簿,但无济于事。我不需要每周更改代码来访问特定的工作簿,而是使用文件名中的前4个字母来标识要在其上执行操作的文件。

Sub cmdImportHours_Click()

    Dim ThisWB As Workbook
    Dim ImportWB As Workbook
    Dim WB As Workbook
    Dim msg1 As String
    Dim msg As Variant

' more variables

    msg1 = "Required file not found. Open the import file and try again."

    Set ThisWB = ThisWorkbook
    ThisWB.Worksheets("Hours").Activate

'The following loop exits after one iteration (the active workbook),
'regardless of how many workbooks are open

    For Each WB In Workbooks
        If Left(WB.Name, 4) = "Time" Then
            WB.Activate
            Exit For
        End If
    Next WB

    If WB Is Nothing Then
        msg = MsgBox(msg1, vbOKOnly)
        Exit Sub
    End If

'more code

End Sub

我希望循环能够查看每个打开的Excel工作簿的名称,但是它仅在查看活动工作簿后退出For循环。

2 个答案:

答案 0 :(得分:1)

那是因为Exit For,所以请注释该行。并且不要在WB之外使用for each,而应使用其他变量,在此代码变量count中,该变量用于计算匹配的工作簿

Dim count As String
count = 0
For Each WB In Workbooks
    If Left(WB.Name, 4) = "Time" Then
        count = count + 1
        WB.Activate
        'Exit For
    End If
Next WB

If count < 1 Then
    msg = MsgBox(msg1, vbOKOnly)
    Exit Sub
End If

答案 1 :(得分:1)

您在所有工作簿上的For Each直接返回一个可用变量,该变量引用所需的工作簿,因此您甚至可以在此处使用变量“ ImportWB”。如果找到了所需的项目,请在Exit For之前退出循环。

我为工作表引入了两个变量,以将它们用于复制操作。

Sub cmdImportHours_Click()
    Dim ImportWB As Workbook
    Dim SourceSheet As Worksheet, DestSheet As Worksheet
    Dim msg1 As String
    Dim msg As Variant

    For Each ImportWB In Workbooks
        If Left(ImportWB.Name, 4) = "Time" Then Exit For
    Next ImportWB

    If ImportWB Is Nothing Then
        msg1 = "Required file not found. Open the import file and try again."
        msg = MsgBox(msg1, vbCritical + vbOKOnly, "Workbook not open")
        Exit Sub
    End If

    Set DestSheet = ThisWorkbook.Worksheets("Hours")
    'DestSheet.Activate is typically not necessary
    Set SourceSheet = ImportWB.Sheets(1)

    DestSheet.Range("A2:B10").Value = SourceSheet.Range("A2:B10").Value
    ' more code
End Sub

由于ThisWorkbook始终是相同的(带有VBA代码的工作簿),因此不必给它一个额外的变量,因此我省略了它。


如果您没有通过上述代码获得已经打开的工作簿,则可以在受保护的视图中打开它...

For i = 1 To Application.ProtectedViewWindows.Count
    Debug.Print "Protected Workbook: " & _
        Application.ProtectedViewWindows(i).Workbook.Name
Next i

...或在另一个Excel实例中。在这种情况下,您可以通过e引用它。 g。

Set ImportWB = GetObject("Path\Filename.xlsx")

有关更多示例,请参见here