Excel VBA Проверьте, открыт ли файл - PullRequest
0 голосов
/ 06 апреля 2020

Это простая функция, и решение должно быть простым, но я не могу найти проблему.

У меня есть функция, которая вызывается в подпрограмме, она проверяет, открыт ли файл , если нет, чтобы открыть его. Функция работает отлично, но когда она возвращается к главному подпрограмме, которая ее вызывает, переменная (True или False) теряет свое значение, и я получаю ошибку 9: нижний индекс вне диапазона в строке Set wb = Workbooks(MasterFileF) в основная подпрограмма.

Function wbOpen(wbName As String) As Boolean
Dim wbO As Workbook

    On Error Resume Next
        Set wbO = Workbooks(wbName)
        wbOpen = Not wbO Is Nothing
        Set wbO = Nothing

End Function



Sub Macro5()

Dim wb As Workbook
Dim path As String
Dim MasterFile As String
Dim MasterFileF As String


Application.ScreenUpdating = False

'Get folder path
path = GetFolder()
If path = "" Then
    MsgBox "No folder selected. Please start macro again and select a folder"
    Exit Sub
Else
End If


MasterFile = Dir(path & "\*Master data*.xls*")
MasterFileF = path & "\" & MasterFile

'Check if workbook open if not open it
If wbOpen(MasterFile) = True Then
    Set wb = Workbooks(MasterFileF)
Else
    Set wb = Workbooks.Open(MasterFileF)
End If

Где я ошибаюсь, что значения переменных функции теряются при возврате в основную подпрограмму?

Ответы [ 2 ]

2 голосов
/ 06 апреля 2020

Я бы немного перевернул твой код

, чтобы пометка Wb Open() f возвращала открытую книгу, если она найдена, через ее аргументы

Function wbOpen(wbName As String, wbO As Workbook) As Boolean
    On Error Resume Next
    Set wbO = Workbooks(wbName)
    wbOpen = Not wbO Is Nothing
End Function

и затем в твоем главном просто код go:

MasterFile = Dir(path & "\*Master data*.xls*")

If Not wbOpen(MasterFile, wb) Then Set wb = Workbooks.Open(path & "\" & MasterFile)

Редактировать

, чтобы добавить расширенную версию для обработки книги с одинаковыми именами, но разными путями

, в этом случае вы должны проверить оба имя файла и путь, но на разных шагах

, поэтому WbOpen() функция становится:

Function wbOpen(wbName As String, wbPath As String, wbO As Workbook) As Boolean
    On Error Resume Next
    Set wbO = Workbooks(wbName)
    On Error GoTo 0 ' restore error handling back

    If Not wbO Is Nothing Then ' in current excel session there already is an open workbook with same name (path excluded) as the searched one

        If wbO.path = wbPath Then ' the already open workbook has the same path as the searched one -> we got it!

            wbOpen = True

        Else ' the already open workbook has a different path from the searched one -> we must investigate ...

            If MsgBox("A workbook named after:" _
                       & vbCrLf & vbCrLf & vbTab & wbName _
                       & vbCrLf & vbCrLf & " is already open but its path is different from:" _
                       & vbCrLf & vbCrLf & vbTab & wbPath _
                       & vbCrLf & vbCrLf & "If you want to open the new found one, the already open one will be closed" _
                       & vbCrLf & vbCrLf & vbCrLf & "Do you want to open the new found one?", vbQuestion + vbYesNo) = vbYes Then

                wbO.Close True ' close the currently opened workbook with same name but different path from searched one
                               ' the opening of the new one will be made in the main sub, after this function returning 'False'
            Else
                wbOpen = True ' you chose not to open the searched one and stay with the currently open one -> return 'True' to say you are done
            End If

        End If

    End If

End Function

и соответствующая часть вашего основного кода изменится на:

MasterFile = Dir(path & "\*.xls*")

If Not wbOpen(MasterFile, path, wb) Then Set wb = Workbooks.Open(path & "\" & MasterFile)
1 голос
/ 06 апреля 2020

Я думаю, что проблема заключается в вашей wbOpen функции. Вы устанавливаете этот объект книги локально и не возвращаете значение для Boolean. Смотрите ниже:

Function wbOpen(ByVal wbName As String) As Boolean

    Dim wbO As Workbook

    For Each wbO In Application.Workbooks
        If InStr(1, wbO.Name, wbName) Then
            wbOpen = True
            Exit Function
        End If
    Next wbO

    wbOpen = False

End Function



Sub Macro5()

    Dim wb As Workbook
    Dim path As String
    Dim MasterFile As String
    Dim MasterFileF As String

    Application.ScreenUpdating = False

    'Get folder path
    path = GetFolder()
    If path = "" Then
        MsgBox "No folder selected. Please start macro again and select a folder"
        Application.ScreenUpdating = True
        Exit Sub
    End If

    MasterFile = Dir(path & "\*Master data*.xls*")
    MasterFileF = path & "\" & MasterFile

    'Check if workbook open if not open it
    If wbOpen(MasterFile) = True Then
        Set wb = Workbooks(MasterFileF)
    Else
        Set wb = Workbooks.Open(MasterFileF)
    End If

    Application.ScreenUpdating = True

End Sub
...