Проверьте, существует ли файл с помощью VBA

82
Sub test()

thesentence = InputBox("Type the filename with full extension", "Raw Data File")

Range("A1").Value = thesentence

If Dir("thesentence") <> "" Then
    MsgBox "File exists."
Else
    MsgBox "File doesn't exist."
End If

End Sub

В этом случае, когда я беру текстовое значение из поля ввода, оно не работает. Однако, если удалить его "the sentence"из If Dir()и заменить его фактическим именем в коде, он работает. Кто-нибудь может помочь?

Динеш Гоэль
источник

Ответы:

142

Обратите внимание, что ваш код содержит то, Dir("thesentence")что должно быть Dir(thesentence).

Измените свой код на этот

Sub test()

thesentence = InputBox("Type the filename with full extension", "Raw Data File")

Range("A1").Value = thesentence

If Dir(thesentence) <> "" Then
    MsgBox "File exists."
Else
    MsgBox "File doesn't exist."
End If

End Sub
Cylian
источник
1
Это помогло мне частично, я думаю, когда я использую этот код, компилятор не рассматривает "thisntence" как каталог, поэтому я использовал еще одну строку кода до этого. "\" & Date $ Directory = Dir (Path, vbDirectory) </code>, когда я использовал переменную строку ** Directory ** в разделе If Dir (Directory) <> "", тогда это сработало хорошо
мухаммад тайяб
19

Используйте FileDialogобъект Office, чтобы пользователь мог выбрать файл из файловой системы. Добавьте ссылку в свой проект VB или в редактор VBA Microsoft Office Libraryи посмотрите справку. Это намного лучше, чем когда люди идут полным путем.

Вот пример, msoFileDialogFilePickerпозволяющий пользователю выбрать несколько файлов. Вы также можете использовать msoFileDialogOpen.

'Note: this is Excel VBA code
Public Sub LogReader()
    Dim Pos As Long
    Dim Dialog As Office.FileDialog
    Set Dialog = Application.FileDialog(msoFileDialogFilePicker)

    With Dialog
        .AllowMultiSelect = True
        .ButtonName = "C&onvert"
        .Filters.Clear
        .Filters.Add "Log Files", "*.log", 1
        .Title = "Convert Logs to Excel Files"
        .InitialFileName = "C:\InitialPath\"
        .InitialView = msoFileDialogViewList

        If .Show Then
            For Pos = 1 To .SelectedItems.Count
                LogRead .SelectedItems.Item(Pos) ' process each file
            Next
        End If
    End With
End Sub

Есть много вариантов, поэтому вам нужно просмотреть полные файлы справки, чтобы понять все, что возможно. Вы можете начать с объекта Office 2007 FileDialog (конечно, вам нужно будет найти правильную справку для используемой версии).

Эрике
источник
1
+1 Намного лучше, так как это Excel Application.FileDialog (msoFileDialogOpen)
Alex K.
18

Исправление в fileExists от @UberNubIsTrue:

