Difference between revisions of "ES/Manuales/GuiaAOO/TemasAvanzados/Macros/Python/PythonCalc/ReferenciaARangos"

From Apache OpenOffice Wiki
< ES‎ | Manuales‎ | GuiaAOO‎ | TemasAvanzados‎ | Macros‎ | Python‎ | PythonCalc
Jump to: navigation, search
(+cat)
Line 58: Line 58:
  
 
Observa que hemos estado usando el método '''getString()''' para obtener el contenido de una celda y '''setString(cadena)''' para establecerlo, más adelante veremos todas las posibilidades que tenemos para introducir u obtener datos de las celdas de nuestra hoja de calculo, así como sus diferencias.
 
Observa que hemos estado usando el método '''getString()''' para obtener el contenido de una celda y '''setString(cadena)''' para establecerlo, más adelante veremos todas las posibilidades que tenemos para introducir u obtener datos de las celdas de nuestra hoja de calculo, así como sus diferencias.
 +
 +
 +
== Referencia a un rango de celdas ==
 +
 +
Podemos acceder a un rango de celdas por su nombre, usando el mismo método usado para acceder a una celda.
 +
<source lang=python>
 +
    activa = doc.getCurrentController().getActiveSheet()
 +
    rango = activa.getCellRangeByName('A1:E5')
 +
    doc.getCurrentController().select(rango)
 +
</source>
 +
 +
 +
Para acceder a un rango de celdas por su posición, hay que usar un método diferente: '''getCellRangeByPosition''', que requiere de cuatro argumentos.
 +
<source lang=python>
 +
    activa = doc.getCurrentController().getActiveSheet()   
 +
    # Seleccionamos el rango B1:C10
 +
    rango = activa.getCellRangeByPosition(1, 0, 2, 9)
 +
    doc.getCurrentController().select(rango)
 +
</source>
 +
 +
 +
Observa que este nuevo método requiere cuatro argumentos: la columna y fila donde empieza nuestro rango y la columna y fila donde termina, recuerda que los números de fila y columna empiezan en 0, algunos piensan que los dos últimos argumentos son el ancho y alto del rango a usar, no es así, estos argumentos también son números de índices de columna y fila respectivamente y tienes que tener la precaución de establecer los segundos iguales o mas grandes que los primeros, sino, te dará un error en tiempo de ejecución y por supuesto sin sobrepasar el máximo de filas y columnas de la hoja de calculo. Observa también, como en la ultima línea seleccionamos el rango referenciado.
 +
 +
Otra posibilidad, es usar nombres definidos de rangos, es decir, aquellos que establecemos desde el '''Cuadro de nombre''' en la hoja de calculo, ya sabes, ese cuadro de lista desplegable (combobox) que esta al lado de la barra de formulas, que también puedes establecer desde el menú ''''Insertar | Nombres | Definir...'''' cuya teclas de acceso rápido son {{Key|Ctrl|F3}}. En el siguiente ejemplo, seleccionamos el rango de celdas llamado Datos. Toma nota de que si el rango no existe en la hoja desde donde se intenta referenciar, te dará un error.
 +
<source lang=python>
 +
    activa = doc.getCurrentController().getActiveSheet()   
 +
    rango = activa.getCellRangeByName('Datos')
 +
    doc.getCurrentController().select(rango)
 +
</source>
 +
 +
 +
Este método no es sensible a mayúsculas o minúsculas. Observa como primero obtenemos una referencia a la interfaz <idl>com.sun.star.sheet.XNamedRanges</idl> y dado que esta hereda la interfaz <idl>com.sun.star.container.XNameAccess</idl> podemos usar el método '''getElementNames''' para obtener todos los nombres con rango en el documento. Si el usuario es el que proporciona el nombre del rango, como siempre, es mejor validar que el rango exista.
 +
<source lang=python>
 +
    nr = doc.NamedRanges
 +
    nombre = 'Datos'
 +
    nombres_rangos = nr.getElementNames()
 +
   
 +
    if nombre in nombres_rangos:
 +
        rango = nr.getByName(nombre).getReferredCells()
 +
        doc.getCurrentController().select(rango)
 +
    else:
 +
        msgbox(u'No existe el rango: %S' % nombre)
 +
</source>
 +
 +
 +
No confundas estos nombres de rangos, con los que puedes establecer en el menú '''Datos | Definir rango...''', ya que estos últimos se refieren a rangos considerados como una tabla de datos, de hecho, puedes tener un mismo nombre para un rango de celdas y para un rango de datos, pero son dos cosas diferentes, los segundos, los veremos más adelante.
 +
 +
