🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA FileDialog en Excel — FilePicker, FolderPicker y lectura de .SelectedItems

|

VBA FileDialog en Excel — FilePicker, FolderPicker y lectura de .SelectedItems

TL;DR — Application.FileDialog abre 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, msoFileDialogSaveAs o msoFileDialogOpen. Llame a .Show: devuelve -1 si el usuario eligió algo y 0 si canceló, no la ruta. La ruta está en .SelectedItems(1), una colección basada en 1. FileDialog le 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, GetOpenFilename y GetSaveAsFilename
  • Los cuatro tipos de cuadro de diálogo y para qué sirve cada uno
  • Por qué .Show devuelve -1 y 0 en lugar de True/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.

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