工作簿。在特定情况下打开失败

时间:2018-01-15 10:10:09

标签: excel excel-vba vba

所以我在我的项目中有一个函数,用于查找工作簿,检查它是否打开,然后打开该工作簿,如果它已关闭。

    Public Function CheckOpen(wbName As String)
    Dim wb As Workbook
    Dim Ret_type As Integer
    Dim strMsg As String
    Dim strTitle As String
    Dim tempstr As String
    Dim x As Integer, y As Integer

    On Error Resume Next
    Set wb = Application.Workbooks(wbName)
    On Error GoTo 0

    strTitle = "Workbook Not Open"
    strMsg = "Workbook " + wbName + " isn't open, press 'Retry' to fix."

    If wb Is Nothing Then
        'The workbook isn't open
         Ret_type = MsgBox(strMsg, vbRetryCancel + vbQuestion, strTitle)

         Select Case Ret_type
            Case 4
             'Retry Case
               On Error Resume Next
               For x = 1 To 2
                    For y = 1 To 2
                        Workbooks.Open (FindFilePath(x) + FileEndingManager(wbName, y))
                        Debug.Print (FindFilePath(x) + FileEndingManager(wbName, y))
                    Next y
               Next x
            Case 2
             'Cancel Case
                MsgBox "You clicked 'CANCEL' button."
            End Select
      End If

    End Sub

TO CLARIFY:此功能在直接调用时有效。如:

    Sub TestCheck()
         Call CheckOpen("WorkbookName")
    End Sub

没关系。一切正常。但是,当我从实际电子表格中输入的函数调用此函数时,会出现MsgBox,但它从不打开所需的工作簿。

我不明白发生了什么。

1 个答案:

答案 0 :(得分:0)

使用函数(UDF)

如评论@jkpieterse

中所述
  

从单元格调用的函数不能执行打开工作簿等功能

功能可以像Excel内置函数一样从单元格中调用,并且始终向单元格返回内容(即使它&#39) ; s只是一个错误)。

对于返回错误的函数,它必须有一行像

FunctionName = *a value that complies with the function declaration*

Excel中的自动完成功能可用,即使它们返回#VALUE!错误,如果您未按上述方式设置返回,也会发生错误。这可能会让用户感到沮丧!

UDF中的任何其他错误也会导致#VALUE!错误,找到它们的唯一方法是使用F8逐步执行该功能。他们不会在编译时出现!

因此,至少有两个理由不使用sub足够的函数。

如果您想更改任何书籍或工作表对象,请声明Sub 程序。

谨慎使用UDF!

回答你的问题:

我尝试将您的代码重构为工作表可调用函数,该函数将在使用您的变量时使用Sub过程。

我不知道FindFilePath(x)FileEndingManager(wbName, Y)这样做是假设它们有效。

Public Function CheckOpen(wbName As String) As Boolean
Dim wb As Workbook

On Error Resume Next
Set wb = Application.Workbooks(wbName)
On Error GoTo 0
If Not wb Is Nothing Then
    CheckOpen = True 'the essence of a "Function" - it returns a value!
End If

End Function

或者您可以使用不需要On Error Resume Next

的替代功能
Public Function CheckOpen1(wbName As String) As Boolean
Dim wb As Workbook

For Each wb In Workbooks 'in all the workbooks you have open
    If wb.Name = wbName Then
        CheckOpen = True 'if not, CheckOpen will remain FALSE
    End If
Next

End Function 

然后你的Sub程序如下:

FileEndingManager(wbName, y)
Sub TestCheck()
Dim Ret_type As Integer
Dim strMsg As String
Dim strTitle As String
Dim tempstr As String
Dim x As Integer, y As Integer

If Not CheckOpen("WorkbookName") Then
    strTitle = "Workbook Not Open"
    strMsg = "WorkbookName isn't open, press 'Retry' to fix."
    Ret_type = MsgBox(strMsg, vbRetryCancel + vbQuestion, strTitle)

    Select Case Ret_type
    Case 4
        'Retry Case
        On Error Resume Next
        For x = 1 To 2
            For y = 1 To 2
                Workbooks.Open (FindFilePath(x) + FileEndingManager(wbName, y))
                Debug.Print (FindFilePath(x) + FileEndingManager(wbName, y))
            Next y
        Next x
        On Error GoTo 0 'end the Resume Next ASAP
        'Check if the x, y loop has opened WorkbookName
        If Not CheckOpen("WorkbookName") Then 'probably can't be opened
            strMsg = "WorkbookName can't be opened! Clicking OK will exit sub."
            MsgBox strMsg, vbCritical, strTitle
            Exit Sub
        End If
    Case 2 'Tell user something they know! Not necessary
        'Cancel Case
        MsgBox "You clicked 'CANCEL' button." 'delete this line and just exit
        Exit Sub
    End Select
End If
'Haven't exited yet so safe to proceed
'...do things with WorkbookName
End Sub