Function fileExists(s_directory As String, s_fileName As String) As Boolean

  Dim obj_fso As Object, obj_dir As Object, obj_file As Object
  Dim ret As Boolean
   Set obj_fso = CreateObject("Scripting.FileSystemObject")
   Set obj_dir = obj_fso.GetFolder(s_directory)
   ret = False
   For Each obj_file In obj_dir.Files
     If obj_fso.fileExists(s_directory & "\" & s_fileName) = True Then
        ret = True
        Exit For
      End If
   Next

   Set obj_fso = Nothing
   Set obj_dir = Nothing
   fileExists = ret

 End Function

РЕДАКТИРОВАТЬ: сокращенная версия

' Check if a file exists
Function fileExists(s_directory As String, s_fileName As String) As Boolean

    Dim obj_fso As Object

    Set obj_fso = CreateObject("Scripting.FileSystemObject")
    fileExists = obj_fso.fileExists(s_directory & "\" & s_fileName)

End Function
amackay11
источник
2
Почему код проверяет одно и то же имя файла несколько раз (по одному для каждого файла в s_directory)? Нет смысла повторять этот тест. Вы заметите, что переменная цикла (obj_file) не используется кодом цикла.
grantnz
1
@grantnz Действительно! Я сделал ленивое копирование / вставку и настраивал, пока он не сработал. Укороченная версия выше. Благодарю.
amackay11
Кто-нибудь заметил, что иногда этот тест сообщает о ложном срабатывании, то есть возвращает «Истина», даже если файл не существует в файловой системе. В своем приложении я проверяю наличие файла на сервере в моей сети, если это дает вам подсказку.
pablete
6

просто избавься от этих речевых знаков

Sub test()

Dim thesentence As String

thesentence = InputBox("Type the filename with full extension", "Raw Data File")

Range("A1").Value = thesentence

If Dir(thesentence) <> "" Then
    MsgBox "File exists."
Else
    MsgBox "File doesn't exist."
End If

End Sub

Это то, что мне нравится:

Option Explicit

Enum IsFileOpenStatus
    ExistsAndClosedOrReadOnly = 0
    ExistsAndOpenSoBlocked = 1
    NotExists = 2
End Enum


Function IsFileReadOnlyOpen(FileName As String) As IsFileOpenStatus

With New FileSystemObject
    If Not .FileExists(FileName) Then
        IsFileReadOnlyOpen = 2  '  NotExists = 2
        Exit Function 'Or not - I don't know if you want to create the file or exit in that case.
    End If
End With

Dim iFilenum As Long
Dim iErr As Long
On Error Resume Next
    iFilenum = FreeFile()
    Open FileName For Input Lock Read As #iFilenum
    Close iFilenum
    iErr = Err
On Error GoTo 0

Select Case iErr
    Case 0: IsFileReadOnlyOpen = 0 'ExistsAndClosedOrReadOnly = 0
    Case 70: IsFileReadOnlyOpen = 1 'ExistsAndOpenSoBlocked = 1
    Case Else: IsFileReadOnlyOpen = 1 'Error iErr
End Select

End Function    'IsFileReadOnlyOpen
почему
источник
3
Я никогда раньше не слышал о «речевых знаках». Странный. На мой взгляд, это неправильное название. Многие вещи требуют цитат, но это не речь.
ErikE
4
@ErikE +1 за приятное наблюдение ... Картинки здесь
whytheq
1
Судя по всему, «речевые знаки» - это неофициальный вариант «кавычек».
ErikE
@ErikE ... Я знаю, вернее, я сказал: «Я знаю»
whytheq
6
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function

На моем сайте работает почти очень хорошо. Если я назову его пустой строкой, Dir вернет connection.odc !! Было бы здорово, если бы вы, ребята, могли поделиться своим результатом.

Во всяком случае, мне это нравится:

Function FileExists(fullFileName As String) As Boolean
  If fullFileName = "" Then
    FileExists = False
  Else
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
  End If
End Function
Иоахим Бролин
источник
1
Старый пост, но похоже, dir("")дает вам имя первого файла в текущем каталоге. В вашем случае это был файл с именем connection.odc.
Кори
4
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function
Ронни Ройстон
источник
3

Я не уверен, что конкретно не так с вашим кодом, но я использую эту функцию, которую нашел в Интернете (URL-адрес в комментариях), чтобы проверить, существует ли файл:

Private Function File_Exists(ByVal sPathName As String, Optional Directory As Boolean) As Boolean
    'Code from internet: http://vbadud.blogspot.com/2007/04/vba-function-to-check-file-existence.html
    'Returns True if the passed sPathName exist
    'Otherwise returns False
    On Error Resume Next
    If sPathName <> "" Then

        If IsMissing(Directory) Or Directory = False Then

            File_Exists = (Dir$(sPathName) <> "")
        Else

            File_Exists = (Dir$(sPathName, vbDirectory) <> "")
        End If

    End If
End Function
Дэн
источник
1
Это вернет true, если вы укажете путь и не знаете, каталог это или нет. Если вы хотите проверить, является ли путь только файлом, это не сработает на 100%. ? dir$("C:\Users\Chloe\AppData\Local\Temp\")даст первый файл в этом каталоге, и он не будет равен "", поэтому он вернет истину, даже если вы оставите Directoryаргумент выключенным или установите для него значение false.
Хлоя
@Chloe Я предполагаю, что вы укажете расширение файла вместе с именем файла, поэтому двусмысленность каталога на самом деле не применима в этом случае. Но конечно, он мог быть более надежным. Это просто зависит от того, насколько глубокий раствор вам нужен. Но это, безусловно, работает для случая, указанного ОП
Дэн
1

Очень старый пост, но поскольку он помог мне после внесения некоторых изменений, я подумал, что поделюсь. Если вы проверяете, существует ли каталог, вам нужно добавить аргумент vbDirectory к функции Dir, иначе вы будете возвращаться 0каждый раз. (Изменить: это было ответом на ответ Роя, но я случайно сделал это обычным ответом.)

Private Function FileExists(fullFileName As String) As Boolean
    FileExists = Len(Dir(fullFileName, vbDirectory)) > 0
End Function
Word Nerd
источник
1

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

  • Len(Dir(path)) > 0 or Or Len(Dir(path, vbDirectory)) > 0  'version 1 - ... <> "" should be more inefficient generally
    
    • (просто Len(Dir(path))не работало для каталогов (Excel 2010 / Win7))
  • CreateObject("Scripting.FileSystemObject").FileExists(path)  'version 2 - could be faster sometimes, but only works for files (tested on Excel 2010/Win7)
    

как PathExists(path)функция:

Public Function PathExists(path As String) As Boolean
    PathExists = Len(Dir(path)) > 0 Or Len(Dir(path, vbDirectory)) > 0
End Function
Андреас Ковидиот
источник