Aprender y divertirse con la Hoja de Cálculo
Página personal de Antonio Roldán Martínez

Inicio Sin decimales Aritmética Divisibilidad Combinatoria  Congruencias Juegos Diccionario general Estadística Teoría de Números (R. Parra)

Exploraciones Trucos Estudios Sugerencias Funciones y macros


Estás en
Inicio > Exploraciones > Funciones y macros

 

Funciones y macros

En este apartado se incluirán algunas técnicas referentes a la programación del lenguaje Basic integrado en las hojas de cálculo. La gran mayoría de los textos se referirán a OpenOffice.org Calc, aunque algunos serán de aplicación a Microsoft Excel. 

Las técnicas incluidas no seguirán un orden estricto, sino que se irán publicando según surjan las cuestiones que motiven su estudio.

Define tus propias funciones
Macros de apertura
Cómo sumar datos dispersos etiquetados
Parpadeo de un dato elegido

 


 

Define tus propias funciones

En ocasiones desearás definir funciones que la hoja de cálculo no ofrece. Por ejemplo, en Electricidad nos puede convenir definir la resistencia equivalente a otras dos situadas en paralelo, o en Geometría, la función que devuelve una hipotenusa en función de los dos catetos. Mediante un uso sencillo de las macros puedes lograrlo.

Secuencia para definir tus propias funciones

1) Abrir el Editor de Basic

 

En OpenOffice
 

Sigue el menú Herramientas > Macros > Organizar macros > OpenOffice.org Basic para abrir el editor.


Si es la primera función que defines, busca la carpeta Standard correspondiente al nombre de tu modelo (si lo acabas de crear, se llamará Sin Nombre). No señales la otra carpeta Standard, que es más general.

Una vez elegida la carpeta, pulsa el botón Nuevo para abrir un módulo contenedor. Se te ofrecerá el nombre de module1, module2 u otro similar. Acepta el nombre o cámbialo según tu criterio. Al aceptar el nombre se abrirá el editor de macros. Por defecto aparecerá la macro Main, que puedes borrar o ignorar.

Escribe debajo el código de tu función, según se explica en el siguiente apartado.

En Excel

Sigue el menú Herramientas > Macro > Editor de Visual Basic, o pulsa Alt + F11

Si es la primera función que defines, la pantalla aparecerá en gris. Debes crear un módulo nuevo con Insertar - Módulo, y Excel le dará el nombre de Módulo 1.

Escribe debajo el código de tu función, según se explica en el siguiente apartado.

 

 

 

2) Escritura del código

Terminada la secuencia anterior, comienza a escribir el código de una función-

Debes comenzar con

Function nombre de la función ( argumento )

y terminar con

End function

y entre ambas, el código de la función

En ese código debemos usar el nombre de la función seguida del signo igual y de su definición

Es mejor verlo con un ejemplo:

Function cubo ( numero )
cubo=numero*numero*numero
End function

En el ejemplo, el nombre de la función es cubo, y su argumento numero (lo traduciríamos como "Cubo de un número")
Después volvemos a escribir cubo, el signo igual, y su definición.

3) Uso de la función

Una vez escrito el código, cierra el Editor de Basic y usa tu función en cualquier celda. En la imagen puedes ver una celda definida mediante la nueva función CUBO.

Con esto ya tienes definida la función.

Con la técnica explicada, esa función sólo estará activa en la hoja de cálculo en la que la has creado, no en otras. Al cerrar la hoja ya no podrás usarla.

Función con varios argumentos

Una función puede actuar sobre varios argumentos, por ejemplo la resistencia equivalente a la que se aludía en el primer párrafo. En ese caso, se deberán separa mediante una coma:

Function resisequiv(r1, r2)
resisequiv = r1 * r2 / (r1 + r2)
End Function

Cuando uses esta función en una celda, debes sustituir la coma por un punto y coma., por ejemplo resisequiv(4;6). Estudia el ejemplo de la imagen:

 

Variables auxiliares

En una definición puedes usar las estructuras del Basic: FOR...NEXT, SELECT CASE, etc. Aquí sólo usaremos DIM, para crear variables auxiliares. Observa este ejemplo

Function area6(lado)
Dim perimetro, apotema

