TL;DR —
Application.GetOpenFilenamemuestra el cuadro de diálogo Abrir y devuelve la ruta que el usuario eligió como cadena de texto; no abre el archivo. Para abrirlo de verdad sigue teniendo que llamar aWorkbooks.Open. Cuando el usuario hace clic en Cancelar, devuelve el valor booleanoFalse, así que declare la variableAs Variant(nuncaAs String) y compruebeIf fname = False Then Exit Subantes de usarla.
Sub AskThenOpen()
Dim fname As Variant ' Variant, para que la cancelacion pueda devolver False
fname = Application.GetOpenFilename( _
"Excel Files (*.xlsx;*.xlsm), *.xlsx;*.xlsm", , "Choose a workbook")
If fname = False Then Exit Sub ' el usuario cancelo
Workbooks.Open fname ' GetOpenFilename solo dio la ruta
End Sub
GetOpenFilename es la forma más corta de dejar de escribir rutas fijas en el código. Muestra el conocido
cuadro de diálogo Abrir, deja que el usuario navegue y le devuelve lo que eligió. Pero dos hechos sobre esta
función provocan la mayoría de las preguntas en internet, y ambos nacen del mismo malentendido: esta
función devuelve una ruta; no abre el archivo y no falla de forma escandalosa cuando el usuario cancela.
Tenga claros esos dos puntos y se convertirá en una línea única a la que recurrirá constantemente.
Lo que aprenderá
- El modelo mental que conecta
GetOpenFilename,GetSaveAsFilenameyFileDialog - Por qué devuelve una ruta, no un libro abierto, y la línea que aún le queda por escribir
- La trampa de la cancelación: devuelve
False, así que la variable debe serAs Variant - La sintaxis de
FileFilter, con varias extensiones y varios grupos de filtros - Cómo devolver varias rutas a la vez con
MultiSelect:=True(una matriz basada en 1) - Cuándo basta con
GetOpenFilenamey cuándo dar el paso aFileDialog
El modelo mental: una nota adhesiva que dice «¿qué archivo?»
Piense en GetOpenFilename como si le entregara al usuario una nota adhesiva que pregunta «¿qué archivo?»:
él anota una ruta y se la devuelve. Eso es todo lo que hace. No va hasta el archivador a sacar el archivo:
fname = Application.GetOpenFilename(...) ' devuelve una cadena de RUTA, p. ej. "C:\Data\Jan.xlsx"
Workbooks.Open fname ' USTED se encarga de abrirlo
El informe más habitual de «GetOpenFilename no funciona» en realidad es «lo llamé y mi archivo no se abrió». Claro que no se abrió: obtuvo la ruta; abrirla es una línea aparte. Una vez que interiorice que pedir una ruta y actuar sobre la ruta son dos pasos, la función se vuelve sencilla y predecible.
La trampa de la cancelación: devuelve False, así que Dim As Variant
Esta es la que más duele. Cuando el usuario hace clic en Cancelar, GetOpenFilename devuelve el valor
booleano False. Eso le obliga a tomar una decisión al declarar la variable:
Dim fname As Variant ' CORRECTO: puede contener una ruta String O el booleano False
' Dim fname As String ' INCORRECTO: False se convierte al texto "False"
Si declara fname As String, VBA convierte discretamente el False devuelto en la cadena "False", de
modo que If fname = False nunca se activa y su código sigue adelante con una «ruta» basura llamada
False. Declararla As Variant mantiene el booleano como booleano, así que If fname = False Then Exit Sub
sí captura la cancelación. Es exactamente la misma trampa que leer un InputBox
cancelado: la solución es la misma: guarde el resultado en un Variant y compruebe el tipo de respuesta que
obtuvo antes de fiarse de ella.
El FileFilter: descripción, coma, patrón
El primer argumento controla qué archivos muestra el cuadro de diálogo. Su forma es una descripción, una coma y luego el patrón, y puede encadenar varios grupos:
' Un grupo: etiqueta y luego el patron (o los patrones)
fname = Application.GetOpenFilename("Text Files (*.txt), *.txt")
' Varias extensiones en un grupo: separe los patrones con punto y coma
fname = Application.GetOpenFilename("Excel Files (*.xlsx;*.xlsm), *.xlsx;*.xlsm")
' Varios grupos entre los que el usuario puede alternar: separe con comas los pares etiqueta/patron
fname = Application.GetOpenFilename( _
"Excel Files, *.xlsx;*.xlsm, CSV Files, *.csv, All Files, *.*")
Dentro de un mismo filtro, las distintas extensiones se unen con punto y coma (*.xlsx;*.xlsm). Para
ofrecer varios filtros entre los que el usuario pueda alternar en la lista desplegable, separe con
comas los pares etiqueta/patrón. El segundo argumento opcional, FilterIndex, elige qué grupo queda
seleccionado de forma predeterminada; el tercero, Title, establece el título del cuadro de diálogo.
Aplicar bien la regla de la coma frente al punto y coma es lo que separa un filtro que funciona de uno que
no muestra nada.
Varios archivos: MultiSelect devuelve una matriz basada en 1
Pase MultiSelect:=True y el tipo devuelto cambia: en lugar de una sola cadena de ruta obtiene una
matriz de rutas, o de nuevo False si el usuario canceló:
Sub OpenSeveral()
Dim files As Variant, i As Long
files = Application.GetOpenFilename( _
"Excel Files, *.xlsx;*.xlsm", , , , True) ' ultimo argumento = MultiSelect
If Not IsArray(files) Then Exit Sub ' False (cancelar) no es una matriz
For i = LBound(files) To UBound(files) ' la matriz empieza en 1
Workbooks.Open files(i)
Next i
End Sub
Dos detalles importan. Compruebe IsArray(files) en lugar de = False, porque cuando tiene éxito ahora
sostiene una matriz, no una cadena. Y recorra con LBound a UBound: la matriz que
devuelve GetOpenFilename empieza en 1, y aunque escribir directamente For i = 1 To ... funciona en
este caso, LBound/UBound es la costumbre que nunca falla. Cada elemento es una ruta completa lista para
Workbooks.Open.
¿GetOpenFilename o FileDialog? Elija según lo que necesite
Para la tarea del día a día —pedir un archivo para leer— GetOpenFilename gana en sencillez: una línea,
la ruta vuelve directamente, sin ningún objeto que configurar. Dé el paso a
FileDialog cuando necesite una carpeta (GetOpenFilename no puede elegir
una), cuando quiera el control más rico del objeto de diálogo o cuando prefiera leer desde .SelectedItems.
Para preguntar dónde guardar en vez de qué abrir, la función espejo es
GetSaveAsFilename. Las tres comparten la regla: devuelven una ruta, y
abrirla o guardarla es la siguiente línea que usted escribe.
Cómo ayuda ExcelMaster
Los dos errores aquí son del tipo silencioso: declarar el resultado As String (de modo que la cancelación
se cuela como el texto "False") y esperar que el archivo se abra cuando lo único que recibió fue una ruta.
Ambos compilan sin problemas y fallan en tiempo de ejecución en la máquina de otra persona.
ExcelMaster le permite decir lo
que quiere —«pídeme un CSV y luego impórtalo en una hoja nueva»— y escribe la llamada a GetOpenFilename
con el filtro correcto, la protección de cancelación con Variant y el Workbooks.Open (o la importación)
que de verdad actúa sobre la ruta. Usted se queda con el libro y con el código.
Preguntas frecuentes
¿Cómo uso GetOpenFilename en Excel VBA?
Llame a fname = Application.GetOpenFilename(fileFilter, filterIndex, title). Declare fname As Variant y
compruebe If fname = False Then Exit Sub para captar una cancelación. Si tiene éxito, fname contiene la
ruta elegida como cadena; pásela a Workbooks.Open para abrirla.
GetOpenFilename en sí solo devuelve la ruta; no abre nada.
¿Por qué GetOpenFilename no abre el archivo?
Porque no se supone que lo haga: devuelve la ruta que el usuario seleccionó y ahí se detiene. Abrir el
archivo es un paso aparte: Workbooks.Open fname para un libro, o un
FileSystemObject / Dir para otros archivos. El
cuadro de diálogo solo pregunta «¿qué archivo?»; actuar sobre la respuesta es cosa de su código.
¿Cómo compruebo si el usuario hizo clic en Cancelar en GetOpenFilename?
Declare la variable As Variant y compruebe If fname = False Then Exit Sub. Al cancelar, la función
devuelve el booleano False; si tiene éxito, devuelve una cadena de ruta. Si en cambio declara la variable
As String, False se convierte al texto "False", la comprobación nunca se dispara y la macro continúa
con una ruta no válida.
¿Cómo selecciono varios archivos con GetOpenFilename?
Pase MultiSelect:=True (el quinto argumento). El valor devuelto se convierte en una matriz de cadenas de
ruta, o en False si se cancela. Compruebe primero IsArray(result) y luego recorra
For i = LBound(result) To UBound(result) y abra cada result(i). Como el tipo devuelto cambia a una
matriz, no compruebe = False para la cancelación: use IsArray.
¿Cuál es la sintaxis de FileFilter en GetOpenFilename?
Cada filtro es una descripción seguida de una coma y un patrón: "Excel Files (*.xlsx), *.xlsx". Una varias
extensiones en un mismo filtro con punto y coma: "*.xlsx;*.xlsm". Ofrezca varios filtros separando con
comas los pares etiqueta/patrón: "Excel, *.xlsx, CSV, *.csv, All, *.*". El argumento opcional
FilterIndex establece cuál queda seleccionado de forma predeterminada.
Probado en
Probado en: Excel 365 (Windows 11), VBA 7.1 — última verificación el 26/09/2026.
Guías relacionadas: VBA FileDialog · VBA GetSaveAsFilename · VBA Open Workbook · VBA InputBox · VBA Dir · VBA UBound