De los rangos de celdas, también es posible obtener información, para ello se hace uso de la estructura <idl>com.sun.star.table.CellRangeAddress</idl> a través del método '''getRangeAddress''' que te devuelve información de: la hoja donde esta el rango, la columna y fila donde comienza y la columna y fila donde acaba.
 +
<source lang=python>
 +
    activa = doc.getCurrentController().getActiveSheet()   
 +
    rango = activa.getCellRangeByName('Datos')
 +
    ra = rango.getRangeAddress()
 +
   
 +
    message = """
 +
    El rango esta en la hoja: %s
 +
    Columna inicio: %s
 +
    Fila Inicio: %s
 +
    Columna final: %s
 +
    Fila final: %s
 +
    """ % (ra.Sheet, ra.StartColumn, ra.StartRow, ra.EndColumn, ra.EndRow)
 +
   
 +
    msgbox(message)
 +
</source>
 +
 +
 +
Esta estructura ('''getRangeAddress''') también es usada por varios métodos para manipular rangos que veremos más adelante, por lo que es importante que la tengas presente.
 +
  
 
[[Category:ES]]
 
[[Category:ES]]
 
[[Category:Manuales]]
 
[[Category:Manuales]]
 
[[Category:ES/Python]]
 
[[Category:ES/Python]]

Revision as of 04:23, 15 May 2013


Seguro que sabes, si eres usuario habitual de una hoja de calculo, que el trabajo con rangos es esencial en estos documentos, por lo mismo, el trabajo con rangos desde código es igualmente importante, ya vimos como aseguramos que estamos trabajando en una hoja de calculo, así que dejo a tu criterio esta validación. En la siguientes secciones nos centraremos en aprender como hacer referencia a distintos tipos de rangos para después poder manipularlos, darles formato o hacer con ellos lo que queramos.


Referencia a celdas individuales

Podemos acceder a las celdas de una hoja de calculo de varias maneras, principalmente por su nombre o por su posición, pero muy importante, primero tienes que acceder a la hoja donde están las celdas que te interesa manipular, como acceder a hojas es un tema que ya hemos tratado, pero en cada ejemplo podrás notar que repasamos estos conocimientos, la forma más simple de hacer referencia a una celda es por su nombre.

    activa = doc.getCurrentController().getActiveSheet()
    # Referencia a la celda E5
    celda = activa.getCellRangeByName('E5')
    # Mostramos el contenido de la celda
    msgbox (celda.getString())
    # Mostramos direccion de esta celda
    ca = celda.getCellAddress()
    message = u'Columna: %s\nFila: %s\nHoja: %s' % (ca.Column, ca.Row, ca.Sheet)
    msgbox (message)


Observa como comprobamos en la ultima linea, que efectivamente hemos hecho referencia a la celda que nos interesa, es decir a la celda E5, que en columna y fila es la 4, por que recordamos que los números de columna y fila empiezan en 0, observa la estructura com.sun.star.table.CellAddress, esta, es muy importante pues a muchos métodos para manipular celdas, se les tienen que pasar estructuras como esta, solo tiene tres propiedades, la hoja (valor tipo integer que también empieza en 0) donde esta la celda referenciada, la columna (long) y la fila (long) de esta celda.

Ahora accedemos a una celda por su posición, recuerda que los índices de inicio desde código empiezan en 0, por lo que para hacer referencia a la celda E5, tenemos que poner la columna 4 y fila 4, el primer valor es para la columna y el segundo para la fila, no esta de más comentarte que tengas cuidado de no establecer una posición fuera de la hoja, pues te dará un error, si el valor de la fila y columna se la solicitas al usuario, “deberías” de validar que los valores proporcionados son correctos.

    activa = doc.getCurrentController().getActiveSheet()
 
    col = 9
    fil = 14
    if col < activa.getColumns().getCount() and fil < activa.getRows().getCount():
        celda = activa.getCellByPosition(col, fil)
        msgbox (celda.getString())
    else:
        msgbox('Valores incorrectos')


Es frecuente que el acceso por nombre a una celda se use para establecer valores preestablecidos, como títulos de campos por ejemplo, y el acceso por posición es muy útil para realizar ciclos, como el ejemplo siguiente que inserta el año como titulo en la celda A1 y los meses del año de la celda A2 a la A13.

import uno
import datetime
 