perimetro = 6 * lado
apotema = lado * Sqr(3) / 2
area6 = perimetro * apotema / 2
End Function

que devuelve el área de un hexágono en función del lado. El nombre de la función, en este caso area6, debe figurar en la definición, aunque uses otras variables.


Macros de apertura

En ocasiones podemos desear que se ejecute cualquier operación al abrir una hoja de cálculo, como borrar un rango, abrir una hoja determinada, dar un valor a una celda, etc.
Para lograrlo debes, en primer lugar, escribir o grabar una macro con las operaciones que deseas. Una vez escrita, el procedimiento para que se ejecute al abrir una hoja cambia mucho si trabajas en Excel o si lo haces en OpenOffice.org.

En Excel

Basta con entrar en el Editor de Visual Basic (Alt - F11), buscar la macro que has escrito y cambiarle el nombre por Auto_Open. Nada más.

Ejemplos

Sub Auto_Open()
Sheets("Hoja3").Select
Range("E6").Select
ActiveCell.FormulaR1C1 = "22"
End Sub
 

Esta macro, al abrir el archivo, seleccionará la Hoja3, situará el cursor en la celda E6 y escribirá en ella un 22


 

Sub Auto_Open
Range("A1:D20").Select
Selection.ClearContents
End Sub
 

Esta otra selecciona el rango A1:D20 y borra su contenido

 

En OpenOffice.org

 Aquí el procedimiento es totalmente distinto.

Escribes o grabas una macro y le das el nombre que desees. Supongamos que fuera Sub inicio().

Una vez construida la macro, abres el menú Herramientas - Personalizar, eliges la pestaña Eventos y señalas con el ratón el evento de Abrir Documento.
 

Pulsas sobre el botón Asignar macro, y la buscas (por ejemplo inicio). Debes saber dónde está. En la imagen estaría en el documento Sin nombre, macros Standard, módulo Module2. Aceptas dos veces y ya tienes una macro de inicio.
 

 

 

en cuyo caso se considerará un desplazamiento de +1 fila y 0 columnas.

Se desarrollan a continuación posibles códigos para resolver la situación. Se escriben en negro las líneas que funcionan indistintamente en Excel y OpenOffice, en verde las que hay que usar sólo en Excel, y en rojo las que sólo se escribirán en  OpenOffice. Finalmente, lo escrito en azul y en cursiva corresponderá a comentarios. Para editar este código se deberán seguir las instrucciones del apartado Define tus propias funciones.


Cómo sumar datos dispersos etiquetados

 En ocasiones se usan tablas de recogida de datos en las que existen algunos de la misma naturaleza pero que aparecen dispersos. Por ejemplo, calificaciones correspondientes a preguntas aisladas en una clase.

Como no se pregunta cada día a los mismos alumnos o alumnas, sus notas aparecerán en la tablas de forma desordenada. Sin embargo, lo usual es que vengan acompañadas de una etiqueta que recuerde a quién pertenece la calificación. Si después se desean contar o sumar estos datos, ninguna función de Excel u OpenOffice nos resolvería el problema de forma satisfactoria.

Un ejemplo típico se da cuando la organización de los datos se efectúa mediante múltiples fichas personales, que pueden llenar toda una hoja. En la imagen se registran los pedidos de botellas que ha efectuado un socio de un Club de Vinos. A la derecha figuran los totales mensuales, que se habrán obtenido con las funciones generales de Excel.

 

 

Imaginemos que existen numerosas fichas de este tipo y que se desea sumar o contar todas las botellas enviadas en el mes de Abril. En ese caso se deberá explorar toda la hoja, y cuando se encuentre la etiqueta "Abril", sumar la cantidad que figure a su derecha. Para lograrlo podemos definir en Basic dos funciones nuevas. Habrá que tener en cuenta cuántas filas y columnas separan la etiqueta del dato. En este ejemplo sería +1 columna (está a su derecha) y 0 filas, pero la etiqueta puede estar escrita superiormente al dato, como en

 

Alfredo Gómez
8,3

 

en cuyo caso se considerará un desplazamiento de +1 fila y 0 columnas.

