【问题标题】:VBA check if file existsVBA 检查文件是否存在
【发布时间】:2013-04-27 09:42:58
【问题描述】:

我有这个代码。它应该检查文件是否存在,如果存在则打开它。如果文件存在,它确实有效,但是,如果它不存在,则每当我将文本框留空并单击提交按钮时,它都会失败。如果文本框为空白,我想要的是显示错误消息,就像文件不存在一样。

运行时错误“1004”

Dim File As String
File = TextBox1.Value
Dim DirFile As String

DirFile = "C:\Documents and Settings\Administrator\Desktop\" & File
If Dir(DirFile) = "" Then
  MsgBox "File does not exist"
Else
    Workbooks.Open Filename:=DirFile
End If

【问题讨论】:

  • 您没有提供代码的问题部分(即包含提交按钮的表单)。你能分享你的文件吗?
  • 上面的代码是我提交按钮的内容

标签: excel vba file file-exists


【解决方案1】:
Function FileExists(ByRef strFileName As String) As Boolean
' TRUE if the argument is an existing file
' works with Unicode file names
    On Error Resume Next
    Dim objFSO As Object
    Set objFSO = CreateObject("Scripting.FileSystemObject")
    FileExists = objFSO.FileExists(strFileName)
    On Error GoTo 0
End Function

为了让函数运行得更快,可以将objFSO设为一个全局变量,代码可以这样修改并保存在一个模块中:

Option Explicit
Dim objFSO As Object
Function FileExists(ByRef strFileName As String) As Boolean
' TRUE if the argument is an existing file
' works with Unicode file names
    On Error Resume Next
    If objFSO Is Nothing Then Set objFSO = CreateObject("Scripting.FileSystemObject")
    FileExists = objFSO.FileExists(strFileName)
    On Error GoTo 0
End Function

要使strFileName 成为 Unicode 字符串,例如,您可以从单元格值中获取它或以特殊方式定义它,因为 Excel 的 VBE 不会以 Unicode 格式保存字符串常量。 VBE 确实支持已保存在字符串变量中的 Unicode 字符串。您将不得不查看此内容以了解更多详细信息。

希望这对某人有所帮助^_^

