En el tutorial anterior hablé sobre uno de los objetos más importantes en la jerarquía del modelo de objetos de VBA: el objeto Workbook. Merece la pena seguir hablando de él, pues se utiliza constantemente (por lo menos yo lo hago) para asegurarme de que trabajo con los objetos adecuados.
Hoy trabajaremos con algunos ejemplos útiles del objeto Workbook
:
Asignar un objeto Workbook a una variable
Como abordé en tutoriales anteriores, es posible asignar un objeto a una variable y luego usar la variable para hacer referencia al objeto Workbook.
Por ejemplo, el siguiente código genera un libro nuevo y luego lo asigna a la variable wb
. Para ello es necesario usar la instrucción Set
.
Una vez se ha asignado el libro a la variable, todas las propiedades del libro están disponibles también en la variable.
Sub AsignarAVariable()
Dim wb As Workbook
Set wb = Workbooks.Add
wb.SaveAs Filename:="C:\Users\sergio\Desktop\Ejemplo.xlsx"
End Sub
Observa que en la primera línea se declara wb
como variable del tipo objeto. Esto le indica a VBA que esta variable puede contener un objeto de este tipo.
En la siguiente línea, se utiliza la instrucción Set
para asignar la variable al libro nuevo que se añade. Una vez hecha esta asignación, ya puedes usar la variable wb
para guardar el libro (o cualquier otra acción que quieras hacer con él).
Recorrer con un bucle los libros abiertos
En el anterior tutorial utilicé algunos ejemplos de código que utilizan bucles.
Existen diferentes formas de crear un bucle que recorra los libros abiertos en este momento. Supón que quieres guardar y cerrar todos los libros abiertos, excepto el que tiene el código. Para ello utiliza el siguiente procedimiento.
Sub CerrarGuardarLibros()
Dim wb As Workbook
For Each wb In Workbooks
If wb.Name <> ThisWorkbook.Name Then
wb.Close SaveChanges:=True
End If
Next wb
End Sub
El código anterior utiliza el bucle For Each-Next
para recorrer cada libro de trabajo de la colección Workbooks
. Para ello, primero hay que declarar wb
como variable de tipo objeto.
En cada vuelta (o ciclo) del bucle se analiza el nombre de un libro y, si no coincide con el que tiene el código, se cierra después de guardar su contenido.
Puedes obtener el mismo resultado con un bucle diferente como te muestro a continuación:
Sub CerrarGuardarLibros()
Dim wbCuenta As Integer
wbCuenta = Workbooks.Count
For i = wbCuenta To 1 Step -1
If Workbooks(i).Name <> ThisWorkbook.Name Then
Workbooks(i).Close SaveChanges:=True
End If
Next i
End Sub
En este caso no necesitas declarar una variable de objeto, sino contar el número total de libros abiertos. Una vez obtenido el recuento, se utiliza el bucle For-Next
para recorrer cada libro. Como puedes comprobar, se utiliza el número de índice para hacer referencia al libro.
Observa también que en el código anterior, se está recorriendo el bucle desde wbCuenta
hasta 1 (es decir, con un paso de -1). Es necesario hacerlo así porque con cada ciclo el libro se cierra y por tanto cambian los números de índice asignados a cada libro.
El fastidioso error 9 en tiempo de ejecución
Uno de los errores más fastidiosos (por no decir otra palabra ????) que puedes encontrar al trabajar con libros es el error ‘9’ en tiempo de ejecución.
Como norma general este tipo de errores no ofrecen mucha información y nos dejan a nosotros la tarea de averiguar qué ha fallado.
Algunas de las causas por las que se produce el error 9 en tiempo de ejecución son las siguientes:
- El libro al que estás intentando acceder no existe. Por ejemplo, si estás intentando acceder al sexto libro usando
Workbooks(6)
y solo hay cinco libros abiertos. - Si usas un nombre de libro incorrecto. Por ejemplo, si el nombre del libro es Ejemplo.xlsx y usas Ejemplos.xlsx.
- Si no has guardado el libro por primera vez e intentas acceder a él incluyendo la extensión después del nombre del libro.
- Si el libro se encuentra cerrado.
Revisa la línea en la que se produce el error y verás que casi siempre el problema está en un nombre mal escrito (te lo digo por experiencia).
Cómo obtener una lista de los libros abiertos
Si quieres obtener la lista de los libros que tienes abiertos en un momento determinado e introducirla en el libro actual (donde estás ejecutando el código), puedes usar el siguiente procedimiento:
Sub ListaLibros()
Dim wbCuenta As Integer
wbCuenta = Workbooks.Count
ThisWorkbook.Worksheets.Add
ActiveSheet.Range("A1").Activate
For i = 1 To wbCuenta
Range("A1").Offset(i - 1, 0).Value = Workbooks(i).Name
Next i
End Sub
El código anterior genera una nueva hoja e introduce en ella la lista de los libros abiertos.
Si quieres mostrar también la ruta completa a los libros introduce este procedimiento:
Sub ListaRutaCompleta()
Dim wbCuenta As Integer
wbCuenta = Workbooks.Count
ThisWorkbook.Worksheets.Add
ActiveSheet.Range("A1").Activate
For i = 1 To wbCuenta
Range("A1").Offset(i - 1, 0).Value = Workbooks(i).Path & "\" & Workbooks(i).Name
Next i
End Sub
Abrir un libro específico haciendo doble clic en una celda
Siguiendo con el último ejemplo, una vez obtenida la lista de libros, quizá quieras abrirlos directamente haciendo doble clic en la celda correspondiente. El siguiente código tienes que introducirlo en el módulo del objeto ThisWorkbook
(para que puedas usarlo en todo el libro). Se trata de un procedimiento de evento e introducirlo en un módulo estándar no servirá:
Private Sub Workbook_SheetBeforeDoubleClick(ByVal Sh As Object, ByVal Target As Range, Cancel As Boolean)
Workbooks.Open Target.Value
End Sub
Resumen
Cuando trabajas con Excel, el 99% del tiempo lo haces dentro de libros. Tareas cotidianas como crear hojas nuevas, guardar o cerrar un libro, se hacen más llevaderas cuando se automatizan con VBA. En todos los ejemplos de automatizaciones que hemos visto en este y en el anterior tutorial he utilizado el objeto Workbook.