Se desarrollan a continuación posibles códigos para resolver la situación. Se escriben en negro las líneas que funcionan indistintamente en Excel y OpenOffice, en verde las que hay que usar sólo en Excel, y en rojo las que sólo se escribirán en  OpenOffice. Finalmente, lo escrito en azul y en cursiva corresponderá a comentarios. Para editar este código se deberán seguir las instrucciones del apartado Define tus propias funciones.


Sumar los datos de todas las apariciones de una etiqueta

Public Function sumar_etiq(a$,filas, columnas) Esta función sumaría los datos de las apariciones de la etiqueta: mes, alumno/a, marca de coche, etc. a$ representa a la etiqueta que estamos buscando

                                                                    Los parámetros filas y columnas representan el desplazamiento que existe entre etiqueta y dato. En el ejemplo de los vinos serían 0 y +1 respectivamente.
Dim i, j, suma, suma0

Dim g$

suma = 0
For i = 1 To 3000 
filas que abarcan los datos. Hay que cambiar el 3000 por el número de cada ejemplo concreto
For j = 1 To 20  
columnas que abarquen los datos

g$ = ActiveWorkbook.Sheets(1).Cells(i, j).Value
Línea sólo para Excel. Lee el contenido de las celdas para descubrir la etiqueta y recogerla en la variable g$

g$= StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(j-1,i-1).String Línea sólo para OpenOffice. Similar a la anterior.


If g$ = a$ Then   
Comprueba si la celda contiene la etiqueta solicitada

suma0 = ActiveWorkbook.Sheets(1).Cells(i+filas, j+columnas).Value Lee el dato asignado a la etiqueta (para Excel)

suma0= StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(j-1`columnas,i-1+filas).String Línea sólo para OpenOffice. Similar a la anterior. Las filas y columnas presentan orden inverso


suma = suma + suma0
End If

Next j
 

Next i
 

sumar_etiq = suma
 

End Function

Una vez definida, se puede usar en cualquier celda. En el ejemplo de los vinos, para buscar Abril deberíamos escribir en cualquier celda 

=SUMAR_ETIQ("Abril",0,1)

El 1 representa el desplazamiento de una columna a la derecha y el 0 que el dato se encuentra en la misma fila.



Contar las apariciones de una etiqueta

Se puede definir una función CONTAR_ETIQ de forma similar, con pocos cambios:

Public Function contar_etiq(a$,filas, columnas) Esta función sumaría los datos de las apariciones de la etiqueta: mes, alumno/a, marca de coche, etc. a$ representa a la etiqueta que estamos buscando

                                                                    Los parámetros filas y columnas representan el desplazamiento que existe entre etiqueta y dato. En el ejemplo de los vinos serían 0 y +1 respectivamente.
Dim i, j, conta, conta0
Dim g$

conta = 0
For i = 1 To 3000 
filas que abarcan los datos. Hay que cambiar el 3000 por el número de cada ejemplo concreto
For j = 1 To 20  
columnas que abarquen los datos

g$ = ActiveWorkbook.Sheets(1).Cells(i, j).Value
Línea sólo para Excel. Lee el contenido de las celdas para descubrir la etiqueta y recogerla en la variable g$

g$= StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(j-1,i-1).String Línea sólo para OpenOffice. Similar a la anterior.

If g$ = a$ Then    Comprueba si la celda contiene la etiqueta solicitada

suma0 = ActiveWorkbook.Sheets(1).Cells(i+filas, j+columnas).Value Lee el dato asignado a la etiqueta (para Excel)
 

suma0= StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(j-1`columnas,i-1+filas).String Línea sólo para OpenOffice. Similar a la anterior. Las filas y columnas presentan orden inverso


if conta0>0 then conta = conta + 1
End If

Next j
Next i
contar_etiq = conta
End Function

Una vez definida, se puede usar en cualquier celda. En el ejemplo de los vinos, para buscar Abril deberíamos escribir en cualquier celda 

=SUMAR_ETIQ("Abril",0,1)

El 1 representa el desplazamiento de una columna a la derecha y el 0 que el dato se encuentra en la misma fila.


if conta0>0 then conta = conta + 1
End If
Next j
Next i
contar_etiq = conta
End Function


Parpadeo de un dato elegido


