Difference between revisions of "ES/Manuales/GuiaAOO/TemasAvanzados/Macros/StarBasic/TrabajandoConCalc/TrabajandoConHojas"
(Created page with "{{DISPLAYTITLE:Trabajando con hojas}} {{ES/AyudaWiki/Borrador}} == Accediendo a las hojas == Para acceder a todas las hojas de un documento de hoja de calculo, usamos. <sou...") |
(→Accediendo a las hojas) |
||
Line 12: | Line 12: | ||
'Acceso al documento desde donde se llama a esta macro | 'Acceso al documento desde donde se llama a esta macro | ||
− | oDoc | + | oDoc = ThisComponent |
'Nos aseguramos de que sea una hoja de calculo | 'Nos aseguramos de que sea una hoja de calculo | ||
If oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | If oDoc.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | ||
'Referencia a TODAS las hojas del documento | 'Referencia a TODAS las hojas del documento | ||
− | oHojas | + | oHojas = oDoc.getSheets() |
'Mostramos cuantas son | 'Mostramos cuantas son | ||
MsgBox oHojas.getCount() | MsgBox oHojas.getCount() | ||
Line 41: | Line 41: | ||
GlobalScope.BasicLibraries.LoadLibrary( "Tools" ) | GlobalScope.BasicLibraries.LoadLibrary( "Tools" ) | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
'Obtenemos una matriz con los nombres de todas las hojas | 'Obtenemos una matriz con los nombres de todas las hojas | ||
− | mNombresHojas() | + | mNombresHojas() = oHojas.getElementNames() |
'Construimos el mensaje | 'Construimos el mensaje | ||
− | sMensaje | + | sMensaje = "El archivo " & FileNameOutOfPath( oDoc.getLocation() ) & _ |
Chr(13) & "tiene las siguientes hojas" & Chr(13) & Chr(13) | Chr(13) & "tiene las siguientes hojas" & Chr(13) & Chr(13) | ||
− | sMensaje | + | sMensaje = sMensaje & Join( mNombresHojas(), Chr(13) ) |
'Lo mostramos | 'Lo mostramos | ||
Line 72: | Line 72: | ||
Dim co1 As Integer | Dim co1 As Integer | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
'Obtenemos una matriz con los nombres de todas las hojas | 'Obtenemos una matriz con los nombres de todas las hojas | ||
− | mNombresHojas() | + | mNombresHojas() = oHojas.getElementNames() |
− | For co1 | + | For co1 = LBound( mNombresHojas() ) To UBound( mNombresHojas() ) |
MsgBox mNombresHojas(co1) | MsgBox mNombresHojas(co1) | ||
Next | Next | ||
Line 94: | Line 94: | ||
Dim oHoja As Object | Dim oHoja As Object | ||
− | oDoc | + | oDoc = ThisComponent |
'Accedemos a una hoja por su nombre | 'Accedemos a una hoja por su nombre | ||
− | oHoja | + | oHoja = oDoc.getSheets.getByName("Datos Agosto") |
'Solo comprobamos que es la hoja correcta | 'Solo comprobamos que es la hoja correcta | ||
Line 115: | Line 115: | ||
Dim sNombreHoja As String | Dim sNombreHoja As String | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
− | sNombreHoja | + | sNombreHoja = "Datos Agosto" |
'Comprobamos que la hoja exista para poder acceder a ella | 'Comprobamos que la hoja exista para poder acceder a ella | ||
If oHojas.hasByName( sNombreHoja ) Then | If oHojas.hasByName( sNombreHoja ) Then | ||
'Accedemos a una hoja por su nombre | 'Accedemos a una hoja por su nombre | ||
− | oHoja | + | oHoja = oHojas.getByName( sNombreHoja ) |
MsgBox oHoja.getName() & " - existe en el documento" | MsgBox oHoja.getName() & " - existe en el documento" | ||
Else | Else | ||
Line 145: | Line 145: | ||
Dim oHoja As Object | Dim oHoja As Object | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
'Accedemos a la hoja por el indice | 'Accedemos a la hoja por el indice | ||
− | oHoja | + | oHoja = oHojas.getByIndex( 1 ) |
MsgBox oHoja.getName() | MsgBox oHoja.getName() | ||
Line 166: | Line 166: | ||
Dim iNumeroHoja As Integer | Dim iNumeroHoja As Integer | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
− | iNumeroHoja | + | iNumeroHoja = 1 |
'Comprobamos que la hoja exista | 'Comprobamos que la hoja exista | ||
− | If iNumeroHoja < | + | If iNumeroHoja < oHojas.getCount() Then |
'Accedemos a la hoja por el índice | 'Accedemos a la hoja por el índice | ||
− | oHoja | + | oHoja = oHojas.getByIndex( iNumeroHoja ) |
MsgBox oHoja.getName() | MsgBox oHoja.getName() | ||
Else | Else | ||
Line 193: | Line 193: | ||
Dim co1 As Integer | Dim co1 As Integer | ||
− | oDoc | + | oDoc = ThisComponent |
− | oHojas | + | oHojas = oDoc.getSheets() |
'Nota que el limite, es el total de hojas menos uno, por que comienza en 0 | 'Nota que el limite, es el total de hojas menos uno, por que comienza en 0 | ||
− | For co1 | + | For co1 = 0 To oHojas.getCount()-1 |
− | oHoja | + | oHoja = oHojas.getByIndex( co1 ) |
MsgBox oHoja.getName() | MsgBox oHoja.getName() | ||
Next | Next | ||
Line 217: | Line 217: | ||
'Hacemos una referencia a la hoja activa | 'Hacemos una referencia a la hoja activa | ||
− | oHoja | + | oHoja = ThisComponent.getCurrentController.getActiveSheet() |
Msgbox oHoja.getName() | Msgbox oHoja.getName() | ||
Line 240: | Line 240: | ||
Dim oHojas As Object | Dim oHojas As Object | ||
− | oHojas | + | oHojas = ThisComponent.getSheets() |
− | ExisteHoja | + | ExisteHoja = oHojas.hasByName(NombreHoja) |
End Function | End Function | ||
Line 265: | Line 265: | ||
'Si no es una hoja de calculo devuelve falso (False) | 'Si no es una hoja de calculo devuelve falso (False) | ||
If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | ||
− | oHojas | + | oHojas = Documento.getSheets() |
− | ExisteHoja2 | + | ExisteHoja2 = oHojas.hasByName(NombreHoja) |
End If | End If | ||
Line 282: | Line 282: | ||
dim oHoja As Object | dim oHoja As Object | ||
− | oHoja | + | oHoja = DevuelveHoja1( "Datos Enero" ) |
If IsNull(oHoja) Then | If IsNull(oHoja) Then | ||
MsgBox "La hoja no existe" | MsgBox "La hoja no existe" | ||
Line 296: | Line 296: | ||
Dim oHojas As Object | Dim oHojas As Object | ||
− | oHojas | + | oHojas = ThisComponent.getSheets() |
If oHojas.hasByName(NombreHoja) Then | If oHojas.hasByName(NombreHoja) Then | ||
− | DevuelveHoja1 | + | DevuelveHoja1 = oHojas.getByName(NombreHoja) |
End If | End If | ||
Line 312: | Line 312: | ||
dim oHoja As Object | dim oHoja As Object | ||
− | oHoja | + | oHoja = DevuelveHoja2( ThisComponent, "Datos Enero" ) |
If IsNull(oHoja) Then | If IsNull(oHoja) Then | ||
MsgBox "La hoja no existe" | MsgBox "La hoja no existe" | ||
Line 327: | Line 327: | ||
If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | If Documento.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then | ||
− | oHojas | + | oHojas = Documento.getSheets() |
If oHojas.hasByName(NombreHoja) Then | If oHojas.hasByName(NombreHoja) Then | ||
− | DevuelveHoja2 | + | DevuelveHoja2 = oHojas.getByName(NombreHoja) |
End If | End If | ||
End If | End If | ||
Line 335: | Line 335: | ||
End Function | End Function | ||
</source> | </source> | ||
− | |||
== Insertando hojas == | == Insertando hojas == |
Revision as of 17:55, 20 August 2013
Contents
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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> Trim(InputBox("Nombre de la nueva hoja")) 'Verificamos que no este vacio If sNombre <nowiki><></nowiki> "" Then 'Referencia a todas las hojas oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> Trim(InputBox("Nombre de la nueva hoja")) If sNombre <nowiki><></nowiki> "" Then oHojas <nowiki>=</nowiki> ThisComponent.getSheets() If Not oHojas.hasByName(sNombre) Then 'Si no existe la insertamos al final oHojas.insertNewByName( sNombre, oHojas.getCount() ) End If oHoja <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() For co1 <nowiki>=</nowiki> 0 To ThisComponent.getSheets.getCount() - 1 oHoja <nowiki>=</nowiki> ThisComponent.getSheets.getByIndex(co1) If oHoja.getName() <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 0 To ThisComponent.getSheets.getCount() - 1 oHoja <nowiki>=</nowiki> ThisComponent.getSheets.getByIndex(co1) If oHoja.getName() <nowiki>=</nowiki> NombreHoja then BuscarIndiceHoja <nowiki>=</nowiki> co1 Exit Function End If Next BuscarIndiceHoja <nowiki>=</nowiki> -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 <nowiki>=</nowiki> Trim(InputBox("Nombre de la nueva hoja")) If sNombre <nowiki><></nowiki> "" Then oHojas <nowiki>=</nowiki> ThisComponent.getSheets() oHojaActiva <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() If Not oHojas.hasByName(sNombre) Then 'Buscamos el índice de la hoja activa pos <nowiki>=</nowiki> BuscarIndiceHoja(oHojaActiva.getName()) oHojas.insertNewByName( sNombre, pos ) End If oHoja <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki><></nowiki> "" Then oHojas <nowiki>=</nowiki> ThisComponent.getSheets() oHojaActiva <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() Select Case Posicion Case 1 : iPos <nowiki>=</nowiki> 0 Case 2 : iPos <nowiki>=</nowiki> oHojas.getCount() Case 3 : iPos <nowiki>=</nowiki> oHojaActiva.getRangeAddress.Sheet Case 4 : iPos <nowiki>=</nowiki> oHojaActiva.getRangeAddress.Sheet + 1 Case Else : iPos <nowiki>=</nowiki> 0 End Select If Not oHojas.hasByName(NombreHoja) Then oHojas.insertNewByName(NombreHoja, iPos) End If getNuevaHoja <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> Trim( InputBox( "Nombre de la hoja a borrar" )) If sNombre <nowiki><></nowiki> "" Then oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> Trim( InputBox( "Nombre de la hoja a borrar" )) If sNombre <nowiki><></nowiki> "" Then oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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() <nowiki>=</nowiki> Array("5","l","o","f","e","v","y","d","h","u",) 'Mostramos los datos desordenados MsgBox Join( mDatos(), Chr(13) ) 'Ordenamos los datos mDatos() <nowiki>=</nowiki> 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() <nowiki>=</nowiki> 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 <nowiki>=</nowiki> UBound(Datos) For co1 <nowiki>=</nowiki> 1 To NumDatos For co2 <nowiki>=</nowiki> NumDatos To co1 Step -1 If Orden <nowiki>=</nowiki> 1 Then If Datos(co2) <nowiki><</nowiki> Datos(co2 - 1) Then Call Intercambio Datos(co2), Datos(co2 - 1) End If Else If Not (Datos(co2) <nowiki><</nowiki> 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 <nowiki>=</nowiki> Dato1 Dato1 <nowiki>=</nowiki> Dato2 Dato2 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets() 'Matriz con los nombres de todas las hojas mNombres() <nowiki>=</nowiki> oHojas.getElementNames() 'Ordenamos la matriz Call OrdenarBurbuja( mNombres(), 1 ) 'Recorremos la matriz For co1 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> "Datos" sNombreNuevo <nowiki>=</nowiki> "Datos nuevos" oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets() 'Nombre de la hoja activa sNombre <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet.getName() 'Contador para construir el nuevo nombre co1 <nowiki>=</nowiki> 1 'El nuevo nombre es igual mas un guión bajo y un numero sNombre2 <nowiki>=</nowiki> sNombre & "_" & Format(co1) 'Hace el ciclo mientras el nuevo nombre exista Do While oHojas.hasByName( sNombre2 ) 'Si ya existe incrementamos el contador co1 <nowiki>=</nowiki> co1 + 1 'y construimos el nuevo nombre sNombre2 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> "Resumen" sNombreNuevo <nowiki>=</nowiki> "Terminado" oHojas <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets() For co1 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets() For co1 <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets() 'Para que solo cambie las primeras 12 If oHojas.getCount() > 12 Then Limite <nowiki>=</nowiki> 12 Else 'O las que haya si son menos de 12 Limite <nowiki>=</nowiki> oHojas.getCount() End If For co1 <nowiki>=</nowiki> 1 To Limite 'Obtenemos el nombre del mes sMes <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() oHojaActiva.isVisible <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets.getByIndex(1) oHoja.isVisible <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets.getByIndex(0) oHoja.isVisible <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getSheets.getByIndex(1) oHoja.isVisible <nowiki>=</nowiki> 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 <nowiki>=</nowiki> ThisComponent.getCurrentController.getActiveSheet() oHojas <nowiki>=</nowiki> ThisComponent.getSheets() For co1 <nowiki>=</nowiki> 0 To oHojas.getCount() - 1 If oHojas.getByIndex(co1).getName <nowiki><></nowiki> oHojaActiva.getName() Then oHojas.getByIndex(co1).isVisible <nowiki>=</nowiki> 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 |