Sprawdź, czy plik istnieje, używając 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

W tym przypadku, gdy pobieram wartość tekstową z pola wprowadzania, to nie działa. Jeśli jednak usuniesz "the sentence"z If Dir()i zastąpisz to rzeczywistą nazwą w kodzie, zadziała. Czy ktoś może pomóc?

Dinesh Goel
źródło

Odpowiedzi:

142

Zwróć uwagę, że kod zawiera to, Dir("thesentence")co powinno być Dir(thesentence).

Zmień swój kod na ten

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
źródło
1
Pomogło mi to częściowo. Myślę, że kiedy używam tego kompilatora kodu, nie traktuję "thesentence" jako katalogu, więc użyłem tylko jednej linii kodu więcej przed If: <code> Dim Path as String Dim Directory as String Path = InitialPath & "\" & Date $ Directory = Dir (Path, vbDirectory) </code> kiedy użyłem ciągu zmiennej ** Directory ** w obszarze If Dir (Directory) <> "" to działało dobrze
muhammad tayyab
19

Użyj FileDialogobiektu Office, aby użytkownik wybrał plik z systemu plików. Dodaj odniesienie do projektu VB lub w edytorze VBA Microsoft Office Libraryi zajrzyj do pomocy. Jest to o wiele lepsze niż wprowadzanie ludzi pełnymi ścieżkami.

Oto przykład użycia, msoFileDialogFilePickeraby umożliwić użytkownikowi wybór wielu plików. Możesz również użyć 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

Istnieje wiele opcji, więc aby zrozumieć wszystko, co jest możliwe, musisz zapoznać się z pełnymi plikami pomocy. Możesz zacząć od obiektu FileDialog pakietu Office 2007 (oczywiście musisz znaleźć właściwą pomoc dla używanej wersji).

ErikE
źródło
1
+1 Dużo lepiej, ponieważ jest to Excel Application.FileDialog (msoFileDialogOpen)
Alex
18

Korekta pliku istnieje z @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

EDYCJA: wersja skrócona

' 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
źródło
2
Dlaczego kod wielokrotnie testuje tę samą nazwę pliku (raz dla każdego pliku w katalogu s_directory)? Nie ma sensu powtarzać tego testu. Zauważysz, że zmienna pętli (obj_file) nie jest używana przez kod pętli.
grantnz
1
@grantnz Rzeczywiście! Zrobiłem leniwe kopiowanie / wklejanie i modyfikowałem, aż zadziałało. Wersja skrócona znajduje się powyżej. Dzięki.
amackay11
Czy ktoś zauważył, że czasami ten test zgłasza fałszywie dodatni wynik, tj. Zwraca „Prawda”, nawet jeśli plik nie istnieje w systemie plików. W mojej aplikacji sprawdzam istnienie pliku na serwerze w mojej sieci, jeśli to daje wskazówkę.
pablete
6

po prostu pozbądź się tych znaków mowy

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

To jest ten, który mi się podoba:

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
whytheq
źródło
3
Nigdy wcześniej nie słyszałem o „znakach mowy”. Dziwne. Moim zdaniem trochę błędna nazwa. Wiele rzeczy wymaga cytatów, ale nie jest to mowa.
ErikE,
4
@ErikE +1 za miłą obserwację ... Zdjęcia tutaj
whytheq
1
Najwyraźniej „znaki mowy” to nieformalna wersja „cudzysłowów”.
ErikE,
@ErikE ... Wiem, a raczej powiedziałem „Wiem”
dlaczego
6
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function

Działa bardzo dobrze, prawie na mojej stronie. Jeśli zadzwonię z „” pustym ciągiem znaków, Dir zwróci „ connection.odc ” !! Byłoby wspaniale, gdybyście podzielili się swoim wynikiem.

W każdym razie podoba mi się to:

Function FileExists(fullFileName As String) As Boolean
  If fullFileName = "" Then
    FileExists = False
  Else
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
  End If
End Function
Joachim Brolin
źródło
1
Stary post, ale wygląda na to, że dir("")podaje nazwę pierwszego pliku w bieżącym katalogu. W twoim przypadku był to plik o nazwie connection.odc.
Corey
4
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function
Ronnie Royston
źródło
3

Nie jestem pewien, co jest nie tak z twoim kodem, ale używam tej funkcji, którą znalazłem online (adres URL w komentarzach), aby sprawdzić, czy plik istnieje:

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
Dan
źródło
1
To zwróci true, jeśli podasz ścieżkę i nie wiesz, czy jest to katalog, czy nie. Jeśli chcesz sprawdzić, czy ścieżka jest tylko plikiem, nie zadziała to w 100%. ? dir$("C:\Users\Chloe\AppData\Local\Temp\")poda pierwszy plik w tym katalogu i nie będzie równy "", dlatego zwróci wartość true, nawet jeśli pozostawisz Directoryargument wyłączony lub ustawisz go na fałsz.
Chloe,
@Chloe Myślę, że zakłada się, że określisz rozszerzenie pliku wraz z nazwą pliku, więc niejednoznaczność bycia katalogiem nie ma w tym przypadku zastosowania. Ale jasne, mogłoby być solidniejsze. Zależy to tylko od tego, jak głębokiego rozwiązania potrzebujesz. Ale z pewnością działa w przypadku określonym przez PO
Dan,
1

Bardzo stary post, ale ponieważ pomógł mi po wprowadzeniu pewnych modyfikacji, pomyślałem, że się nim podzielę. Jeśli sprawdzasz, czy katalog istnieje, będziesz chciał dodać argument vbDirectory do funkcji Dir, w przeciwnym razie będziesz zwracać za 0każdym razem. (Edycja: to była odpowiedź na odpowiedź Roya, ale przypadkowo uczyniłem to zwykłą odpowiedzią.)

Private Function FileExists(fullFileName As String) As Boolean
    FileExists = Len(Dir(fullFileName, vbDirectory)) > 0
End Function
Word Nerd
źródło
1

w oparciu o inne odpowiedzi tutaj, chciałbym podzielić się moimi jednowierszowymi, które powinny działać dla katalogów i plików :

  • Len(Dir(path)) > 0 or Or Len(Dir(path, vbDirectory)) > 0  'version 1 - ... <> "" should be more inefficient generally
    
    • (po prostu Len(Dir(path))nie działa dla katalogów (Excel 2010 / Win7))
  • CreateObject("Scripting.FileSystemObject").FileExists(path)  'version 2 - could be faster sometimes, but only works for files (tested on Excel 2010/Win7)
    

jako PathExists(path)funkcja:

Public Function PathExists(path As String) As Boolean
    PathExists = Len(Dir(path)) > 0 Or Len(Dir(path, vbDirectory)) > 0
End Function
Andreas Covidiot
źródło