En algunas situaciones prácticas podemos tener una gran abundancia de datos que hagan casi imposible su exploración visual. Entre ellos pueden existir algunos cuya ubicación nos interese. Por ejemplo, un lector me indicaba que para él sería útil que se destacaran los pagos que vencieran en la fecha actual. Así, cada vez que abriera la hoja, encontraría parpadeando los que hubieran llegado a su fecha.

No es fácil conseguir que parpadeen las celdas que contengan un dato que nos interese. Por eso nos vamos a tener que basar en unos datos previos que le indiquen a la hoja de cálculo qué tiene que buscar, dónde y cuántos segundos ha de mantener el parpadeo. Con más calma quizás se pudiera prescindir de alguno de ellos, pero el tema no merece más atención.

En la imagen vemos una posible cabecera. En las celdas situadas debajo podemos imaginarnos que existen grandes cantidades de datos, y que entre ellos está el elegido. En este caso hemos usado una fecha 07/11/45 y deberán parpadear todas las celdas inferiores que la contengan.
 

 
La macro que construyamos deberá leer las celdas y asignarles una variable. Supongamos que en E6 se lee Valor, en G6 Fila, H6 Columna y J6 Pausa. Esas son las variables que usaremos en el código Basic.

Una vez leídas se inician también t0, que leerá el reloj interno (timer) e indi, que llevará la cuenta de las celdas que contienen el dato elegido. También hay que preparar memorias fil y col que nos indiquen dónde está situado el dato.

Así, la estructura de nuestra macro podría ser:

(A) Se leen las variables 

 
Leemos Valor, Fila, Columna y Pausa, el reloj en t0 y se pone a cero el contador de veces que aparece el dato (indi) y las memorias fil y col

pausa=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(9,5).value
valor=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(4,5).value
fila=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(6,5).value
columna=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(7,5).value
t0=timer
t1=t0
indi=0
for i=0 to 50:fil(i)=0:col(i)=0:next i


(B) Se recorren las filas y columnas. 

 
Cuando se encuentre el dato elegido se incrementa indi y se rellenan fil(indi) y col(indi) con la referencia de la celda.

(C) Se programa una pausa temporal. 

 
Se puede hacer con esta rutina:

t1=t0
while t1
‘Se realiza el trabajo de recorrer celdas y parpadear
t1=timer
wend


La hora del reloj está almacenada en t0. La otra variable t1 va leyendo el timer y cuando sobrepasa la pausa se detiene. Dentro del bucle se realiza el parpadeo.

(D) Parpadeo de las celdas elegidas

Consistirá simplemente en asignar dos colores distintos a las celdas y separarlos mediante un pequeño intervalo de tiempo:

if indi>0 then
for i=1 to indi
StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(col(i),fil(i)).cellbackcolor=rgb(255,100,200)
next i
end if
‘colorea de rojo apagado

for i=1 to 1e4:next i

‘mantiene ocupado el ordenador por un tiempo

if indi>0 then
for i=1 to indi
StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(col(i),fil(i)).cellbackcolor=rgb(255,255,255)
next i

‘Vuelve a colorear de blanco

 
Como ejercicio de programación es divertido. Seguro que alguien lo puede mejorar. 

Copiamos a continuación todo el código en Basic de OpenOffice.org

Sub parpadeo
dim pausa,valor,fila,columna,celda
dim t0,t1,i,j,k,indi
dim fil(50),col(50)

pausa=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(9,5).value
valor=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(4,5).value
fila=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(6,5).value
columna=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(7,5).value

t0=timer
t1=t0
indi=0
for i=0 to 50:fil(i)=0:col(i)=0:next i
for i=8 to fila
for j=1 to columna
celda=StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(j,i).value
if celda=valor then

indi=indi+1
fil(indi)=i:col(indi)=j
end if
next j
next i
while t1

if indi>0 then
for i=1 to indi
StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(col(i),fil(i)).cellbackcolor=rgb(255,100,200)
next i
end if
for i=1 to 1e4:next i
if indi>0 then
for i=1 to indi
StarDesktop.CurrentComponent.sheets(0).GetCellByPosition(col(i),fil(i)).cellbackcolor=rgb(255,255,255)
next i
end if
t1=timer
wend

End Sub