def pruebas():
    ctx = uno.getComponentContext()
    sm = ctx.getServiceManager()
 
    desktop = sm.createInstanceWithContext('com.sun.star.frame.Desktop', ctx)
    doc = desktop.getCurrentComponent()
 
    activa = doc.getCurrentController().getActiveSheet()
    activa.getCellRangeByName('A1').setString(datetime.date.today().year)
    for i in range(1,13):
        activa.getCellByPosition(0, i).setString(datetime.date(2013, i, 1).strftime('%B'))
 
    return


Observa que hemos estado usando el método getString() para obtener el contenido de una celda y setString(cadena) para establecerlo, más adelante veremos todas las posibilidades que tenemos para introducir u obtener datos de las celdas de nuestra hoja de calculo, así como sus diferencias.


Referencia a un rango de celdas

Podemos acceder a un rango de celdas por su nombre, usando el mismo método usado para acceder a una celda.

    activa = doc.getCurrentController().getActiveSheet()
    rango = activa.getCellRangeByName('A1:E5')
    doc.getCurrentController().select(rango)


Para acceder a un rango de celdas por su posición, hay que usar un método diferente: getCellRangeByPosition, que requiere de cuatro argumentos.

    activa = doc.getCurrentController().getActiveSheet()    
    # Seleccionamos el rango B1:C10
    rango = activa.getCellRangeByPosition(1, 0, 2, 9)
    doc.getCurrentController().select(rango)


Observa que este nuevo método requiere cuatro argumentos: la columna y fila donde empieza nuestro rango y la columna y fila donde termina, recuerda que los números de fila y columna empiezan en 0, algunos piensan que los dos últimos argumentos son el ancho y alto del rango a usar, no es así, estos argumentos también son números de índices de columna y fila respectivamente y tienes que tener la precaución de establecer los segundos iguales o mas grandes que los primeros, sino, te dará un error en tiempo de ejecución y por supuesto sin sobrepasar el máximo de filas y columnas de la hoja de calculo. Observa también, como en la ultima línea seleccionamos el rango referenciado.

Otra posibilidad, es usar nombres definidos de rangos, es decir, aquellos que establecemos desde el Cuadro de nombre en la hoja de calculo, ya sabes, ese cuadro de lista desplegable (combobox) que esta al lado de la barra de formulas, que también puedes establecer desde el menú 'Insertar | Nombres | Definir...' cuya teclas de acceso rápido son  Ctrl  +  F3 . En el siguiente ejemplo, seleccionamos el rango de celdas llamado Datos. Toma nota de que si el rango no existe en la hoja desde donde se intenta referenciar, te dará un error.

    activa = doc.getCurrentController().getActiveSheet()    
    rango = activa.getCellRangeByName('Datos')
    doc.getCurrentController().select(rango)


Este método no es sensible a mayúsculas o minúsculas. Observa como primero obtenemos una referencia a la interfaz com.sun.star.sheet.XNamedRanges y dado que esta hereda la interfaz com.sun.star.container.XNameAccess podemos usar el método getElementNames para obtener todos los nombres con rango en el documento. Si el usuario es el que proporciona el nombre del rango, como siempre, es mejor validar que el rango exista.

    nr = doc.NamedRanges
    nombre = 'Datos'
    nombres_rangos = nr.getElementNames()
 
    if nombre in nombres_rangos:
        rango = nr.getByName(nombre).getReferredCells()
        doc.getCurrentController().select(rango)
    else:
        msgbox(u'No existe el rango: %S' % nombre)


No confundas estos nombres de rangos, con los que puedes establecer en el menú Datos | Definir rango..., ya que estos últimos se refieren a rangos considerados como una tabla de datos, de hecho, puedes tener un mismo nombre para un rango de celdas y para un rango de datos, pero son dos cosas diferentes, los segundos, los veremos más adelante.

De los rangos de celdas, también es posible obtener información, para ello se hace uso de la estructura com.sun.star.table.CellRangeAddress a través del método getRangeAddress que te devuelve información de: la hoja donde esta el rango, la columna y fila donde comienza y la columna y fila donde acaba.

    activa = doc.getCurrentController().getActiveSheet()    
    rango = activa.getCellRangeByName('Datos')
    ra = rango.getRangeAddress()
 
    message = """
    El rango esta en la hoja: %s
    Columna inicio: %s
    Fila Inicio: %s
    Columna final: %s
    Fila final: %s
    """ % (ra.Sheet, ra.StartColumn, ra.StartRow, ra.EndColumn, ra.EndRow)
 
    msgbox(message)


Esta estructura (getRangeAddress) también es usada por varios métodos para manipular rangos que veremos más adelante, por lo que es importante que la tengas presente.

Personal tools