Borrar celdas
Cuando trabajas con una Hc-Calc como soporte para, por ejemplo, crear un listado, si usas el mismo instrumento de forma sucesiva, puede ser un engorro tener que borrar el contenido introducido antes para introducir nuevo contenido. Este problema se acentúa cuando el número de celdas a borrar es elevado o las celdas están dispersas y te interesa que se borren unas pero no otros, por contener, por ejemplo, textos que te interesa mantener.
En esos y otros casos similares, disponer de una macro o de un script que te ahorre trabajo no vendría nada mal, ¿no te parece?. Vamos a ver qué podemos hacer.
En primer lugar contamos con una solución basada en el código-macro: grabaremos una macro de borrado de celda y multiplicaremos esta acción tantas veces como celdas deseemos borrar.
Sub mcrBorrarCeldadim document as objectdim dispatcher as objectdocument = ThisComponent.CurrentController.Framedispatcher = createUnoService("com.sun.star.frame.DispatchHelper")dim args1(0) as new com.sun.star.beans.PropertyValueargs1(0).Name = "ToPoint"args1(0).Value = "$A$3"dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1())dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array())End Sub
Eliminados los comentarios que ahora no son necesario, podemos ver cómo funciona esta macro:
- Primero se crea las variables de la macro, ambas de tipo Object (document y dispatcher)
- Después se asigna a ambos los objetos correspondientes, el objeto documento activo (document = ThisComponent.CurrentController.Frame) y el objeto Dispatcher (dispatcher = createUnoService("com.sun.star.frame.DispatchHelper"))
- A continuación se construye la estructura-matriz que identifica el objeto celda sobre el que actuamos y se concreta el código que identifica la celda-diana ($A$3") sobre la que se realizarán las acciones posteriores.
dim args1(0) as new com.sun.star.beans.PropertyValueargs1(0).Name = "ToPoint"args1(0).Value = "$A$3"
- ... y se ejecuta el salto a dicha celda (dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args1()))
- Por último se ejecuta la instrucción de borrado de la celda mediante una instrucción de sintaxis similar a la anterior (dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()))
Para trabajar sobre cualquier otra celda es suficiente con sustituir el valor String que la identifica ("$A$3") por una variable a la que asignar el identificador o nombre (formato String) de la nueva celda.
Y para generalizar este procedimiento, sólo tenemos que repetirlo tantas veces como deseemos, aunque caben otras opciones, como veremos más abajo.
Supongamos que hemos creado un docap para gestionar la creación de una base de datos en la que se recogen los que constan en el expediente de resultados académicos del alumnado de EP. Para ello hemos creado una Hc-Gestor a modo de ficha personal como la que se ilustra (1)
Podemos ver que el número de celdas a borrar (manualmente) es suficientemente grande como para que ir de una en una o por pequeños grupos no sea una solución eficiente; además el posicionamiento de las celdas y la existencia de "etiquetas" nos impide optar por el "borrón y cuenta nueva". Estas mismas circunstancias hacen que tampoco sea funcional utilizar repetidamente una macro simple de borrado como la anterior.
En casos, una primera opción consiste en seleccionar las celdas sobre las que actuar (borrar contenido) y proceder posteriormente a su borrado. La orden de borrado es la misma que la que aplicamos a una celda individual (dispatcher.executeDispatch(document, ".uno:ClearContents", "", 0, Array()), pero la selección de las celdas puede realizarse de dos modos diferentes:
- Desplazando el cursor de modo que se seleccione una a una cada una de las celdas de la tabla. Ver mcrBorrarTabla1 (en el IDE). En este se crea una matriz-base que identifica la celda origen (del proceso) y tantas matriz de selección de celdas como movimientos de selección se realicen, con la doble peculiaridad de que el args().Name se identifica como "By" y la acción-movimiento (dispatcher) como instrucción derecha-Izquierda-Arriba-Abajo (ver macro) (2) -> vg. ".uno:GoRightSel"
- O arrastrando el cursos mediante el ratón desde la celda superior-izquierda hasta la celda inferior-derecha del espacio-tabla. Ver mcrBorrarTabla32. En este caso se omiten las matrices de selección celda-a-celda y se genera una en el primer argumento (args().Name) y la acción (dispatcher) son de posicionamiento ("ToPoint") y el segundo argumento (args().Value) contiene el intervalo de celdas sobre las que se actuará ("$G$6:$J$11").
La segunda opción pasa por emplear código OOo Basic no procedente de Grabar macro. Este cambio nos permite simplificar el script y consiste, fundamentalmente en hacer uso de la instrucción (método) clearContents(), que recibe una clave numérica como parámetro, el cual identifica el tipo de dato a borrar:
- 1 -> Borra datos numéricos, manteniendo el formato.
- 4 -> Borra datos alfanuméricos (String), manteniendo el formato.
- 1023 -> Borra todo tipo de contenido, incluido formato.
Este método lo aplicamos al objeto celda, referenciado por el nombre de su variable (oCelda). Un ejemplo:
Sub BorrarCeldaDim oDoc As Object, oHoja As Object, oCelda As ObjectDim sNombreHoja As StringsNombreHoja = "Expediente"oDoc = ThisComponentoHoja = oDoc.getSheets.getByName(sNombreHoja)oCelda = oHoja.getCellRangeByName("C6")oCelda.clearContents(4) 'Borra contenido alfanumérico sin borrar formatoEnd Sub
También podemos borrar un conjunto de celdas (rango) de una vez, sustituyendo el nombre de la celda por la referencia al rango sin hacer otra modificación (3). Así que el mismo script de antes, con algunos cambios, sirve también para borrar un rango de celdas (vg "G6:J11" borra el contenido de la tabla de calificaciones). Los cambios son de denominación de variable y sus implicaciones (4)...
oRango As Object en sustitución de oCelda As Object
... y otro de parámetro
oRango = oHoja.getCellRangeByName("G6:J11") en sustitución de oCelda = oHoja.getCellRangeByName("C6")
El uso de instrucciones OOo Basic, además de script de borrado directo de celdas o de rangos de celda, también nos permite trabajar con subrutinas, como en el ejemplo que muestro a continuación y que nos permite borrar todas las celdas de contenido de nuestro ejemplo:
Script
Sub BorrarCeldas
Dim mCeldas(3) As String
Dim sNombreHoja As String
Dim i As Integer
mCeldas = Array ("C6:D6","C10:D10","C12:D12","G6:J11")
sNombreHoja = "Expediente"
Borrar(sNombreHoja,mCeldas())
End Sub
Subrutina
Sub Borrar(nHoja As String, mC() As Variant)
Dim oHoja As Object, oCelda As Object
Dim i As Integer
oHoja = ThisComponent.getSheets.getByName(nHoja)
For i = LBound(mC()) To UBound(mC())
oCelda = oHoja.getCellRangeByName(mC(i))
oCelda.clearContents(4)
Next
End Sub
Documento. [BorrarCeldas.ods]
NOTAS
(1) No viene al caso ahora crear este docap ni explicar nada más sobre su funcionamiento y posibles usos. Dado que el objetivo de esta entrada es explicar cómo borrar celdas (y rangos del celdas) me limitaré a dar respuesta a este objetivo.
(2) Podemos reducir las líneas de código dando al parámetro args().Value el valor numérico que se ajuste a número de movimientos a realizar. Esto simplifica significativamente la macro. Ver mcrBorrarTabla2.
(3) Si te fijas, el método que se usa para identificar la celda es en realidad un método relativo al rango de celda única: getCellRangeByName()
(4) Con las implicaciones de denominación de la variable en el resto de la sintaxis del script en la instrucción de identificación del rango y en la llamada al método de borrado (oRango.clearContents(4))
No hay comentarios:
Publicar un comentario
Comenta esta entrada