Verifique si el archivo existe usando 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

En esto, cuando recojo el valor de texto del cuadro de entrada, no funciona. Sin embargo, si lo elimina "the sentence"de If Dir()y lo reemplaza con un nombre real en el código, funciona. ¿Alguien puede ayudar?

Dinesh Goel
fuente

Respuestas:

142

Tenga en cuenta que su código contiene lo Dir("thesentence")que debería ser Dir(thesentence).

Cambie su código a este

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
fuente
1
Me ayudó parcialmente, creo que cuando uso este compilador de código no considera "thesentence" como un directorio, por lo que había usado solo una línea más de código antes If: <code> Dim Path as String Dim Directory as String Path = InitialPath & "\" & Date $ Directory = Dir (Path, vbDirectory) </code> cuando utilicé ** Directory ** variable string en If Dir (Directory) <> "" entonces funcionó bien
muhammad tayyab
19

Utilice el FileDialogobjeto de Office para que el usuario elija un archivo del sistema de archivos. Agregue una referencia en su proyecto VB o en el editor VBA Microsoft Office Libraryy busque en la ayuda. Esto es mucho mejor que hacer que las personas ingresen por caminos completos.

A continuación se muestra un ejemplo msoFileDialogFilePickerque permite al usuario elegir varios archivos. También puede utilizar 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

Hay muchas opciones, por lo que deberá ver los archivos de ayuda completos para comprender todo lo que es posible. Puede comenzar con el objeto FileDialog de Office 2007 (por supuesto, necesitará encontrar la ayuda correcta para la versión que está usando).

ErikE
fuente
1
+1 Mucho mejor, ya que esta es Excel Application.FileDialog (msoFileDialogOpen)
Alex K.
18

Corrección al archivo Existe de @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

EDITAR: versión abreviada

' 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
fuente
2
¿Por qué el código prueba el mismo nombre de archivo varias veces (una vez para cada archivo en s_directory)? No tiene sentido repetir esta prueba. Notará que el código de bucles no usa la variable de bucle (obj_file).
grantnz
1
@grantnz ¡De hecho! Había hecho el perezoso copiar / pegar y ajustar hasta que funcionó. La versión abreviada está arriba. Gracias.
amackay11
Alguien ha notado que a veces esta prueba reporta un falso positivo, es decir, devuelve ´Verdadero´ incluso cuando un archivo no existe en el sistema de archivos. En mi aplicación, verifico la existencia de un archivo en un servidor de mi red, si eso le da una pista.
pablete
6

solo deshazte de esas marcas de habla

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

Este es el que me gusta:

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
por qué
fuente
3
Nunca antes había oído hablar de "marcas de habla". Extraño. Es un nombre poco apropiado en mi opinión. Muchas cosas requieren comillas, pero no son palabras.
ErikE
4
@ErikE +1 para una buena observación ... Fotos aquí
whytheq
1
Aparentemente, las "marcas de habla" son una versión informal de las "comillas".
ErikE
@ErikE ... lo sé o más bien dije "lo sé"
whytheq
6
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function

Funciona muy bien, casi, en mi sitio. Si lo llamo con "" la cadena vacía, Dir devuelve " connection.odc " !! Sería genial si pudieran compartir su resultado.

De todos modos, me gusta esto:

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
fuente
1
Publicación anterior, pero parece que dir("")le da el nombre del primer archivo en el directorio actual. En su caso, fue un archivo llamado connection.odc.
Corey
4
Function FileExists(fullFileName As String) As Boolean
    FileExists = VBA.Len(VBA.Dir(fullFileName)) > 0
End Function
Ronnie Royston
fuente
3

No estoy seguro de qué está mal con su código específicamente, pero uso esta función que encontré en línea (URL en los comentarios) para verificar si existe un archivo:

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
fuente
1
Esto devolverá verdadero si proporciona una ruta y no sabe si es un directorio o no. Si desea probar si una ruta es solo un archivo, esto no funcionará al 100%. ? dir$("C:\Users\Chloe\AppData\Local\Temp\")dará el primer archivo en ese directorio, y no será igual a "", por lo tanto, devolverá verdadero incluso si deja el Directoryargumento desactivado o lo establece en falso.
Chloe
@Chloe Supongo que se supone que especificará una extensión de archivo junto con el nombre del archivo, por lo que la ambigüedad de ser un directorio no se aplica realmente en ese caso. Pero claro, podría ser más robusto. Solo depende de la profundidad de la solución que necesite. Pero ciertamente funciona para el caso especificado por el OP
Dan
1

Publicación muy antigua, pero como me ayudó después de que hice algunas modificaciones, pensé en compartir. Si está verificando si existe un directorio, querrá agregar el argumento vbDirectory a la función Dir; de lo contrario, regresará 0cada vez. (Editar: esto fue en respuesta a la respuesta de Roy, pero accidentalmente la convertí en una respuesta regular).

Private Function FileExists(fullFileName As String) As Boolean
    FileExists = Len(Dir(fullFileName, vbDirectory)) > 0
End Function
Nerd de la palabra
fuente
1

basado en otras respuestas aquí, me gustaría compartir mis frases breves que deberían funcionar para directorios y archivos :

  • Len(Dir(path)) > 0 or Or Len(Dir(path, vbDirectory)) > 0  'version 1 - ... <> "" should be more inefficient generally
    
    • (simplemente Len(Dir(path))no funcionó para directorios (Excel 2010 / Win7))
  • CreateObject("Scripting.FileSystemObject").FileExists(path)  'version 2 - could be faster sometimes, but only works for files (tested on Excel 2010/Win7)
    

como PathExists(path)función:

Public Function PathExists(path As String) As Boolean
    PathExists = Len(Dir(path)) > 0 Or Len(Dir(path, vbDirectory)) > 0
End Function
Andreas Dietrich
fuente