Upload
wayalam
View
143
Download
14
Embed Size (px)
DESCRIPTION
Visual Basic para Open Office
Citation preview
Programación de Macros en Open Office con Open Basic
(Curso Intermedio de 42 Horas)
Escrito por: José Andrés Martínez Silva
Inspirado en: múltiples fuentes disponibles en el mundo de Software Libre
Con la ayuda de: cada uno de los alumnos que tomó este curso por primera vez
Material en constante revisión, desarrollo y ampliación
Versión 0.2
Ultima revisión Martes 18 de Septiembre de 2007
Tabla de ContenidosPresentación...............................................................................................................................5Convenciones..............................................................................................................................5Capítulo 1....................................................................................................................................6
Introducción............................................................................................................................6Por dónde comenzar?.............................................................................................................7Código de Muestra................................................................................................................10Hola Mundo...........................................................................................................................10Marcadores............................................................................................................................11Variables................................................................................................................................13Tipos de Datos......................................................................................................................15Práctica con Tipos de Dato Numéricos................................................................................16Vectores y Matrices...............................................................................................................18Práctica con Vectores...........................................................................................................19Operadores en Open Basic..................................................................................................19
Operadores Matemáticos:................................................................................................20Operadores Lógicos:........................................................................................................20Operadores de Comparación:..........................................................................................20
Capítulo 2:.................................................................................................................................22Control de Flujo:....................................................................................................................22
If ... Then ... Else..............................................................................................................22Expresiones If Anidadas...................................................................................................24Estructura de Control Select Case...................................................................................25Bucles o ciclos de ejecución.............................................................................................27Determinando los números pares....................................................................................28Empleando Do While Loop...............................................................................................28Imprimiendo los números menores que la mitad del número mayor...............................29Do Loop While..................................................................................................................29Do Until Loop....................................................................................................................30Do Loop Until....................................................................................................................31Procedimientos y Funciones.............................................................................................31Calculando en que momento y porque valor se debe renovar el seguro del carro.........32Recursividad.....................................................................................................................35Determinando el Ingreso al Cine mediante funciones.....................................................36
Capítulo 3:.................................................................................................................................38
La Biblioteca de Funciones de Open Basic:.........................................................................38Funciones para Conversión de Variables.........................................................................38Funciones para Validación del Contenido de las Variables.............................................39Trabajando con Diferentes Niveles de Acceso:................................................................41Funciones para Acceso a Cadenas..................................................................................43Funciones para Búsqueda y Reemplazo dentro de Cadenas.........................................44Buscar y Reemplazar Mejorado.......................................................................................45Función para dar Formato a las Cadenas........................................................................46Trabajando con Fechas....................................................................................................48Qué Hora es?...................................................................................................................49Mensajes de Texto............................................................................................................50Diálogos Básicos con MsgBox.........................................................................................51Captura de Datos Mediante Cuadros de Diálogo............................................................53Captura de datos con InputBox........................................................................................54
Capítulo 4:.................................................................................................................................56UNO, la API de Open Office:................................................................................................56
Utilización de UNO desde Open Basic.............................................................................56Carga de un archivo con Open Basic...............................................................................57Creación de un Nuevo Documento..................................................................................57
Capítulo 5:.................................................................................................................................59Trabajando con Documentos de Texto:................................................................................59
Elementos que Componen un Documento de Texto........................................................59Trabajando con los Párrafos de un Texto.........................................................................60Propiedades y Métodos de un Objeto..............................................................................62Contando los Párrafos......................................................................................................62Cursor dentro del Documento..........................................................................................63Aclaraciones Necesarias Sobre los Conceptos Expuestos de UNO...............................64
Servicios e Interfaces...................................................................................................64Propiedades.................................................................................................................65Módulos........................................................................................................................65
Módulos Básicos de UNO................................................................................................66Colecciones y Contenedores............................................................................................67Modificando el Estilo de la Primera Letra de Cada Párrafo.............................................68
Capítulo 6:.................................................................................................................................70Trabajando con Hojas de Cálculo:........................................................................................70
Accediendo a una Hoja de Cálculo..................................................................................70Filas, Columnas y Celdas.................................................................................................71XRay: Herramienta para Desarrollo.................................................................................72
El Profesor Ahora Cuenta con Excel................................................................................72Mejorando lo Presente......................................................................................................74Generando Gráficos a Partir de los Datos Existentes en una Hoja de Cálculo...............78Asociando los Macros a Documentos Específicos..........................................................80Buscando Cadenas..........................................................................................................80Diálogos Personalizados para Macros.............................................................................82Integrando un Buscador en Línea a OO..........................................................................82Añadiendo un Diálogo a la Macro Anterior.......................................................................83Calculadora RPN programada en Open Basic................................................................89
Capítulo 7..................................................................................................................................98Introducción a Open Base....................................................................................................98
Implementando un Sistema para Control de Citas Básico..............................................98Integración de Macros a los Formularios de Base.........................................................105Ejemplos de Programación de Macros con Bases de Datos.........................................109Macros y ejercicios con Hojas de Cálculo......................................................................114Accediendo a Directorios y Archivos...............................................................................119Trabajando con DataPilot y alternativa al DataPilot.......................................................123Macro que modifica los datos de un DataPilot y lo refresca de forma automática........127Cuando DataPilot no es suficiente..................................................................................128Subformas en Base........................................................................................................131Programando Diálogos MultiStep...................................................................................139Make a Table Query, desde Open Base.........................................................................143
Bibliografía:..............................................................................................................................148Agradecimientos:.....................................................................................................................150
Programar muchas veces no es visto por la gente como un trabajo, al menos no con la remuneración que debería tener. Tienen razón quienes piensan que no es un trabajo, es más un reto creativo, el placer de
dominar la máquina y hacerla funcionar a voluntad. Se equivocan quienes no son capaces de reconocer el valor real de esta tarea creativa, pues si no cuentan con nadie que controle la máquina por ellos, que harán
entonces en poder de la máquina y su software por defecto?
Presentación:
Existen muchas formas y lenguajes en los que se puede programar, existen también muchos paradigmas y teorías que sirven de guía a los desarrolladores, pero en último caso será la mente del programador la que decida que solución dar al problema al que se enfrenta.
En las páginas siguientes se desarrollará un curso orientado a aquellas personas que desean aprender a escribir macros para Open Office haciendo uso de Open Basic. El curso no exige un conocimiento previo en programación, aunque saber algo de C o C++ podría ayudar.
Convenciones:
Se emplearán las siguientes convenciones para indicar partes claves del texto:
Este símbolo indica el comienzo de una explicación detallada
Este símbolo precede una nota importante para tener en cuenta a la hora de estar trabajando
Este símbolo indica el comienzo de un ejercicio práctico
Capítulo 1:
Introducción:
Open Basic (equivalente a StarOffice Basic) es un lenguaje de programación perteneciente a la familia de lenguajes tipo Basic (Beginners Allpurpose Symbolic Instruction Code1), es similar a Visual Basic y Visual Basic for Applications de Microsoft, aunque no cuenta con todas sus características.
Open Basic es un lenguaje interpretado línea por línea, esto quiere decir que el fin de línea es algo digno de tener en cuenta cuando se esté escribiendo un programa. Cuando la instrucción que se pretenda escribir no quepa en una sola línea puede emplearse el símbolo _ para escribir varias líneas como una sola:
ResultadoNomina = (calculo1 * calculo2)/numero_personas + _(porcentajeobtenido * 90) – 8*(numeroaleatorio2 + 100) + _otrosvalores
Por otra parte, si en algún momento se desea usar una sola línea para ingresar varias instrucciones cortas, puede dividirse la línea empleando el símbolo :
aux1 = 5 + topic1 : aux2 = 10 + topic3 : aux3 = aux1 + aux2
Aunque líneas largas y cortas son soportadas por el lenguaje, es importante tener siempre en cuenta que al momento de escribir un programa debe pensarse no sólo en los usuarios finales del mismo, sino en los “lectores” del código fuente2, es decir aquellos programadores que querrán ampliar o modificar el programa original, e incluso el mismo autor del programa quien puede retomarlo meses después. Siempre será más fácil para cualquiera de estos lectores, entender un código escrito de forma clara y limpia, que uno escrito de forma descuidada. Por esta razón es importante mantener el código fuente tan limpio y claro como sea posible.
1 Encuentra más información acerca de BASIC en el siguiente enlace: http://es.wikipedia.org/wiki/BASIC2 Recuerde que usted ahora está usando Software Libre por lo tanto debe comenzar a pensar como un
miembro de esta comunidad: http://www.gnu.org/philosophy/freesw.es.html
Por dónde comenzar?
Lo primero que debe hacerse para comenzar a programar con Open Basic es cargar Open Office en cualquiera de sus componentes, bien sea el procesador de texto, la hoja de cálculo, la base de datos, etc. Para este ejemplo en particular se trabajará con el componente hoja de cálculo.
Paso 1: inicie la hoja de cálculo de Open Office como lo hace habitualmentePaso 2: seleccione la opción: Tools > Macros > Organize Macros > OpenOffice.org Basic como se muestra en la siguiente imagen:
Paso 3: seleccione el item Standard que se encuentra dentro del grupo My Macros y de click sobre el botón New:
Paso 4: aparecerá frente a usted un cuadro de diálogo solicitándole el nombre de su módulo – un módulo es un conjunto de macros, piense en él como un programa , diligencie el nombre que desee y de click sobre el botón aceptar, acto seguido aparecerá el IDE3 de Open Office para el desarrollo de programas con Open Basic:
3 Integrated Development Environment
Importante: el nombre de un módulo NO puede contener espacios en blanco ni caracteres especiales como tildes, ñ, etc...
A partir de este punto se empleará este IDE para ir escribiendo y probando los diferentes códigos que se expondrán en este curso
Código de Muestra
Al cargarse por primera vez el IDE en un nuevo módulo, aparece un código de muestra con algunos elementos que conviene aclarar de una vez:
REM ***** BASIC *****
Sub Main
End Sub
La palabra REM indica un comentario, es decir una línea de código que no se ejecuta, pero que se incluye en el código con algún fin, generalmente el de documentar un punto importante del código o el de presentar los créditos de un tercero cuyo código está siendo empleado para un desarrollo propio.
La palabra Sub indica el comienzo de una subrutina dentro del módulo, es decir una parte del módulo que realiza una acción específica. Las subrutinas se comienzan con la palabra Sub seguida del nombre que se le quiera dar y se terminan con la palabra End seguida de la palabra Sub.
Hola Mundo
En todos los lenguajes de programación que existen, siempre conviene comenzar por implementar un pequeño programa denominado Hola Mundo. Se trata en la mayoría de los casos de un par de líneas de código muy simples que tienen como único fin acercar al aprendiz a la fuente del conocimiento sin atemorizarlo por oscuras y profundas que puedan parecer sus aguas.
En el caso de Open Basic el Hola Mundo es tan simple como es posible:
REM Este es el Programa Hola Mundo en Open Basic
Sub HolaMundoPrint "Hola Mundo en Open Basic"
End Sub
Para correr (ejecutar) este programa desde el IDE debe darse click sobre el botón como se ilustra en la imagen siguiente:
Luego de lo cual aparecerá el siguiente cuadro de diálogo:
Marcadores
En cualquier lenguaje de programación se requiere declarar variables y constantes, así como funciones. La palabra con la que se designa el nombre de estos elementos en Open Basic es Marcadores. Un Marcador es el nombre que se le da a una variable, a una constante o a una función. Existen algunas reglas que se deben respetar al momento de definir un Marcador:
1. Los Marcadores sólo pueden contener caracteres alfa numéricos y el signo de subrayado _.
2. Los caracteres especiales como las tildes, ñ, diéresis, no están permitidos3. Un Marcador debe comenzar con una letra o un _4. La longitud máxima de un Marcador es de 255 caracteres5. No existe diferencia entre mayúsculas y minúsculas; sin embargo para mantener el
código lo más limpio posible debe respetarse la forma en que se escribe un Marcador,
escribiéndolo siempre de la misma manera. Es importante observar esta regla pues si bien en términos generales Open Basic no diferencia entre mayúsculas y minúsculas, al usar más adelante algunos elementos avanzados si será necesario respetar la forma de escritura de los marcadores, así que es mejor acostumbrarse a hacerlo desde un comienzo
Ejemplos de Marcadores admitidos
NombreMediconombrepacienteaux1_sumador
Ejemplo de Marcadores inválidos
MarcadorInválido8sumaniños
Otra forma de incluir comentarios en un programa de Open Basic es incluyéndolos directamente en la línea sobre la que se está trabajando, para hacer esto se incluye un apostrofe al final del código y a continuación el comentario, por ejemplo:
NombreMédico 'este Marcador es inválido por la tilde
Variables
Una variable es una representación simbólica que denota una cantidad o expresión4. En Open Basic no es necesario definir una variable antes de usarla, de hecho las variables son definidas al momento de ser usadas por primera vez, a esta característica se le conoce con el nombre de Declaración Implícita de variables. Sin embargo si bien esta característica puede parecer atractiva a simple vista en realidad se puede convertir en fuente de problemas, ya que un simple error tipográfico podría declarar una nueva variable y generar un resultado desconcertante en un programa, por ejemplo en el siguiente fragmento de código:
Sub ErrorFacilDeCometeraux1 = 5 'se declara una variable aux1 con el valor de 5b = aux*2 'se declara b para almacenar el valor de aux1 X 2'pero por accidente se cambia el nombre de aux1 a auxPrint b 'el resultado no sera 10 como se podria esperar
End Sub
Para evitar este tipo de problemas Open Basic cuenta con la opción de forzar la declaración Explícita de las variables que se deseen usar, para activar esta opción debe incluirse la siguiente línea al comienzo de cada programa:
Option Explicit
El mismo código anterior incluyendo esta opción se ve de la siguiente forma:
REM Declaracion Explicita de Variables
Option Explicit 'de esta forma se obliga a declarar cada variable
4 http://en.wikipedia.org/wiki/Variable
'antes de poder usarla
Sub ComoEvitarloDim aux1 'se declara la variable aux1aux1 = 5 'aux1 recine el valor de 5Dim b 'se declara bb = aux*2 'b almacena el valor de aux1 X 2'pero por accidente se cambia el nombre de aux1 a auxPrint b 'el resultado no sera 10 como se podria esperar
End Sub
Ahora cuando se intenta ejecutar el programa aparece el siguiente mensaje de error:
De esta forma es imposible declarar accidentalmente variables y se tiene un mayor control sobre el programa que se está desarrollando, por lo tanto es una opción altamente recomendada y se usará a partir de este punto durante el resto de este curso.
Obsérvese como para declarar una variable se antepone al marcador la palabra Dim.
Tipos de Datos
Cuando una variable es definida de la forma: Dim Nombre, se le está asignando implícitamente el tipo variant. Esto permite que la variable almacene cualquier tipo de datos, un número entero, una cadena alfanumérica, etc. Sin embargo es preferible ser explícito a la hora de definir el tipo de una variable. La siguiente tabla ilustra las diferentes declaraciones que se deben usar para los diferentes tipos de datos soportados por Open Basic:
Tipo de Dato Forma de Declaración Forma Alternativa Valores Almacenados
Entero Dim Var1 As Integer Dim Var1% 32768, 32767
Cadena Dim Var1 As String Dim Var1$ Hola Mundo!
Entero Largo Dim Var1 As Long Dim Var1& 2147483648, 2147483647
Simple Dim Var1 As Single Dim Var1! Valores positivos o negativos entre 3.402823 x 1038 y 1.401298 x 1045
Doble (los de mayor precisión)
Dim Var1 As Double Dim Var1# Valores positivos o negativos entre 1.79769313486232 x 10308
y 4.94065645841247 x 10
324
Moneda Dim Var1 As Currency Dim Var1@ Valores entre 922337203685477.5808 y +922337203685477.5808
Boolean Dim Var1 As Boolean True, False
Date Dim Var1 As Date Fecha
Originalmente se definió el tipo Simple como una alternativa para el manejo de números de punto flotante en máquinas con poca capacidad de memoria, hoy en día esta consideración es irrelevante por lo que este tipo no es usado en la práctica.
Práctica con Tipos de Dato Numéricos
El siguiente ejercicio pretende demostrar la diferencia entre trabajar con tipos de dato Double y tipos de dato Integer
REM Ejercicio con tipos de datos numericos
Option Explicit 'se prefiere la declaracion explicita de variables
Sub ProfeCuchillaREM esta subrutina representa a un profesor muy exigenteREM que esta calificando a uno de sus alumnosREM como buen profesor cuchilla no sube una decima
Dim Parcial1 As DoubleDim Parcial2 As DoubleDim Parcial3 As Double' La declaracion de estas variables se habria podido realizar en
una' sola linea de la siguiente forma:' Dim Parcial1 As Double, Parcial2 As Double, Parcial3 As Double
Dim ExamenFinal As DoubleDim NotaFinal As Double
Parcial1 = 3.01Parcial2 = 2.21Parcial3 = 3.70
ExamenFinal = 3.00
NotaFinal = Parcial1 + Parcial2 + Parcial3 + ExamenFinalNotaFinal = NotaFinal/4Print NotaFinal
End Sub
Al ejecutar este ejercicio se obtiene la siguiente respuesta:
Pero si al mismo ejercicio se le introduce el siguiente cambio:
REM Ejercicio con tipos de datos numericos
Option Explicit 'se prefiere la declaracion explicita de variables
Sub ProfeCuchillaREM esta subrutina representa a un profesor muy exigenteREM que esta calificando a uno de sus alumnosREM como buen profesor cuchilla no sube una decima
Dim Parcial1 As DoubleDim Parcial2 As DoubleDim Parcial3 As Double' La declaracion de estas variables se habria podido realizar en
una' sola linea de la siguiente forma:' Dim Parcial1 As Double, Parcial2 As Double, Parcial3 As Double
Dim ExamenFinal As DoubleDim NotaFinal As Integer 'El profe ya no es tan cuchilla
'y redondea la nota
Parcial1 = 3.01Parcial2 = 2.21Parcial3 = 3.70
ExamenFinal = 3.00
NotaFinal = Parcial1 + Parcial2 + Parcial3 + ExamenFinalNotaFinal = NotaFinal/4Print NotaFinal
End Sub
La respuesta obtenida cambia significativamente – al menos para el estudiante:
Así como en el ejercicio anterior se definieron valores de punto flotante, también pueden definirse valores exponenciales como: 1.34E4; para otro tipo de valores como los hexadecimales se deben definir variables tipo LONG que los almacenen y se ingresan de la siguiente forma: &HEE, &H02; es decir siempre antecedidos por los símbolos &H
Vectores y Matrices
Un vector es un arreglo unidimensional, es decir una fila o columna de posiciones donde se pueden almacenar objetos – variables. Una matriz es un arreglo bidimensional, es decir un conjunto de filas y columnas de posiciones donde se pueden almacenar objetos – variables.
Para definir un vector se emplea una sintaxis como la utilizada para definir cualquier otro tipo de variable, pero luego del marcador y dentro de paréntesis se especifica el tamaño del vector – el número de posiciones:
Dim MiVector(5) As Integer
Para definir una matriz aplica la anterior explicación, pero con la adición de un valor más dentro de los paréntesis – quedando especificado de esta forma el número de columnas y el número de filas de la misma:
Dim MiMatriz(5, 3) As Integer
Aclaración importante: al definir un vector como Dim MiVector(5) se está definiendo un vector de 6 posiciones no 5 , numeradas desde el número 0 hasta el número 5
Práctica con Vectores
Para acceder a las diferentes posiciones de un Vector basta con indicar dentro del paréntesis la posición a la que se quiere acceder, para entender esto mejor se presenta de nuevo el ejemplo del Profesor Cuchilla empleando en esta oportunidad un Vector para almacenar las notas de los parciales:
REM Ejercicio con Vectores
Option Explicit 'se prefiere la declaracion explicita de variables
Sub ProfeCuchillaREM esta subrutina representa a un profesor muy exigenteREM que esta calificando a uno de sus alumnosREM como buen profesor cuchilla no sube una decima
Dim NotasParciales(2) As DoubleNotasParciales(0) = 3.01NotasParciales(1) = 2.21NotasParciales(2) = 3.70
Dim ExamenFinal As DoubleDim NotaFinal As Double 'El profe ya no es tan cuchilla y
redondea la nota
ExamenFinal = 3.00
NotaFinal = NotasParciales(0) + NotasParciales(1) + NotasParciales(2) + ExamenFinal
NotaFinal = NotaFinal/4Print NotaFinal
End Sub
Operadores en Open Basic
Hasta este punto se han presentado algunos ejemplos en los cuales se ha venido haciendo uso de operadores matemáticos simples, la suma: + y la división: /. Open Basic cuenta con un amplio rango de operadores de diferentes tipos, los cuales es conveniente presentar
ahora para poder continuar con el desarrollo de este curso.
Operadores Matemáticos:
+ : se emplea como se ha visto hasta ahora para realizar la adición entre números, pero también se puede utilizar para sumar fechas y concatenar cadenas de texto5
: se utiliza para sustraer números y fechas* : se emplea para multiplicar números/ : se emplea para la división de números\ : este operador también se utiliza para dividir números pero el resultado que devuelve es redondeado^ : se utiliza para elevar enteros a potenciasMOD : este último operador se utiliza para obtener el residuo de una división
Operadores Lógicos:
Los operadores lógicos se emplean con tipos de datos enteros o booleanos, permiten relacionar dichos elementos mediante las reglas del álgebra de Boole6.
AND: Operación de Y LógicoOR: Operación de O LógicoXOR: Operación de O exclusivoNOT: NegaciónEQV: Prueba de equivalenciaIMP: Implicación (si la primera expresión es verdadera, la segunda también debe serlo)
Operadores de Comparación:
Los operadores de comparación permiten – valga la redundancia – comparar dos variables de cualquier tipo.
= : Igualdad, aplica a números, fechas y cadenas de texto<> : Desigualdad, aplica a números, fechas y cadenas de texto> : Comprobación de mayor que, aplica a números, fechas y cadenas de texto>= : Comprobación de mayor o igual que, aplica a números, fechas y cadenas de texto< : Comprobación de menor que, aplica a números, fechas y cadenas de texto
5 También es posible concatenar cadenas de texto usando el símbolo , (coma)6 http://en.wikipedia.org/wiki/Boolean_algebra_%28logic%29
<= : Comprobación de menor o igual que, aplica a números, fechas y cadenas de texto
Tiempo para relajarse
Capítulo 2:
Control de Flujo:
Los ejemplos presentados anteriormente corresponden a una clase muy básica de programas, una en la cual dados unos datos de entrada se realizan operaciones aritméticas sobre los mismos y se imprime el resultado. A partir de este punto se comenzará a evaluar la información sobre la que se está trabajando y a tomar decisiones dependiendo de los resultados de dicha evaluación.
If ... Then ... Else
Una de las expresiones para control de flujo de un programa que más se emplea es la de evaluar un valor y tomar una decisión si se cumple determinado valor . Retomando el ejemplo del profesor anterior, se podría presentar una nota más amable – no necesariamente más alegre al alumno en cuestión :
REM Ejercicio con Vectores
Option Explicit 'se prefiere la declaracion explicita de variables
Sub ProfeCuchillaREM esta subrutina representa a un profesor muy exigenteREM que esta calificando a uno de sus alumnosREM como buen profesor cuchilla no sube una decima
Dim NotasParciales(2) As DoubleNotasParciales(0) = 3.01NotasParciales(1) = 2.21NotasParciales(2) = 3.70
Dim ExamenFinal As DoubleDim NotaFinal As Double
ExamenFinal = 3.00
NotaFinal = NotasParciales(0) + NotasParciales(1) + NotasParciales(2) + ExamenFinal
NotaFinal = NotaFinal/4
REM dependiendo del resultado de la operacion se muestra un
mensaje
If NotaFinal < 3.0 Then Print "Usted ha reprobado el curso, su nota final es: " +
NotaFinalREM en la linea anterior se emplea + para concatenar
variablesElse Print "Usted ha aprobado el curso, su nota final es: " +
NotaFinalEnd If
End Sub
La ejecución de este programa ahora arroja el siguiente resultado:
Pero si las notas del estudiante son otras, el mensaje también cambia:
REM Ejercicio con Vectores
Option Explicit 'se prefiere la declaracion explicita de variables
Sub ProfeCuchilla
Dim NotasParciales(2) As DoubleNotasParciales(0) = 3.01NotasParciales(1) = 2.21NotasParciales(2) = 3.70
Dim ExamenFinal As DoubleDim NotaFinal As Double
ExamenFinal = 3.20
NotaFinal = NotasParciales(0) + NotasParciales(1) + NotasParciales(2) + ExamenFinal
NotaFinal = NotaFinal/4
REM dependiendo del resultado de la operacion se le muestra un mensaje u otro al usuario
If NotaFinal < 3.0 ThenPrint "Usted ha reprobado el curso, su nota final es: " + NotaFinalREM en la linea anterior se emplea + para concatenar variables
ElsePrint "Usted ha aprobado el curso, su nota final es: " + NotaFinal
End If
End Sub
Expresiones If Anidadas
Comúnmente se requiere la evaluación en cadena de varias expresiones If, es decir que una vez evaluada una condición se requiera evaluar una segunda condición. Para lograr este propósito es necesario usar varias instrucciones If “anidadas”. Otra posibilidad es que evaluada como falsa una primera condición se requiera evaluar la validez de una segunda condición, para lo cual se emplea la Instrucción ElseIf, el siguiente ejemplo ilustra mejor esta idea:
Sub CondicionesAnidadas
Dim EdadAsistente As IntegerDim ClasificacionPelicula As String
EdadAsistente = 15
ClasificacionPelicula = "E"
If ClasificacionPelicula = "R" Then
If EdadAsistente < 18 ThenPrint "Este asistente no puede ingresar a la
pelicula1"Else
Print "Ingreso Permitido"End If
ElseIf ClasificacionPelicula <> "R" ThenPrint "Pelicula Apta para Todo Publico"
End If
End Sub
Estructura de Control Select Case
En Ocasiones el anidamiento consecutivo de estructuras If hace que el código pierda legibilidad, por este motivo y porque se trata de una forma más adecuada de solucionar las situaciones en las cuales se deben realizar validaciones encadenadas se emplea la estructura de control Select.
La forma básica de emplear esta estructura es la siguiente:
Select Case NombreDeLaVariable 'se abre estructura de controlCase Opcion1: 'se define el valor número 1 a probar
instrucciones para esta opcion 'que hacer en este casoCase Opcion2:
instrucciones para esta opcion 'que hacer en este caso...Case OpcionN:
instrucciones para esta opcion 'que hacer en este casoCase Else:
instrucciones para esta opcion 'que hacer en cualquier otro casoEnd Select 'Se cierra la estructura de control
El mismo ejemplo del control de acceso a las películas puede implementarse usando una estructura de control SELECT de la siguiente manera, se adicionó la validación para películas XXX ya que como se plantea el ejercicio la primera vez un menor de edad podría ingresar a una película cualquiera que no fuera clasificación R:
Ingreso a peliculas – explicación SELECT CASE
REM Ejercicio para Ingreso a Peliculas
Option Explicit 'se prefiere la declaracion explicita de variables
Sub CondicionesAnidadas
Dim EdadAsistente As IntegerDim ClasificacionPelicula As String
EdadAsistente = 18
ClasificacionPelicula = "YXX"
Select Case ClasificacionPeliculaCase "E":
Print "Pelicula Apta para Todo Publico"Case "R":
If EdadAsistente < 18 ThenPrint "Pelicula Solo Adultos"
ElsePrint "Ingreso Permitido"
End IfCase "XXX":
If EdadAsistente < 18 ThenPrint "Pelicula Solo Adultos XXX"
ElsePrint "Ingreso Permitido"
End IfCase Else:
Print "Ingrese bajo su propia responsabilidad"End Select
End Sub
Dado que en el caso de que la variable ClasificacionPelicula valga R o valga XXX se realizan las mismas operaciones puede reescribirse el código anterior de la siguiente forma:
REM Ejercicio para Ingreso a Peliculas
Option Explicit 'se prefiere la declaracion explicita de variables
Sub CondicionesAnidadas
Dim EdadAsistente As IntegerDim ClasificacionPelicula As String
EdadAsistente = 17
ClasificacionPelicula = "R"
Select Case ClasificacionPeliculaCase "E":
Print "Pelicula Apta para Todo Publico"Case "XXX","R":
If EdadAsistente < 18 ThenPrint "Pelicula Solo Adultos XXX"
ElsePrint "Ingreso Permitido"
End IfCase Else:
Print "Ingrese bajo su propia responsabilidad"End Select
End Sub
Bucles o ciclos de ejecución
Una estructura de control muy importante es aquella que permite ejecutar varias veces la misma instrucción hasta que cierta condición es cierta. Open Basic provee dos estructuras para realizar este tipo de tareas. La primera de ellas es la estructura For ... Next, en la cual una instrucción se realiza hasta el momento en que el valor del contador del bucle o ciclo es alcanzado. Su sintáxis básica es la siguiente:
For NombreVariable = ValorInicial To Valor FinalInstrucciones a realizar
Next NombreVariable 'se incrementa la variable que actua como contador
La segunda forma de definir un bucle en Open Basic es utilizando la instrucción Do ... Loop, la diferencia fundamental es que utilizando esta segunda forma no se trabaja con un contador, sino con una condición lógica. Es decir que mientras ocurra algo con una condición lógica determinada, el contenido del bucle será ejecutado.
Determinando los números pares
Empleando lo visto hasta el momento y utilizando la estructura de control For Next, se presenta el siguiente ejemplo, el cual imprime en pantalla los números pares que existen en el rango 1 a 10:
REM Ejercicio para aprender a trabajar con Ciclos
Option Explicit 'se prefiere la declaracion explicita de variables
Sub BuclesEjemplo1
REM La idea de este ejemplo es ilustrar el usoREM basico de la estructura For Next
REM El ejemplo imprime los numeros pares del 1 al 10
Dim Contador As IntegerContador = 1For Contador = 1 To 10
If Contador MOD 2 = 0 ThenPrint Contador ," es un numero par " REM Usando la , para concatenar cadenas
ElseEnd If
Next Contador
End Sub
Empleando Do While Loop
Como se dijo anteriormente la principal diferencia entre las dos estructuras para control de ciclos de Open Basic, está en que Do ... Loop no hace uso de un contador sino de una condición lógica, las condiciones lógicas que pueden usarse son las siguientes:
Do While Loop: esta forma comprueba la validez de una condición al comienzo de cada paso y si es cierta realiza las instrucciones que se encuentren en el cuerpo del Loop.
Imprimiendo los números menores que la mitad del número mayor
Para ilustrar mejor el uso de la estructura Do While Loop se presenta el siguiente código de ejemplo. En el mismo se definen dos variables: NumeroMenor y NumeroMayor. La idea del ejemplo es que el ciclo ejecutará las instrucciones que contiene siempre y cuando la diferencia entre el NumeroMenor y el NumeroMayor sea menor que la mitad del NumeroMayor:REM Ejercicio para aprender a trabajar con Ciclos
Option Explicit 'se prefiere la declaracion explicita de variables
Sub BuclesEjemplo2
REM La idea de este ejemplo es ilustrar el usoREM basico de la estructura Do While Loop
Dim NumeroMayor, NumeroMenor As IntegerNumeroMenor = 1NumeroMayor = 10
REM Mientras el NumeroMenor sea menos que la mitadREM del NumeroMayor se ejecutaran las instruccionesREM del ciclo
Do While NumeroMayorNumeroMenor > NumeroMayor/2Print NumeroMenor," es menor que la mitad de",NumeroMayorNumeroMenor = NumeroMenor+1
Loop
End Sub
Do Loop While
Es muy similar al caso anterior, pero sólo realiza la validación luego de haber ejecutado por primera vez el contenido del bucle. De esta forma garantiza que al menos se ejecute una vez. Empleando esta estructura el ejemplo anterior quedaría de la siguiente forma:
REM Ejercicio para aprender a trabajar con Ciclos
Option Explicit 'se prefiere la declaracion explicita de variables
Sub BuclesEjemplo2
REM La idea de este ejemplo es ilustrar el usoREM basico de la estructura Do While Loop
Dim NumeroMayor, NumeroMenor As IntegerNumeroMenor = 1NumeroMayor = 10
REM Mientras el NumeroMenor sea menos que la mitadREM del NumeroMayor se ejecutaran las instruccionesREM del ciclo
DoPrint NumeroMenor," es menor que la mitad de",NumeroMayorNumeroMenor = NumeroMenor+1
Loop While NumeroMayorNumeroMenor > NumeroMayor/2
End Sub
Sin embargo para este caso en particular los resultados de la ejecución no difieren.
Do Until Loop
Mientras que en Do While se ejecutan las instrucciones contenidas en el ciclo mientras una condición es válida, en Do Until se ejecutan las instrucciones que se encuentran en el ciclo hasta que una condición sea cierta. Por ejemplo el siguiente código ilustra como se puede emplear esta estructura de control para imprimir las fechas anteriores a un día específico – en el caso del ejemplo el que corresponde a la variable FechaDeCorte :
REM Ejercicio empleando el Do Until Loop
Option Explicit 'se prefiere la declaracion explicita de variables
Sub BuclesEjemplo2
REM La idea de este ejemplo es ilustrar el usoREM basico de la estructura Do Until Loop
Dim FechaDeCorte, FechaActual As Date
'Las fechas se ingresan en formato MM/DD/YYYYFechaDeCorte = "08/31/2007"FechaActual = "08/13/2007"
Do Until FechaActual = FechaDeCortePrint "Aun no es dia de corte: "+FechaActualFechaActual = FechaActual+1
Loop
Print "Fecha de corte alcanzada: "+FechaActual
End Sub
Do Loop Until
Al igual que con Do Loop While, la única diferencia entre esta cuarta forma y su similar, es que el contenido del bucle se ejecuta antes de validar la condición necesaria para continuar.
Procedimientos y Funciones
Cuando un programa comienza a crecer en tamaño debido a la complejidad del problema que debe resolver, se hace uso de los procedimientos y las funciones para dividirlo en unidades más pequeñas. La diferencia fundamental entre un procedimiento y una función es que la segunda retorna un valor, mientras que el primero realiza una tarea pero no retorna ningún valor. Una vez escritas las funciones y los procedimientos, pueden ser llamados desde la rutina de ejecución principal.
La forma básica de un procedimiento es la siguiente:
Sub NombreProcedimiento'codigo que debe ejecutarse
End Sub
Por otra parte, la forma básica de una función es la siguiente:
Function7 NombreFuncion'codigo que debe ejecutarseNombreFuncion = ValorRetorno 'las funciones retornan un valor
End Function
Dado que las funciones devuelven un valor, es posible especificar el tipo de valor que devuelven al momento de su declaración de forma similar a como se hace con la declaración de variables:
Function NombreFuncion As Double'codigo que debe ejecutarseNombreFuncion = ValorRetorno 'retorna un valor Double
End Function
Adicionalmente las funciones y los procedimientos pueden recibir parámetros, esto es especialmente útil cuando se desea realizar por fuera de la rutina principal de ejecución una serie de operaciones sobre valores dados o capturados al momento de correr el programa. Para definir los parámetros que recibe una función y el tipo de los mismos se emplea la siguiente sintaxis:
Function NombreFuncion(Param1 As Double, Param2 As Double) As Double'codigo que debe ejecutarseNombreFuncion = ValorRetorno 'retorna un valor Double
End Function
Calculando en que momento y porque valor se debe renovar el seguro del carro
El siguiente ejemplo ilustra el uso de funciones para determinar en que momento y por que valor se debe pagar el seguro del auto:
REM Introduccion a los procedimientos y Funciones
Option Explicit
Sub Main 'esta sera la rutina central del programa
7 Puede usarse indistintamente la palabra Sub o Function para declarar una función, con el fin de mantener la legibilidad del código se sugiere usar Function
Dim ValorCarro As LongValorCarro = 20000000Dim FechaSOAT As DateFechaSOAT = "08/13/2006"
Dim DebeRenovarSOAT As Boolean
DebeRenovarSOAT = CalculaFecha(FechaSOAT)
If DebeRenovarSOAT = False ThenPrint "aun no es necesario renovar el SOAT"
ElsePrint "debe renovar el SOAT, el valor a pagar es de: " +
CalculaValorAPagar(ValorCarro)
End If
End Sub
Sub CalculaFecha(Fecha As Date) As BooleanDim Aux As DateAux = Date 'De esta forma se asigna la fecha actual a una
variableIf Aux Fecha < 365 Then 'aun no ha pasado un ano desde la
renovacionCalculaFecha = False
ElseCalculaFecha = True
End IfEnd Sub
Sub CalculaValorAPagar(Valor As Long) As DoubleCalculaValorAPagar = Valor * 1/100
End Sub
Es posible especificar parámetros opcionales para los procedimientos y funciones, es decir parámetros que si no son enviados no generarán un error en la ejecución del programa, de la siguiente manera: Sub NombreFuncion(Valor1 As Long, Optional Valor2 As Double)
Es posible – y constituye una buena práctica de programación – incluir puntos de salida en las funciones en caso de que algún error se presente el siguiente ejemplo ilustra como hacerlo en el caso del ejercicio del carro planteado párrafos atrás8:
REM Introduccion a los procedimientos y Funciones
Option Explicit
Sub Main 'esta sera la rutina central del programa
Dim ValorCarro As LongValorCarro = 20000000Dim FechaSOAT As DateFechaSOAT = "08/05/2006"
Dim DebeRenovarSOAT As Boolean
DebeRenovarSOAT = CalculaFecha(FechaSOAT)
If DebeRenovarSOAT = FALSE ThenPrint "aun no es necesario renovar el SOAT"
ElsePrint "debe renovar el SOAT, el valor a pagar es de: " +
CalculaValorAPagar(ValorCarro)
End If
End Sub
Sub CalculaFecha(Fecha As Date) As BooleanDim Aux As DateAux = Date 'De esta forma se asigna la fecha actual a una
variableIf Aux Fecha < 365 Then 'si aun no ha pasado un ano desde la
renovacion del SOATCalculaFecha = False
ElseCalculaFecha = True
End IfEnd Sub
Sub CalculaValorAPagar(Valor As Long) As Double
8 Para entender mejor el ejemplo presentado ejecute el código con las líneas resaltadas comentadas y luego con las líneas resaltadas sin comentar
Dim Error As BooleanIf Valor < 0 Then 'En caso de que el valor del carro sea
negativoError = True
ElseEnd If
If Error ThenExit Sub
End IfCalculaValorAPagar = Valor * 1/100
End Sub
Recursividad
Por recursividad se entiende la capacidad que tiene una función de llamarse a si misma hasta que encuentre el valor deseado. En Open Basic es posible incluir funciones recursivas. Para ilustrar mejor el concepto se incluye a continuación uno de los ejemplos clásicos de recursividad, el cálculo del factorial9:
Sub Main Msgbox CalcularFactorial( 3 ) Msgbox CalcularFactorial( 42 ) Msgbox CalcularFactorial( 3.14 )End Sub
Function CalcularFactorial( Numero ) If Numero < 0 Or Numero <> Int( Numero ) Then CalcularFactorial = "Número no válido para cálculo del factorial" ElseIf Numero = 0 Then CalcularFactorial = 1 Else
' Esta es la llamada recursiva: CalcularFactorial = Numero * CalcularFactorial( Numero 1 ) EndifEnd Function
9 Este ejemplo ha sido tomado de forma literal de la Guía de Programación para Star Office 8.
Determinando el Ingreso al Cine mediante funciones
El siguiente ejercicio hace uso de los conceptos vistos hasta el momento para recrear un control de acceso al cine basado en dos criterios, la edad del asistente y la clasificación de la película:
REM Ejercicio para aprender a trabajar con Funciones
Option Explicit 'se prefiere la declaracion explicita de variables
Sub Main 'Hilo central de ejecucionDim FechaNacimiento As DateDim ClasificacionPelicula As String
FechaNacimiento = "08/18/1989"ClasificacionPelicula = "R"
If DeterminarEdadMinima(ClasificacionPelicula) <= CalcularEdad(FechaNacimiento) Then10
MsgBox("Bienvenido a la Pelicula",0,"Taquilla Cine")Else
MsgBox("Usted no puede ingresar, lo sentimos",0,"Taquilla Cine")
End If
End Sub
Sub CalcularEdad(FechaN As Date) As Integer 'la edad se devuelve como un entero correspondiente a la edad en dias
Dim aux as Dateaux = DateCalcularEdad = aux FechaN
End Sub
Sub DeterminarEdadMinima(Clasificacion As String) As Integer 'la edad dada en numero de dias
SELECT CASE ClasificacionCASE "XXX", "R", "+18":
DeterminarEdadMinima = 18*365CASE "E", "Todos":
DeterminarEdadMinima = 1*365CASE "+12", "PG":
10 Esta línea debe ir completa, por motivos de formato en el texto se separa pero en el código debe ir como una sola línea
DeterminarEdadMinima = 12*365CASE ELSE
DeterminarEdadMinima = 0END SELECT
End Sub
Tiempo para relajarse
Capítulo 3:
La Biblioteca de Funciones de Open Basic:
Open Basic cuenta con una serie de funciones incluidas que hacen más fácil el trabajo diario del programador, a continuación se irán presentando funciones que podrán usarse para tareas como: conversión de variables, comprobación del contenido de las variables, manipulación de cadenas de texto, trabajo con fechas y monedas, diálogos de texto simple y diálogos de texto con que capturan valores.
Funciones para Conversión de Variables
En Open Basic existe la conversión implícita de variables, de tal manera una variable puede cambiar su tipo cuando es asignada a otra del tipo deseado, por ejemplo:
REM 'Conversion de variables
Option Explicit
Sub ConversionImplicita
Dim A As IntegerDim B As String
A = 100B = A
Print BEnd Sub
Sin embargo, al igual que los otros ejemplos de acciones implícitas, los resultados de trabajar de esta manera no son siempre los deseados, por esta razón es mejor emplear las funciones que convierten las variables de forma explicita de un tipo de datos a otro:
Nombre Descripción Parámetros de Entrada
CStr Convierte una variable de cualquier tipo a una cadena de texto
Una variable de cualquier tipo
CInt Convierte una variable de cualquier tipo a un Una variable de cualquier tipo
entero – si se intenta convertir una cadena de caracteres el resultado obtenido es 0 en sistemas tipo UNIX
CLng Convierte una variable de cualquier tipo a un tipo Long
Una variable de cualquier tipo – si se intenta convertir una cadena de caracteres el resultado obtenido es 0 en sistemas tipo UNIX
CSng Convierte una variable de cualquier tipo a un tipo Simple
Una variable de cualquier tipo – si se intenta convertir una cadena de caracteres el resultado obtenido es 0 en sistemas tipo UNIX
CDbl Convierte una variable de cualquier tipo a un tipo Double
Una variable de cualquier tipo – si se intenta convertir una cadena de caracteres el resultado obtenido es 0 en sistemas tipo UNIX
CBool Convierte una variable de cualquier tipo a un tipo Boolean
Una variable de cualquier tipo. Si se convierte el entero 1 el resultado es True, si se convierte el entero 0 el resultado es False
Val Convierte una variable de tipo string a una de tipo entero
Una cadena que represente un valor numérico
CDate Convierte una variable a tipo Date
Funciones para Validación del Contenido de las Variables
En ocasiones al intentar convertir una variable a otro tipo el intérprete de Basic emite mensajes de error y detiene la ejecución del programa. Un caso en el que esto ocurre es el siguiente:
Option Explicit
Sub ConversionExplicitaErrorDim MyVar2 As StringDim MyVar5 As Date
MyVar2 = "27022006"MyVar5 = CDate(MyVar2)
Print MyVar5
End Sub
Al intentar ejecutarlo se obtiene el siguiente mensaje de error:
Existen tres funciones básicas para comprobar el contenido de las variables:
Nombre Descripción Parámetros de Entrada
IsNumeric Determinar si el contenido de una variable es numérico
La variable que se desea evaluar
IsDate Determinar si el contenido de una variable es una fecha
La variable que se desea evaluar
IsArray Determinar si el contenido de una variable es un arreglo
La variable que se desea evaluar
Empleando la segunda de estas funciones es posible modificar el código anterior para evitar el mensaje de error:
REM 'Conversion de variables
Option Explicit
Sub ConversionExplicita
Dim MyVar2 As StringDim MyVar5 As Date
MyVar2 = "27022006"If IsDate(MyVar2) Then
MyVar5 = CDate(MyVar2)Print MyVar5
ElsePrint "La variable no es una fecha, no puede ser
convertida"End If
End Sub
Las variables cuentan con diferentes niveles de acceso, dentro de Open Basic se habla de los siguientes: público, privado, global. Una variable privada es accesible únicamente dentro de la sub rutina dentro de la cual se definió, mientras que una variable pública es accesible para todas las sub rutinas de un módulo. Una variable global es accesible para todos los módulos definidos dentro de una misma librería en Open Office. El acceso a las variables por defecto es definido como privado a menos que se especifique lo contrario.
Trabajando con Diferentes Niveles de Acceso:
Los siguientes ejemplos ilustran los diferentes resultados que se obtienen en un mismo programa al modificar los niveles de acceso de las variables empleadas.REM 'Modificando el acceso a las variables
Option Explicit
Sub MainDim MyVar1,MyVar2 As Integer 'Las variables son privadas por
defectoMyVar1=10MyVar2=1Print Sumar(MyVar1,MyVar2)Print Restar(MyVar1,MyVar2)Print MyVar1Print MyVar2
End Sub
Sub Sumar(Input1, Input2 As Integer) As IntegerDim Aux As IntegerAux = Input1+Input2'MyVar1 = 0 'se modifica el valor de la variable dentro de esta
funcionSumar = Aux
End Sub
Sub Restar(Input1, Input2 As Integer) As IntegerDim Aux As IntegerAux = Input1Input2'MyVar2 = 0 'se modifica el valor de la variable dentro de esta
funcionRestar = Aux
End Sub
En esta primera versión del programa todo funciona como es de esperarse, las líneas comentadas que modifican el valor de las variables definidas en la sub rutina Main deben dejarse comentadas para que el programa pueda ser ejecutado, de lo contrario aparecerá un error como el siguiente:
En el segundo escenario las variables han sido declaradas públicas y los resultados de la ejecución cambian por completo:
REM 'Modificando el acceso a las variables
Option Explicit
' las variables son publicas se declaran por fuera del procedimientoPublic MyVar1 As Integer Public MyVar2 As Integer
Sub MainMyVar1=10MyVar2=1Print Sumar(MyVar1,MyVar2)Print Restar(MyVar1,MyVar2)Print MyVar1Print MyVar2
End Sub
Sub Sumar(Input1, Input2 As Integer) As IntegerDim Aux As IntegerAux = Input1+Input2MyVar1 = 0 'se modifica el valor de la variable dentro de esta
funcionSumar = Aux
End Sub
Sub Restar(Input1, Input2 As Integer) As IntegerDim Aux As IntegerAux = Input1Input2MyVar2 = 0 'se modifica el valor de la variable dentro de esta
funcionRestar = Aux
End Sub
La ejecución de este programa arroja ahora los resultados: 11, 1, 0, 0; la razón de esto es que las variables son públicas y se pueden modificar en cualquier parte del programa.
Funciones para Acceso a Cadenas
Cuando se desea trabajar con variables de tipo texto Open Basic cuenta con funciones que facilitan la búsqueda y el acceso a la información dentro de éstas.
Función (parámetros)
Descripción Resultado
Left(Cadena,n) Devuelve los caracteres de Cadena que se encuentren hasta n posiciones después del inicio
Left(“Hola Mundo”,5) = Hola⌴
Right(Cadena,n) Devuelve los caracteres de Cadena que se encuentren hasta n posiciones antes del final
Right(“Hola Mundo”,5) = Mundo
Mid(Cadena,ori,n) Devuelve n caracteres de Cadena contando a partir de la posición ori
Mid(“Hola Mundo”,2,4) = ola⌴
Len(Cadena) Devuelve la longitud de la cadena
Funciones para Búsqueda y Reemplazo dentro de Cadenas
Open Basic cuenta con las siguientes funciones integradas que permiten la búsqueda dentro de variables tipo String y el reemplazo parcial o total del contenido de las mismas:
Función Parámetros Descripción Retorno
InStr ([Start As Long,] Text1 As String, Text2 As String[, Compare])
Realiza una búsqueda de la cadena Text2 dentro de la cadena Text1, a partir de la posición Start o desde el inicio de Text1 si este parámetro no se especifica. En caso de que el parámetro opcional Compare valga 0 la búsqueda es Case Sensitive
Un valor entero con la posición donde se encontró el inicio de la coincidencia o 0 en caso de no encontrar nada
Mid (Text As String, Start As Long , Length As Long, TextR As String)
Reemplaza la porción de texto de Text que se encuentra entre la posición Start y la posición Length por TextR
El siguiente ejemplo ilustra una búsqueda y reemplazo simple dentro de una cadena:
REM 'Manipulacion de cadenas
Option Explicit
Sub BusquedaYReemplazoDim MiCadena1 As StringDim Reemplazo As String
MiCadena1 = "Señor Juan Ramón Vargas"Reemplazo = "Doctor"
Print MiCadena1
Mid(MiCadena1,1,6,"Doctor") 'la primera posicion de la cadena es 1 no 0
Print MiCadena1
End Sub
Buscar y Reemplazar Mejorado
El ejercicio anterior plantea un nuevo problema, cómo hacer para qué al cambiar la palabra Señor por Doctor se conserve el espacio entre el título y el nombre, las respuestas – brindadas por los primeros alumnos de este curso – a continuación:
Opción 1:
REM 'Manipulacion de cadenas
Option Explicit
Sub BusquedaYReemplazoDim MiCadena1 As StringDim Reemplazo As StringDim Cadena as StringMiCadena1 = "Señor Juan Ramón Vargas"Reemplazo = "Doctor"
Print MiCadena1
Mid(MiCadena1,1,6,"Doctor") 'la primera posicion de la cadena es 1 no 0
Cadena = Left(MiCadena1,6)+ " " + Right(MiCadena1,17)Print Cadena
End Sub
Opción 2:
REM 'Manipulacion de cadenas
Option Explicit
Sub BusquedaYReemplazoDim MiCadena1 As StringDim Reemplazo As String
Dim Tamano, TamanoReemplazo As Integer
MiCadena1 = "Señor Juan Ramón Vargas"Reemplazo = "Doctor"
Print MiCadena1
Tamano = Len(MiCadena1)TamanoReemplazo = Len(Reemplazo)
Print Reemplazo + " " + Right (MiCadena1, Tamano TamanoReemplazo)
End Sub
Función para dar Formato a las Cadenas
En ocasiones luego de haber realizado los cálculos necesarios para obtener un valor, se desea presentar dicho valor de la forma más adecuada posible al usuario final, para formatear las variables de texto y presentarlas como se desee se utiliza la función Format:
Format (Number [, Format As String])
El formato que se desea dar se especifica como una cadena de texto, a esta cadena se le conoce con el nombre de plantilla y dentro de la misma es posible emplear los siguientes símbolos: el número cero (0), el símbolo número (#), el punto (.) , la coma (,) y el símbolo de moneda ($):
REM 'Formato a numero
Option Explicit
Sub PresentarSueldo
Dim SueldoCalculado As Long
Dim Visualizacion,Plantilla As String
SueldoCalculado = 5945670 'este valor es el sueldo de una persona
REM a continuacion se le daran diferentes formatos
REM para su presentacion:
REM el simbolo $ se emplea para que aparezca en pantalla
REM como dinero, el simbolo 0 se requiere para que el numero
REM sea visible
Plantilla = "$0"
Visualizacion = Format(SueldoCalculado,Plantilla)
Print Visualizacion
REM ahora se especifica una plantilla mas compleja en la cual
REM se indica la forma en la que se desea presentar la cifra
Plantilla = "$#,###,###.00"
Visualizacion = Format(SueldoCalculado,Plantilla)
Print Visualizacion
End Sub
Trabajando con Fechas
Aunque es posible asignar una fecha a una variable tipo Date mediante la asignación de una cadena de la forma “YYYY/MM/DD”, esto sólo funcionaría en los sistemas para los cuales se haya definido éste como el formato de fecha a utilizar. Para evitar problemas a la hora de portar aplicaciones de un equipo a otro o de un sistema operativo a otro es necesario utilizar la función DateSerial que incluye Open Basic. Su sintaxis básica es la siguiente: DateSerial (año, mes, día).
REM 'Trabajo con Fechas
Option Explicit
Sub FechasYHoras
Dim FechaNacimiento As Date
FechaNacimiento = DateSerial(1970,2,18)
Print "Fecha de Nacimiento: " + FechaNacimiento
End Sub
Existe también la función TimeSerial que se emplea para definir registros de tiempo que serán almacenados en las variables tipo Date, su sintaxis básica es la siguiente: TimeSerial (hour, minute, second).
REM 'Trabajo con Fechas
Option Explicit
Sub FechasYHoras
Dim FechaNacimiento As Date
Dim HoraNacimiento As Date
FechaNacimiento = DateSerial(1970,2,18)
Print "Fecha de Nacimiento: " + FechaNacimiento
HoraNacimiento = TimeSerial(2,15,00)
Print "Hora de Nacimiento: " + HoraNacimiento
End Sub
Qué Hora es?
Open Basic cuenta con tres funciones que permiten saber la fecha, la hora y el momento actual (fecha + hora). Dichas funciones y su sintaxis se exponen a continuación:
Función Retorno
Date Devuelve la fecha actual
Time Devuelve la hora actual
Now Devuelve la fecha + hora actual
Mensajes de Texto
Hasta el momento la salida de todos los programas presentados en el curso se ha realizado mediante la instrucción Print, esto está bien para comenzar a entender algunos conceptos básicos de programación sin embargo deja mucho que desear a la hora de interactuar con el usuario final11, por eso se presenta a continuación la función MsgBox la cual provee una forma más conveniente de mostrar información en pantalla.
MsgBox (Text As String [,Type As Integer [,Dialogtitle As String]])
La función MsgBox recibe tres parámetros de entrada, uno de ellos obligatorio correspondiente al texto que se desea mostrar los otros dos opcionales. El segundo parámetro es un número entero que se puede especificar para solicitar un tipo específico de ventana para el usuario, los valores posibles de este segundo parámetro son:
0 : Presenta una ventana con el botón OK – Aceptar únicamente
1 : Presenta una ventana con los botones Aceptar y Cancelar
2 : Presenta un diálogo de error con los botones: Abortar, Reintentar, Ignorar
3 : Presenta una ventana con los botones Si, No y Cancelar
4 : Presenta una ventana con los botones Si, No
5 : Presenta una ventana con los botones Reintentar y Cancelar
16 : Agrega un ícono de parada al diálogo que se está presentando
32 : Agrega un ícono de interrogación al diálogo que se está presentando
48 : Agrega un ícono de exclamación al diálogo que se está presentando
64 : Agrega un ícono de información al diálogo que se está presentando
El Tercer parámetro de la función es una cadena de texto que se usa como título del cuadro
11 “Programming today is a race between software engineers striving to build bigger and better idiotproof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.” Rick Cook, The Wizardry Compiled – tomado de: http://www.quotationspage.com/search.php3?homesearch=programming&sourceid=Mozillasearch
de diálogo presentado al usuario.
Diálogos Básicos con MsgBox
Usando uno de los ejemplos anteriores se cambiará la forma de presentar la información al usuario usando MsgBox en lugar de Print y aprovechando los símbolos especiales para los mensajes de error.
REM Introduccion a los procedimientos y Funciones
Option Explicit
Sub Main 'esta sera la rutina central del programa
Dim ValorCarro As Long
ValorCarro = 20000000
Dim FechaSOAT As Date
FechaSOAT = "08/05/2006"
Dim DebeRenovarSOAT As Boolean
DebeRenovarSOAT = CalculaFecha(FechaSOAT)
If DebeRenovarSOAT = FALSE Then
MsgBox("aun no es necesario renovar el SOAT",0,"Resultados de la Consulta")
Else
If CalculaValorAPagar(ValorCarro) <> 0 Then
MsgBox("debe renovar el SOAT, el valor a pagar es de: " + CalculaValorAPagar(ValorCarro),48,"Resultados de la Consulta")
End If
End If
End Sub
Sub CalculaFecha(Fecha As Date) As Boolean
Dim Aux As Date
Aux = Date 'De esta forma se asigna la fecha actual a una variable
If Aux Fecha < 365 Then 'si aun no ha pasado un ano desde la renovacion del SOAT
CalculaFecha = False
Else
CalculaFecha = True
End If
End Sub
Sub CalculaValorAPagar(Valor As Long) As Double
Dim Error As Boolean
If Valor < 0 Then 'En caso de que el valor del carro sea negativo
Error = True
Else
End If
If Error Then
MsgBox("El valor ingresado no es válido",16,"Valor Incorrecto")
Exit Sub
End If
CalculaValorAPagar = Valor * 1/100
End Sub
Los resultados de la ejecución del código anterior son visualmente más claros para el usuario final que si se emplea la instrucción Print.
Es posible especificar cual de los botones de un cuadro de diálogo se debe activar por defecto, para hacerlo se emplean las siguientes reglas: si se desea el primer botón activo por defecto, al valor del tipo de diálogo debe sumársele 128, si se desea que sea el segundo botón el activo por defecto debe sumársele 256 a dicho valor y, si se desea que sea el tercer botón la opción por defecto se suma 512 al valor que identifica el tipo de cuadro de diálogo. Un ejemplo de esto es el siguiente código, en el cual al aparecer un cuadro con los botones Aceptar y Cancelar se muestra como opción por defecto Cancelar, es decir el segundo botón de la ventana:
MsgBox("aun no es necesario renovar el SOAT",257,"Resultados de la
Consulta")
Captura de Datos Mediante Cuadros de Diálogo
El siguiente paso en este curso consiste en comenzar a capturar los valores empleados en la ejecución de los programas directamente desde el usuario, en lugar de hacerlo mediante la declaración en código como se ha venido presentando hasta este punto. Para capturar los datos del usuario se emplea la función InputBox:
InputBox (Msg As String[, Title As String[, Default As String[, x_pos As Integer, y_pos As Integer]]]])
Los parámetros de esta función corresponden a:
Msg: el mensaje que se desea presentar al usuario solicitándole un valorTitle: el título de la ventanaDefault: el valor por defecto que debe mostrarse y capturarse en caso de no recibir entrada de datos por parte del usuario
Los valores x_pos y y_pos se emplean para definir la ubicación de la ventana relativa al escritorio donde se esté ejecutando la aplicación.
Captura de datos con InputBox
REM Introduccion a los procedimientos y Funciones
Option Explicit
Sub Main 'esta sera la rutina central del programa
Dim ValorCarro As LongDim FechaSOAT As DateDim Aux As StringDim Aux2Date As Date
'A partir de este ejercicio los valores seran capturados'y luego procesadosAux = InputBox("Ingrese el valor de su vehículo: ","Cálculo de
SOAT","1000000")REM Dado que InputBox devuelve un string se emplea una variable
AuxREM para almacenar temporalmente la informacion capturada, luego
seREM emplean las funciones de conversion para llevarla al tipo
requeridoValorCarro = CLng(Aux)
Aux2Date = DateAux2Date = Aux2Date 365
Aux = InputBox("Ingrese la fecha en que renovó el seguro: ","Cálculo de SOAT",Aux2Date)
FechaSOAT = CDate(Aux)
Dim DebeRenovarSOAT As Boolean
DebeRenovarSOAT = CalculaFecha(FechaSOAT)
If DebeRenovarSOAT = FALSE ThenMsgBox("aun no es necesario renovar el
SOAT",257,"Resultados de la Consulta") Else
If CalculaValorAPagar(ValorCarro) <> 0 ThenMsgBox("debe renovar el SOAT, el valor a pagar es de:
" + CalculaValorAPagar(ValorCarro),48,"Resultados de la Consulta")End If
End If
End Sub
Sub CalculaFecha(Fecha As Date) As BooleanDim Aux As DateAux = Date 'De esta forma se asigna la fecha actual a una
variableIf Aux Fecha < 365 Then 'si aun no ha pasado un ano desde la
renovacion del SOATCalculaFecha = False
ElseCalculaFecha = True
End IfEnd Sub
Sub CalculaValorAPagar(Valor As Long) As Double
Dim Error As BooleanIf Valor < 0 Then 'En caso de que el valor del carro sea
negativoError = True
ElseEnd If
If Error ThenMsgBox("El valor ingresado no es válido",16,"Valor
Incorrecto")Exit Sub
End IfCalculaValorAPagar = Valor * 1/100
End Sub
Tiempo para relajarse
Capítulo 4:
UNO, la API de Open Office:
UNO: Universal Network Objects por sus siglas en inglés es una poderosa API12 con la que cuenta Open Office13, la cual puede ser utilizada desde diferentes lenguajes y brinda las herramientas necesarias para la construcción de macros que realicen tareas complejas sobre documentos e información existente.
Si bien Open Basic es un lenguaje por procedimientos, cuenta con los mecanismos necesarios para poder interactuar con los objetos de UNO, así también por el hecho de ser UNO un conjunto de objetos se hace necesario introducir en este punto algunos conceptos de la programación orientada a objetos que permitirán entender las explicaciones posteriores.
Utilización de UNO desde Open Basic
Para poder utilizar los objetos de UNO desde Open Basic es necesario declarar una variable de un tipo diferente a los vistos hasta ahora:
Dim ObjetoSimulado As Object
Una vez creado el objeto se debe inicializar asignándole un servicio:
ObjetoSimulado = createUnoService( com.sun.star.frame.Desktop )′ ′
Al momento de trabajar con documentos en Open Office, se emplean con mayor frecuencia los siguientes servicios:
com.sun.star.frame.Desktop : permite abrir, importar y crear documentoscom.sun.star.document.OfficeDocument : permite guardar, exportar e imprimir los documentos
12 http://en.wikipedia.org/wiki/API13 Para ser más exactos la API de OpenOffice está basada en UNO pero tiene algunas diferencias, la
información actualizada de la API de Open Office está disponible en línea en la siguiente dirección: http://api.openoffice.org/
Los servicios cuentan con interfaces, las interfaces son colecciones de métodos (funciones). El servicio com.sun.star.document.OfficeDocument provee la interfaz com.sun.star.frame.XComponentLoader la cual permite abrir documentos.
El servicio com.sun.star.frame.Desktop se carga por defecto al momento de iniciar Open Office y para acceder a él basta con invocar la variable global StarDesktop
Carga de un archivo con Open Basic
El siguiente ejemplo ilustra la forma en que se carga un documento existente en Open Office – para ejecutarlo exitosamente es indispensable que en el PC donde se corra exista un documento con el nombre requerido :
REM Cargar un archivo con Open Basic
Option Explicit
Sub MainDim Doc As ObjectDim Url As StringDim Dummy()Url = "file:///home/mad/Temp/pruebaclase.odt" 'formato URL14
Doc = StarDesktop.loadComponentFromURL(Url, "_blank", 0, Dummy())End Sub
Creación de un Nuevo Documento
Así como es posible cargar un documento existente es posible crear un nuevo documento:
REM Crear un nuevo archivo con Open Basic
Option Explicit
Sub MainDim Dummy()Dim Url As String
14 En el sistema operativo MSWindows esta ruta podría verse como: file:///C:/Mis%20Documentos/prueba.odt
Dim Doc As ObjectUrl = "private:factory/swriter"Doc = StarDesktop.loadComponentFromURL(Url, "_blank", 0,
Dummy())End Sub
Tiempo para relajarse
Capítulo 5:
Trabajando con Documentos de Texto:
Una vez presentados los conceptos básicos sobre UNO se presenta a continuación la información necesaria para comenzar a trabajar con documentos de texto desde Open Basic.
Elementos que Componen un Documento de Texto
En un documento de texto existen 4 clases básicas de información: el texto como tal, las plantillas que puedan haberse utilizado para el formato, los elementos diferentes de texto como tablas, gráficos, ecuaciones, y los parámetros de configuración global del documento.
La forma en que se recorren los documentos de texto en Open Office es utilizando enumeraciones, el siguiente ejemplo asume la existencia de un archivo de texto con párrafos en él:
REM Cargar un archivo con Open Basic
Option Explicit
Sub PruebaConDocDim Doc As ObjectDim Enum As ObjectDim ElementoTexto As Object' Crear objeto documentoDoc = StarDesktop.CurrentComponent' Crear objeto enumeraciónEnum = Doc.Text.createEnumeration' recorrer en bucle todos los elementos del textoWhile Enum.hasMoreElements
ElementoTexto = Enum.nextElement If ElementoTexto.supportsService("com.sun.star.text.TextTable") Then MsgBox "El bloque actual contiene una tabla."
End If If ElementoTexto.supportsService("com.sun.star.text.Paragraph") Then MsgBox "El bloque actual contiene un párrafo."
End IfWend
End Sub
La estructura de control de flujo While ... Wend resulta ideal cuando se requiere ejecutar una operación sobre un conjunto de elementos cuyo tamaño es desconocido de antemano y resulta, por esto mismo imposible usar un For ... Next
Si se utiliza la función MsgBox de la forma en que se presenta anteriormente se asume que los valores siguientes son: 0 y soffice
La instrucción ElementoTexto.supportsService permite saber si el objeto ElementoTexto soporta un servicio específico. Al decir: If ElementoTexto.supportsService("com.sun.star.text.TextTable") se está preguntando si el objeto ElementoTexto es de echo una Tabla dentro de un texto.
Trabajando con los Párrafos de un Texto
Es momento de integrar lo visto anteriormente con esta nueva parte de los objetos de UNO, el siguiente ejercicio presenta un programa que recorre un documento de texto y realiza ciertos reemplazos sobre el contenido de cada uno de los párrafos.
Sub ReemplazoEnDocDim Doc As ObjectDim Enumeracion As ObjectDim ElementoTexto As ObjectDoc = StarDesktop.CurrentComponent 'trabajar sobre el documento
actualEnumeracion = Doc.Text.createEnumerationWhile Enumeracion.hasMoreElements
ElementoTexto = Enumeracion.nextElement If ElementoTexto.supportsService("com.sun.star.text.Paragraph") Then ElementoTexto.String = Reemplazar(ElementoTexto.String, "a", "A")
ElementoTexto.String = Reemplazar(ElementoTexto.String, "e", "E") ElementoTexto.String = Reemplazar(ElementoTexto.String, "i", "I") End If
WendEnd Sub
Esta rutina requiere una función adicional no definida en Open Office:
Function Reemplazar(Origen As String, Busqueda As String, ParteNueva As String)
Dim Resultado As String Dim PosInicial As Long Dim PosActual As Long Resultado = "" PosInicial = 1 PosActual = 1 If Busqueda = " " Then Resultado = Origen Else Do While PosActual <> 0 PosActual = InStr(PosInicial,Origen,Busqueda,0) If PosActual <> 0 Then Resultado = Resultado + Mid(Origen,PosInicial,PosActual PosInicial) Resultado = Resultado + ParteNueva PosInicial = PosActual + Len(Busqueda) Else Resultado = Resultado + Mid(Origen, PosInicial, Len(Origen)) End If ' Posicion <> 0 Loop End If Reemplazar = ResultadoEnd Function
Usar Function en lugar de Sub a la hora de definir una función es más una guía para el programador y/o para el lector del código, ya se ha visto de acuerdo con los ejemplos anteriores que definiendo funciones empezando por Sub, éstas funciona sin ningún problema.
Propiedades y Métodos de un Objeto
Los objetos cuentan con propiedades y métodos, se ha venido haciendo uso de las dos cosas en los ejemplos anteriores y en este punto resulta más claro ilustrar cada concepto:
Cuando se usa la instrucción:
ElementoTexto.supportsService("com.sun.star.text.Paragraph")
Se está utilizando un método del objeto ElementoTexto, mejor aún del objeto UNO que éste representa. Los métodos son como las funciones o procedimientos, pero sólo pueden ser accedidos por objetos de una clase específica.
Cuando se usa la instrucción:
ElementoTexto.String = Reemplazar(ElementoTexto.String, "a", "A")
Se está accediendo a una propiedad del objeto ElementoTexto denominada String y se le está cambiando el valor de acuerdo con el valor de retorno – en este caso – de la función Reemplazar.
Los párrafos de un texto se subdividen a su vez en tantos elementos como formatos diferentes existan, por ejemplo la línea: esta es una prueba de formatos representa en realidad más de un párrafo, uno por cada formato definido.
Contando los Párrafos
Para el siguiente ejercicio cree un documento de texto que contenga una línea como la presentada en la observación anterior, es decir una donde se utilicen varios formatos de texto.
Sub CuantosParrafosHayDim Contador As IntegerDim Doc As Object
Dim Enum1 As ObjectDim Enum2 As ObjectDim ElementoTexto As ObjectDim FragmentoTexto As ObjectDoc = StarDesktop.CurrentComponentEnum1 = Doc.Text.createEnumerationContador = 0'bucle para todos los párrafosWhile Enum1.hasMoreElements
ElementoTexto = Enum1.nextElementIf
ElementoTexto.supportsService("com.sun.star.text.Paragraph") Then Enum2 = ElementoTexto.createEnumeration ' bucle para todos los subpárrafos While Enum2.hasMoreElements FragmentoTexto = Enum2.nextElement Contador = Contador + 1 Wend
End IfWendMsgBox("Hay "+Contador+" párrafos en total",0,"Contador de
Párrafos")End Sub
Cursor dentro del Documento
Un objeto que sirve con fines ilustrativos para continuar entiendo más acerca de esta adición al Open Basic es el objeto TextCursor el cual permite desplazarse dentro de un documento. No debe confundirse este objeto con el cursor visible que se presenta al usuario, son dos conceptos diferentes.
La creación de un objeto TextCursor se realiza de la siguiente manera – las líneas no resaltadas se incluyen pues no sería lógico pensar en un cursor de texto sin un documento sobre el cual trabajar :
Dim Doc As ObjectDim Cursor As ObjectDoc = StarDesktop.CurrentComponentCursor = TextDocument.Text.createTextCursor()
El objeto TextCursor cuenta con los siguientes métodos para desplazarse a un lado y otro dentro de un documento:
Método Descripción
goLeft(n, selecciona) se mueve a la izquierda n caracteres, los selecciona si selecciona es verdadero
goRight(n, selecciona) se mueve a la derecha n caracteres, los selecciona si selecciona es verdadero
gotoStart(selecciona) sitúa el cursor al comienzo del documento
gotoEnd(selecciona) sitúa el cursor al final del documento
gotoStartOfWord(selecciona) sitúa el cursor al comienzo de la palabra actual
gotoEndOfWord(selecciona) sitúa el cursor al final de la palabra actual
gotoNextWord(selecciona) sitúa el cursor al comienzo de la siguiente palabra en el párrafo actual
gotoPreviousWord(selecciona)
sitúa el cursor al comienzo de la palabra anterior en el párrafo actual
TextCursor cuenta con otros métodos que permiten el movimiento entre líneas y párrafos, los cuales serán explicados a medida que se utilicen en el desarrollo de este curso
Aclaraciones Necesarias Sobre los Conceptos Expuestos de UNO
A continuación se aclaran algunos de los elementos que se han venido utilizando en los últimos ejemplos, con el fin de continuar profundizando en el estudio del trabajo con UNO desde Open Basic.
Servicios e Interfaces: un servicio es una colección abstracta de interfaces y propiedades. Una interfaz es una colección de métodos.
El concepto se aclara mucho más con una asociación a la vida real, si se piensa en un vehículo como el servicio de análisis, puede decirse que el vehículo ofrece dos interfaces básicas: la interfaz del control de aceleración y la interfaz del control de dirección. La
interfaz de control de aceleración cuenta con dos métodos básicos: aceleración y frenado. La interfaz de control de dirección cuenta con dos métodos básicos: giro a la derecha y giro a la izquierda. Adicionalmente el servicio vehículo cuenta con las propiedades Color y Número de Sillas. Lo anterior se puede representar gráficamente en lenguaje UML15 de la siguiente forma:
Propiedades: las propiedades son las características de un servicio. Por ejemplo el servicio vehículo presentado anteriormente podría tener la propiedad: Color – Azul. Las propiedades siempre se presentan en parejas nombre – valor. Existen también algunas propiedades que son en realidad un arreglo de valores, por ejemplo las propiedades de un documento de texto o de una hoja de cálculo.
Módulos: los módulos en UNO agrupan servicios, interfaces, tipos, enumeraciones y estructuras de datos. Algunos módulos que se utilizan en el trabajo diario son: text, table, drawing y sheet. La estructura fundamental en que se organizan los módulos de UNO se presenta a continuación con el fin de proveer una idea general al lector y de esta forma ayudarle a comprender mejor los ejercicios previos y los venideros:
15 http://en.wikipedia.org/wiki/Unified_Modeling_Language
Módulos Básicos de UNO
Los siguientes son los módulos que más se utilizan al momento de programar con Open Basic16:
1. com.sun.star.chart: provee todos los servicios para trabajar con gráficos de datos. El más utilizado es tal vez ChartDocument(), el cual se utiliza para especificar los datos que deben ser representados gráficamente así como las características generales del gráfico.
2. com.sun.star.drawing: ofrece todos los servicios que se emplean para dibujar líneas, círculos, polígones, etc.
3. com.sun.star.frame: brinda el servicio Desktop(), mediante el cual se pueden abrir documentos existentes o crear nuevos documentos.
16 Para acceder a la documentación completa de la API para cada uno de los módulos puede acceder a la dirección web: http://api.openoffice.org/docs/common/ref/com/sun/star/moduleix.html
4. com.sun.star.presentation: provee los servicios necesarios para trabajar con presentaciones.
5. com.sun.star.sheet: agrupa los servicios necesarios para trabajar con hojas de cálculo. Uno de los servicios más importantes dentro de los que ofrece es SpreadheetDocument(), el cual permite trabajar con este tipo de documentos.
6. com.sun.star.table: provee los servicios que se emplean para trabajar con tablas en documentos de texto y hojas de cálculo.
7. com.sun.star.text: agrupa los servicios requeridos para trabajar con documentos de texto. El servicio TextDocument() brinda todas las interfaces necesarias para trabajar con este tipo de documentos.
Colecciones y Contenedores
Algunos de los componentes de UNO se agrupan en Colecciones y/o Contenedores. Un ejemplo de esto lo constituyen las hojas en un libro de hoja de cálculo, las cuales internamente son vistas como una colección de hojas de cálculo. De forma similar un documento de texto es en realidad una colección de párrafos.
Existen tres clases de colecciones diferentes de acuerdo con el tipo de acceso que proveen:
1. Los elementos de la colección tienen nombre y es posible acceder a cada elemento por su nombre. Este es el caso de un libro de hoja de cálculo, en el cual es posible ir de hoja en hoja utilizando el nombre que se haya designado a cada una de estas.
2. Los elementos no tienen nombre pero pueden accederse mediante un índice numérico.
3. Los elementos no tienen nombre y tampoco es posible acceder mediante un índice, es necesario recorrer completamente la colección. Este caso corresponde a las enumeraciones con las que se trabajaron los documentos de texto de los ejemplos presentados anteriormente.
Modificando el Estilo de la Primera Letra de Cada Párrafo
El siguiente ejemplo hace uso de los conceptos presentados y del objeto TextCursor para recorrer un documento y modificar la primera letra de cada párrafo dejándola en Negrilla – algo similar a lo que se ve en los cuentos infantiles .
Sub CambiarLasPrimerasLetrasREM la idea de esta macro es que recorra parrafo por parrafoREM un documento de texto y modifique la primera letra de cadaREM parrafo dejandola en negrita y 16 puntos
Dim Documento As ObjectDim Cursor As ObjectDim Enum1 As ObjectDim ElementoTexto As Object
Documento = StarDesktop.CurrentComponent 'se trabaja sobre el documento actualCursor = Documento.Text.createTextCursor()
REM linea de depuracion para saber que puede hacerse con el cursor
'MsgBox(Cursor.dbg_properties,1)
REM en este punto ya se tiene el documento y el cursor, REM se comienza ahora a trabajar parrafo por parrafo
Enum1 = Documento.Text.createEnumerationWhile Enum1.hasMoreElements
ElementoTexto = Enum1.nextElementIf
ElementoTexto.supportsService("com.sun.star.text.Paragraph") Then REM situar cursor al comienzo del parrafo Cursor.gotoStartOfParagraph(False) REM seleccionar la primera letra Cursor.goRight(1,True) REM cambiar a negrilla la letra seleccionada Cursor.charWeight = com.sun.star.awt.FontWeight.BOLD REM cambiar el tamano a la primera letra
Cursor.charHeight = 16 REM enviar el cursor al siguiente parrafo Cursor.gotoNextParagraph(False)
End IfWend
Capítulo 6:
Trabajando con Hojas de Cálculo:
Open Basic cuenta con las herramientas necesarias para poder programar poderosas macros que permitan la edición de hojas de cálculo así como la explotación de la información almacenada en ellas. A partir de este capítulo se trabajará con las ayudas de desarrollo existentes cuando sea posible hacerlo.
Accediendo a una Hoja de Cálculo
Para trabajar con las hojas de cálculo se utiliza el módulo com.sun.star.sheet y su servicio SpreadsheetDocument(). Para el siguiente ejemplo se requiere un documento de hoja de texto que contenga una hoja con el nombre nomina:
Sub CargarHojaXNombreDim Doc As ObjectDim Hoja As ObjectDoc = StarDesktop.CurrentComponentHoja = Doc.Sheets.getByName("nomina")REM si aun no es claro lo que hace este ejemplo cambieREM el nombre de la hoja nomina por uno que no exista
End Sub
También es posible cargar una hoja de un un documento de hoja de cálculo mediante su índice:
Sub CargarHojaXIndiceDim Doc As ObjectDim Hoja As ObjectDoc = StarDesktop.CurrentComponentHoja = Doc.Sheets(1)'MsgBox(Hoja.dbg_methods,1,"Qué Métodos Soporta este Objeto?")'MsgBox(Hoja.dbg_properties,1,"Qué Propiedades Tiene este
Objeto?")XRay Hoja 'XRay herramienta de depuracion para desarrolladoresREM a continuacion se cambia el nombre de la hojaHoja.setName("nuevo nombre")
End Sub
Filas, Columnas y Celdas
Como resulta apenas natural Open Basic provee mecanismos para acceder a las filas, las columnas y por supuesto las celdas de una hoja de cálculo. Para acceder a las filas y columnas se utilizan los servicios: com.sun.star.table.TableColumns y com.sun.star.table.TableRows, para acceder a las celdas puede emplearse com.sun.star.table.getCellByPosition.El siguiente ejemplo hace uso de los tres servicios enumerados anteriormente para realizar una navegación básica sobre una hoja de cálculo muy sencilla:
Sub NavegacionSimpleDim Doc As ObjectDim Hoja As ObjectDim Fila1 As ObjectDim Columna1 As ObjectDim Celda As Object
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(1)'XRay Hoja 'XRay herramienta de depuracion para desarrolladoresREM a continuacion se cambia el nombre de la hojaHoja.setName("filas celdas y columas")
Fila1 = Hoja.Rows(0)Columna1 = Hoja.Columns(0)
REM a continuacion se modifican las propiedades visibles deREM la fila y la columna seleccionadasColumna1.OptimalWidth = TrueFila1.IsVisible = False
REM a continuacion se inserta un nuevo textoCelda = Hoja.GetCellByPosition(0,5)'XRay CeldaMsgBox("Contenido Original: "+Celda.getString,1,"Info Celda")Celda.setString("Total")Celda = Hoja.GetCellByPosition(1,5)MsgBox("Contenido Original: "+Celda.getString,1,"Info Celda")'XRay CeldaCelda.setFormula("=sum(b1:b5)")
End Sub
XRay: Herramienta para Desarrollo
En los ejemplos anteriores se ha observado una línea como Xray NombreVariable, esta línea hace uso de una macro que resulta muy útil a la hora de programar nuevas macros, una macro desarrollada por Bernard Marcelly y que se convierte en una valiosa herramienta para poder acceder a las propiedades, métodos e interfaces de cada objeto que se emplea a la hora de construir un programa. XRay es una herramienta de Software Libre (licencia LGPL17) que puede ser descargada en forma de archivo sxw – por razones de compatibilidad con la versión anterior de la suite de Open Basic – desde la siguiente dirección web: http://ooomacros.org/dev.php#101416 – en esta misma dirección se encuentra un interesante conjunto de macros para Open Office . Las instrucciones de uso y el procedimiento de instalación se encuentran en este mismo archivo y una vez XRay se encuentra activa en el sistema es posible usarla para depurar cualquier objeto de la forma en que se ha presentado previamente.
El Profesor Ahora Cuenta con Excel
Implementación de una macro sencilla que haciendo uso de los conceptos presentados – y los conocimientos que el lector pueda tener en Excel recree el ejercicio del profesor presentando al comienzo de este curso, pero ahora leyendo las calificaciones de un archivo de Hoja de Cálculo y no sólo para un estudiante.
Solución 1:
Sub ProfeCuchillaMejoradoREM primera parte: cargar la hoja con las calificacionesDim Doc As ObjectDim Hoja As ObjectDim Celda As ObjectDim Columna As Integer
Dim ContadorX As IntegerDim NumeroAlumnos As Integer
NumeroAlumnos = 4
17 http://www.gnu.org/licenses/lgpl.html
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2) 'los indices comienzan en 0
REM para cada alumno obtenga el promedio
For ContadorX = 1 To 4Columna = ContadorXCelda = Hoja.GetCellByPosition(ContadorX,7)SELECT CASE Columna
CASE 1:Celda.setFormula("=AVERAGE(b2:b5)")
CASE 2:Celda.setFormula("=AVERAGE(c2:c5)")
CASE 3:Celda.setFormula("=AVERAGE(d2:d5)")
CASE 4:Celda.setFormula("=AVERAGE(e2:e5)")
END SELECTNEXT
End Sub
En esta solución se emplea un Case para determinar el promedio que debe realizarse:
Solución 2:
Sub ProfeCuchillaMejorado2Dim Doc As ObjectDim Hoja As ObjectDim Fila1 As ObjectDim Columna1 As ObjectDim Celda As Object
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2)
Fila1 = Hoja.Rows(0)Columna1 = Hoja.Columns(0)
REM a continuacion se modifican las propiedades visibles deREM la fila y la columna seleccionadasColumna1.OptimalWidth = True
For Contador = 1 To 4
Celda = Hoja.GetCellByPosition(Contador,7)Celda.setFormula("=sum(" + chr(Contador+65) + "3:" +
chr(Contador+65) + "6)/4") Next contador
End Sub
En esta solución se emplea la función chr para convertir en carácter el valor de la suma Contador + 65 y así establecer dinámicamente el valor que debe incluirse en la suma
Solución 3:
Sub ProfeCuchillaMejorado3Dim Doc As ObjectDim Hoja As ObjectDim Fila1 As ObjectDim Columna1 As ObjectDim Celda As Object
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2)
Fila1 = Hoja.Rows(0)Columna1 = Hoja.Columns(0)
Columna1.OptimalWidth = True
For Contador = 1 To 4 Celda = Hoja.GetCellByPosition(Contador,7)
Celda.setFormula("=average(" + Celda.columns.ElementNames(0) + "3:" + Celda.columns.ElementNames(0) + "6)")
Next contadorEnd Sub
Finalmente en esta solución se emplea el método ElementNames para saber el nombre de la columna sobre la que se está trabajando.
Mejorando lo Presente
Ahora y tomando como base las ideas de los asistentes a este curso18, se presenta una versión mejorada del ejercicio anterior, en el cual no sólo se toma el nombre de la celda mediante ElementNames sino que permite trabajar con un número mucho significativamente
18 A los cuales quiero agradecer pues sin su esfuerzo y colaboración gran parte del material acá presentado no existiría
mayor de estudiantes y calificaciones. Adicionalmente se presenta la forma de incluir en el archivo de Open Office Sheet un botón que llame la macro para que su ejecución resulte más sencilla para el usuario final.
Para este ejercicio se supone la existencia de un archivo como el que ilustra la siguiente imagen:
Sub ProfeCuchillaReloadedDim Doc As ObjectDim Hoja As ObjectDim Celda As ObjectDim Aux, CantidadEstudiantes, CantidadNotas As Double
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2)'se asume que los datos estan en la 3ra hoja
Celda = Hoja.GetCellByPosition(0,7)
Celda.CharColor = &HFFFFFF 'la idea es que los caracteres no se vean
Celda.setFormula("=COUNTA(c2:az2)") CantidadEstudiantes=Celda.getValue
Celda = Hoja.GetCellByPosition(0,8)Celda.CharColor = &HFFFFFF 'la idea es que los caracteres no se
veanCelda.setFormula("=COUNTA(c1:c100)")'XRay Celda CantidadNotas=Celda.getValueAux = CantidadNotas+1
For Contador = 1 To CantidadEstudiantes Celda = Hoja.GetCellByPosition(Contador+1,CantidadNotas+2) Celda.setFormula("=average(" + Celda.columns.ElementNames(0) + "3:" + Celda.columns.ElementNames(0) + Aux +")") Next contadorEnd Sub
Ahora el profesor que ejecuta esta macro puede calificar a todos sus alumnos y obtener el promedio de al menos 90 calificaciones. Para hacer la vida del profesor más fácil se incluirá en la hoja de cálculo desde la que se llama la macro un botón para realizar dicha acción.
Para incluir un botón es necesario activar dentro de la hoja de cálculo la barra de herramientas de Controles para Formas:
Una vez activa se puede ver en la hoja de cálculo un elemento como el siguiente:
Para poder incluir un nuevo elemento dentro de la hoja de cálculo debe activarse el modo de
edición haciendo click sobre el botón:
A continuación y para incluir un botón debe darse click sobre el botón:
Luego de esto el cursor cambia de aspecto y permite seleccionar la región donde se desea ubicar el botón. Una vez ubicado el nuevo botón la hoja de cálculo se ve como se ilustra a continuación:
Para modificar las propiedades del botón que se agregó basta con dar click con el botón derecho sobre éste y seleccionar del menú contextual que aparece la opción Control, la cual
trae una ventana con dos pestañas, en la primera de ellas (General) puede definirse la cadena de texto que se desea mostrar en el botón empleando para tal fin el campo Label, en la segunda pestaña (Events) se utiliza la opción ... que aparece junto a la acción: Mouse Button Pressed para acceder al listado de Macros disponibles y asociar a esta acción la macro deseada.
Generando Gráficos a Partir de los Datos Existentes en una Hoja de Cálculo
Para Generar un gráfico en Calc se emplea la secuencia:
1. Definición de la zona donde va a aparecer el gráfico2. Definición del rango de datos que se va a graficar3. Generación de un tipo de gráfica específica con sus propiedades correspondientes
El siguiente ejemplo asume la existencia de una tabla con información del tipo siguiente:
El código que se emplea para generar un Gráfico de Barras para esta información se presenta a continuación:
REM ***** BASIC *****Global aRect As New com.sun.star.awt.RectangleGlobal mRangeAddress(0) As New com.sun.star.table.CellRangeAddressGlobal oCharts As Object
Sub chart_init Dim Doc As Object
Dim Hoja As ObjectDim Celda As ObjectDim Aux, CantidadEstudiantes, CantidadNotas As Double
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(0)'se asume que los datos estan en la 1ra hoja
Hombres Mujeres20 512 129 13
10 103 2
BogotáManizalesPereiraCaliMedellín
REM definicion de la zona donde aparecera el grafico aRect.X = 8000 '8 cm a la derecha aRect.Y = 1000 '1 cm hacia abajo aRect.Width = 12000 '12 cm de ancho aRect.Height = 10000 '10 cm de alto REM definicion del rango del que se toman los datos mRangeAddress(0).Sheet = 0 mRangeAddress(0).StartColumn = 0 mRangeAddress(0).StartRow = 0 mRangeAddress(0).EndColumn = 2 mRangeAddress(0).EndRow = 5 oCharts = Doc.Sheets(0).Charts 'XRay oChartsEnd Sub
Sub chart1_sample chart_init() oCharts.removeByName("BarChart") 'se elimina si existe uno previo oCharts.addNewByName("BarChart",aRect,mRangeAddress(),TRUE, TRUE)End Sub
De la misma manera es posible incluir otro tipo de gráficos:
Gráficos de Línea:
Sub chart3_sampleDim oChart As Objectchart_init()oCharts.addNewByName("LineDiagram",aRect,mRangeAddress(),TRUE,
TRUE)oChart = oCharts.getByName("LineDiagram").embeddedObjectoChart.diagram =
oChart.createInstance("com.sun.star.chart.LineDiagram")oChart.diagram.DataRowSource =
com.sun.star.chart.ChartDataRowSource.COLUMNSEnd Sub
Asociando los Macros a Documentos Específicos
Hasta el momento se han desarrollado macros que se han guardado en los módulos generales de Open Office, sin embargo en muchas ocasiones es necesario guardar las macros en un documento que va a ser enviado luego a otra persona. Para poder adjuntar macros a un documento es necesario crear un módulo dentro del documento y dentro del mismo ingresar la o las macros que se desean adjuntar.
Buscando Cadenas
Una de las tareas que regularmente se tienen que realizar es la búsqueda de cadenas sobre un documento – bien sea una hoja de cálculo o un documento de texto . El siguiente ejemplo ilustra una búsqueda simple en la cual las mayúsculas y las minúsculas no importan:
Sub BuscarREM la idea con esta macro es recibir una cadena porREM parte del usuario y luego realizar la búsquedaREM Sin en la cadena viene un * se realiza una búsquedaREM por semejanza
Dim Cadena As StringDim DocDim HojaDim DescriptorBusqueda
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2)
Cadena = InputBox("Ingrese cadena a buscar")
DescriptorBusqueda = Hoja.createSearchDescriptor()
REM ahora es necesario fijar las propiedades de la busquedaDescriptorBusqueda.SearchString = Cadena
'XRay DescriptorBusqueda
Resultado = Hoja.findFirst(DescriptorBusqueda)
' XRay Resultado
If Resultado.String <> "" ThenMsgBox("La cadena se encuentra en el documento como:
"+Resultado.String,1,"BUSCADOR")Else
MsgBox("La cadena NO se encuentra en el documento",1,"BUSCADOR")
End If
' XRay Hoja
End Sub
También es posible realizar búsquedas que se vean afectadas por las mayúsculas y minúsculas definidas por el usuario, para este fin se emplea la propiedad: SearchCaseSensitive y se define con el valor True.
Pero qué ocurre en el resultado anterior si no existe un resultado para la búsqueda? La expresión Resultado.String <> “” tiene un problema y es que implica la existencia de Resultado, pero en caso de que una búsqueda no retorne ningún resultado Resultado NO existe y el programa arrojaría un error. Para solucionar este inconveniente se emplea la formulación lógica If NOT con la función isNull:
Sub BuscarREM la idea con esta macro es recibir una cadena porREM parte del usuario y luego realizar la búsquedaREM Sin en la cadena viene un * se realiza una búsquedaREM por semejanza
Dim Cadena As StringDim DocDim HojaDim DescriptorBusqueda
Doc = StarDesktop.CurrentComponentHoja = Doc.Sheets(2)
Cadena = InputBox("Ingrese cadena a buscar")
DescriptorBusqueda = Hoja.createSearchDescriptor()
REM ahora es necesario fijar las propiedades de la busquedaDescriptorBusqueda.SearchString = Cadena
DescriptorBusqueda.SearchCaseSensitive = True
' XRay DescriptorBusqueda
Resultado = Hoja.findFirst(DescriptorBusqueda)If NOT isNull(Resultado) Then
MsgBox("La cadena se encuentra en el documento como: "+Resultado.String,1,"BUSCADOR")
ElseMsgBox("La cadena NO se encuentra en el
documento",1,"BUSCADOR")End If
End Sub
Diálogos Personalizados para Macros
Hasta el momento los diálogos que emplean las macros presentadas, corresponden a los elementos que provee por defecto Open Basic para interactuar con el usuario, sin embargo en muchas ocasiones este tipo de elementos no es suficiente o se desea una mayor flexibilidad. Para alcanzar esta flexibilidad se presenta a continuación el diseño de diálogos personalizados y la forma como pueden asociarse con macros desarrolladas en Open Basic.
Integrando un Buscador en Línea a OO
El siguiente ejemplo ha sido tomado del sitio web: http://www.linux.com/articles/56307 y servirá como base del ejemplo siguiente en el que se incluirán los diálogos diseñados manualmente.
Supóngase que se desea incluir una macro en el sistema que permita buscar en línea el significado de una palabra en particular, para tal efecto se requiere que la macro permita seleccionar una palabra y que luego mediante un navegador web se conecte a un sitio como la wikipedia y obtenga su significado.
REM ***** BASIC *****
Sub WikipediaLookupoDoc=thisComponentoLookup=oDoc.CurrentController.getViewCursorIf oLookup.String ="" then MsgBox "Seleccione una palabra antes de
ejecutar la macro" : EndShell("firefox",1, "http://en.wikipedia.org/wiki/" & oLookup.String)
End Sub
Es importante resaltar como en este ejemplo se toma el documento actual llamando directamente a thisComponent, también como toda la declaración de las variables se realiza de forma implícita.
Añadiendo un Diálogo a la Macro Anterior
Si bien el ejemplo anterior es un código útil para incluir un buscador en línea, puede mejorarse en gran medida con un cuadro de diálogo que permita seleccionar diferentes motores para realizar la búsqueda. El siguiente ejemplo tomado de: http://freetrans.blogspot.com/2007/03/poniendoenprcticaooobasic.html ilustra la forma de hacer esto todo el ejemplo se desarrollará como una librería .
Paso 1: Cargar el Listado de Macros y Seleccionar la Opción Organizer Para Crear una Nueva Librería
Paso 2: Acceder al Listado de Librerías Dentro del Organizador
Paso 3: Crear una Nueva Librería
Con la nueva librería creada debe verse algo como los siguiente desde el organizador:
Al hacer click sobre el símbolo + a la izquierda de la nueva librería se despliega el contenido de la misma, dentro del cual por defecto aparece un primer módulo: Module1, se procede ahora a crear el diálogo deseado, para lo cual se accede al IDE de Open Office dando click sobre el botón Edit:
Una vez dentro del IDE se debe hacer click con el botón derecho sobre la pestaña del nuevo módulo y se selecciona a continuación las opciones que se ilustran en la siguiente imagen:
Como resultado de lo anterior aparecerá la interfaz para diseño de Diálogos de Open Basic en la cual se emplearán las herramientas existentes para crear un diálogo simple con un
listado desplegable de tres opciones y los botones de Aceptar y Cancelar:
Es muy importante editar las propiedades de los botones Aceptar y Cancelar y utilizar el campo Tipo para definir el tipo de botón que se desea usar:
Paso 4: Con el diálogo listo, se escribe la macro – inspirada en la que se presentó anteriormente – para que haga uso de éste en su interacción con el usuario:
REM ***** BASIC *****
Sub LookupWithGUI()
Dim Dialog As Object, Library As ObjectDim TheDialog As Object, DialogField As ObjectDim exitOK As String, CurrentItemPos As IntegerDim MotorBusqueda As String
'Los botones que se definan en el dialogo deben ser del tipo'OK y Cancel respectivamente para que la Macro pueda funcionar
URLArray=Array("http://www.google.com.co/search?q=definicion%3A",_"http://search.yahoo.com/search?p=",_"http://es.wikipedia.org/wiki/Special:Search?search=")
ThisDoc=ThisComponentLookupWord=ThisDoc.CurrentController.getViewCursor
'Validar que se haya seleccionado algoIf LookupWord.String <> "" Then
exitOK=com.sun.star.ui.dialogs.ExecutableDialogResults.OKLibrary=DialogLibraries.GetByName("Buscador1")TheDialog=Library.GetByName("Dialog1")
Dialog=CreateUnoDialog(TheDialog)'XRay Dialog 'depuracion del dialogoDialogField=Dialog.GetControl("ComboBox1")
'Se insertan las opciones en el ComboBox1DialogField.addItem("Google",1)DialogField.addItem("Yahoo!",2)DialogField.addItem("Wikipedia",3)
If Dialog.Execute=exitOK Then'XRay DialogField 'depuracion del combo boxMotorBusqueda = DialogField.SelectedText SELECT CASE MotorBusqueda
CASE "Google":Shell("firefox",1, URLArray(0) &
LookupWord.String)CASE "Yahoo!":
Shell("firefox",1, URLArray(1) & LookupWord.String)
CASE "Wikipedia":Shell("firefox",1, URLArray(2) &
LookupWord.String)CASE ELSE:
MsgBox("Selección Invalida",16,"Curso de Open Basic")
END SELECTEnd If
Dialog.Dispose
ElseMsgBox("Debe seleccionar una palabra antes de ejecutar esta
macro",16,"Curso Open Basic")
End If
End Sub
Calculadora RPN programada en Open Basic
A continuación se presenta una macro que integra una calculadora RPN simple a Open Office. El diálogo que representa dicha calculadora es el siguiente:
Solución 1: la solución más básica a este ejercicio no tiene en cuenta consideraciones como que podría ocurrir si al usuario le da por escribir en el display de la calculadora, sin embargo sirve para ilustrar la idea general del ejercicio:
REM ***** BASIC *****
Public Dialog As Object, Library As ObjectPublic TheDialog As Object, DialogField As ObjectPublic ButtonPressed As ObjectPublic Operando1 As Long, Operando2 As Long, Resultado As Long Sub Main 'Dim Dialog As Object, Library As Object 'Dim TheDialog As Object, DialogField As Object 'Dim ButtonPressed As Object Library = DialogLibraries.GetByName("CalculadoraSimple") TheDialog = Library.GetByName("Dialog1")
Dialog = CreateUnoDialog(TheDialog) 'XRay Dialog 'depuracion del dialogo
DialogField = Dialog.GetControl("TextField1") DialogField.setText("RPN Ready")
'Calculadora incializada y lista para usarse If Dialog.execute = 0 Then 'la calculadora se cierra cuando se cierra la ventana Dialog.Dispose End If
End Sub
Sub EnterPresionado Dim Aux As String 'se toma el valor que hay en el display y 'se define como primer operando DialogField = Dialog.GetControl("TextField1") Aux = DialogField.getText() 'se convierte la cadena en Entero Operando1 = CLng(Aux) 'se limpia el display DialogField.setText("")End Sub
Sub Sumar Dim Aux As String 'se toma el valor que hay en el display y 'se define como segundo operando DialogField = Dialog.GetControl("TextField1") Aux = DialogField.getText() 'se convierte la cadena en Entero Operando2 = CLng(Aux) 'se limpia el display Resultado = 0 Resultado = Operando1 + Operando2 Aux = CStr(Resultado) DialogField.setText(Aux)End Sub
Sub Restar Dim Aux As String 'se toma el valor que hay en el display y 'se define como segundo operando DialogField = Dialog.GetControl("TextField1") Aux = DialogField.getText() 'se convierte la cadena en Entero Operando2 = CLng(Aux) 'se limpia el display
Resultado = 0 Resultado = Operando1 Operando2 Aux = CStr(Resultado) DialogField.setText(Aux)End Sub
Sub Multiplicar Dim Aux As String 'se toma el valor que hay en el display y 'se define como segundo operando DialogField = Dialog.GetControl("TextField1") Aux = DialogField.getText() 'se convierte la cadena en Entero Operando2 = CLng(Aux) 'se limpia el display Resultado = 0 Resultado = Operando1 * Operando2 Aux = CStr(Resultado) DialogField.setText(Aux)End Sub
Sub Limpiar 'Esta funcion deja en 0 todas las variables 'del calculo y blanquea el display Operando1 = 0 Operando2 = 0 Resultado = 0 DialogField.setText("")End Sub
Sub PintarNumero0 Dim Aux As String DialogField = Dialog.GetControl("TextField1") 'se toma lo que haya en el display y se le concatena 'el 0 a la derecha, salvo si es otro 0 Aux = DialogField.getText If Aux <> "RPN Ready" Then If Aux <> "0" Then Aux = Aux + "0" Else Aux = "0" End If Else Aux = "0" End If 'se actualiza el display DialogField.setText(Aux)End Sub
Sub PintarNumero1 Dim Aux As String DialogField = Dialog.GetControl("TextField1") 'se toma lo que haya en el display y se le concatena 'el 1 a la derecha Aux = DialogField.getText If Aux <> "RPN Ready" Then If Aux <> "0" Then Aux = Aux + "1" Else Aux = "1" End If Else Aux = "1" End If 'se actualiza el display DialogField.setText(Aux)End Sub
....
Sub PintarNumero9 Dim Aux As String DialogField = Dialog.GetControl("TextField1") 'se toma lo que haya en el display y se le concatena 'el 1 a la derecha Aux = DialogField.getText If Aux <> "RPN Ready" Then If Aux <> "0" Then Aux = Aux + "9" Else Aux = "9" End If Else Aux = "9" End If 'se actualiza el display DialogField.setText(Aux)End Sub
Las soluciones 2 y 3 – enviadas las dos por participantes de este curso – resuelven el problema del display.
Solución 2, enviada por Yasser Camacho:
REM ***** BASIC *****Public Aux As StringPublic Dialog,Library,theDialog,DialogField As ObjectPublic actual, Actual1, ActualUno, ActualOperador As StringPublic operando1, Operando2, ResultadoFinal As Long
Sub Main
Library=DialogLibraries.getByName("calculadora")theDialog=Library.getByName("Dialog1")Dialog=CreateUnoDialog(theDialog)DialogField=Dialog.getControl("Texto")'XRay DialogFieldDialogField.enable = 0 'Deshabilita el teclado del PCIf Dialog.execute=0 Then
Dialog.DisposeEnd If
End Sub
Sub boton_ceroDialogField=Dialog.getControl("Texto")'XRay DialogFieldactual=DialogField.getTextIf actual = "0" or actual = "" Then
DialogField.SetText ("")ElseDialogField.setText (actual + "0")
End IfEnd Sub
Sub boton_unoDialogField=Dialog.getControl("Texto")actual=DialogField.getTextIf actual = "0" or actual = "" Then
DialogField.SetText ("1")ElseDialogField.setText (actual + "1")
End IfEnd Sub
...
Sub boton_nueveDialogField=Dialog.getControl("Texto")actual=DialogField.getText
If actual = "0" or actual = "" ThenDialogField.SetText ("9")ElseDialogField.setText (actual + "9")
End IfEnd Sub
Sub boton_enterDialogField=Dialog.getControl("Texto")ActualUno = DialogField.GetTextOperando1 = CLng (ActualUno)DialogField.SetText ("")'Print operando1End Sub
Sub boton_clearDialogField=Dialog.getControl("Texto")Actual1 = DialogField.GetTextCuentaClear = Len(Actual1)If CuentaClear > 0 Then
Actual1=Left(Actual1,CuentaClear 1)DialogField.SetText(Actual1)
End If'Print Actual1'XRay Actual1End Sub
Sub boton_sumaDialogField=Dialog.getControl("Texto")Actual2=DialogField.GetTextOperando2=Clng(Actual2)If Not IsNull (Operando1) Then
ResultadoFinal = Operando1 + Operando2DialogField.SetText (ResultadoFinal)
End IfEnd Sub
Sub boton_restaDialogField=Dialog.getControl("Texto")Actual2=DialogField.GetTextOperando2=Clng(Actual2)If Not IsNull (Operando1) Then
ResultadoFinal = Operando1 Operando2DialogField.SetText (ResultadoFinal)
End IfEnd Sub
Sub boton_multiplicacion
DialogField=Dialog.getControl("Texto")Actual2=DialogField.GetTextOperando2=Clng(Actual2)If Not IsNull (Operando1) Then
ResultadoFinal = Operando1 * Operando2DialogField.SetText (ResultadoFinal)
End IfEnd Sub
Solución 3, enviada por Fernando Méndez y Javier García:
REM ***** BASIC *****
Public operando1, operando2 as doublePublic aux as stringPublic dialogfield, textoOperando1, textoOperando2, textoOperacion as objectPublic dialog as object, library as objectpublic thedialog as object
Sub main
Library = DialogLibraries.getbyname("Standard")thedialog = Library.getByname("Calculadora_dg")Dialog = CreateUnoDialog(Thedialog)
If dialog.execute = 0 thenDialog.Dispose
end if
End sub
sub ceroDialogField = Dialog.getcontrol("txtPantalla")dialogfield.enable=1if Dialogfield.text="0" then
Dialogfield.text=""end ifDialogField.setText(Dialogfield.text+"0")dialogfield.enable=0
end sub
sub unoDialogField = Dialog.getcontrol("txtPantalla")dialogfield.enable=1
if Dialogfield.text="0" thenDialogfield.text=""
end ifDialogField.setText(Dialogfield.text+"1")dialogfield.enable=0
end sub
...
sub nueveDialogField = Dialog.getcontrol("txtPantalla")dialogfield.enable=1if Dialogfield.text="0" then
Dialogfield.text=""end ifDialogField.setText(Dialogfield.text+"9")dialogfield.enable=0
end subsub enter
DialogField = Dialog.getcontrol("txtPantalla")operando1= CDbl(dialogfield.text)Dialogfield.text=""textoOperando1=Dialog.getcontrol("lblOperando1")textoOperando1.text=cstr(Operando1)
end subsub suma
DialogField = Dialog.getcontrol("txtPantalla")operando2= CDbl(dialogfield.text)Dialogfield.text=operando1+operando2
textoOperando2=Dialog.getcontrol("lblOperando2")textoOperando2.text=cstr(Operando2)textoOperacion=Dialog.getcontrol("lblOperacion")textoOperacion.text="+"
end subsub resta
DialogField = Dialog.getcontrol("txtPantalla")operando2= CDbl(dialogfield.text)Dialogfield.text=operando1operando2
textoOperando2=Dialog.getcontrol("lblOperando2")textoOperando2.text=cstr(Operando2)textoOperacion=Dialog.getcontrol("lblOperacion")textoOperacion.text=""
end subsub multiplica
DialogField = Dialog.getcontrol("txtPantalla")operando2= CDbl(dialogfield.text)
Dialogfield.text=operando1*operando2
textoOperando2=Dialog.getcontrol("lblOperando2")textoOperando2.text=cstr(Operando2)textoOperacion=Dialog.getcontrol("lblOperacion")textoOperacion.text="*"
end subsub clear
operando1=0DialogField = Dialog.getcontrol("txtPantalla")DialogField.text=""
textoOperando1=Dialog.getcontrol("lblOperando1")textoOperando1.text=""
textoOperacion=Dialog.getcontrol("lblOperacion")textoOperacion.text=""
textoOperando2=Dialog.getcontrol("lblOperando2")textoOperando2.text=""
end sub
Tiempo para relajarse
Capítulo 7:
Introducción a Open Base:
La forma básica de utilización de Base resultará familiar para las personas que han venido trabajando antes con otras herramientas como Access o Kexi, OOO Base cuenta con un asistente para la creación de tablas que resulta adecuado para la mayoría de las necesidades de los usuarios regulares.
Implementando un Sistema para Control de Citas Básico
El siguiente ejercicio pretende alcanzar la implementación de un sistema básico para el control de citas de un grupo de médicos, el modelo básico sobre el que se desarrollará el sistema es el siguiente:
Paso 1: Creación de la nueva base de datos en Open Base
Paso 2: Creación de las tablas mediante la vista de diseño. Para evitar inconvenientes con los tipos de datos INTEGER se sugiere usar tipos de datos NUMERIC para los campos de cédula. Asimismo se sugiere definir dichos campos como la llave primaria de las tablas que los incluyan – las llaves primarias sugeridas aparecen en el gráfico anterior con un símbolo
gráfico al lado derecho .
Tabla Paciente:
Tabla Doctor:
Tabla Cita:
Paso 3: Creadas estas tres tablas se procede a crear las formas requeridas para trabajar con ellas, con el fin de probar que lo definido hasta el momento esté bien. Una buena idea a la hora de diseñar los formularios podría ser la de definir el nombre para cada control. Asimismo se recomienda emplear campos tipos Formatted Field cuando se debe exigir un formato de entrada específico, para cadenas de texto un TextBox es suficiente. No olvide asociar mediante la pestaña Data cada cuadro para ingreso de datos con el campo correspondiente en la base de datos
Si al momento de diseñar la forma no se incluye la barra de navegación, pero en las propiedades de la forma se solicita la misma aparecerá cuando se desee usar la forma:
Es posible copiar y pegar formas previamente diseñadas para usarlas como base al momento de diseñar nuevas, esto puede significar un ahorro importante de tiempo, sin embargo es importante adecuar la forma que se está copiando a la nueva tabla, sus nuevos campos, etc...
De esta manera la nueva forma requerida para el ingreso de la información de los pacientes está lista en muy poco tiempo:
Dado que los estados de afiliación de un pacientes deben ser valores predefinidos en un conjunto X, resulta buena idea dejar este campo como un listado de selección y alimentar dicho listado con los valores de una tabla especificada para tal fin:
Atención: las siguientes imágenes aparecen cuando se tiene activo el asistente de controles dentro del diseño de las formas:
Tan pronto como se define el nuevo control List Box dentro de la forma aparece el Asistente y como primer paso es necesario seleccionar la tabla que alimentará las opciones del listado:
Una vez definida la tabla que se desea usar, el asistente pregunta por el campo del cual se deben obtener los valores:
Finalmente el Asistente debe saber en que campo de la tabla sobre la que trabajará esta forma serán guardados los valores seleccionados, asimismo necesita saber si se desea guardar el mismo valor que se está presentando al usuario – en este caso en particular sería posible que el usuario seleccionara Activo, pero que en la tabla paciente se grabara el valor de 0 :
Al momento de diseñar la forma para el ingreso de citas es recomendable emplear controles tipo Date para capturar las fechas, estos campos pueden configurarse para manejar un rango y formato específico, así como para que incluyan un botón de ir hacia adelante o hacia atrás bien sea por día, por mes o por año:
Hasta este punto no se han definido las relaciones para las 3 tablas que se han implementado, sin embargo resulta una buena idea hacerlo ahora y activar las opciones de eliminación y de actualización en cascada.
Integración de Macros a los Formularios de Base
Ahora se desea incluir algunas funcionalidades en el formulario para diligenciar las observaciones que requieren hacer uso de lo visto de macros hasta el momento y de algunos conceptos básicos de SQL. Para comprender los siguientes ejemplos se presenta la forma base sobre la que se desarrollarán los mismos:
Ejemplo 1: Macro que pinte el número de historia médica a partir de la cédula del paciente.
La siguiente macro se encarga de capturar el valor digitado en el campo cédula paciente tan pronto como el cuadro de texto pierde el foco (para tal fin se asocia el evento When Losing Focus del campo de cédula paciente con la macro obtenerIdHistoriaClinica), con este valor llama a la función consultaridxcedula la cual realiza una consulta en la base de datos sobre la tabla HistoriaClinica para recuperar el número de historia correspondiente a la cédula digitada. Es muy importante observar la forma en que se manejan las comillas dentro de las sentencias de SQL:
REM ***** BASIC + BASE *****
Public Doc, Formularios, FormularioActual, Forma, Control, Componente As Object
Sub obtenerIdHistoriaClinica Dim CedulaPaciente, idHistoria As String Doc = StarDesktop.CurrentComponent
Formularios = Doc.getFormDocuments() 'recuperar los formularios de la base de datos actual
FormularioActual = Formularios.getByIndex(4) 'acceder al formulario que se desea 'En este momento estoy parado en el objeto Formulario FObservacion 'Ahora obtengo lo que hay dentro de este objeto Componente = FormularioActual.getComponent.getDrawPage.getForms 'traer las formas dentro del formulario
Forma = Componente.getByName("FObservacion") 'coincide el nombre de la forma con el del formulario 'Forma = Componente.getByIndex(0) 'forma alternativa Control = Forma.getByName("CedulaPFormattedField") CedulaPaciente = Control.Text 'ahora debo realizar la consulta en la base de datos para saber a que 'historia clinica corresponde esta cedula y poner el valor en el cuadro 'de texto idHistoria = consultarIdxCedula(CedulaPaciente) 'Ahora que tengo el valor lo pinto en el cuadro Control = Forma.getByName("HistoriaIDTextBox") Control.setString(idHistoria) 'este es el valor que retorna la consultaEnd Sub
Function consultarIdxCedula(cedula As String) As String Dim ConextoBaseDatos As Object Dim OrigenDatos As Object Dim Conexion As Object Dim ManejadorInteraccion as Object Dim Expresion As Object Dim ResultSet As Object
ContextoBaseDatos = createUnoService("com.sun.star.sdb.DatabaseContext") OrigenDatos = ContextoBaseDatos.getByName("centromedico2")
If Not OrigenDatos.IsPasswordRequired Then Conexion = OrigenDatos.GetConnection("","")
Else ManejadorInteraccion = createUnoService("com.sun.star.sdb.InteractionHandler")
Conexion = OrigenDatos.ConnectWithCompletion(ManejadorInteraccion) End If
Expresion = Conexion.createStatement()
ResultSet = Expresion.executeQuery("SELECT ""id_historiaclinica"" FROM ""HistoriaClinica"" WHERE ""cedula_paciente"" = "+cedula+"")
'XRay ResultSet
If Not IsNull(ResultSet) Then If ResultSet.next <> False Then consultarIdxCedula = ResultSet.getString(1)
Else consultarIdxCedula = ""End If
End If
End Function
Ejemplo 2: Macro que pinte la fecha actual como valor por defecto del campo fecha
En este segundo ejemplo se implementa la macro que al momento en que un usuario activa el campo para ingreso de fecha (para tal fin se asocia el evento When Receiving Focus del campo de fecha con la macro obtenerIdHistoriaClinica), pinta automáticamente la fecha del día actual:
Sub obtenerYPintarFecha 'La idea con esta macro es que tan pronto como el usuario active el cuadro 'para ingreso de la fecha le aparezca la fecha del día Dim Aux As Date Doc = StarDesktop.CurrentComponent
Formularios = Doc.getFormDocuments()
FormularioActual = Formularios.getByIndex(4)
Componente = FormularioActual.getComponent.getDrawPage.getForms
Forma = Componente.getByName("FObservacion")
Control = Forma.getByName("FechaCitaFormattedField")
Aux = Date
Control.Text = Aux
End Sub
Ejemplos de Programación de Macros con Bases de Datos
Con el fin de aclarar el tema de desarrollo de macros que interactúan con bases de datos en Open Base, se presentan a continuación una serie de ejercicios prácticos, el primero de ellos ha sido tomado de la guía escrita por Roberto C Benitez y que es posible descargar desde el siguiente URL: http://www.geocities.com/rbenitez22/OOo/index.html
Ejemplo 1: Consulta sencilla que trae todos los registros de una tabla. Se asume para la ejecución de este ejemplo que existe una base de datos previamente creada con una tabla con algunos datos en ella:
Luego con el fin de poder escribir y probar las macros se incluye en la base de datos un formulario simple como el que se ilustra a continuación y estando dentro de él se invoca el editor de macros. Todas las macros que se vayan a usar con una base de datos deben quedar dentro del archivo de dicha base de datos.
REM ***** BASIC *****
Sub Ejemplo1REM SIMPLE CONNECTION
Dim Context Dim DB Dim Conn Dim Stmt Dim Result Dim strSQL As String 'Paso1: crear el contexto de base de datos Context=CreateUnoService("com.sun.star.sdb.DatabaseContext") 'Paso2: definir la base de datos a usar DB=Context.getByName("basedeprueba") 'Paso3: establecer conexion con la base de datos Conn=DB.getConnection("","") 'Paso 4: crear el objeto para ejecutar consultas SQL Stmt=Conn.createStatement() 'Paso 5: definir la sentencia SQL a ejecutar strSQL= "SELECT ""nombre_alumno"" FROM ""alumno""" 'OJO con la forma en que se escriben las comillas 'Paso 6: ejecutar la sentencia y trabajar con el resultado Result=Stmt.executeQuery(strSQL) While Result.next() 'XRay Result MsgBox (Result.getString(1),0,"Nombre del Alumno")
'el indice empleado en getString corresponde al indice de la columna
'en la tabla Wend Conn.close()End Sub
Ejemplo 2: La siguiente macro provee al sistema de la capacidad requerida para presentar un desplegable con los nombres de los estudiantes inscritos en un curso previamente seleccionado.
Lo primero que se revisará es la forma en la que se construye la consulta SQL. El formulario al que se le conectará esta macro es el siguiente:
La idea es que cuando el usuario seleccione un curso del listado desplegable 1, en el listado desplegable 2 aparezcan únicamente los estudiantes inscritos en dicho curso. Se asume que en la base de datos se han creado las tablas que se ilustran a continuación y que existe información en las mismas:
Tabla calificación
Tabla curso
Las relaciones entre las tablas son las siguientes:
Al armar la consulta por partes puede entenderse mejor el resultado final:
Paso 1: obtener el código de una materia conociendo el nombre de la misma:
SELECT codigo_curso FROM curso WHERE nombre_curso LIKE 'Matem%'
Paso 2: obtener el código de los estudiantes que están tomando dicha materia:
SELECT codigo_estudiante FROM curso_estudiante WHERE codigo_curso = 14001
Paso 3: obtener el nombre de estos estudiantes y reunir todos los elementos:
SELECT nombre_estudiante FROM estudiante WHERE codigo_estudiante IN (SELECT codigo_estudiante FROM curso_estudiante WHERE codigo_curso IN (SELECT codigo_curso FROM curso WHERE nombre_curso LIKE 'Matem%'))
Finalmente el código de la macro requerida:
Function materiaSeleccionada (oEvent As Object) Dim oButton, oModel, oParentForm, oListaEstudiantes As Object Dim materiaSeleccionada, AuxSQL(0) As String Dim fuenteDesplegable As Variant
oButton = oEvent.Source oModel = oButton.getModel() oParentForm = oModel.getParent() 'Paso 1: determinar la materia seleccionada materiaSeleccionada = oButton.selectedItem 'Paso 2: obtener la fuente original con la que se llena el listado oListaEstudiantes = oParentForm.getByName("EstudiantesListBox") 'metodos obtenidos mediante XRay para consultar y modificar una propiedad 'setPropertyValue ( aPropertyName as string, aValue as variant ) 'getPropertyValue ( PropertyName as string ) AS variant
'Paso 3: consulta que trae los estudiantes del curso seleccionado AuxSQL(0) = "SELECT ""nombre_estudiante"",""codigo_estudiante"" FROM ""estudiante"" WHERE ( ( ""codigo_estudiante"" IN ( SELECT ""codigo_estudiante"" FROM ""curso_estudiante"" WHERE ""codigo_curso"" IN ( SELECT ""codigo_curso"" FROM ""curso"" WHERE ""nombre_curso"" LIKE '"+materiaSeleccionada+"' ) ) ) )" oListaEstudiantes.setPropertyValue("ListSource",AuxSQL) 'La fuente del desplegable ha sido modificada, 'pero el desplegable no se actualiza oListaEstudiantes.refresh() 'Ahora el desplegable se ha actualizado
materiaSeleccionada = TrueEnd Function
Macros y ejercicios con Hojas de Cálculo
Dada un archivo de Calc con 3 hojas de cálculo en él, se desea implementar un buscador que haciendo uso de diálogos reciba una cadena de texto por parte del usuario y le permita seleccionar gráficamente la hoja dentro de la cual desea realizar la búsqueda.
Observación importante: para que este ejemplo funcione debe implementarse sobre un archivo de CALC que cuente al menos con tres hojas
Diálogo 1: Bienvenida al usuario
El diálogo 1 provee al usuario de 3 botones de acción básica, el primero se encarga de llamar el diálogo de búsqueda, el segundo aún no cuenta con ninguna funcionalidad y el tercero de los botones servirá para cerrar el diálogo principal.
Diálogo 1:
Diálogo 2:
El primer módulo del ejercicio se encarga de presentar los diálogos anteriores:
'esta macro se carga al momento de abrir el documento'http://www.oooforum.org/forum/viewtopic.phtml?t=57062&highlight=createunodialog
Option Explicit
Global oDialog1 as Object 'prueba con variable GLOBALGlobal oDialog2 as Object 'prueba con variable GLOBAL
Sub show_Dialog1 ' loadDialog needs the library and dialog names oDialog1 = loadDialog ("Standard", "Dialog1") 'Now run the dialog oDialog1.executeEnd Sub
Sub show_Dialog2 ' loadDialog needs the library and dialog names oDialog2 = loadDialog ("Standard", "Dialog2") 'Now run the dialog oDialog2.executeEnd Sub
Sub salir oDialog1.endExecute()End Sub
Function LoadDialog(Libname as String, DialogName as String, Optional oLibContainer) Dim oLib as Object Dim oLibDialog as Object Dim oRuntimeDialog as Object If IsMissing(oLibContainer ) then oLibContainer = DialogLibraries End If oLibContainer.LoadLibrary(LibName) oLib = oLibContainer.GetByName(Libname) oLibDialog = oLib.GetByName(DialogName) oRuntimeDialog = CreateUnoDialog(oLibDialog) LoadDialog() = oRuntimeDialogEnd Function
El siguiente módulo es el encargado de realizar la búsqueda, es importante destacar como este módulo hace uso de las variables globales definidas en el módulo anterior para poder acceder a los diálogos y sus componentes internos:
REM Rutina que realiza la busqueda dentro de la hojaOption Explicit 'recuerde incluir esta linea para evitar lios mas adelante
Sub Buscar 'Objetos requeridos Dim ControlCampoTexto Dim ControlRadioButton(2) 'Arreglo de Botones Dim DocumentoCalc, HojaActiva, DescriptorBusqueda Dim ResultadoObtenido, ResultadoActual
'Cadenas de Texto Requeridas Dim CadenaIngresada As String
'Otras Variables Dim ContadorAux, I As Integer
'Paso 1: recibir cadena a buscar ControlCampoTexto = oDialog2.getControl("TextField1") CadenaIngresada = ControlCampoTexto.getText()
'Paso 2: determinar en que hoja buscar ControlRadioButton(0) = oDialog2.getControl("HOptionButton1") ControlRadioButton(1) = oDialog2.getControl("HOptionButton2") ControlRadioButton(2) = oDialog2.getControl("HOptionButton3")
'XRay ControlRadioButton
For ContadorAux = 0 To 2 If ControlRadioButton(ContadorAux).getState = True Then Exit For End If Next ContadorAux
'Paso 3: buscar '3.1 Obtener el documento y luego ubicarse en la hoja deseada para buscar
DocumentoCalc = thisComponent
HojaActiva = DocumentoCalc.getSheets.getByIndex(ContadorAux) 'XRay HojaActiva
'3.2 Buscar la cadena dentro de la hoja seleccionada 'Crear descriptor de la busqueda DescriptorBusqueda = HojaActiva.createSearchDescriptor()
'Configurar el descriptor de la busqueda 'XRay DescriptorBusqueda 'Cadena a buscar DescriptorBusqueda.SearchString = CadenaIngresada 'Buscar solo palabras completas 'DescriptorBusqueda.SearchWords = True
'Realizar la busqueda ResultadoObtenido = HojaActiva.findAll(DescriptorBusqueda) 'Presentar al usuario el numero de resultados obtenidos
If NOT isNull(ResultadoObtenido) Then MsgBox "La cadena ingresada se encontró " + ResultadoObtenido.getCount() + " veces" 'Presentar al usario una ventana que le permita navegar por los resultados ResultadoActual = HojaActiva.findFirst(DescriptorBusqueda) For I = 1 To ResultadoObtenido.getCount()1 MsgBox (ResultadoActual.String,1,"Resultados de su Busqueda")
ResultadoActual = HojaActiva.findNext(ResultadoActual,DescriptorBusqueda) Next I MsgBox (ResultadoActual.String,1,"Resultados de su Busqueda") Else MsgBox "La cadena ingresada No se encontró" End If
End Sub
Accediendo a Directorios y Archivos
El siguiente ejemplo provee los mecanismos requeridos para:
1. Explorar un directorio y obtener los archivos que contiene2. Explorar un directorio y recuperar un tipo específico de archivos3. Abrir un archivo seleccionado por el usuario
El ejercicio se desarrolla sobre un formulario incluido en una hoja de cálculo como el que se muestra a continuación:
La primera macro es la que se asocia al botón Ver Listado de Archivos, la misma se encarga de presentar en un MsgBox el listado de todos los archivos contenidos en un directorio específico:
Sub ListarArchivosREM Esta macro lista los archivos existentes en un directorio
especificoREM Tomado de la Guía de Programacion de Star Office 8Dim ArchivoSiguiente As StringDim TodosLosArchivos As String
TodosLosArchivos = ""'ArchivoSiguiente = Dir("C:\", 0)
ArchivoSiguiente = Dir("/home/mad/Temp/rips/CC1/", 0)While ArchivoSiguiente <> ""
TodosLosArchivos = TodosLosArchivos & Chr(13) & ArchivoSiguiente
ArchivoSiguiente = DirWendMsgBox TodosLosArchivos
End Sub
La siguiente macro hace uso del mismo principio, pero ahora sólo trae los archivos de un tipo específico, el tipo de los archivos a traer se especifica en la instrucción Dir de la forma *.ext
Sub ListarArchivosExcelREM Esta macro lista los archivos existentes en un directorio
especificoREM Tomado de la Guía de Programacion de Star Office 8Dim ArchivoSiguiente As StringDim TodosLosArchivos As String
TodosLosArchivos = ""'ArchivoSiguiente = Dir("C:\", 0)ArchivoSiguiente = Dir("/home/mad/Temp/rips/CC1/*.xls", 0)While ArchivoSiguiente <> ""
TodosLosArchivos = TodosLosArchivos & Chr(13) & ArchivoSiguiente
ArchivoSiguiente = DirWendMsgBox TodosLosArchivos
End Sub
Ahora se presenta la macro que captura la extensión que el usuario ingrese en un campo de texto y trae sólo los archivos que cuentan con esa extensión:
Function ListarSolicitadosPorUsuario(senal As Object)' en este ejemplo se hace uso de la misma idea' anterior, pero el filtro lo ingresa manualmente' el usuarioDim Control1, ModeloControl1, FormaCalc, CuadroTextoDim ext As StringDim ArchivoSiguiente As StringDim TodosLosArchivos As String
Control1 = senal.SourceModeloControl1 = Control1.getModel()FormaCalc = ModeloControl1.getParent()
'XRay FormaCalc
CuadroTexto = FormaCalc.getByName("ExtensionArchivo")'XRay CuadroTextoext = CuadroTexto.getPropertyValue("Text") 'equivale a:
CuadroTexto.Text'La siguiente es una forma alternativa valida'ext = CuadroTexto.String
' Se listan los archivos, pero solo los que tengan esta extension
TodosLosArchivos = ""'ArchivoSiguiente = Dir("C:\", 0)ArchivoSiguiente = Dir("/home/mad/Temp/rips/CC1/*."+ext, 0)While ArchivoSiguiente <> ""
TodosLosArchivos = TodosLosArchivos & Chr(13) & ArchivoSiguiente
ArchivoSiguiente = DirWendMsgBox TodosLosArchivos
ListarSolicitadosPorUsuario = True 'es importante devolver un valor al finalEnd Function
La siguiente macro presenta además de los nombres de los archivos, las propiedades de tamaño y última fecha de modificación para cada uno de ellos:
Function ListarDetalleSolicitadosPorUsuario(sEmisor As Object)' en este ejemplo se hace uso de la misma idea' anterior, pero el filtro lo ingresa manualmente' el usuarioDim Control1, ModeloControl1, FormaCalc, CuadroTextoDim ext As StringDim ArchivoSiguiente As StringDim TodosLosArchivos As String
Control1 = sEmisor.SourceModeloControl1 = Control1.getModel()FormaCalc = ModeloControl1.getParent()CuadroTexto = FormaCalc.getByName("ExtensionArchivo")ext = CuadroTexto.getPropertyValue("Text")
' Se listan los archivos, pero solo los que tengan esta extension
TodosLosArchivos = ""'ArchivoSiguiente = Dir("C:\", 0)
ArchivoSiguiente = Dir("/home/mad/Temp/rips/CC1/*."+ext, 0)While ArchivoSiguiente <> ""
'http://www.asciitable.com/ TodosLosArchivos = TodosLosArchivos & Chr(13) & ArchivoSiguiente & Chr(9) & FileLen("/home/mad/Temp/rips/CC1/"+ArchivoSiguiente) & Chr(9) & FileDateTime("/home/mad/Temp/rips/CC1/"+ArchivoSiguiente)
ArchivoSiguiente = DirWendMsgBox TodosLosArchivos
ListarDetalleSolicitadosPorUsuario = True 'es importante devolver un valor al finalEnd Function
Finalmente se incluye la macro que abre un archivo de acuerdo con la selección que realiza el usuario empleando el componente incluido en la forma para tal fin, la misma fue enviada por Fernando Méndez y Javier García:
Function SeleccionarArchivo(senal as object)
Dim Boton, Modelo, Forma, CampoTexto as objectDim ruta, ruta2, letra as stringdim i as integer
Boton = Senal.SourceModelo = Boton.getModel()Forma = Modelo.getParent()CampoTexto = forma.getbyname("flsSelection")ruta = CampoTexto.text()
for i=1 to len(ruta)letra=mid(ruta,i,1)if letra="\" thenletra ="/"end ifruta2=ruta2+letra
next i
Dim UbicacionArchivo as stringDim oArchivoDim Argumentos() 'Arreglo de objetos
UbicacionArchivo = "file:///"&ruta2oArchivo =
starDesktop.LoadComponentFromURL(UbicacionArchivo,"_blank",0,argumentos())
end Function
Trabajando con DataPilot y alternativa al DataPilot
Para los usuarios de la hoja de cálculo MS Excel, trabajar con tablas dinámicas (o tablas pivote) es una mas de sus tareas cotidianas, en Calc existe una alternativa a dichas tablas y el siguiente ejemplo pretende introducirlas así como analizar la forma de programar macros que interactúen con ellas.
Para el siguiente ejercicio es necesario contar con una hoja de Calc que presente información acerca de la ocupación de diferentes hoteles mes a mes:
Se usará ahora la herramienta Data Pilot para crear un resumen de esta información y facilitar su análisis. Los pasos para conseguir una tabla dinámica en Calc a partir de una hoja con información como la siguiente son:
Paso 1: ubicado en la esquina superior izquierda de la hoja con los datos que desea analizar, seleccione la opción Data > DataPilot > Start
Hotel Mes OcupaciónZuana Enero 6369Zuana Febrero 13008Zuana Marzo 9473Zuana Abril 7284Zuana Mayo 6968Zuana Junio 7016Zuana Julio 8192Zuana Agosto 5706Zuana Septiembre 9759Zuana Octubre 12641Zuana Noviembre 5414Zuana Diciembre 9319Irotama Enero 14342Irotama Febrero 7273Irotama Marzo 9725Irotama Abril 8845Irotama Mayo 5610Irotama Junio 6877
Paso 2: para este caso en particular se empleará como fuente de datos la selección actual, sin embargo es posible también especificar otra fuente registrada en Open Office, lo cual indica que es posible usar los datos de una base de datos para generar un DataPilot:
Paso 3: después de esto aparecerá el asistente para la creación del DataPilot presentando la siguiente información:
La idea con este asistente es arrastrar cada una de las columnas del rango seleccionado a la posición que tendrán en el DataPilot. Por ejemplo para que la tabla dinámica generada presente la información resumida de la ocupación debe arrastraste el campo ocupación a la posición etiquetada como Data Fields, si desea presentarse esta información por mes, es posible por ejemplo arrastrar el campo mes a la posición Column Fields y para permitir al usuario filtrar o visualizar la información por un Hotel específico debe arrastrarse el campo Hotel a la posición Page Fields, con lo que el DataPilot queda configurado de la siguiente manera:
Finalmente se despliegan las opciones disponibles bajo el botón More para indicar que el DataPilot generado se desea en una nueva hoja dentro de la hoja de cálculo:
El resultado obtenido es el siguiente:
De esta manera se ha conseguido generar un resumen de la información de la ocupación total de los hoteles mes a mes, con la posibilidad de analizar cada hotel en particular o el conjunto total de hoteles.
Es importante aclarar en este punto que si realiza algún cambio sobre la información base del DataPilot – por ejemplo se modifican los valores de las ocupaciones o se incluye un nuevo hotel , éste no se actualiza de forma automática, para que el DataPilot presente el resumen actualizado es necesario dar click derecho sobre él y seleccionar la opción Refresh.
Macro que modifica los datos de un DataPilot y lo refresca de forma automática
El siguiente ejemplo presenta la forma en que pueden modificarse los datos fuente de un DataPilot y luego actualizar automáticamente el mismo:
Sub Ejemplo6'Modificar los datos empleados por el Data Pilot de la hoja2'Actualizar el Data Pilot'Ocultar la hoja de datos
Dim documentoActivo, hojaActiva, Celda, dispatcher, view, frameDim I as Integer
documentoActivo = thisComponent'XRay documentoActivohojaActiva = documentoActivo.getSheets.getByIndex(0)
'hojaActiva = documentoActivo.getSheets.getByIndex(0)'hojaActiva.IsVisible = True
'seleccionar un rango de datos para modificar'los datos que se quieren modificar están en el rango C2:C49
For I=1 To 48Celda = hojaActiva.getCellByPosition(2,I)Celda.setFormula("=RANDBETWEEN(5000;15000)")
Next I
'los datos han cambiado, refrescar el Data Pilot
'tomado de: http://www.oooforum.org/forum/viewtopic.phtml?t=52897&highlight=datapilot
'view es una representacion abstracta del controlador del doc abierto
view = ThisComponent.CurrentController
'frame es la ventana como tal en la que estoy trabajando'Description
'represents the environment for a desktop component 'Frames are the anchors for the office components and they are
the components' 'link to the outside world. They create a skeleton for the whole
office api
'infrastructure by building frame hierarchys. These hierarchies contains all
'currently loaded documents and make it possible to walk during these trees.
frame = view.Frame 'recupera el frame que tiene asociado el calc abierto
' Description com.sun.star.frame.DispatchHelper ' provides an easy way to dispatch an URL using one call instead of multiple ones.
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
'situarse en la hoja con el data pilothojaActiva = documentoActivo.getSheets.getByIndex(1)Celda = hojaActiva.getCellByPosition(0,0)
view.select(Celda) 'equivale a dar click sobre la columna con el fin de activar el Data Pilot
dispatcher.executeDispatch(frame, ".uno:RecalcPivotTable", "", 0, Array()) 'refresca el Data Pilot
'se oculta la hoja con los datos que usa el data pilothojaActiva = documentoActivo.getSheets.getByIndex(0)hojaActiva.IsVisible = False
MsgBox("Data Pilot Actualizado",0,"Order From Chaos!")
End Sub
Cuando DataPilot no es suficiente
Ocurre que DataPilot tiene la limitante de no permitir la inclusión de más de 8 campos en los campos de datos y para algunos escenarios es importante poder incluir más de estos campos. Sin embargo – y como ocurre tantas veces en el mundo del Software Libre – ya existe una solución a este inconveniete desarrollada por Ian Laurenson y disponible en su sitio web: http://homepages.paradise.net.nz/hillview/OOo/MyDataPilot3.ods.MyDataPilot3 es una macro que provee una interesante alternativa a DataPilot y permite la inclusión de n campos en los datos que se desean analizar.
Instrucciones de instalación se requiere haber descargado previamente el archivo anterior :
Paso 1: Seleccione la opción Tools > Macro > Organize Macros > OpenOffice.org BasicPaso 2: Clic sobre el botón OrganizerPaso 3: Seleccione la pestaña Libraries y luego de clic sobre la opción Import:
Paso 4: seleccione el archivo MyDataPilot3.ods cuando aparezca el explorador de archivos
Paso 5: Seleccione las librerías que vienen incluidas en el archivo y de clic sobre el botón Ok
Dado que es posible que ya exista en Open Office una librería con el módulo Standard el siguiente mensaje de error puede aparecer:
Si esto ocurre simplemente se debe editar esta librería desde el organizador de macros e incluir allí19 una sub rutina como la siguiente:
Sub CargarMyDataPilotBasicLibraries.LoadLibrary("MyDataPilot")subMyDataPilot
End Sub
19 Por allí se hace alusión a My Macros & Dialogs.Standard
En esta misma ubicación y siguiendo la misma idea es posible incluir una macro que cargue automáticamente los rayos X:
Sub LoadingXRayLibraries BasicLibraries.LoadLibrary("XrayTool")End Sub
Subformas en Base
Aunque el siguiente ejemplo no tiene que ver con Macros directamente es una opción que provee Open Base que puede resultar interesante para las personas que están migrando de MS Office. La idea es generar una forma que presente la información no sólo de una tabla sino de tablas o consultas que puedan estar relacionadas con esta, empleando para tal fin las Sub Formas. Este ejemplo se desarrolla sobre la misma base de datos del colegio que se empleó en un ejercicio anterior.
Paso 1: diseñar o definir en SQL una consulta que permita recuperar los estudiantes inscritos, sus nombres, sus calificaciones y la descripción de las mismas para una materia específica. Aunque es posible definir esta consulta utilizando SQL en ocasiones – y para aquellos que vienen trabajando así desde hace tiempo – resulta conveniente usar la vista de diseño para tal fin. En la vista de diseño se añaden las tablas sobre las que se quiere realizar una consulta, se definen los campos a recuperar y se introducen los criterios que filtran los resultados obtenidos. La siguiente imagen ilustra un diseño que arroja un resultado aproximado a la consulta deseada:
La forma como tal traerá la información de la tabla curso, pues lo que se desea es que al ver un curso aparezcan las calificaciones que se han generado en el mismo:
A continuación se indica que se desea incluir una sub forma y que la misma estará basada en tablas o consultas existentes:
Acto seguido se selecciona la consulta que acaba de crearse mediante la herramienta de diseño y se indican los campos de la misma que se desean incluir:
En este punto se debe indicar que relación existe entre la información de la forma principal y la de la subforma, de esta manera es como se recuperarán los estudiantes inscritos en un curso específico y sus calificaciones cuando se presente el registro de dicho curso:
Programando Diálogos MultiStep
En ocasiones es deseable contar con un diálogo que presente en diferentes pasos diferente información, en lugar de contar con varios diálogos. Un ejemplo claro de esto son los Asistentes o Wizard que se observan en diferentes ocasiones al emplear Open Office. Para programar un diálogo de varios pasos es necesario modificar la propiedad Step de la ventana principal del diálogo y ubicar en cada Step los componentes deseados. El siguiente ejemplo enviado por Fernando Méndez y Javier García ilustra claramente la idea:
Paso 1 del diálogo:
Paso 2 del diálogo:
Paso 3 del diálogo:
Obsérvese como es el mismo diálogo, pero con diferentes controles de acuerdo con el valor que tenga la propiedad Pag (step) en un momento dado. Obsérvese también que dicha propiedad es una propiedad de la ventana que contiene a los demás elementos, así como de cada uno de los controles. Esto quiere decir que para ver un control en determinado paso del
diálogo, el valor de Page (step) del control y el valor del paso en el diálogo deben coincidir. Por otra parte si se desea contar con un par de controles del tipo Anterior Siguiente, los mismos deben aparecer a lo largo de todos los pasos del diálogo, para estos controles debe fijarse la propiedad Page (step) en 0.
La macro que se incluye en este ejemplo ilustra como es posible navegar de un paso a otro mediante los controles anteriormente mencionados:
REM ***** BASIC *****Option Explicit
Public oDialog1 as Object 'solo hay un dialogo con diferentes pasos
Sub Main
End Sub
Function lanzarMenu (senal As Object)REM esta funcion lanza el dialogo de varios pasosREM y oculta la forma de la que se llamaDim emisor, modelo, formaDim dialogo, libreria, visualizacionDialogo
emisor = senal.Sourcemodelo = emisor.getModel()forma = modelo.getParent()'XRay forma 'para determinar que metodo usar para ocultarla
'A continuacion se carga el dialogo principaloDialog1 = loadDialog ("Standard", "Dialog1")'Now run the dialogoDialog1.execute
End Function
Function siguientePaso (senal As Object)Dim controlSiguiente As ObjectDim controlAnterior As Objectdim i as longi = ODialog1.model.step
controlSiguiente = oDialog1.getControl("CommandButton1")controlAnterior = oDialog1.getControl("CommandButton2")
if i = 3 thencontrolSiguiente.Model.Enabled = NOT
controlSiguiente.Model.Enabled elseif i = 1 thencontrolAnterior.Model.Enabled = NOT
controlAnterior.Model.Enabledend if
oDialog1.Model.Step = oDialog1.Model.Step + 1
'XRay controlSiguiente
siguientePaso = TrueEnd Function
Function pasoAnterior (senal As Object)Dim controlSiguiente As ObjectDim controlAnterior As Objectdim i as longi = ODialog1.model.step
controlSiguiente = oDialog1.getControl("CommandButton1")controlAnterior = oDialog1.getControl("CommandButton2")
if i = 4 thencontrolSiguiente.Model.Enabled = NOT
controlSiguiente.Model.Enabledelseif i = 2 thencontrolAnterior.Model.Enabled = NOT
controlAnterior.Model.Enabled end if
oDialog1.Model.Step = oDialog1.Model.Step 1
'XRay oDialog1
pasoAnterior = TrueEnd Function
Function LoadDialog(Libname as String, DialogName as String, Optional oLibContainer)
Dim oLib as ObjectDim oLibDialog as ObjectDim oRuntimeDialog as ObjectIf IsMissing(oLibContainer ) then
oLibContainer = DialogLibrariesEnd IfoLibContainer.LoadLibrary(LibName)oLib = oLibContainer.GetByName(Libname)oLibDialog = oLib.GetByName(DialogName)
oRuntimeDialog = CreateUnoDialog(oLibDialog)LoadDialog() = oRuntimeDialog
End Function
Make a Table Query, desde Open Base
Para finalizar este curso se presenta a continuación un par de macros que ilustran las capacidades que brinda Open Office y en especial Base, para desarrollar nuevas herramientas que con el tiempo permitan contar con macros muy poderosas. Se asume para este ejemplo que existe una base de datos y que la misma cuenta con una tabla de clientes y una tabla de empleados. La idea central del ejemplo es permitir al usuario final interactuar con la base de datos mediante un formulario o diálogo, de forma que no acceda directamente a la estructura de la base como tal, para tal fin se incluye una forma dentro de la base de datos con dos botones en ella, asociados a dos macros diferentes, la primera de ellos toma una tabla y genera una copia de la misma con todos los datos incluidos, la segunda presenta un formulario simple de consulta donde el usuario final puede realizar búsquedas por cadenas de texto.
El formulario principal luce de la siguiente manera:
El diálogo que se provee para la primera consulta es el siguiente:
La idea con este diálogo es que el usuario seleccione una tabla dentro de las que existen en la base de datos y que al presionar el botón siguiente se genere una réplica de la misma en la base de datos, empleando para tal fin la sintaxis estándar de SQL. Se ha dividido el problema en dos sub rutinas, la primera de ellas se encarga de presentar el diálogo, la segunda captura el nombre de la tabla seleccionada y ejecuta la operación:
Sub MakeTableQuery'Esta rutina toma una consulta sobre una tabla'especifica y genera una nueva tabla a partir de los resultados'obtenidos
'Se requiere un diálogo en el cual el usuario seleccione la'tabla sobre la cual quiere trabajar'El listado de tablas se obtendra consultando la base de'datos como tal
'Paso 1: establecer conexion con la base de datos para obtener'el listado de tablas disponible:
ContextoBaseDatos = createUnoService("com.sun.star.sdb.DatabaseContext")
OrigenDatos = ContextoBaseDatos.getByName("sisepuede")
TablasDisponibles = OrigenDatos.getTables.getElementNames
'XRay TablasDisponibles
'Paso 2: cargar el dialogo y en la lista desplegable'ingresar los nombres de las tablas existentesoDialog1 = loadDialog ("Standard", "Dialog1")
'esto pasa antes de pintar el DialogoListaDesplegable = oDialog1.getControl("ComboBox1")
ListaDesplegable.addItems(TablasDisponibles,0)
'Now run the dialogoDialog1.execute
End Sub
Sub MakeTableQuery2Dim ConsultaSQL As StringDim SQLRunner, ResultSet
TablaSeleccionada = ListaDesplegable.getSelectedTextConsultaSQL = "SELECT * INTO CACHED
""copiade"+TablaSeleccionada+""" FROM """+TablaSeleccionada+""""
'Se crea a continuacion el objeto requerido para ejecutar consultas sobre la DB
If Not OrigenDatos.IsPasswordRequired Then Conexion = OrigenDatos.GetConnection("","") 'user, password
Else ManejadorInteraccion = createUnoService("com.sun.star.sdb.InteractionHandler")
Conexion = OrigenDatos.ConnectWithCompletion(ManejadorInteraccion)
End If
SQLRunner = Conexion.createStatement()ResultSet = SQLRunner.executeQuery(ConsultaSQL)
End Sub
Por otra parte, el diálogo para la segunda consulta es el siguiente:
La idea en esta ocasión es que el usuario final escriba el apellido – o parte del apellido – del cliente que desea buscar y presentar en el cuadro de texto de la parte inferior los resultados obtenidos. Nuevamente se ha dividido el problema en dos partes:
Sub ClientLikeQuery1'conexion con la base de datos para obtener
ContextoBaseDatos = createUnoService("com.sun.star.sdb.DatabaseContext")
OrigenDatos = ContextoBaseDatos.getByName("sisepuede")
oDialog2 = loadDialog ("Standard", "Dialog2")
'Now run the dialogoDialog2.execute
End Sub
Sub ClientLikeQuery2Dim CriterioBusqueda As String
Dim ConsultaSQL As StringDim CadenaAux As StringDim I As LongDim SQLRunner, ResultSet, Aux
'Capturar la cadena introducida por el usuarioCuadroEntrada = oDialog2.getControl("TextField1")CriterioBusqueda = CuadroEntrada.getText()
CuadroResultados = oDialog2.getControl("TextField2")'XRay CuadroResultados
'Realizar una busqueda por semejanza sobre la tablaConsultaSQL = "SELECT * FROM ""Customers"" WHERE ""LastName""
LIKE '"+CriterioBusqueda+"%'"
'Se crea a continuacion el objeto requerido para ejecutar consultas sobre la DB
If Not OrigenDatos.IsPasswordRequired Then Conexion = OrigenDatos.GetConnection("","") 'user, password
Else ManejadorInteraccion = createUnoService("com.sun.star.sdb.InteractionHandler")
Conexion = OrigenDatos.ConnectWithCompletion(ManejadorInteraccion)
End If
SQLRunner = Conexion.createStatement()ResultSet = SQLRunner.executeQuery(ConsultaSQL)'XRay ResultSet
'Presentar los resultados en el cuadro de resultadosIf Not IsNull(ResultSet) Then
While ResultSet.next 'a continuacion se construye la cadena que se va a pintar en el cuadro de resultados For I=0 To ResultSet.getColumns.Count1 Aux = ResultSet.Columns.getByIndex(I) CadenaAux = CadenaAux + Chr(9) + Aux.getString() Next I CadenaAux = CadenaAux + Chr(13) CuadroResultados.setText(CadenaAux)
WendEnd If
End Sub
Bibliografía:
Este curso no hubiera podido desarrollarse sin la ayuda invaluable de las siguientes fuentes:
● Guía de programación de StarOffice 8 para BASIC, Sun Microsystems, Inc. Junio 2005● Useful Macro Information For OpenOffice, Andrew Pitonyak, Enero 2006● Forms & Dialogs, Roberto C. Benitez, 2007● Creating order from chaos, Peter Kupfer y Richard Detwiler, 2007● Migrating from Microsoft Office to OpenOffice.org 1.1.1: A guide for intermediate to
advanced users. Varios, 2004● Database Development OpenOffice.org & OOBasic, Roberto C. Benitez, 2006● StarOffice Programmer’s Tutorial, Sun Microsystems, Inc., 2000● OpenOffice.org User Guide for Version 2.x, Varios, 2006
Por supuesto una gran parte de las ayudas se encuentran en línea:
● api: Project Home, http://api.openoffice.org/● First Steps, http://api.openoffice.org/docs/DevelopersGuide/FirstSteps/FirstSteps.xhtml● OooMacros, http://ooomacros.org/dev.php#101416● Extensions development basic OpenOffice.org Wiki,
http://wiki.services.openoffice.org/wiki/Extensions_development_basic#XRay_tool● Traducciones Libres: Poniendo en práctica OpenOffice.org Basic,
http://freetrans.blogspot.com/2007/03/poniendoenprcticaooobasic.html● Spreadsheet Documents,
http://api.openoffice.org/docs/DevelopersGuide/Spreadsheet/Spreadsheet.xhtml#1_1_Overview
● OpenOffice.org Forum at OooForum.org, http://www.oooforum.org/● documentation:, http://documentation.openoffice.org/● Table of Contents OpenOffice 2 (Data) ooBase Tutorials – fdb1main,
http://sheepdogguides.com/fdb/fdb1main.htm● How to use OpenOffice 2.0's database tool,
http://searchenterpriselinux.techtarget.com/tip/0,289483,sid39_gci1148271,00.html● OpenOffice.org Database Explained, http://www.pitonyak.org/database/● Spreadsheet Documents,
http://api.openoffice.org/docs/DevelopersGuide/Spreadsheet/Spreadsheet.xhtml#1_5_1_Spreadsheet_View
● Office Development, http://api.openoffice.org/docs/DevelopersGuide/OfficeDev/OfficeDev.xhtml#1_1_1_2_1
_FrameControllerModel_Paradigm_in_OpenOffice.org● Iannz OpenOffice.org page, http://homepages.paradise.net.nz/hillview/OOo/
Agradecimientos:
Este curso no hubiera podido desarrollarse sin las personas que asistieron a él, a cada uno de ellos gracias por su colaboración, buen ánimo y sobre todo por las preguntas y cuestiones que permitieron desarrollar este curso en direcciones que en un comienzo parecían impensables.
Este material no habría podido completarse sin la paciencia de mi esposa, quien soportó mis largas jornadas de trabajo en la noche durante los días que preparé la primera versión de este material.