Trabajando con hojas

From Apache OpenOffice Wiki
Jump to: navigation, search


Editing.png Esta página está en estado borrador.

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.

ES.Plantillas.Logo foro es.png
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

Personal tools