【讨论】:

    【解决方案2】:

    简洁明了的方式:

    Public Function IsFile(s)
        IsFile = CreateObject("Scripting.FileSystemObject").FileExists(s)
    End Function
    

    【讨论】:

    • 即使 "s" 是文件夹名称,它也会返回 True :-(
    【解决方案3】:

    我使用这个函数来检查文件是否存在:

    Function IsFile(ByVal fName As String) As Boolean
    'Returns TRUE if the provided name points to an existing file.
    'Returns FALSE if not existing, or if it's a folder
        On Error Resume Next
        IsFile = ((GetAttr(fName) And vbDirectory) <> vbDirectory)
    End Function
    

    【讨论】:

    • 既然你有On Error Resume Next,在你的主线之后我会介绍On Error GoTo 0,只是为了防止错误挂起。无论如何,我喜欢这种方法,因为可以检查文件的存在而不会意外检查文件夹的存在。
    • 这是否处理 fName 既不是文件也不是目录的情况?似乎@brettdj 和 iDevlop 的答案的组合最好: IsFile = ((GetAttr(fName) And vbDirectory) vbDirectory) And Len(Dir(DirFile)) 0
    • 进一步调查,似乎 GetAttr(fName) 将引发异常 53 - FileNotFoundException,调用 Resume Next,并且 IsFile 将保持其先前值 (False)。所以你的函数 确实 处理所有情况。我可能不会测试它,但它也可能比 brettdj 运行得更快,因为它不调用 Dir,这看起来很像系统命令 (?)。根据我的 C/C++ 经验,调用系统命令大约需要 1 秒,可能还要一秒才能恢复可执行文件。优秀!我之前对你的答案投了赞成票。我不明白为什么这不是最高票数。
    • @iDevlop - 我再次测试了这个案例。如果在这个函数中接收到错误,当我们回到调用者函数时,我们仍然有那个错误。 (错误 53:找不到文件)
    • @ZygD 然后您可以在end function 之前添加err.clear。就我个人而言,我总是在我真正处理它们的代码区域之前清除错误。
    【解决方案4】:

    这是我更新的代码。在保存之前检查版本是否存在并保存为下一个可用的版本号。

    Sub SaveNewVersion()
        Dim fileName As String, index As Long, ext As String
        arr = Split(ActiveWorkbook.Name, ".")
        ext = arr(UBound(arr))
    
        fileName = ActiveWorkbook.FullName
    
        If InStr(ActiveWorkbook.Name, "_v") = 0 Then
            fileName = ActiveWorkbook.Path & "\" & Left(ActiveWorkbook.Name, InStr(ActiveWorkbook.Name, ".") - 1) & "_v1." & ext
        End If
    
       Do Until Len(Dir(fileName)) = 0
    
            index = CInt(Split(Right(fileName, Len(fileName) - InStr(fileName, "_v") - 1), ".")(0))
            index = index + 1
            fileName = Left(fileName, InStr(fileName, "_v") - 1) & "_v" & index & "." & ext
    
        'Debug.Print fileName
       Loop
    
        ActiveWorkbook.SaveAs (fileName)
    End Sub
    

    【讨论】:

      【解决方案5】:

      类似的东西

      最好使用工作簿变量来提供对打开的工作簿的进一步控制(如果需要)

      更新以测试该文件名是一个实际的工作簿 - 这也使得初始检查变得多余,除了向用户发送消息而不是文本框为空白

      Dim strFile As String
      Dim WB As Workbook
      strFile = Trim(TextBox1.Value)
      Dim DirFile As String
      If Len(strFile) = 0 Then Exit Sub
      
      DirFile = "C:\Documents and Settings\Administrator\Desktop\" & strFile
      If Len(Dir(DirFile)) = 0 Then
        MsgBox "File does not exist"
      Else
       On Error Resume Next
       Set WB = Workbooks.Open(DirFile)
       On Error GoTo 0
       If WB Is Nothing Then MsgBox DirFile & " is invalid", vbCritical
      End If
      

      【讨论】:

      • 此方法并非 100% 可靠,因为它不区分文件名和文件夹名。
      • @iDevlop 我已经测试了文件名是否有效。
      • 当文件名是 unicode 时不起作用。在下面查看我发布的答案。
      【解决方案6】:

      为了检查存在,也可以使用(适用于文件和文件夹)

      Not Dir(DirFile, vbDirectory) = vbNullString
      

      如果文件或目录存在,则结果为True

      例子:

      If Not Dir("C:\Temp\test.xlsx", vbDirectory) = vbNullString Then
          MsgBox "exists"
      Else
          MsgBox "does not exist"
      End If
      

      【讨论】:

      • 当文件名是 unicode 时不起作用。在下面查看我发布的答案。
      【解决方案7】:

      我会把它扔出去然后躲起来。 检查文件是否存在的通常原因是避免在尝试打开文件时出错。如何使用错误处理程序来处理:

      Function openFileTest(filePathName As String, ByRef wkBook As Workbook, _
                            errorHandlingMethod As Long) As Boolean
      'Returns True if filePathName is successfully opened,
      '        False otherwise.
         Dim errorNum As Long
      
      '***************************************************************************
      '  Open the file or determine that it doesn't exist.
         On Error Resume Next:
         Set wkBook = Workbooks.Open(fileName:=filePathName)
         If Err.Number <> 0 Then
            errorNum = Err.Number
            'Error while attempting to open the file. Maybe it doesn't exist?
            If Err.Number = 1004 Then
      '***************************************************************************
            'File doesn't exist.
               'Better clear the error and point to the error handler before moving on.
               Err.Clear
               On Error GoTo OPENFILETEST_FAIL:
               '[Clever code here to cope with non-existant file]
               '...
               'If the problem could not be resolved, invoke the error handler.
               Err.Raise errorNum
            Else
               'No idea what the error is, but it's not due to a non-existant file
               'Invoke the error handler.
               Err.Clear
               On Error GoTo OPENFILETEST_FAIL:
               Err.Raise errorNum
            End If
         End If
      
         'Either the file was successfully opened or the problem was resolved.
         openFileTest = True
         Exit Function
      
      OPENFILETEST_FAIL:
         errorNum = Err.Number
         'Presumabley the problem is not a non-existant file, so it's
         'some other error. Not sure what this would be, so...
         If errorHandlingMethod < 2 Then
            'The easy out is to clear the error, reset to the default error handler,
            'and raise the error number again.
            'This will immediately cause the code to terminate with VBA's standard
            'run time error Message box:
            errorNum = Err.Number
            Err.Clear
            On Error GoTo 0
            Err.Raise errorNum
            Exit Function
      
         ElseIf errorHandlingMethod = 2 Then
            'Easier debugging, generate a more informative message box, then terminate:
            MsgBox "" _
                 & "Error while opening workbook." _
                 & "PathName: " & filePathName & vbCrLf _
                 & "Error " & errorNum & ": " & Err.Description & vbCrLf _
                 , vbExclamation _
                 , "Failure in function OpenFile(), IO Module"
            End
      
         Else
            'The calling function is ok with a false result. That is the point
            'of returning a boolean, after all.
            openFileTest = False
            Exit Function
         End If
      
      End Function 'openFileTest()
      

      【讨论】:

        【解决方案8】:

        您应该设置一个条件循环来检查 TextBox1 的值。

        If TextBox1.value = "" then
           MsgBox "The file not exist" 
           Exit sub 'exit the macro
        End If
        

        希望对你有所帮助。

        【讨论】:

          【解决方案9】:

          可能是由文件名变量引起的

          File = TextBox1.Value
          

          应该是

          Filename = TextBox1.Value
          

          【讨论】:

          • 这不是一个糟糕的答案。使用“文件”或任何其他关键字作为变量名给很多人带来了麻烦。尽管这不是问题的解决方案,但它仍然是一个好点。
          猜你喜欢
          • 2017-11-10
          • 2012-07-19
          • 1970-01-01
          • 2015-04-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-12-25
          相关资源
          最近更新 更多