programing

VBA 파일 존재 여부 확인

firstcheck 2023. 4. 8. 16:28
반응형

VBA 파일 존재 여부 확인

난 이 코드가 있어.파일이 있는지 확인하고 파일이 있으면 열어야 합니다.파일이 존재하면 동작하지만 존재하지 않으면 텍스트 상자를 공백으로 두고 [전송]버튼을 클릭하면 실패합니다.텍스트 상자가 비어 있으면 파일이 존재하지 않는 것처럼 오류 메시지를 표시하는 것이 좋습니다.

런타임 오류 "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

이와 같은 것

워크북 변수를 사용하여 열린 워크북을 추가로 제어하는 것이 좋습니다(필요한 경우).

파일 이름이 실제 워크북임을 테스트하도록 업데이트됨 - 텍스트 상자가 비어 있지 않으면 사용자에게 메시지를 보내는 것 외에 초기 검사도 중복됩니다.

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

이 기능을 사용하여 파일 존재 여부를 확인합니다.

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

존재 여부 확인에는 다음 항목도 사용할 수 있습니다(파일 및 폴더 모두 사용 가능).

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

깔끔하고 짧은 방법:

Public Function IsFile(s)
    IsFile = CreateObject("Scripting.FileSystemObject").FileExists(s)
End Function
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예를 들어 Excel의 VBE는 문자열 상수를 Unicode에 저장하지 않으므로 셀 값에서 가져오거나 특별한 방법으로 정의할 수 있습니다.VBE는 문자열 변수에 이미 저장되어 있는 Unicode 문자열을 지원합니다.좀 더 자세히 알아보셔야 할 것 같아요

이게 누군가에게 도움이 되길 바래 ^_^

Filename 변수가 원인일 수 있습니다.

File = TextBox1.Value

그럴 것 같네요.

Filename = TextBox1.Value

다양한 FileExist 메서드의 속도

많은 프로젝트에서 파일이 존재하는지 확인해야 했기 때문에 가장 빠른 옵션을 결정하고 싶었습니다.마이크로 타이머 코드(벤치마킹 VBA 코드 참조)를 사용하여 2865개의 파일이 있는 로컬 폴더에 대해 테이블 아래의 File Exist 함수를 실행하여 어떤 것이 더 빠른지 확인했습니다.우승자는 GetAttr을 사용했다.테스트 2에 FSO 메서드를 사용하는 것은 오브젝트가 글로벌하게 정의된 경우보다 조금 빨랐지만 GetAttr 메서드만큼 빠르지는 않았습니다.

------------------------------------------------------
% of Fastest                Seconds       Name
------------------------------------------------------
100.00000000000%             0.0237387    Test 1 - GetAttr
7628.42784145720%            1.8108896    Test 2 - FSO (Obj Global)
8360.93687615602%            2.0522254    Test 2 - FSO (Obj in Function)
911.27399562739%             0.2163246    Test 3 - Dir
969.96844814586%             0.2302579    Test 4 - Dir$
969.75108156723%             0.2302063    Test 5 - VBA.Dir
933.82240813524%             0.2216773    Test 6 - VBA.Dir$
7810.66612746275%            1.8541506    Test 7 - Script.FSO

Function FileExistsGA(ByVal FileSpec As String) As Boolean
  ' Karl Peterson MS VB MVP
  Dim Attr As Long
  ' Guard against bad FileSpec by ignoring errors
  ' retrieving its attributes.
  On Error Resume Next
  Attr = GetAttr(FileSpec)
  If Err.Number = 0 Then
    ' No error, so something was found.
    ' If Directory attribute set, then not a file.
    FileExistsGA = Not ((Attr And vbDirectory) = vbDirectory)
  End If
End Function

Function FSOFileExists(sFilePathNameExt As String) As Boolean
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    FSOFileExists = fso.FileExists(sFilePathNameExt)
    Set fso = Nothing
End Function

Function FileExistsDir(sFilePathNameExt As String) As Boolean
    If Len(Dir(sFilePathNameExt)) > 0 Then FileExistsDir = True
End Function

Function FileExistsDirDollar(sFilePathNameExt As String) As Boolean
    If Len(Dir$(sFilePathNameExt)) > 0 Then FileExistsDirDollar = True
End Function

Function FileExistsVBADirDollar(sFilePathNameExt As String) As Boolean
    If Len(VBA.Dir$(sFilePathNameExt)) > 0 Then FileExistsVBADirDollar = True
End Function

Function FileExistsVBADir(sFilePathNameExt As String) As Boolean
    If Len(VBA.Dir(sFilePathNameExt)) > 0 Then FileExistsVBADir = True
End Function

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

이것이 OP에 완전히 답하는 것은 아니지만, 제공된 답변 중 어떤 답변이 가장 효율적이라고 생각되는지에 대한 정보를 제공하는 것입니다.

이거 저기 던지고 몸을 숙일게요.파일이 존재하는지 확인하는 일반적인 이유는 파일을 열 때 오류가 발생하지 않도록 하기 위해서입니다.에러 핸들러를 사용해 대처하는 것은 어떨까요.

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()

업데이트 된 코드입니다.저장하기 전에 버전이 존재하는지 확인하고 사용 가능한 다음 버전 번호로 저장합니다.

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

조건 루프를 설정하여 TextBox1 값을 확인해야 합니다.

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

도움이 되길 바랍니다.

언급URL : https://stackoverflow.com/questions/16351249/vba-check-if-file-exists

반응형