Trabajando con hojas
Accediendo a las hojas
Para acceder a todas las hojas de un documento de hoja de calculo, usamos.
Sub TodasLasHojas1()
Dim oDoc As Object
Dim oHojas As Object
'Acceso al documento desde donde se llama a esta macro
oDoc = ThisComponent
'Nos aseguramos de que sea una hoja de calculo
If oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then
'Referencia a TODAS las hojas del documento
oHojas = oDoc.getSheets()
'Mostramos cuantas son
MsgBox oHojas.getCount()
Else
MsgBox "No es un documento de hoja de calculo"
End If
End Sub
Asegúrate de llamar a la macro anterior desde una hoja de calculo, si estas usando el archivo especial Mis Macros, te recomiendo siempre verificar que ThisComponent, apunta efectivamente a un documento de hoja de calculo como se vio más arriba, de ahora en adelante, daré por hecho que lo sabes y tú determinaras si haces la validación o no.
Podemos acceder a los nombres de todas las hojas.
Sub TodasLasHojas2()
Dim oDoc As Object
Dim oHojas As Object
Dim mNombresHojas() As String
Dim sMensaje As String
GlobalScope.BasicLibraries.LoadLibrary( "Tools" )
oDoc = ThisComponent
oHojas = oDoc.getSheets()
'Obtenemos una matriz con los nombres de todas las hojas
mNombresHojas() = oHojas.getElementNames()
'Construimos el mensaje
sMensaje = "El archivo " & FileNameOutOfPath( oDoc.getLocation() ) & _
Chr(13) & "tiene las siguientes hojas" & Chr(13) & Chr(13)
sMensaje = sMensaje & Join( mNombresHojas(), Chr(13) )
'Lo mostramos
MsgBox sMensaje
End Sub
La función FileNameOutOfPath, viene incorporada en OpenOffice.org y nos devuelve solo el nombre del archivo de la ruta pasada.
También podemos mostrar los nombres de las hojas una a una.
Sub TodasLasHojas3()
Dim oDoc As Object
Dim oHojas As Object
Dim mNombresHojas() As String
Dim co1 As Integer
oDoc = ThisComponent
oHojas = oDoc.getSheets()
'Obtenemos una matriz con los nombres de todas las hojas
mNombresHojas() = oHojas.getElementNames()
For co1 = LBound( mNombresHojas() ) To UBound( mNombresHojas() )
MsgBox mNombresHojas(co1)
Next
End Sub
Podemos devolver solo la hoja que nos interesa por su nombre.
Sub UnaHoja1()
Dim oDoc As Object
Dim oHoja As Object
oDoc = ThisComponent
'Accedemos a una hoja por su nombre
oHoja = oDoc.getSheets.getByName("Datos Agosto")
'Solo comprobamos que es la hoja correcta
MsgBox oHoja.getName()
End Sub
Pero si la hoja no existe, la macro anterior te dará un error, el método hasByName es muy útil para saber si una hoja existe, lo cual es indispensable para acceder a ella.
Sub UnaHoja2()
Dim oDoc As Object
Dim oHojas As Object
Dim oHoja As Object
Dim sNombreHoja As String
oDoc = ThisComponent
oHojas = oDoc.getSheets()
sNombreHoja = "Datos Agosto"
'Comprobamos que la hoja exista para poder acceder a ella
If oHojas.hasByName( sNombreHoja ) Then
'Accedemos a una hoja por su nombre
oHoja = oHojas.getByName( sNombreHoja )
MsgBox oHoja.getName() & " - existe en el documento"
Else
MsgBox "La hoja -" & sNombreHoja & "- no existe"
End If
End Sub
Nota que el método hasByName es un método del conjunto de las hojas (getSheets) y te devolverá verdadero (True) en caso de que la hoja exista y falso (False) en caso de que no. Este método no distingue entre mayúsculas y minúsculas.
Podemos acceder a una hoja por su índice, recuerda que los índices en OpenOffice.org empiezan en cero, en las hojas, la numeración empieza de izquierda a derecha.
Sub UnaHoja3()
Dim oDoc As Object
Dim oHojas As Object
Dim oHoja As Object
oDoc = ThisComponent
oHojas = oDoc.getSheets()
'Accedemos a la hoja por el indice
oHoja = oHojas.getByIndex( 1 )
MsgBox oHoja.getName()
End Sub
Del mismo modo que por el nombre, si tratas de acceder a una hoja por un índice que no exista, te dará un error, lo podemos comprobar asegurándonos que el numero de índice a consultar siempre es menor al total de las hojas.
Sub UnaHoja4()
Dim oDoc As Object
Dim oHojas As Object
Dim oHoja As Object
Dim iNumeroHoja As Integer
oDoc = ThisComponent
oHojas = oDoc.getSheets()
iNumeroHoja = 1
'Comprobamos que la hoja exista
If iNumeroHoja < oHojas.getCount() Then
'Accedemos a la hoja por el índice
oHoja = oHojas.getByIndex( iNumeroHoja )
MsgBox oHoja.getName()
Else
MsgBox "Numero de hoja no existe"
End If
End Sub
Por lo que podemos acceder a cada hoja de un documento, también por su índice.
Sub TodasLasHojas4()
Dim oDoc As Object
Dim oHojas As Object
Dim oHoja As Object
Dim co1 As Integer
oDoc = ThisComponent
oHojas = oDoc.getSheets()
'Nota que el limite, es el total de hojas menos uno, por que comienza en 0
For co1 = 0 To oHojas.getCount()-1
oHoja = oHojas.getByIndex( co1 )
MsgBox oHoja.getName()
Next
End Sub
Toma en cuenta que si mueves una hoja de posición en relación con las demás, su índice cambiara, no así su nombre, pero el nombre es susceptible de ser cambiado por el usuario, así que siempre comprueba que exista una hoja antes de intentar acceder a ella.
Otra opción es devolver la hoja activa.
Public Sub HojaActiva()
Dim oHoja As Object
'Hacemos una referencia a la hoja activa
oHoja = ThisComponent.getCurrentController.getActiveSheet()
Msgbox oHoja.getName()
End Sub
Ahora, ya puedes crearte tus útiles funciones para trabajar con hojas, por ejemplo, una función que nos devuelva falso o verdadero según exista o no el nombre de la hoja pasado como argumento, una primera aproximación podría ser.
Option Explicit
Sub SaberSiExisteHoja()
MsgBox ExisteHoja( "Hoja3" )
End Sub
'Saber si una hoja existe
Function ExisteHoja(ByVal NombreHoja As String) As Boolean
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
ExisteHoja = oHojas.hasByName(NombreHoja)
End Function
Podemos hacerla incluso más genérica pasándole el documento donde se desea comprobar la existencia de la hoja y comprobando que sea una hoja de calculo.
Option Explicit
Sub SaberSiExisteHoja2()
MsgBox ExisteHoja2( ThisComponent, "Hoja3" )
End Sub
'Saber si una hoja existe
Function ExisteHoja2(Documento As Object, NombreHoja As String) As Boolean
Dim oHojas As Object
'Si no es una hoja de calculo devuelve falso (False)
If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then
oHojas = Documento.getSheets()
ExisteHoja2 = oHojas.hasByName(NombreHoja)
End If
End Function
Ahora devolvemos la hoja.
Option Explicit
Sub DevuelveReferenciaAHoja1()
dim oHoja As Object
oHoja = DevuelveHoja1( "Datos Enero" )
If IsNull(oHoja) Then
MsgBox "La hoja no existe"
Else
MsgBox oHoja.getName()
End If
End Sub
'Saber si existe la hoja y regresarla, si llamas a esta función,
'tienes que verificar que se devolvió algo con IsNull
Function DevuelveHoja1(ByVal NombreHoja As String) As Object
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
If oHojas.hasByName(NombreHoja) Then
DevuelveHoja1 = oHojas.getByName(NombreHoja)
End If
End Function
De nuevo, si lo deseas, puedes pasarle el documento del cual te interesa devolver la hoja, observa como comprobamos también que la hoja exista, esto lo puedes hacer directamente o usando la función creada más arriba, queda a tu criterio.
Sub DevuelveReferenciaAHoja2()
dim oHoja As Object
oHoja = DevuelveHoja2( ThisComponent, "Datos Enero" )
If IsNull(oHoja) Then
MsgBox "La hoja no existe"
Else
MsgBox oHoja.getName()
End If
End Sub
'Saber si existe la hoja y regresarla, si llamas a esta función,
'tienes que verificar que se devolvió algo con IsNull
Function DevuelveHoja2(Documento As Object, NombreHoja As String) As Object
Dim oHojas As Object
If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then
oHojas = Documento.getSheets()
If oHojas.hasByName(NombreHoja) Then
DevuelveHoja2 = oHojas.getByName(NombreHoja)
End If
End If
End Function
Insertando hojas
Para insertar nuevas hojas, usamos el método: insertNewByName(Nombre, Posición), en donde necesitamos el nombre de la nueva hoja a insertar y la posición donde la queremos, la siguiente macro agrega una hoja nueva al inicio de las demás.
Sub InsertarNuevaHoja1()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
oHojas.insertNewByName("Datos Sep", 0)
End Sub
Ejecuta la macro anterior dos veces y notaras que te dará un error, pues no puedes tener dos hojas con el mismo nombre, entonces, tenemos que verificar si la hoja existe o no.
Sub InsertarNuevaHoja2()
Dim oHojas As Object
Dim oHoja As Object
Dim sNombre As String
'Solicitamos un nombre para la nueva hoja
sNombre = Trim(InputBox("Nombre de la nueva hoja"))
'Verificamos que no este vacio
If sNombre <> "" Then
'Referencia a todas las hojas
oHojas = ThisComponent.getSheets()
'Verificamos si ya existe la hoja
If Not oHojas.hasByName(sNombre) Then
'Si no existe la insertamos el inicio
oHojas.insertNewByName(sNombre, 0)
Else
MsgBox "Esta hoja ya existe"
End If
'Referencia a la nueva hoja o a la existente
oHoja = ThisComponent.getSheets.getByName(sNombre)
'La activamos
ThisComponent.getCurrentController.setActiveSheet(oHoja)
End If
End Sub
Observa que si la hoja ya existe, solo hacemos una referencia a ella. La ultima linea para activar la hoja no es necesaria para que la manipules, solo en caso de que quieras que el usuario haga o manipule algo en ella, si no, puedes omitirla. Es sumamente frecuente en programadores noveles, querer “activar” toda hoja que se quiera manipular, esto no es necesariamente así, de hecho, la mayor parte de las veces, con la referencia es suficiente.
También podemos agregar la hoja al final de todas las demás.
Sub InsertarNuevaHoja3()
Dim oHojas As Object
Dim oHoja As Object
Dim sNombre As String
sNombre = Trim(InputBox("Nombre de la nueva hoja"))
If sNombre <> "" Then
oHojas = ThisComponent.getSheets()
If Not oHojas.hasByName(sNombre) Then
'Si no existe la insertamos al final
oHojas.insertNewByName( sNombre, oHojas.getCount() )
End If
oHoja = ThisComponent.getSheets.getByName(sNombre)
ThisComponent.getCurrentController.setActiveSheet(oHoja)
End If
End Sub
Observa entonces que el argumento posición puede tomar valores desde 0 y hasta el total de hojas devuelto por getCount() pero incluso si es mayor a este valor, no te dará error y la insertara al final de las demás hojas. Si quieres insertar la hoja antes o después de la hoja activa, primero tienes que encontrar el índice de la hoja activa.
Sub IndiceHojaActiva()
Dim co1 As Integer
Dim oHojaActiva As Object
dim oHoja As Object
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
For co1 = 0 To ThisComponent.getSheets.getCount() - 1
oHoja = ThisComponent.getSheets.getByIndex(co1)
If oHoja.getName() = oHojaActiva.getName() then
MsgBox "El indice de la hoja activa es: " & co1
Exit For
End If
Next
End Sub
Que podemos convertir a una función.
Function BuscarIndiceHoja(ByVal NombreHoja As String) As Integer
Dim co1 As Integer
dim oHoja As Object
For co1 = 0 To ThisComponent.getSheets.getCount() - 1
oHoja = ThisComponent.getSheets.getByIndex(co1)
If oHoja.getName() = NombreHoja then
BuscarIndiceHoja = co1
Exit Function
End If
Next
BuscarIndiceHoja = -1
End Function
Observa que si no la encuentra el valor devuelto es -1, lo cual hay que evaluar en caso necesario. Para insertar antes de la hoja activa usamos.
Sub InsertarNuevaHoja4()
Dim oHojas As Object
Dim oHoja As Object
Dim oHojaActiva As Object
Dim sNombre As String
Dim pos As Integer
sNombre = Trim(InputBox("Nombre de la nueva hoja"))
If sNombre <> "" Then
oHojas = ThisComponent.getSheets()
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
If Not oHojas.hasByName(sNombre) Then
'Buscamos el índice de la hoja activa
pos = BuscarIndiceHoja(oHojaActiva.getName())
oHojas.insertNewByName( sNombre, pos )
End If
oHoja = ThisComponent.getSheets.getByName(sNombre)
ThisComponent.getCurrentController.setActiveSheet(oHoja)
End If
End Sub
Para insertar después de la hoja activa, solo sumas uno al valor devuelto por la función BuscarIndiceHoja.
pos = BuscarIndiceHoja(oHojaActiva.getName()) + 1
Podemos aventurar una primera versión de una función genérica para insertar una nueva hoja de calculo donde quieras.
'Como función regresamos la nueva hoja insertada o la existente en su caso
'Posición: 1 = Inicio
' 2 = Final
' 3 = Antes de la hoja activa
' 4 = Después de la hoja activa
Function getNuevaHoja(NombreHoja As String, Posicion As Integer) As Object
Dim oHojas As Object
Dim oHojaActiva As Object
Dim iPos As Integer
If NombreHoja <> "" Then
oHojas = ThisComponent.getSheets()
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
Select Case Posicion
Case 1 : iPos = 0
Case 2 : iPos = oHojas.getCount()
Case 3 : iPos = oHojaActiva.getRangeAddress.Sheet
Case 4 : iPos = oHojaActiva.getRangeAddress.Sheet + 1
Case Else : iPos = 0
End Select
If Not oHojas.hasByName(NombreHoja) Then
oHojas.insertNewByName(NombreHoja, iPos)
End If
getNuevaHoja = ThisComponent.getSheets.getByName(NombreHoja)
End If
End Function
Nota como estamos obteniendo el índice de la hoja activa (oHoja.getRangeAddress.Sheet), con lo cual nos evitamos tener que hacer un ciclo por las hojas del documento. Puedes mejorar esta función para insertar la hoja en cualquier otro documento, así como ingeniártelas para pedirle al usuario el número de hojas nuevas que quiera insertar e insertarlas por supuesto, esa, es tu tarea.
Borrando hojas
Para borrar hojas, usamos el método removeByName(Nombre), donde Nombre es el nombre de la hoja que queremos borrar, no esta de más recomendarte usar con cuidado el borrado de hojas, aunque algo que me gusta mucho de OpenOffice.org, es que muchas de las acciones que hacemos por código, son susceptibles de deshacerse de forma normal con la barra de herramientas o con CTRL+Z, el borrado de hojas es una de ellas, compruébalo.
Sub BorrarHoja1()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
'Borramos la hoja por su nombre
oHojas.removeByName( "Hoja11" )
End Sub
Por supuesto no puedes borrar una hoja que no exista, así que verifícalo.
Sub BorrarHoja2()
Dim oHojas As Object
Dim sNombre As String
sNombre = Trim( InputBox( "Nombre de la hoja a borrar" ))
If sNombre <> "" Then
oHojas = ThisComponent.getSheets()
If oHojas.hasByName( sNombre ) Then
oHojas.removeByName( sNombre )
Else
MsgBox "La hoja no existe"
End If
End If
End Sub
Puedes borrar la hoja activa.
Sub BorrarHojaActiva()
Dim oHojas As Object
Dim oHojaActiva As Object
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
oHojas = ThisComponent.getSheets()
oHojas.removeByName( oHojaActiva.getName() )
End Sub
Ejecuta la macro anterior hasta que no quede ni una, claro, no te dejara por que un documento de hoja de calculo por lo menos debe de tener una hoja, para evitar el error que te da al tratar de borrar la ultima hoja, valida que siempre quede más de una.
Sub BorrarHoja3()
Dim oHojas As Object
Dim sNombre As String
sNombre = Trim( InputBox( "Nombre de la hoja a borrar" ))
If sNombre <> "" Then
oHojas = ThisComponent.getSheets()
If oHojas.hasByName( sNombre ) And oHojas.getCount()>1 Then
oHojas.removeByName( sNombre )
Else
MsgBox "La hoja no existe o solo queda una"
End If
End If
End Sub
Moviendo hojas
Para mover hojas usamos el método moveByName(NombreHoja, PosicionNueva), donde NombreHoja tiene que ser el nombre de una hoja existente.
Sub MoverHoja1()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
'Movemos la hoja especificada al inicio
oHojas.moveByName( "Hoja2", 0 )
End Sub
Ahora, la movemos al final.
Sub MoverHoja2()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
'Movemos la hoja especificada al final
oHojas.moveByName( "Hoja2", oHojas.getCount() )
End Sub
Si usas una versión anterior a la 3.1, ten cuidado con mover tus hojas no más allá de la ultima hoja, pues te puede provocar un error en toda la aplicación, este error (bug) se reportó en su momento (http://www.openoffice.org/issues/show_bug.cgi?id=92477), y ha sido arreglado a partir de esta versión (3.1), aun así, usa siempre getCount() para asegurarte.
Vamos a hacer algo muy divertido, como ya sabemos obtener los nombres e índices de cada hoja, y ahora hemos aprendido a mover hojas, hagamos una macro que nos ordene alfabéticamente nuestras hojas, para ello nos apoyaremos en una función que ordena la matriz que le pasemos.
Sub PruebaOrdenar1()
Dim mDatos()
GlobalScope.BasicLibraries.LoadLibrary( "Tools" )
mDatos() = Array("5","l","o","f","e","v","y","d","h","u",)
'Mostramos los datos desordenados
MsgBox Join( mDatos(), Chr(13) )
'Ordenamos los datos
mDatos() = BubbleSortList( mDatos() )
'Mostramos los datos ordenados
MsgBox Join( mDatos(), Chr(13) )
End Sub
La función BubbleSortList, viene incorporada a las macros de OpenOffice.org y usa el método de burbuja para ordenar la lista pasada, no es el algoritmo más eficiente, pero en listas pequeñas y dada su sencillez de implementación es perfectamente válida para nuestros fines, si quieres saber más de este algoritmo visita: http://es.wikipedia.org/wiki/Bubblesort
También puedes crearte tu versión de este algoritmo, aquí esta la mía, puedes ordenar de forma ascendente o descendente.
Sub PruebaOrdenar2()
Dim mDatos()
mDatos() = Array("5","l","o","f","e","v","y","d","h","u",)
'Mostramos los datos desordenados
MsgBox Join( mDatos(), Chr(13) )
'Ordenamos los datos
Call OrdenarBurbuja( mDatos(), 1 )
'Mostramos los datos ordenados
MsgBox Join( mDatos(), Chr(13) )
End Sub
' Datos = matriz de datos a ordenar
' Orden = 1 ascendente
' 2 descendente
Sub OrdenarBurbuja(ByRef Datos() As Variant, ByVal Orden As Integer)
Dim NumDatos As Long
Dim co1 As Long, co2 As Long
NumDatos = UBound(Datos)
For co1 = 1 To NumDatos
For co2 = NumDatos To co1 Step -1
If Orden = 1 Then
If Datos(co2) < Datos(co2 - 1) Then
Call Intercambio Datos(co2), Datos(co2 - 1)
End If
Else
If Not (Datos(co2) < Datos(co2 - 1)) Then
Call Intercambio Datos(co2), Datos(co2 - 1)
End If
End If
Next co2
Next co1
End Sub
'Macro para intercambiar un par de valores
Sub Intercambio(ByRef Dato1 As Variant, ByRef Dato2 As Variant)
Dim sTmp As Variant
sTmp = Dato1
Dato1 = Dato2
Dato2 = sTmp
End Sub
Ahora si, nuestra macro para ordenar hojas en acción, puedes usar la función o macro que prefieras para ordenar la matriz de nombres obtenida, incluso, crearte tu propia versión si así lo prefieres.
Option Explicit
'Ordenamos las hojas por orden alfabético
Sub OrdenarHojas()
Dim oHojas As Object
Dim mNombres() As Variant
Dim aTmp As Variant
Dim co1 As Integer
Dim oHoja As Object
'Referencia a todas las hojas del documento
oHojas = ThisComponent.getSheets()
'Matriz con los nombres de todas las hojas
mNombres() = oHojas.getElementNames()
'Ordenamos la matriz
Call OrdenarBurbuja( mNombres(), 1 )
'Recorremos la matriz
For co1 = LBound( mNombres() ) To UBound( mNombres() )
'El índice en la matriz, sera el mismo de la posición
oHojas.moveByName( mNombres(co1), co1 )
Next co1
End Sub
Copiando hojas
Para copiar hojas usamos el método copyByName ( NombreHoja, NombreNuevo, Posicion ) de la siguiente manera.
Sub CopiarHoja1()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
'Copiamos la "hoja2" como "Nueva Hoja2" al inicio
oHojas.copyByName( "Hoja2", "Nueva Hoja2", 0 )
End Sub
Por supuesto el nombre de la hoja a copiar debe de existir y el nombre nuevo de la hoja no debe existir, lo mejor, es evaluarlo antes.
Sub CopiarHoja2()
Dim oHojas As Object
Dim sNombre As String
Dim sNombreNuevo As String
sNombre = "Datos"
sNombreNuevo = "Datos nuevos"
oHojas = ThisComponent.getSheets()
'Solo copia la hoja, si la hoja a copiar existe y el nombre nuevo no existe
If oHojas.hasByName(sNombre) And (Not oHojas.hasByName(sNombreNuevo)) Then
oHojas.copyByName( sNombre, sNombreNuevo, oHojas.getCount() )
Else
MsgBox "No se copió la hoja"
End If
End Sub
Podemos intentar copiar una hoja y asegurarnos de que el nombre no exista, tomando como base el nombre actual de la hoja, por ejemplo.
Sub CopiarHojaActiva()
Dim oHojas As Object
Dim oHoja As Object
Dim sNombre As String
Dim sNombre2 As String
Dim co1 As Long
'Referencia a todas las hoja
oHojas = ThisComponent.getSheets()
'Nombre de la hoja activa
sNombre = ThisComponent.getCurrentController.getActiveSheet.getName()
'Contador para construir el nuevo nombre
co1 = 1
'El nuevo nombre es igual mas un guión bajo y un numero
sNombre2 = sNombre & "_" & Format(co1)
'Hace el ciclo mientras el nuevo nombre exista
Do While oHojas.hasByName( sNombre2 )
'Si ya existe incrementamos el contador
co1 = co1 + 1
'y construimos el nuevo nombre
sNombre2 = sNombre & "_" & Format(co1)
Loop
'Sale del ciclo cuando el nuevo nombre no exista, entonces
'podemos copiar la hoja al final (o donde quieras)
oHojas.copyByName(sNombre, sNombre2, oHojas.getCount())
'Referencia a la nueva hoja
oHoja = ThisComponent.getSheets.getByName(sNombre2)
'Y la activamos
ThisComponent.getCurrentController.setActiveSheet(oHoja)
End Sub
Solo te resta preguntarle al usuario cuantas nuevas hojas quiere e insertar ese número de hojas nuevas, pero esa, es tu tarea.
Renombrando hojas
Para renombrar hojas usamos el método setName, de la siguiente manera.
Sub CambiarNombreHoja1()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
'Cambiamos el nombre de la hoja “Hola”, por “Prueba”
oHojas.getByName("Hola").setName( "Prueba" )
End Sub
También puedes usar el índice para referirte a la hoja.
Sub CambiarNombreHoja2()
Dim oHojas As Object
oHojas = ThisComponent.getSheets()
oHojas.getByIndex( 0 ).setName( "Gastos" )
End Sub
Es recomendable validar que la hoja a renombrar exista y que el nuevo nombre no.
Sub CambiarNombreHoja3()
Dim oHojas As Object
Dim sNombreActual As String
Dim sNombreNuevo As String
sNombreActual = "Resumen"
sNombreNuevo = "Terminado"
oHojas = ThisComponent.getSheets()
'Validamos que la hoja exista y el nuevo nombre no
If oHojas.hasByName(sNombreActual) And (Not oHojas.hasByName(sNombreNuevo)) Then
oHojas.getByName( sNombreActual ).setName( sNombreNuevo )
Else
MsgBox "No se renombro la hoja"
End If
End Sub
Solo para divertirnos, cambiamos los nombres de las hojas por números.
Sub CambiarNombreHoja4()
Dim oHojas As Object
Dim co1 As Integer
oHojas = ThisComponent.getSheets()
For co1 = 1 To oHojas.getCount()
oHojas.getByIndex( co1-1 ).setName( co1 )
Next
End Sub
Ahora por letras, el código siguiente podría fallarte si tienes más de 25 hojas en tu documento, tu tarea es decirme ¿porqué? y corregirlo, en algunos casos, “el cambio de nombre no tendrá efecto”, también, te toca averiguar ¿porqué?
Sub CambiarNombreHoja5()
Dim oHojas As Object
Dim co1 As Integer
oHojas = ThisComponent.getSheets()
For co1 = 1 To oHojas.getCount()
oHojas.getByIndex( co1-1 ).setName( Chr( co1+64 ) )
Next
End Sub
O los meses del año:
Sub CambiarNombreHoja6()
Dim oHojas As Object
Dim co1 As Integer
Dim Limite As Byte
Dim sMes As String
oHojas = ThisComponent.getSheets()
'Para que solo cambie las primeras 12
If oHojas.getCount() > 12 Then
Limite = 12
Else
'O las que haya si son menos de 12
Limite = oHojas.getCount()
End If
For co1 = 1 To Limite
'Obtenemos el nombre del mes
sMes = Format( DateSerial(Year(Date),co1,1) ,"mmmm")
oHojas.getByIndex( co1-1 ).setName( sMes )
Next
End Sub
Te queda de tarea lograr completar los meses para que sean los doce del año, es decir, tienes que insertar los meses que te hagan falta si el documento tiene menos de las hojas necesarias, si tiene más de doce borra las sobrantes.
Ocultando y mostrando hojas
Mostrar y ocultar hojas es muy sencillo, solo hay que establecer su propiedad isVisible en verdadero (True) o falso (False) según se requiera de la siguiente manera,
Sub OcultarHoja1()
Dim oHojaActiva As Object
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
oHojaActiva.isVisible = False
End Sub
La macro anterior te ocultara la hoja activa, si la ejecutas varias veces te ira ocultando tus hojas hasta que solo quede una, si solo hay una no te dará error, pero la dejará visible por que, como sabes, tiene que haber al menos una hoja visible en un documento de Calc. También puedes ocultar una hoja por medio de su índice, como en.
Sub OcultarHoja2()
Dim oHoja As Object
oHoja = ThisComponent.getSheets.getByIndex(1)
oHoja.isVisible = False
End Sub
Toma en cuenta que: el índice de la hoja “debe” existir, sino te dará un error, así mismo, si ocultas una hoja, esta no cambia de índice por lo que puedes usar el mismo para acceder a ella, aunque este oculta, la siguiente macro alterna entre mostrar y ocultar la primer hoja del documento.
Sub OcultarHoja3()
Dim oHoja As Object
oHoja = ThisComponent.getSheets.getByIndex(0)
oHoja.isVisible = Not oHoja.isVisible
End Sub
Como ya habrás intuido, para mostrar una hoja oculta simplemente hay que establecer esta propiedad en verdadero (True).
Sub OcultarHoja4()
Dim oHoja As Object
oHoja = ThisComponent.getSheets.getByIndex(1)
oHoja.isVisible = True
End Sub
El siguiente código te oculta todas las hojas, excepto la hoja activa.
Sub OcultarHoja5()
Dim oHojaActiva As Object
Dim oHojas As Object
Dim co1 As Long
oHojaActiva = ThisComponent.getCurrentController.getActiveSheet()
oHojas = ThisComponent.getSheets()
For co1 = 0 To oHojas.getCount() - 1
If oHojas.getByIndex(co1).getName <> oHojaActiva.getName() Then
oHojas.getByIndex(co1).isVisible = False
End If
Next
End Sub
Tu tarea es hacer la función inversa, muestra todas las hojas ocultas.
Protección y desprotección de hojas
Para terminar este capítulo, veamos como proteger una hoja, es decir, establecer una contraseña para evitar modificaciones a la misma, además, recuerda que para que la protección de celdas individuales sea efectiva, la hoja debe estar protegida. Para proteger una hoja, usamos el método Protect, pasándole como argumento, la contraseña que queremos establecer, por supuesto, puedes pasarle una contraseña vacía, con lo que la hoja no estará muy protegida que digamos, pero créeme, muchos usuarios no saben desproteger una hoja, aun sin contraseña.
Sub ProtegerHoja1()
Dim oHojaActiva As Object
oHojaActiva = ThisComponent.getCurrentController().getActiveSheet()
'Para que veas que si me ocurren otras contraseñas
oHojaActiva.Protect( "letmein" )
End Sub
Y para desproteger, usamos el método unProtect, si la hoja tiene contraseña hay que pasársela como argumento, si no es correcta, el método no te devolverá ningún error como en la interfaz del usuario que te avisa que la contraseña es incorrecta, para saber si tuvo éxito o no la desprotección, hay que verificar la propiedad isProtected, si es verdadera (True) la hoja sigue protegida, si es falsa (False), la hoja esta desprotegida.
Sub ProtegerHoja2()
Dim oHojaActiva As Object
oHojaActiva = ThisComponent.getCurrentController().getActiveSheet()
If oHojaActiva.isProtected Then
MsgBox "La hoja esta protegida"
'Intentamos desprotegerla
oHojaActiva.unProtect( "letmein" )
'Verificamos si tuvo éxito la desprotección
If oHojaActiva.isProtected Then
MsgBox "La contraseña no es correcta"
Else
MsgBox "Hoja desprotegida correctamente"
End If
Else
MsgBox "La hoja NO esta protegida"
End If
End Sub
Te queda de tarea modificar la macro para solicitar al usuario la contraseña, verificar si es correcta o no y darle solo tres intentos para ingresarla. Fácil, ¿verdad?. Como comentarios finales, si intentas proteger una hoja que ya tiene contraseña, no obtendrás ningún error, pero la hoja permanecerá con la contraseña original, para cambiarla, primero tienes que desprotegerla y después cambiarla. Cuando proteges una hoja e intentas hacer modificaciones a esta, por ejemplo, escribir en una celda, tampoco retornará ningún error, pero no será efectiva la modificación, procura usar la propiedad para saber si una hoja esta o no protegida (isProtected), para actuar en consecuencia.
| Si tienes dudas acerca de lo aquí explicado, tienes algún problema con AOO, o quieres ampliar la información, no dudes en dirigirte al Foro Oficial en español de Apache OpenOffice para Macros y API UNO |
