TL;DR — Dos formas correctas, una para cada juego de herramientas.
Dires el one-liner cuando no estás ni cerca de un bucleDir;FileSystemObject.FileExistses el valor por defecto seguro porque no tiene estado oculto:
' Built-in, una linea - pero comparte el unico cursor global de Dir:
If Dir("C:\Reports\March.xlsx") <> "" Then MsgBox "It's there"
' Sin estado, mas claro, distingue archivo de carpeta - el valor por defecto mas seguro:
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists("C:\Reports\March.xlsx") Then MsgBox "It's there"
«¿Existe este archivo?» es la pregunta sobre archivos más buscada en VBA, porque la alternativa — abrir un
archivo que no está ahí — lanza el error 1004 en tiempo de ejecución y detiene en seco una macro
desatendida. La buena noticia es que la comprobación es un one-liner. La trampa es que el one-liner obvio,
Dir, arrastra el mismo cursor oculto que impulsa un bucle Dir — así que dónde lo
llamas importa tanto como cómo.
Lo que aprenderás
- El reflejo equivocado — «simplemente ábrelo y atrapa el error» — y por qué es la peor opción
- Las dos respuestas correctas —
DiryFileSystemObject.FileExists - La trampa que define este tema — la comprobación con
Dirreinicia un bucleDir - Cómo
Dirmaneja mal una ruta de carpeta o una barra invertida final FileExistsfrente aFolderExists— di exactamente lo que quieres decir- Por qué «comprobar y luego abrir» todavía necesita una protección de errores (la pequeña carrera, y el arreglo práctico)
El reflejo equivocado: abrirlo y atrapar el error
El atajo tentador es saltarse la comprobación por completo y dejar que el fallo te lo diga:
On Error Resume Next
Set wb = Workbooks.Open(path) ' si no esta, salta el 1004 y se lo traga
On Error GoTo 0
If wb Is Nothing Then MsgBox "Not found"
Esto funciona, pero es la peor de las tres opciones. Es lento (Excel de verdad intenta abrir el archivo),
se traga errores no relacionados — un archivo corrupto, un problema de permisos, un archivo bloqueado,
todos parecen idénticos a «no existe» — y se apoya en On Error Resume Next, que
esconde bugs cuando se deja encendido. Comprobar la existencia es barato y preciso; renunciar a ello para
apoyarte en un manejador de errores cambia una respuesta limpia por una turbia. Comprueba primero.
Las dos respuestas correctas
Dir — el one-liner del built-in. Sin comodín, Dir simplemente comprueba una ruta y devuelve el nombre
del archivo si está ahí o "" si no:
If Dir("C:\Reports\March.xlsx") <> "" Then ' "" significa no encontrado
Corto, sin referencias, sin objeto. Su única desventaja es el cursor compartido (siguiente sección).
FileSystemObject.FileExists — el valor por defecto sin estado. Un predicado de verdad que devuelve
True/False y no toca ningún estado global:
Dim fso As Object: Set fso = CreateObject("Scripting.FileSystemObject")
If fso.FileExists("C:\Reports\March.xlsx") Then ...
Se lee como lo que hace, distingue archivos de carpetas y — la razón por la que es el valor por defecto más
seguro — puedes llamarlo en cualquier sitio, incluso en mitad de un bucle Dir, sin
efectos secundarios. Usa enlace tardío (CreateObject) para que corra en cualquier máquina; ver
VBA FileSystemObject.
La trampa que define este tema: comprobación con Dir dentro de un bucle Dir
Esta es la razón por la que las dos comprobaciones no son intercambiables, y es el mismo comportamiento de
cursor oculto que gobierna Dir. Dir mantiene una sola posición de búsqueda a nivel
de módulo. Llamar a Dir(path) para comprobar un archivo inicia una búsqueda nueva — borrando la posición
de la que dependía tu bucle de enumeración:
name = Dir(folder & "*.xlsx")
Do While name <> ""
If Dir(folder & "done\" & name) = "" Then ' <- reinicia el cursor - el bucle se rompe
Process folder & name
End If
name = Dir() ' ahora avanza la busqueda de "done\", no la de *.xlsx
Loop
El Dir interno vuelve a sembrar el motor, así que el bucle se salta archivos, los repite o no termina nunca.
La regla es absoluta: dentro de un bucle Dir, nunca llames a Dir para comprobar otro archivo — usa
fso.FileExists en su lugar. No tiene ningún cursor que perturbar. Esta única interacción es la razón por
la que «¿qué comprobación de existencia?» no es cuestión de gustos: si hay una enumeración Dir en cualquier
punto de la ruta de llamadas, la respuesta es FileExists.
Cómo Dir maneja mal las carpetas y las barras invertidas finales
Incluso fuera de un bucle, Dir tiene dos casos límite que FileExists evita, porque Dir se construyó
para coincidir con nombres, no para responder un sí/no limpio sobre un archivo:
- Una ruta de carpeta.
Dir("C:\Reports")puede devolver"Reports"— coincidiendo con la carpeta — así que una prueba de «el archivo existe» pasa para algo que es un directorio.fso.FileExists("C:\Reports")devuelve correctamenteFalse(es una carpeta), yfso.FolderExistsresponde la pregunta de la carpeta por separado. - Una barra invertida final.
Dir("C:\Reports\")comprueba la existencia de la carpeta, no de un archivo dentro de ella. Fácil de encontrártelo cuando construyes rutas por concatenación y dejas un separador perdido.
Por defecto Dir también se salta los archivos ocultos y de sistema, así que un archivo que existe de verdad
pero está oculto se informa como ausente a menos que pases el atributo vbHidden. FileExists no tiene
ninguna de estas ambigüedades — responde «hay un archivo exactamente en esta ruta», y punto.
Comprobar y luego abrir: la pequeña carrera, el arreglo práctico
Una advertencia honesta: entre el instante en que compruebas y el instante en que abres, otro proceso podría borrar o bloquear el archivo. En la práctica esta brecha de «tiempo de comprobación frente a tiempo de uso» es diminuta y rara vez importa — pero el patrón correcto no es elegir entre la comprobación y la protección de errores, es usar ambas:
If Not fso.FileExists(path) Then
MsgBox "File not found: " & path ' el caso esperado y comun - un mensaje limpio
Exit Sub
End If
On Error GoTo OpenFailed ' el caso raro - bloqueado, corrupto, permisos
Set wb = Workbooks.Open(path)
La comprobación de existencia maneja el caso ordinario de «no está ahí» con un mensaje claro en lugar de una
caída; el manejador de errores atrapa los fallos genuinamente excepcionales que la
comprobación no puede predecir. Esa es la forma robusta para cualquier
Workbooks.Open en un trabajo automatizado.
Relacionado: ¿el libro ya está abierto?
Un primo cercano de «¿existe el archivo?» es «¿ya está abierto en Excel?», y es una pregunta distinta con
una respuesta distinta — recorrer Workbooks por nombre, sin tocar el disco:
Function IsOpen(fileName As String) As Boolean
Dim wb As Workbook
On Error Resume Next
Set wb = Workbooks(fileName) ' por nombre de archivo, p.ej. "March.xlsx"
On Error GoTo 0
IsOpen = Not wb Is Nothing
End Function
La existencia es sobre el disco; «ya abierto» es sobre la colección Workbooks en memoria. Abrir un archivo
que ya está abierto no lo recarga — Excel simplemente activa la copia en memoria — así que una macro por lotes
que podría ejecutarse dos veces debería comprobar esto antes de llamar a
Workbooks.Open.
El veredicto honesto: qué comprobación, cuándo
- Por defecto,
fso.FileExists. No tiene estado, se lee con claridad, distingue el archivo de la carpeta y — el punto decisivo — es la única comprobación segura si hay un bucleDiren juego. - Usa el one-liner de
Dirsolo para una prueba rápida y aislada donde no haya ninguna enumeraciónDiren marcha y quieras cero preparación. - Nunca sustituyas la comprobación por un abrir-y-atrapar a secas; es más lento y esconde errores de verdad.
- Empareja la comprobación con una protección de errores alrededor de la apertura — la comprobación para el caso común, el manejador para el raro.
Acierta con esto y el fallo de archivo número uno — un 1004 sobre una ruta que no está ahí — se convierte en un mensaje limpio de una línea que tu macro desatendida puede registrar y superar.
Cómo ayuda ExcelMaster
La comprobación de existencia parece trivial hasta que llegas a las partes que no lo son — el cursor de Dir
que una comprobación perdida reinicia, la ruta de carpeta con la que una prueba de archivo coincide por error,
la carrera que significa que todavía necesitas una protección de errores. Acertar con todo ello para cada
archivo que toca una macro por lotes es un montón de fontanería cuidadosa.
ExcelMaster se encarga.
Describe el trabajo — «para cada informe esperado, si el archivo está ahí impórtalo, si no regístralo como
ausente y sigue» — y escribe comprobaciones con fso.FileExists que nunca perturban tu
bucle de carpeta, empareja cada Workbooks.Open con un
manejador de errores, y comprueba si un libro ya está abierto antes de reabrirlo. Tú
describes el resultado; él hace las comprobaciones correctas y sin efectos secundarios.
Preguntas frecuentes
¿Cómo compruebo si un archivo existe en VBA?
Dos buenas formas. El one-liner del built-in es If Dir("C:\path\file.xlsx") <> "" Then — Dir devuelve el
nombre si el archivo existe y "" si no. La forma más clara y sin estado es
CreateObject("Scripting.FileSystemObject").FileExists(path), que devuelve True/False y puede llamarse en
cualquier sitio. Prefiere FileExists, y nunca compruebes con Dir dentro de un
bucle Dir.
¿Por qué mi comprobación de archivo con Dir rompe mi bucle Dir?
Porque Dir mantiene un único cursor de búsqueda oculto. Llamar a Dir(otraRuta) para comprobar un archivo
inicia una búsqueda nueva y borra la posición de la que depende tu bucle de enumeración, así que el bucle se
salta archivos, los repite o corre para siempre. Dentro de un bucle Dir, usa fso.FileExists para comprobar
otros archivos — no tiene estado compartido.
¿Debo usar Dir o FileSystemObject para comprobar que un archivo existe?
Usa FileSystemObject.FileExists como valor por defecto — no tiene estado, distingue archivos de carpetas, y
es seguro de llamar dentro de un bucle Dir. Usa el one-liner de Dir solo para una comprobación rápida y
aislada donde no haya ninguna enumeración Dir en marcha y no quieras preparación. Ver
VBA FileSystemObject.
¿Dir devuelve verdadero para una carpeta?
Puede. Dir("C:\Reports") puede devolver "Reports", coincidiendo con la carpeta, así que una prueba ingenua
de «el archivo existe» pasa para un directorio. Y Dir("C:\Reports\") con una barra invertida final comprueba
la carpeta, no un archivo dentro de ella. FileSystemObject.FileExists evita ambos respondiendo estrictamente
sobre un archivo, con FolderExists para la pregunta de la carpeta.
¿Cómo compruebo si un libro ya está abierto en VBA?
Esa es una pregunta distinta — es sobre memoria, no sobre disco. Recorre la colección Workbooks por nombre
de archivo: Set wb = Workbooks("March.xlsx") dentro de un bloque On Error Resume Next, luego comprueba
Not wb Is Nothing. Abrir un archivo que ya está abierto no lo recarga, así que una macro que podría
ejecutarse dos veces debería comprobar esto antes de llamar a Workbooks.Open.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 21/08/2026.
Guías relacionadas: VBA Dir · VBA FileSystemObject · VBA Open Workbook · VBA On Error · VBA Close Workbook
