Difference between revisions of "ES/Manuales/GuiaAOO/TemasAvanzados/Macros/Python/PythonCalc/TrabajandoConHojas"
(+cat) |
(→Insertando hojas) |
||
Line 95: | Line 95: | ||
− | == Insertando hojas == | + | == 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. | ||
+ | <source lang=python> | ||
+ | hojas = doc.getSheets() | ||
+ | |||
+ | hojas.insertNewByName('Nuevos datos', 0) | ||
+ | </source> | ||
+ | |||
+ | 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. | ||
+ | <source lang=python> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Observa entonces que el argumento posición puede tomar valores desde 0 y hasta el total de hojas devuelto por {{TextColor|Blue|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. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Que podemos convertir a una función. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | 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. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | 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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Para insertar después de la hoja activa, solo sumas uno al valor devuelto por la función {{TextColor|Blue|BuscarIndiceHoja}}. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | pos <nowiki>=</nowiki> BuscarIndiceHoja(oHojaActiva.getName()) + 1 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Podemos aventurar una primera versión de una función genérica para insertar una nueva hoja de calculo donde quieras. | ||
+ | |||
+ | |||
+ | <source lang="oobas"> | ||
+ | '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 | ||
+ | </source> | ||
+ | |||
+ | |||
+ | Nota como estamos obteniendo el índice de la hoja activa ({{TextColor|Blue|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 == | == Borrando hojas == |
Revision as of 04:47, 8 May 2013
Contents
Acceso a las hojas de un archivo Calc
Para acceder a todas las hojas de un archivo usamos el método getSheets.
doc = desktop.getCurrentComponent() hojas = doc.getSheets()
Podemos devolver todos los nombres de las mismas.
doc = desktop.getCurrentComponent() hojas = doc.getSheets() nombres = hojas.getElementNames() msgbox('\n'.join(nombres))
O acceder por nombre a la que nos interesa (getByName), tienes que validar (hasByName) primero que existe esta hoja.
doc = desktop.getCurrentComponent() hojas = doc.getSheets() nombre = 'Hoja1' if hojas.hasByName(nombre): hoja = hojas.getByName(nombre) else: msgbox('No existe la hoja: %s' % nombre)
Podemos acceder a una hoja por su índice, recuerda que los índices en AOO empiezan en cero, en las hojas, la numeración empieza de izquierda a derecha.
doc = desktop.getCurrentComponent() hojas = doc.getSheets() indice = 1 hoja = hojas.getByIndex(indice) msgbox (hoja.getName())
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.
doc = desktop.getCurrentComponent() hojas = doc.getSheets() indice = 1 if indice < hojas.getCount(): hoja = hojas.getByIndex(indice) msgbox (hoja.getName()) else: msgbox(u'No existe este índice: %s' % indice)
Podemos acceder a cada hoja por su índice, pero 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.
doc = desktop.getCurrentComponent() hojas = doc.getSheets() for i in range(hojas.getCount()): msgbox(hojas.getByIndex(i).getName())
También es posible devolver la hoja activa.
doc = desktop.getCurrentComponent() hoja = doc.getCurrentController().getActiveSheet() msgbox(hoja.getName())
Creamos una función genérica para devolver una hoja.
def devuelve_hoja(doc, nombre): if doc.getSheets().hasByName(nombre): return doc.getSheets().getByName(nombre)
Para usarse de forma sencilla.
doc = desktop.getCurrentComponent() nombre = 'Hoja2' hoja = devuelve_hoja(doc, nombre) if hoja: msgbox(hoja.getName()) else: msgbox('No se encontró la hoja: %s' % nombre)re)
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.
hojas = doc.getSheets() hojas.insertNewByName('Nuevos datos', 0)
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.