TL;DR —
Application.FileDialogabre el selector estándar de Windows para que el usuario elija un archivo o una carpeta en lugar de que usted escriba una ruta fija en el código. Elija un tipo:msoFileDialogFilePicker,msoFileDialogFolderPicker,msoFileDialogSaveAsomsoFileDialogOpen. Llame a.Show: devuelve-1si el usuario eligió algo y0si canceló, no la ruta. La ruta está en.SelectedItems(1), una colección basada en 1.FileDialogle da una ruta; abrirla o guardarla sigue corriendo de su cuenta.
Sub PickAFile()
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Title = "Choose a workbook"
.AllowMultiSelect = False
.Filters.Clear
.Filters.Add "Excel Files", "*.xlsx;*.xlsm"
If .Show <> -1 Then Exit Sub ' -1 = elegido, 0 = cancelado
MsgBox "You picked: " & .SelectedItems(1) ' coleccion basada en 1
End With
End Sub
Escribir a mano "C:\Users\Me\Reports\Jan.xlsx" dentro de una macro es la forma más rápida de que deje de
funcionar en cuanto la ejecute otra persona. La costumbre profesional es preguntar. VBA le ofrece tres
herramientas para eso, y conviene tener clara desde el principio la idea que comparten las tres: estas
herramientas devuelven una cadena de ruta; no abren, guardan ni tocan ningún archivo. Obtener la ruta y
actuar sobre ella son dos pasos distintos. FileDialog es la más completa de las tres porque es la única
que también puede pedir una carpeta.
Lo que aprenderá
- El modelo mental que conecta
FileDialog,GetOpenFilenameyGetSaveAsFilename - Los cuatro tipos de cuadro de diálogo y para qué sirve cada uno
- Por qué
.Showdevuelve-1y0en lugar deTrue/False, y cómo comprobarlo - Cómo leer el resultado de
.SelectedItems, una colección basada en 1 - Cómo elegir una carpeta con
FolderPicker, algo que las funciones más sencillas no pueden hacer - Cómo permitir la selección múltiple, añadir filtros y la trampa del reinicio del objeto compartido
El modelo mental: un selector configurable que se lee después
Application.FileDialog no es una función que devuelve una ruta. Es un objeto que se configura, se
muestra y luego se lee. El flujo siempre sigue los mismos tres pasos:
Set fd = Application.FileDialog(msoFileDialogFilePicker) ' 1. elegir el TIPO
' ... configurar .Title, .Filters, .AllowMultiSelect ... ' 2. configurarlo
If fd.Show = -1 Then answer = fd.SelectedItems(1) ' 3. mostrar y luego leer la eleccion
.Show bloquea la ejecución hasta que el usuario hace clic en un botón y devuelve un estado, no la ruta.
La ruta —o las rutas— aparecen en .SelectedItems. Mantenga separadas esas dos ideas y todo el objeto
cobra sentido: mostrar el cuadro de diálogo y leer la elección son líneas distintas. Todo lo demás en esta
página es qué tipo elegir y cómo leer el resultado.
Los cuatro tipos de cuadro de diálogo
El cometido del cuadro de diálogo se elige mediante la constante que se pasa a Application.FileDialog(...):
Application.FileDialog(msoFileDialogFilePicker) ' elegir uno o varios archivos existentes
Application.FileDialog(msoFileDialogFolderPicker) ' elegir una carpeta (ningun archivo)
Application.FileDialog(msoFileDialogOpen) ' como FilePicker, mas un .Execute que abre
Application.FileDialog(msoFileDialogSaveAs) ' elegir una ruta y un nombre para guardar
Para el 90 % de las macros querrá msoFileDialogFilePicker (obtener un archivo para leer) o
msoFileDialogFolderPicker (obtener una carpeta para recorrerla). Los tipos Open y SaveAs incluyen un
método .Execute adicional que realmente ejecuta la apertura o el guardado, pero rara vez lo necesitará:
leer la ruta y llamar usted mismo a Workbooks.Open o
SaveAs es más claro y le da control sobre lo que ocurre después.
Por qué .Show devuelve -1 y 0
Este es el detalle que hace tropezar a quienes esperan que .Show devuelva la ruta elegida. Lo que
devuelve es un estado entero:
If fd.Show = -1 Then
' el usuario hizo clic en OK / Open / Save: existe una seleccion
Else
' el usuario hizo clic en Cancel: .SelectedItems esta vacio, NO lo lea
End If
-1 significa que se hizo una elección; 0 significa que el usuario canceló. Da la casualidad de que -1
es lo que VBA llama True, así que tanto If fd.Show = -1 como If fd.Show funcionan; pero escriba
= -1, porque expresa lo que el número significa. La mitad importante es el Else: si el usuario
canceló, .SelectedItems está vacío y SelectedItems(1) lanza un error en tiempo de ejecución. Controle
siempre la cancelación antes de leer.
Leer el resultado: SelectedItems empieza en 1
La elección del usuario es una colección, .SelectedItems, y como toda colección de VBA cuenta desde
1, no desde 0:
If fd.Show = -1 Then
Dim i As Long
For i = 1 To fd.SelectedItems.Count ' las colecciones empiezan en 1
Debug.Print fd.SelectedItems(i) ' cada elemento es una cadena de ruta completa
Next i
End If
Para elegir un solo archivo, .SelectedItems(1) es todo lo que necesita. El bucle For i = 1 To .Count
solo importa cuando activa la selección múltiple, y empezar ese bucle en 0 es el clásico error por uno
que lanza «Subscript out of range». Cada elemento es una ruta completa que puede pasar directamente a
Workbooks.Open, Dir o un
FileSystemObject.
Elegir una carpeta — lo que solo FileDialog puede hacer
Esta es la razón por la que FileDialog se gana su lugar junto a las funciones más sencillas:
GetOpenFilename solo puede devolver un archivo. Cuando necesita una
carpeta —por ejemplo, para recorrer todos los libros que contiene— FolderPicker es la herramienta:
Sub PickAFolder()
Dim fd As FileDialog, folderPath As String
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
If fd.Show <> -1 Then Exit Sub
folderPath = fd.SelectedItems(1)
If Right(folderPath, 1) <> "\" Then folderPath = folderPath & "\" ' normalizar
MsgBox "Chosen folder: " & folderPath
End Sub
La carpeta se devuelve sin barra invertida final, así que si va a añadir un nombre de archivo
(folderPath & "Report.xlsx") agregue usted mismo la \: olvidarla es el error número uno en las macros
que recorren carpetas. A partir de ahí, Dir(folderPath & "*.xlsx") recorre todos los libros de la
carpeta.
Selección múltiple, filtros y la trampa del reinicio
Dos ajustes cubren casi todo lo demás. AllowMultiSelect = True permite al usuario elegir varios archivos,
que es justo cuando el bucle For i = 1 To .Count de arriba resulta útil. Los filtros restringen lo que
muestra el cuadro de diálogo:
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = True
.Filters.Clear ' REINICIE primero: vea mas abajo
.Filters.Add "Spreadsheets", "*.xlsx;*.xlsm;*.xls"
.Filters.Add "All Files", "*.*"
If .Show = -1 Then MsgBox .SelectedItems.Count & " file(s) chosen"
End With
La trampa que merece un nombre: Application.FileDialog es un único objeto compartido. Los filtros y
ajustes de una llamada anterior pueden seguir ahí. Llame siempre a .Filters.Clear antes de añadir los
suyos y establezca .AllowMultiSelect de forma explícita cada vez, o un ajuste residual de un momento
anterior de la sesión se colará en su cuadro de diálogo. Tratar el objeto como si estuviera recién creado
cuando en realidad está compartido es un error silencioso y difícil de reproducir.
¿FileDialog o GetOpenFilename? Elija según lo que necesite recuperar
Si necesita una carpeta, o quiere el cuadro de diálogo más completo (selección múltiple más filtros
detallados), FileDialog es la respuesta. Si solo necesita la ruta de un archivo para leer,
GetOpenFilename es una sola línea y devuelve la ruta directamente: sin
objeto, sin .SelectedItems. Si necesita una ruta para guardar, esa es
GetSaveAsFilename. Las tres obedecen la misma regla: le dan una ruta, y
abrirla o guardarla sigue siendo la siguiente línea que usted escribe.
Cómo ayuda ExcelMaster
Los dos errores de esta página son silenciosos: leer .SelectedItems después de que el usuario canceló (un
error en tiempo de ejecución) y olvidar la barra invertida final al construir una ruta a partir de una
carpeta elegida (un archivo escrito en el lugar equivocado). Ambos son fáciles de escribir y molestos de
rastrear.
ExcelMaster le permite describir el
paso con palabras corrientes —«déjame elegir una carpeta y luego abrir todos los libros que contiene»— y
escribe el código de FileDialog que controla la cancelación, normaliza la ruta y recorre los archivos
correctamente. Usted se queda con el libro y con el código, y se ahorra el error por uno.
Preguntas frecuentes
¿Cómo abro un cuadro de diálogo de archivo en Excel VBA?
Cree el objeto con Set fd = Application.FileDialog(msoFileDialogFilePicker), configúrelo (.Title,
.Filters, .AllowMultiSelect) y luego llame a fd.Show. .Show devuelve -1 si el usuario eligió algo
y 0 si canceló. Lea la ruta elegida en fd.SelectedItems(1). Tenga en cuenta que esto solo devuelve la
ruta: sigue teniendo que llamar a Workbooks.Open para abrirlo.
¿Cómo permito que el usuario seleccione una carpeta en VBA?
Use Application.FileDialog(msoFileDialogFolderPicker). Es el único cuadro de diálogo de archivo que
devuelve una carpeta en lugar de un archivo: GetOpenFilename no puede
hacerlo. Tras If fd.Show = -1 Then, lea fd.SelectedItems(1) para obtener la ruta de la carpeta, y añada
una barra invertida antes de agregar un nombre de archivo, porque la carpeta se devuelve sin barra
invertida final.
¿Por qué FileDialog.Show devuelve -1 en lugar de la ruta del archivo?
Porque .Show devuelve un estado, no la ruta: -1 significa que el usuario hizo una selección y 0
significa que canceló. La ruta seleccionada (o las rutas) se encuentran en la colección .SelectedItems.
Compruebe primero If fd.Show = -1 Then y lea .SelectedItems(1) solo cuando sea -1, porque tras una
cancelación esa colección está vacía y acceder a ella por índice lanza un error.
¿Cómo selecciono varios archivos con FileDialog?
Establezca .AllowMultiSelect = True antes de llamar a .Show. Cuando el usuario elige varios archivos,
recorra For i = 1 To fd.SelectedItems.Count y lea cada ruta con fd.SelectedItems(i). La colección está
basada en 1, así que empiece el bucle en 1, no en 0: empezar en 0 lanza «Subscript out of range».
¿Cuál es la diferencia entre FileDialog y GetOpenFilename?
GetOpenFilename es una función de una sola línea que devuelve una cadena
con la ruta del archivo (o False al cancelar); es lo más sencillo cuando solo necesita un archivo para
leer. FileDialog es un objeto configurable que además puede elegir carpetas, ofrecer una selección
múltiple más rica y (mediante .Execute) abrir o guardar directamente. Use GetOpenFilename para el caso
común y FileDialog cuando necesite una carpeta o el control adicional.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 26/09/2026.
Guías relacionadas: VBA GetOpenFilename · VBA GetSaveAsFilename · VBA Open Workbook · VBA Dir · VBA FileSystemObject · VBA For Each
