10.05.2013 Views

Información importante sobre macros para OpenOffice - IES Galileo

Información importante sobre macros para OpenOffice - IES Galileo

Información importante sobre macros para OpenOffice - IES Galileo

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>Información</strong> <strong>importante</strong> <strong>sobre</strong> <strong>macros</strong><br />

<strong>para</strong> <strong>OpenOffice</strong><br />

Andrew Pitonyak<br />

(Traducción Arturo Garro)


Gracias<br />

Muchas gracias a mi esposa Michelle por permitirme escribir este libro y por darme coraje.<br />

También doy un agradecimiento a aquellos de la comunidad “open-source” y las listas de<br />

correos que proveen información de mucha ayuda. Finalmente, un agradecimiento a aquellos<br />

que han dado ejemplos incluidos en este documento.<br />

Advertencia<br />

El material en este documento no tiene garantía de aplicación, accuracy, o seguridad. El uso<br />

de la información y los <strong>macros</strong> en este documento es bajo su propio riesgo. Debe asumir que<br />

las <strong>macros</strong> pueden llenar de basura su base de datos, el disco duro, y hacer perder todos sus<br />

datos y no me haré responsable.<br />

Licencia<br />

En este momento, debe considerar que todo el material en este documento creado por mi esta<br />

sujeto a http://www.openoffice.org/licenses/jca.pdf el cual da a la comunidad <strong>OpenOffice</strong><br />

community la posibilidad de usarlo en el sitio <strong>OpenOffice</strong>. Este documento contiene <strong>macros</strong><br />

que no están escritas por mi. En este momento, he obtenido permiso de incluir estas <strong>macros</strong><br />

en este documento pero de las que no heobtenido confirmación también tienen esta misma<br />

licencia. Tomaré las medidas necesarias <strong>para</strong> resolver estos problemas en este documento<br />

durante las actualizaciones.<br />

<strong>Información</strong> de contacto<br />

Andrew Pitonyak • 4446 Mobile Drive #105 • Columbus, OH 43220 • USA<br />

home: andrew@pitonyak.org • work: andrew.pitonyak@qwest.com<br />

home telephone: 614-442-8615<br />

Credenciales<br />

Tengo dos bachilleratos, uno en Informática y otro en Matemáticas. También tengo dos<br />

maestrías en Ciencias, uno en Matemática Industrial Aplicada y otro en Informática. He<br />

trabajado en Oakland University en Rochester Michigan, The Ohio State University en<br />

Columbus Ohio, y en The Technical University Of Dresden en Dresden Germany.<br />

Nota del traductor<br />

Todas las palabras claves de StarBasic dentro del texto han sido puestas en azul <strong>para</strong><br />

diferenciarlas. Sobra decir que deber ser escritas exactamente igual <strong>para</strong> evitar errores de<br />

sintaxis. Es posible que se me haya quedado alguna palabra en inglés en el texto mientras<br />

buscaba su significado.


Tabla de contenido<br />

1 Introducción...........................................................................................................................1<br />

2 Recursos disponibles..............................................................................................................3<br />

2.1 Material incluido............................................................................................................3<br />

2.2 Recursos en línea (on line).............................................................................................3<br />

3 Ejemplos...............................................................................................................................5<br />

3.1 Manipulación de cadenas..............................................................................................5<br />

3.1.1 Remover caracteres de una cadena........................................................................5<br />

3.1.2 Reemplazar texto en una cadena...........................................................................6<br />

3.1.3 Imprimiendo los valores ASCII de una cadena.....................................................7<br />

3.2 Depurando e inspeccionando Macros...........................................................................7<br />

3.2.1 Determinar el tipo de documento..........................................................................7<br />

3.2.2 Desplegando los métodos y propiedades de un objeto..........................................8<br />

3.2.3 Desplegando las propiedades de un objeto en una hoja de cálculo.......................9<br />

4 Ejemplos misceláneos.........................................................................................................19<br />

4.1 Desplegar texto en la barra de estado..........................................................................20<br />

4.2 Despliega todos los estilos en el documento actual....................................................21<br />

4.3 Cambiar entre los documentos abiertos......................................................................21<br />

4.4 Listar fuentes (Quebrado, no funciona) .....................................................................22<br />

4.5 Imprimir el documento actual.....................................................................................23<br />

4.6 Cambiando el tamaño de una lista..............................................................................25<br />

4.7 Open And Close Documents (And The Desktop).......................................................26<br />

4.7.1 Cerrar documentos <strong>OpenOffice</strong>...........................................................................26<br />

4.7.2 Cargar un documento desde una URL.................................................................27<br />

4.8 Creando una tabla........................................................................................................29<br />

4.9 Llamando un programa externo..................................................................................30<br />

4.10 Leer y escribir en un archivo.....................................................................................31<br />

4.11 Creando un estilo de formato numérico....................................................................32<br />

4.12 Retorna una matriz Fibonnaci...................................................................................33<br />

4.13 Insertar texto en un marcador....................................................................................33<br />

4.14 Campos de usuario....................................................................................................33<br />

5 Macros de Calc...................................................................................................................35<br />

5.1 Es este un libro de cálculo?.........................................................................................35<br />

5.2 Imprimiendo el valor de una Celda, Cadena o Fórmula.............................................35<br />

5.3 Estableciendo el valor de una Celda, Formato, Cadena o Fórmula............................35<br />

5.4 Limpiar una celda........................................................................................................36<br />

5.5 Texto seleccionado, Qué es?.......................................................................................36<br />

5.6 Dirección imprimible de una Celda............................................................................38<br />

5.7 Insertar fechas formateadas en una Celda...................................................................39<br />

5.8 Desplegar un rango seleccionado en un cuadro de diálogo........................................39<br />

5.9 Rellenar un rango seleccionado con texto...................................................................40<br />

5.10 Algunos estados del texto seleccionado....................................................................41<br />

5.11 Cambiar el rango seleccionado a un rango de Base de Datos...................................42<br />

5.12 Borrar un rango de Base de Datos.............................................................................42<br />

5.13 Rango bordes de línea...............................................................................................42<br />

i


5.14 Ordenar un rango.......................................................................................................43<br />

5.15 Imprimir todos los datos en una columna.................................................................44<br />

5.16 Usando métodos de bordes (agrupamiento)..............................................................44<br />

5.17 Protegiendo sus datos................................................................................................45<br />

6 Macros de Write .................................................................................................................47<br />

6.1 Texto seleccionado, qué es?........................................................................................47<br />

6.2 Cursores de texto, qué son?.........................................................................................47<br />

6.3 Andrew's Selected Text Framework...........................................................................48<br />

6.3.1 Hay texto seleccionado?......................................................................................48<br />

6.3.2 Cómo obtener una selección................................................................................49<br />

6.3.3 Selected Text, Which End Is Which....................................................................49<br />

6.3.4 Sistema Macro de texto seleccionado..................................................................50<br />

El sistema rechazado................................................................................................51<br />

El sistema aceptable.................................................................................................51<br />

El trabajo principal..................................................................................................52<br />

6.3.5 Desplegando caracteres, un ejemplo simple........................................................53<br />

6.3.6 Remover espacios y líneas vacíos, un gran ejemplo...........................................53<br />

Qué es un espacio en blanco? ..................................................................................53<br />

Rangos de caracteres <strong>para</strong> borrar.............................................................................53<br />

El interativo seleccionador de texto.........................................................................54<br />

La macro principal...................................................................................................55<br />

6.3.7 Removiendo párrafos vacíos, sólo otro ejemplo.................................................55<br />

6.4 Reemplazando espacios seleccionados usando cadenas.............................................56<br />

6.4.1 Com<strong>para</strong>ción de cursores y ejemplos de cadenas................................................58<br />

6.5 Poniéndo atributos de texto.........................................................................................68<br />

6.6 End Sub Insertar texto.................................................................................................69<br />

6.7 Insertar fecha formateada dentro de un documento de texto......................................71<br />

6.8 Insertar una nueva página............................................................................................71<br />

6.8.1 La solución..........................................................................................................71<br />

7 Ejemplo de inversión..........................................................................................................73<br />

7.1 Página resumen...........................................................................................................73<br />

7.2 Hoja de detalles...........................................................................................................73<br />

7.3 Chequear duplicados en una columna.........................................................................74<br />

7.3.1 Dirección imprimible de una celda......................................................................74<br />

7.3.2 Conteo de entradas no vacías en una columna....................................................75<br />

7.3.3 Arreglo ordenado.................................................................................................76<br />

7.3.4 Encontrar el duplicado.........................................................................................77<br />

8 Lenguaje..............................................................................................................................79<br />

8.1 Comentarios................................................................................................................79<br />

8.2 Variables.....................................................................................................................79<br />

8.2.1 Nombres..............................................................................................................79<br />

8.2.2 Declaración..........................................................................................................79<br />

8.2.3 Variables globales malas y estáticas....................................................................80<br />

ii


8.2.4 Tipos....................................................................................................................81<br />

Variables Booleanas................................................................................................82<br />

Variables enteras......................................................................................................83<br />

Variables Entero largo.............................................................................................83<br />

Variables de moneda................................................................................................83<br />

Variables de Sencillos..............................................................................................83<br />

Variables de Dobles.................................................................................................83<br />

Variables de Cadena................................................................................................84<br />

8.2.5 Constantes............................................................................................................84<br />

8.2.6 Areglos o matrices...............................................................................................84<br />

Option Base.............................................................................................................84<br />

LBound(NombreMatriz[,Dimensión]) .....................................................................84<br />

UBound(NombreMatriz[,Dimensión]) ....................................................................84<br />

Está esta matriz definida..........................................................................................85<br />

Listas de matrices y ReDim.....................................................................................85<br />

8.2.7 Probando objetos.................................................................................................86<br />

8.2.8 Condicionales......................................................................................................86<br />

8.3 Funciones y SubProcedimientos.................................................................................87<br />

8.3.1 Parametros opcionales.........................................................................................88<br />

8.3.2 Parámetros por referencia o valor........................................................................89<br />

8.3.3 Recursividad........................................................................................................89<br />

8.4 Control de flujo...........................................................................................................90<br />

8.4.1 If ... Then ... Else.................................................................................................90<br />

8.4.2 IIF........................................................................................................................90<br />

8.4.3 Choose.................................................................................................................91<br />

8.4.4 For....Next............................................................................................................91<br />

8.4.5 Do ... Loop...........................................................................................................92<br />

8.4.6 Select ... Case.......................................................................................................93<br />

8.4.7 Expresiones Case.................................................................................................93<br />

8.4.8 While...Wend.......................................................................................................94<br />

8.4.9 GoSub..................................................................................................................94<br />

8.4.10 GoTo..................................................................................................................95<br />

8.4.11 On GoTo............................................................................................................95<br />

8.4.12 Exit....................................................................................................................96<br />

8.4.13 Manejo de errores...............................................................................................97<br />

8.5 Misceláneos.................................................................................................................97<br />

9 Operadores y precedencia.................................................................................................101<br />

10 Operadores, Instrucciones y Funciones..........................................................................103<br />

10.1 Operador - ..............................................................................................................103<br />

10.2 Operador * ..............................................................................................................103<br />

10.3 Operador + .............................................................................................................103<br />

10.4 Operador ^...............................................................................................................104<br />

10.5 Operador /................................................................................................................104<br />

iii


10.6 Operador AND........................................................................................................105<br />

10.7 Función Abs............................................................................................................106<br />

10.8 Función Array.........................................................................................................106<br />

10.9 Función Asc............................................................................................................107<br />

10.10 Función ATN........................................................................................................108<br />

10.11 Instrucción Beep....................................................................................................108<br />

10.12 Función Blue.........................................................................................................108<br />

10.13 Palabra clave ByVal..............................................................................................109<br />

10.14 Palabra clave Call..................................................................................................109<br />

10.15 Función CBool......................................................................................................110<br />

10.16 Función CByte......................................................................................................111<br />

10.17 Función CDate......................................................................................................111<br />

10.18 Función CDateFromIso.........................................................................................112<br />

10.19 Función CDateToIso.............................................................................................112<br />

10.20 Función CDbl........................................................................................................112<br />

10.21 Instrucción ChDir..................................................................................................113<br />

10.22 Instrucción ChDrive..............................................................................................113<br />

10.23 Función Choose.....................................................................................................114<br />

10.24 Función Chr...........................................................................................................115<br />

10.25 Función CInt..........................................................................................................115<br />

10.26 Función CLng........................................................................................................116<br />

10.27 Instrucción Close...................................................................................................116<br />

10.28 Instrucción Const..................................................................................................117<br />

10.29 Función ConvertFromURL...................................................................................117<br />

10.30 Función ConvertToURL.......................................................................................118<br />

10.31 Función Cos..........................................................................................................118<br />

10.32 Función CreateUnoDialog....................................................................................119<br />

10.33 Función CreateUnoService...................................................................................120<br />

10.34 Función CreateUnoStruct......................................................................................120<br />

10.35 Función CSng........................................................................................................121<br />

10.36 Función CStr.........................................................................................................121<br />

10.37 Función CurDir.....................................................................................................122<br />

10.38 Función Date.........................................................................................................122<br />

10.39 Función DateSerial................................................................................................123<br />

10.40 Función DateValue................................................................................................124<br />

10.41 Función Day..........................................................................................................124<br />

10.42 Instrucción Declare...............................................................................................125<br />

10.43 Instrucción DefBool..............................................................................................125<br />

10.44 Instrucción DefDate..............................................................................................126<br />

10.45 Instrucción DefDbl................................................................................................126<br />

10.46 Instrucción DefInt.................................................................................................127<br />

10.47 DefLng Statement..................................................................................................127<br />

10.48 Instrucción DefObj................................................................................................128<br />

iv


10.49 Instrucción DefVar................................................................................................128<br />

10.50 Instrucción Dim.....................................................................................................128<br />

10.51 Función DimArray................................................................................................129<br />

10.52 Función Dir...........................................................................................................130<br />

10.53 Instrucción Do...Loop...........................................................................................132<br />

10.54 Instrucción End.....................................................................................................132<br />

10.55 Función Environ....................................................................................................133<br />

10.56 Función EOF.........................................................................................................134<br />

10.57 Función EqualUnoObjects....................................................................................134<br />

10.58 Operador EQV......................................................................................................135<br />

10.59 Función Erl............................................................................................................136<br />

10.60 Función Err............................................................................................................136<br />

10.61 Función Error........................................................................................................137<br />

10.62 Función Error........................................................................................................138<br />

10.63 Instrucción Exit.....................................................................................................138<br />

10.64 Función Exp..........................................................................................................139<br />

10.65 Función FileAttr....................................................................................................140<br />

10.66 Instrucción FileCopy.............................................................................................141<br />

10.67 Función FileDateTime..........................................................................................141<br />

10.68 Función FileExists.................................................................................................142<br />

10.69 Función FileLen....................................................................................................142<br />

10.70 Función FindObject...............................................................................................143<br />

10.71 Función FindPropertyObject.................................................................................143<br />

10.72 Función Fix...........................................................................................................144<br />

10.73 For...Next Statement..............................................................................................144<br />

10.74 Función Format.....................................................................................................144<br />

10.75 Función FreeFile...................................................................................................147<br />

10.76 FreeLibrary Function.............................................................................................147<br />

10.77 Instrucción Function..............................................................................................148<br />

10.78 Instrucción Get......................................................................................................149<br />

10.79 Función GetAttr....................................................................................................150<br />

10.80 Función GetProcessServiceManager....................................................................151<br />

10.81 Función GetSolarVersion......................................................................................151<br />

10.82 Función GetSystemTicks......................................................................................152<br />

10.83 Instrucción GlobalScope.......................................................................................152<br />

10.84 Function.................................................................................................................153<br />

10.85 Function.................................................................................................................153<br />

10.86 Function.................................................................................................................153<br />

10.87 Function.................................................................................................................154<br />

10.88 Función Green.......................................................................................................154<br />

10.89 Palabra clave Private.............................................................................................155<br />

10.90 Palabra clave Public..............................................................................................155<br />

10.91 Función Red..........................................................................................................156<br />

v


10.92 Notación y nombres de archivo URL....................................................................156<br />

10.92.1 Notación URL...............................................................................................156<br />

10.92.2 Rutas con espacios y otros caracteres especiales..........................................156<br />

11 Index................................................................................................................................159<br />

vi


1Introducción<br />

<strong>OpenOffice</strong>.org Basic es el nombre del lenguaje de <strong>macros</strong> incluido con <strong>OpenOffice</strong>.org.<br />

<strong>OpenOffice</strong>.org Basic tiene mucho en común con Visual Basic de manera que si usted sabe<br />

Visual Basic, esto será una gran ventaja.<br />

<strong>OpenOffice</strong>.org Basic está basada en subrutinas y funciones. Están implementadas con las<br />

palabras clave “Sub” y “Function”. Me referiré genericamente a estos como procedimientos.<br />

Cada procedimiento proveerá alguna funcionalidad y puede llamar a otros procedimientos.<br />

(No está permitida la recursividad). La diferencia entre un “Sub” y una “Function” es que<br />

“Function” puede retornar un valor y por eso está permitido el uso en la parte derecha de una<br />

declaración.<br />

Una colección de procedimientos está contenido en un módulo. Un documento puede<br />

contener modulos, y pueden existir globalmente aparte de un documento. Colecciones de<br />

módulos están guardados en una librería.<br />

????<br />

En <strong>OpenOffice</strong>.org Basic, puede accesar el documento o la aplicación a través de las dos<br />

variables globales “ThisComponent” y “StarDesktop” respectivamente. Después de tener un<br />

documento, puede accesar su interface. Veamos un ejemplo<br />

Dim oText As Object<br />

Dim oDoc As Object<br />

oDoc = ThisComponent ' Obtiene el documento activo<br />

oText = oDoc.Text ' Obtiene el servicio TextDocument<br />

?? Gracias a Kelvin demo@onlineconnections.com.au por su aporte en cosas como quitar<br />

la palabra clave “ByVal”<br />

1


2Recursos disponibles<br />

2.1Material incluido<br />

No olvide el poder de las páginas de ayuda. Hay mucha información <strong>sobre</strong> la sintaxis de las<br />

<strong>macros</strong>. Después de abrir las páginas de ayuda, puede accesar el combo en la esquina<br />

superior izquierda que dice “Help about <strong>OpenOffice</strong>.org Basic” Es también instructivo<br />

investigar y usar las <strong>macros</strong> que viene en el <strong>OpenOffice</strong>. Hay, por ejemplo, <strong>macros</strong> <strong>para</strong> las<br />

propiedades de impresión y los nombres de objetos. Las he usado <strong>para</strong> determinar que puedo<br />

hacer con un objeto cuando encuentro la documentación confusa.<br />

Abra un documento y seleccione el menú “Herramientas=>Macro”. En la caja de lista,<br />

busque un módulo llamado "Tools". Expanda el módulo “Tools”, encontrará otro llamado<br />

“Debug”. Estas <strong>macros</strong> están implementadas <strong>para</strong> imprimir y mostrar información de<br />

depuración, servicios, atributos, etc. Específicamente vea WritedbgInfo(document) o<br />

printdbgInfo(sheet). Son buenos ejemplos.<br />

Para usar la librería de <strong>macros</strong> “Tools”, deberá primero cargarla. Desde el Basic IDE<br />

(Ambiente de Desarrollo Integrado) 1 o desde un documento, seleccione<br />

“Herramientas=>Macro”, seleccione la librería “Tools” y presione “F5” o haga click en<br />

“Run”.<br />

2.2Recursos en línea (on line)<br />

Hay mucha información disponible en línea, el problema es encontrarla. Mientras usted se<br />

siente confortable con este <strong>para</strong>digma, las cosas no están lo suficientemente claras. Aquí hay<br />

algunos vínculos que he encontrado útiles.<br />

• http://www.openoffice.org es el vínculo principal.<br />

• http://api.openoffice.org contiene información de referencia <strong>sobre</strong> API2 . Mucha<br />

información buena, solamente tiene que decifrarla. Cuando esté más a gusto con este<br />

<strong>para</strong>digma, esto le ayudará grandemente.<br />

• http://api.openoffice.org/basic/man/tutorial/tutorial.pdf Usted deberá tener este<br />

documento.<br />

• http://udk.openoffice.org/common/man/tutorial/office_automation.html<br />

• http://api.openoffice.org/common/ref/com/sun/star/module-ix.html información vieja de<br />

API que encontré útil.<br />

• http://documentation.openoffice.org el sitio de documentación es muy bueno. Verifique la<br />

sección “how to” 3 . Hay un documento fantástico <strong>sobre</strong> cómo usar las <strong>macros</strong>! Está<br />

disponible en<br />

http://documentation.openoffice.org/HOW_TO/various_topics/How_to_use_bas<br />

ic_<strong>macros</strong>.sxw<br />

• http://docs.sun.com/db/coll/999.2?q=star+office le permite bajar los manuales de<br />

StarOffice. Yo encontré el tutorial de starbasic útil por los ejemplos.<br />

Otros sitios que contienen ejemplos y código generalmente útil son:<br />

1 N.T. Por las siglas de Integrated Development Environment<br />

2 N.T. API son las siglas en inglés Aplication Program Interface, o Interface de programas de aplicación.<br />

3 N.T. “cómo hacerlo”. La página está en inglés y esa expresión en intraducible.<br />

3


• http://www.darwinwars.com/lunatic/bugs/oo_<strong>macros</strong>.html<br />

• http://disemia.com/software/openoffice/<br />

• http://kienlein.com/pages/oo.html<br />

4


3 Ejemplos<br />

3.1 Manipulación de cadenas<br />

Basic ofrece algunos métodos <strong>para</strong> la manipulación de cadenas.<br />

Función Descripción<br />

Asc(s$) Devuelve el valor ASCII (American Standard Code for Information<br />

Interchange) del primer caracter de la cadena. Genera un error si la<br />

cadena está vacía.<br />

LCase(s$) Devuelve la cadena en minúsculas. La ayuda en línea tiene errores en<br />

1.0.2.<br />

Len(s$) Retorna el tamaño de la cadena s.<br />

Left(s$, n%) Devuelve los primeros n caracteres de s o una cadena vacía si n es<br />

cero.<br />

LSet s$ = Text<br />

LTrim(s$) Devuelve una cadena sin los espacios iniciales. Espacios no<br />

significan espacios en blanco, solamente espacios. Esto no modifica<br />

la cadena.<br />

Mid(s$, i%[, n%]) Regresa una cadena desde la locación i del tamaño de n. Si n es<br />

omitido, retornará todos los caracteres desde i hasta el final de la<br />

cadena.<br />

Mid(s$, i%, n%, r$) Reemplaza la cadena del medio especificada arriba con la cadena r.<br />

Esto no modifica la cadena s. Si el valor de r es mayor que n,<br />

entonces solamente los primeros n caracteres en r serán reemplazados<br />

en s.<br />

Add UCase(), RTrim, Trim<br />

En la ayuda en línea, el ejemplo <strong>para</strong> la conversión de minúsculas/mayúsculas es incorrecto.<br />

Aqui está el ejemplo como debería de leerse.<br />

Sub ExampleLUCase<br />

Dim sVar As String<br />

sVar = "Las Vegas"<br />

Print LCase(sVar) REM Returns "las vegas"<br />

Print UCase(sVar) REM Returns "LAS VEGAS"<br />

end Sub<br />

3.1.1 Remover caracteres de una cadena<br />

Esto removerá los caracteres de una cadena. Lo dis<strong>para</strong>tado de esta macro es que sería mejor<br />

escrita con el método mid(). La diferencia es que el método mid() modifica la cadena actual<br />

mientras que esta retorna una nueva cadena. Yo pude hacerla usando el método mid(), pero<br />

me di cuenta de esto hasta que fue demasiado tarde.<br />

'Remueve cierto número de caracteres de una cadena<br />

5


Function RemoveFromString(s$, index&, num&) As String<br />

If num = 0 Or Len(s) < index Then<br />

'Si no se remueve nada o está fuera del rango, se devuelve la cadena<br />

RemoveFromString = s<br />

ElseIf index Len(s) Then<br />

RemoveFromString = Left(s,index - 1)<br />

Else<br />

RemoveFromString = Left(s,index - 1) + Right(s, Len(s) - index - num + 1)<br />

End If<br />

End If<br />

End Function<br />

3.1.2 Reemplazar texto en una cadena<br />

Esto puede ser usado <strong>para</strong> borrar areas de una cadena especificando que la cadena de<br />

reemplazo es una cadena vacía. Inicialmente pensé que podía usar el método mid() <strong>para</strong> esto<br />

también, pero este método no puede hacer que la cadena sea más grande de lo que<br />

actualmente es. Por esto tuve que escribir esta macro. No modifica la cadena actual, pero en<br />

su lugar crea una nueva cadena con los reemplazos hechos.<br />

Rem s$ es la cadena a ser modificada<br />

Rem index es un "long" indicando dónde será hecho el reemplazo. (base 1)<br />

Rem Si index es Len(s) entonces el texto será insertado al final.<br />

Rem num es un "long" indicando cuántos caracteres reemplazar.<br />

Rem Si num es cero entonces nada es removido, pero la nueva cadena es insertada.<br />

Rem replaces es la cadena a reemplazar dentro de la cadena original.<br />

Function ReplaceInString(s$, index&, num&, replaces$) As String<br />

If index


End Function<br />

3.1.3 Imprimiendo los valores ASCII de una cadena<br />

Esto se ve como una macro rara, pero yo la uso <strong>para</strong> decidir como será guardado el texto en<br />

el documento. Esto imprime una cadena completa como una serie de número s ASCII.<br />

Sub PrintAll<br />

PrintAscii(ThisComponent.text.getString())<br />

End Sub<br />

Sub PrintAscii(TheText As String)<br />

If Len(TheText) < 1 Then Exit Sub<br />

Dim msg$, i%<br />

msg = ""<br />

For i = 1 To Len(TheText)<br />

msg = msg + Asc(Mid(TheText,i,1)) + " "<br />

Next i<br />

Print msg<br />

End Sub<br />

3.2 Depurando e inspeccionando Macros<br />

Frecuentemente es dificil determinar qué métodos y propiedades están disponibles en un<br />

objeto. Los métodos en esta sección pueden ser de ayuda.<br />

3.2.1 Determinar el tipo de documento<br />

Esta macro viene con <strong>OpenOffice</strong> y está incluida aquí como una demostración <strong>sobre</strong> cómo<br />

determinar el tipo de documento.<br />

'******************************************************************<br />

'Autor: Incluida con <strong>OpenOffice</strong><br />

'<br />

Function GetDocumentType(oDoc)<br />

On Local Error GoTo NODOCUMENTTYPE<br />

If oDocument.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Then<br />

GetDocumentType() = "scalc"<br />

ElseIf oDocument.SupportsService("com.sun.star.text.TextDocument") Then<br />

GetDocumentType() = "swriter"<br />

ElseIf oDocument.SupportsService("com.sun.star.drawing.DrawingDocument") Then<br />

GetDocumentType() = "sdraw"<br />

ElseIf oDocument.SupportsService("com.sun.star.formula.FormulaProperties") Then<br />

GetDocumentType() = "smath"<br />

End If<br />

NODOCUMENTTYPE:<br />

If Err 0 Then<br />

GetDocumentType = ""<br />

Resume GOON<br />

GOON:<br />

End If<br />

End Function<br />

7


3.2.2 Desplegando los métodos y propiedades de un objeto<br />

Esta es una excelente subrutina. El primer <strong>para</strong>metro es el objeto en cuestión. El segundo<br />

<strong>para</strong>metro puede ser “” <strong>para</strong> desplegar los métodos y cualquier otra cadena <strong>para</strong> desplegar las<br />

propiedades del objeto. La lista de propiedades o métodos es frecuentemente tan larga que<br />

excede el tamaño de la pantalla. Esta subrutina evita esto al partir la lista en piezas pequeñas.<br />

'******************************************************************<br />

'A subroutine to display all the methods or properties of an input<br />

'Author: Tony Bloomfield<br />

'email: tonyb.lx@btinternet.com<br />

Sub DisplayMethods(oObj As Object, SWhat As String)<br />

DIM sMethodList As String, sMsgBox As String<br />

DIM fs, ep As Integer<br />

DIM i As Integer<br />

DIM EOL As Boolean<br />

if sWhat = "" then<br />

sMethodList = oObj.DBG_methods<br />

else<br />

sMethodList = oObj.DBG_Properties<br />

endif<br />

fs = 1<br />

EOL = FALSE<br />

While fs


3.2.3 Desplegando las propiedades de un objeto en una hoja de<br />

cálculo.<br />

Esta macro debe ser ejecutada <strong>para</strong> creer. Herr Hermann Kienlein hizo un impresionante<br />

trabajo con esto. Esta macro crea una nueva hoja de cálculo y la rellena con información<br />

<strong>sobre</strong> los objetos. Yo modifiqué extensivamente esta macro porque usaba variables globales.<br />

Las variables globales interferían con mis propias variables locales. Esto me ayudaba a usarla<br />

en mi propio código existente.<br />

'******************************************************************<br />

'Author: Hermann Kienlein<br />

'email: info@kienlein.com<br />

'online: http://www.kienlein.com/pages/oo.html<br />

Option Explicit ' Fuerza a declarar las variables<br />

Sub Main<br />

MainObjectDisplay(ThisComponent)<br />

End Sub<br />

' ------------------------------------------------------<br />

'Crea un nuevo documento y luego crea nuevas hojas en el documento.<br />

' Da nombres a las hojas e inserta información en las mismas.<br />

Sub MainObjectDisplay(oObject As Object)<br />

Dim oInfo As Object, oDeskNeu As Object, oNewDoc As Object<br />

Dim sNewUrl As String, nSheetsUsed As Long<br />

Dim sInterfaces As String<br />

nSheetsUsed = 0<br />

oDeskNeu = createUnoService("com.sun.star.frame.Desktop")<br />

'sNewUrl = "staroffice.factory:scalc" ' This did not work<br />

sNewUrl = "private:factory/scalc"<br />

oNewDoc = oDeskNeu.loadComponentFromURL( sNewUrl,"_blank",0,NoArgs())<br />

ObjInfo(oNewDoc, nSheetsUsed, "ThisComponent", oObject)<br />

On Local Error GoTo AllDone<br />

sInterfaces = oObject.dbg_supportedinterfaces<br />

On Local Error GoTo NoController<br />

If InStr(sInterfaces, "com.sun.star.frame.XModel") 0 Then<br />

oInfo = oObject.getCurrentController()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getCurrentController", oInfo)<br />

End If<br />

NoController:<br />

On Local Error GoTo NoDocInfo<br />

'??<br />

' If InStr(sInterfaces, "com.sun.star.document.XDocumentInfoSupplier") 0 Then<br />

oInfo = oObject.getDocumentInfo()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getDocumentInfo", oInfo)<br />

9


' End If<br />

NoDocInfo:<br />

On Local Error GoTo NoSelection<br />

'??<br />

' If InStr(sInterfaces, "com.sun.star.frame.XSelectionSupplier") 0 Then<br />

oInfo = oObject.getCurrentSelection()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getCurrentSelection", oInfo)<br />

' End If<br />

NoSelection:<br />

On Local Error GoTo NoLibraryContainer<br />

If InStr(sInterfaces, "com.sun.star.script.XStarBasicAccess") 0 Then<br />

oInfo = oObject.getLibraryContainer()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getLibraryContainer", oInfo)<br />

End If<br />

NoLibraryContainer:<br />

On Local Error GoTo NoViewData<br />

If InStr(sInterfaces, "com.sun.star.document.XViewDataSupplier") 0 Then<br />

oInfo = oObject.getViewData()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getViewData", oInfo)<br />

End If<br />

NoViewData:<br />

On Local Error GoTo NoEvents<br />

If InStr(sInterfaces, "com.sun.star.document.XEventsSupplier") 0 Then<br />

oInfo = oObject.getEvents()<br />

ObjInfo(oNewDoc, nSheetsUsed, "getEvents", oInfo)<br />

End If<br />

NoEvents:<br />

AllDone:<br />

On Local Error GoTo 0<br />

End Sub<br />

' ------------------------------------------------------<br />

Sub ObjInfo(oDoc As Object, nSheetsUsed&, sSheetName$, obj As Object)<br />

Dim i2 As Integer, bProp As Boolean<br />

Dim nRow&, nCol&, oSheet As Object<br />

nRow = 0<br />

ncol = 0<br />

'on error goto err_ObjInfo<br />

If Not isNull(obj) Then<br />

GoToNextSheet(oDoc, nSheetsUsed, sSheetName)<br />

oSheet = oDoc.Sheets.getByIndex(nSheetsUsed-1)<br />

'oCell.String=CStr(obj.WindowServiceName)<br />

SetCell(nCol, nRow, oSheet, TypeName(obj), 1, 0)<br />

SetCell(nCol, nRow, oSheet, VarType(obj), -1, 2)<br />

10


i2 = InStr(obj.dbg_methods,"getPropertySetInfo")<br />

If i2 > 0 Then<br />

bProp = true<br />

Else<br />

bProp = false<br />

End If<br />

ListItems (nCol, nRow, obj.dbg_methods, ";", obj, true, oSheet)<br />

MoveRow(nCol, nRow, 2)<br />

If Not isNull (obj.dbg_properties) Then<br />

'NextSheet()<br />

ListItems (nCol, nRow, obj.dbg_properties, ";", obj, false, oSheet)<br />

End If<br />

If bProp Then<br />

GetProps(nCol, nRow, obj, oSheet)<br />

bProp = false<br />

End If<br />

MoveRow(nCol, nRow, 1)<br />

ListItems (nCol, nRow, obj.dbg_supportedinterfaces, chr$(10), obj, false, oSheet)<br />

'CleanDbg 'noch keine Ahnung, für was das gut ist<br />

'NextSheet()<br />

End If<br />

exit_ObjInfo:<br />

Exit Sub<br />

err_ObjInfo:<br />

'print err<br />

If err=423 Then<br />

obName = inputbox("Das Objekt hat keine name-Eigenschaft."_<br />

+" Welchen Namen soll das neue Tabellenblatt haben?")<br />

Resume Next<br />

Else<br />

msgbox error$, 16<br />

Resume exit_ObjInfo<br />

End If<br />

End Sub<br />

' ------------------------------------------------------<br />

' ListItems - übergebenen String nach Trennzeichen durchsuchen<br />

' und Zeilenweise ausgeben<br />

' ------------------------------------------------------<br />

Sub ListItems(nCol&, nRow&, itemstring$, sep$, oBj As Object, gt As Boolean, oSheet As Object)<br />

'dim oCurs As Object<br />

Dim frag As String, sleft As String, sPrf As String<br />

Dim act As Integer, ex As Integer, nextpos As Integer<br />

Dim nextchr As Integer, lstr As Integer, lfrag As Integer<br />

Dim ch As Integer<br />

lstr = Len(itemstring)<br />

act =1<br />

'Everything left of the first colon<br />

SetCell(nCol, nRow, oSheet, Left(itemstring,InStr(1,itemstring, ":")), 0, 0)<br />

'If there is no colon, then we are done here<br />

If InStr(1,itemstring,":") < 1 Then<br />

11


SetCell(nCol, nRow, oSheet, itemstring, 0, 0)<br />

Exit Sub<br />

End If<br />

act= act+InStr(1,itemstring,":") 'also jetzt auf dem ersten :<br />

'act = act+1 'ein Zeichen weiter positionieren<br />

MoveRow(nCol, nRow, 1)<br />

While act "" Then<br />

Do<br />

nextchr = Asc(Mid(frag,1,1)<br />

If nextchr = "10" Then<br />

Mid(frag,1,1," ")<br />

frag = LTrim(frag) 'linksbündig ausrichten<br />

Else<br />

exit Do<br />

End If<br />

Loop<br />

End If<br />

MoveRow(nCol, nRow, 1)<br />

SetCell(nCol, nRow, oSheet, frag, 0, 0)<br />

If gt Then<br />

GtVal(nCol, nRow, frag,oBj, oSheet)<br />

End If<br />

Wend<br />

itemstring = ""<br />

End Sub<br />

' ------------------------------------------------------<br />

' Sub um Properties auszulesen, Object muß allerdins<br />

' .PropertySetInfo.Methode<br />

' unterstützen<br />

Sub GetProps(nCol&, nRow&, obj, oSheet As Object)<br />

Dim vVariant as Variant<br />

dim nVar As Integer<br />

dim mProperties as variant<br />

dim mProps1 as variant<br />

dim sItemDescription<br />

dim nCount As Integer<br />

dim iP As Integer, iP1 As Integer<br />

dim n$<br />

dim p<br />

dim tmp$<br />

dim j%<br />

dim vItem<br />

dim sString<br />

12


MoveRow(nCol, nRow, 2)<br />

mProperties = obj.PropertySetInfo.Properties<br />

nCount = UBound(mProperties)-LBound(mProperties) + 2<br />

SetCell(nCol, nRow, oSheet, "Properties With Values", 0, 1)<br />

SetCell(nCol, nRow, oSheet, "Name", 1, 0)<br />

SetCell(nCol, nRow, oSheet, "Value", -1, 1)<br />

For iP = LBound(mProperties) To UBound(mProperties)<br />

p = mProperties(iP)<br />

n$ = p.name<br />

vVariant = obj.getPropertyValue(n$)<br />

SetCell(nCol, nRow, oSheet, n$, 1, 0)<br />

nVar = VarType(vVariant)<br />

Select Case nVar<br />

Case 1 'isNull<br />

SetCell(nCol, nRow, oSheet, "NULL-VALUE", 0, 1)<br />

Case 9 'object<br />

If Not isNull (vVariant.dbg_properties) Then<br />

ListItems (nCol, nRow, vVariant.dbg_properties, ";", vVariant, false, oSheet)<br />

MoveRow(nCol, nRow, 2)<br />

End If<br />

if not isNull (vVariant.dbg_supportedinterfaces) then<br />

ListItems (nCol, nRow, vVariant.dbg_supportedinterfaces, _<br />

chr$(10), vVariant, false, oSheet)<br />

MoveRow(nCol, nRow, 2)<br />

End If<br />

If Not isNull (vVariant.dbg_methods) Then<br />

ListItems (nCol, nRow, vVariant.dbg_methods, ";", _<br />

vVariant, false, oSheet)<br />

MoveRow(nCol, nRow, 2)<br />

End If<br />

Case Else<br />

If IsArray(vVariant) Then<br />

tmp$ = ""<br />

For j% = LBound(vVariant) To UBound(vVariant)<br />

vItem = vVariant(j%)<br />

If IsNull(vItem) Then<br />

sItemDescription = "NULL-Value"<br />

ElseIf IsObject(vItem) Then<br />

If Not isNull(vItem.dbg_properties) Then<br />

sItemDescription = CStr(vItem.dbg_properties)<br />

End If<br />

Else<br />

sItemDescription = cstr(vItem)<br />

End If<br />

tmp$ = tmp$ & sItemDescription<br />

Next j%<br />

ListItems(nCol, nRow, tmp$,";",vVariant,false, oSheet)<br />

Else<br />

SetCell(nCol, nRow, oSheet, cstr(vVariant), 0, 1)<br />

End If<br />

end select<br />

13


MoveRow(nCol, nRow, 1)<br />

MoveCol(nCol, nRow, -1)<br />

Next iP<br />

End Sub<br />

' ------------------------------------------------------<br />

' GetValue - Inhalte auslesen<br />

' ------------------------------------------------------<br />

Sub GtVal (nCol&, nRow&, sGVal As String, oBje As Object, oSheet As Object)<br />

dim is1 As Integer, iAr As Integer<br />

dim s1 As String, s2 As String, s3 As String<br />

dim aR1(10) as variant<br />

dim o1 As Object<br />

is1 =InStr(sGVal," ") 'erstes Space suchen<br />

s1 = Mid(sGval,1,is1)<br />

s2 = Mid(sGVal,1,is1," ")<br />

sGVal = LTrim(sGVal)<br />

is1 = InStr(sGVal," ")<br />

s2 = Mid(sGVal,1,is1)<br />

s1 = LTrim(s1)<br />

s1= RTrim(s1)<br />

s2 = LTrim(s2)<br />

s2 = RTrim(s2)<br />

Select Case s1<br />

Case "SbxSTRING"<br />

Select Case s2<br />

Case "getURL"<br />

s3 = oBje.getURL()<br />

Case "getLocation"<br />

s3 = oBje.getLocation()<br />

Case "getImplementationName"<br />

s3 = oBje.getImplementationName()<br />

Case "getUserFieldName"<br />

s3 = oBje.getUserFieldName(0)<br />

Case "getUserFieldValue"<br />

s3 = oBje.getUserFieldValue(0)<br />

Case Else<br />

s3 = s2<br />

End Select<br />

's3 = oBje.&s2<br />

'msgbox(CStr(oBje)&s2)<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

Case "SbxBOOL"<br />

Select Case s2<br />

Case "hasControllersLocked"<br />

s3= CStr(oBje.hasControllersLocked())<br />

Case "isModified"<br />

s3= CStr(oBje.isModified())<br />

Case "AutoloadEnabled"<br />

14


s3= CStr(oBje.AutoloadEnabled())<br />

Case "hasElements"<br />

s3= CStr(oBje.hasElements())<br />

Case "IsEncrypted"<br />

s3= CStr(oBje.IsEncrypted())<br />

Case "isReadonly"<br />

s3= CStr(oBje.isReadonly())<br />

Case Else<br />

s3 = " "<br />

End Select<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

Case "SbxINTEGER"<br />

Select Case s2<br />

Case "getUserFieldCount"<br />

s3 = CStr(oBje.getUserFieldCount())<br />

Case "EditingCycles"<br />

s3 = CStr(oBje.EditingCycles())<br />

Case Else<br />

s3 = ""<br />

End Select<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

Case "SbxLONG"<br />

Select Case s2<br />

Case "getCount"<br />

s3 = CStr(oBje.getCount())<br />

Case Else<br />

s3 = ""<br />

End Select<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

Case "SbxOBJECT"<br />

Select Case s2<br />

Case "getElementType"<br />

s3 = CStr(VarType(oBje.getElementType()))<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

Case "getText"<br />

o1 = oBje.getText()<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, o1.dbg_properties, 3, 0)<br />

SetCell(nCol, nRow, oSheet, o1.dbg_methods, -7, 0)<br />

Case Else<br />

End Select<br />

Case "SbxARRAY"<br />

Select Case s2<br />

Case "getImplementationId"<br />

aR1() = oBje.getImplementationId()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getImplementationID()) To _<br />

15


UBound(oBje.getImplementationID())<br />

s3 = CStr(aR1(iAr))<br />

SetCell(nCol, nRow, oSheet, s3, 1, 0)<br />

next iAr<br />

MoveCol(nCol, nRow, -(4+1+UBound(oBje.getImplementationID())))<br />

Case "getArgs"<br />

'?? Why is this commented out to print?<br />

aR1() = oBje.getArgs()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getArgs()) To UBound(oBje.getArgs())<br />

o1 = aR1(iAr)<br />

s3 = o1.dbg_properties<br />

'GetProps(aR1(iAr)<br />

'oCell.String = s3<br />

MoveCol(nCol, nRow, 1)<br />

Next iAr<br />

MoveCol(nCol, nRow, -(4+1+UBound(oBje.getArgs())))<br />

Case "getTypes"<br />

aR1() = oBje.getTypes()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getTypes()) To UBound(oBje.getTypes())<br />

o1 = aR1(iAr)<br />

s3 = VarType(o1)<br />

SetCell(nCol, nRow, oSheet, s3, 1, 0)<br />

Next iAr<br />

MoveCol(nCol, nRow, -(4+1+UBound(oBje.getTypes())))<br />

Case "getElementNames"<br />

aR1() = oBje.getElementNames()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getElementNames()) To _<br />

UBound(oBje.getElementNames())<br />

'o1 = aR1(iAr)<br />

's3 = VarType(o1)<br />

SetCell(nCol, nRow, oSheet, aR1(iAr), 1, 0)<br />

Next iAr<br />

MoveCol(nCol, nRow, -(4+1+UBound(oBje.getElementNames())))<br />

Case "getSupportedServiceNames"<br />

aR1() = oBje.getSupportedServiceNames()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getSupportedServiceNames()) To _<br />

UBound(oBje.getSupportedServiceNames())<br />

'o1 = aR1(iAr)<br />

's3 = VarType(o1)<br />

SetCell(nCol, nRow, oSheet, aR1(iAr), 1, 0)<br />

Next iAr<br />

MoveCol(nCol, nRow, _<br />

-(4+1+UBound(oBje.getSupportedServiceNames())))<br />

Case "getPrinter"<br />

aR1() = oBje.getPrinter()<br />

MoveCol(nCol, nRow, 4)<br />

For iAr = LBound(oBje.getPrinter()) To UBound(oBje.getPrinter())<br />

16


o1 = aR1(iAr)<br />

s3 = CStr(VarType(aR1(iAr)))<br />

'?? We never print this<br />

MoveCol(nCol, nRow, 1)<br />

Next iAr<br />

MoveCol(nCol, nRow, -(4+1+UBound(oBje.getPrinter())))<br />

Case Else<br />

s3 = " "<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

End Select<br />

Case Else<br />

s3 = " "<br />

MoveCol(nCol, nRow, 4)<br />

SetCell(nCol, nRow, oSheet, s3, -4, 0)<br />

End Select<br />

end sub<br />

' -----------------------------------------------------<br />

Sub SetCell(nCol&, nRow&, oSheet As Object, s$, colInc%, rowInc%)<br />

oSheet.getCellByPosition(nCol, nRow).String = s$<br />

If colInc 0 Then MoveCol(nCol, nRow, colInc%)<br />

If rowInc 0 Then MoveRow(nCol, nRow, rowInc)<br />

End Sub<br />

' ------------------------------------------------------<br />

Sub MoveCol(nCol&, nRow&, i%)<br />

nCol = nCol + i<br />

If nCol < 0 Then<br />

nRow = nRow + 1<br />

nCol = 0<br />

End If<br />

End Sub<br />

' ------------------------------------------------------<br />

Sub MoveRow(nCol&, nRow&, i%)<br />

nRow = nRow + i<br />

If nRow < 0 Then<br />

nRow = 0<br />

End If<br />

End Sub<br />

' ------------------------------------------------------<br />

'Create a new sheet if required with the given name.<br />

Sub GoToNextSheet(oDoc As Object, nSheetsUsed&, sSheetName$, Optional nWhichSheet%)<br />

Dim oSheets As Object, oSheet As Object<br />

oSheets = oDoc.Sheets<br />

If isNumeric(nWhichSheet) Then<br />

oSheets.insertNewByName("Sheet"&CStr(oSheets.Count()+1), nWhichSheet)<br />

oSheet = oSheet.getByIndex(nWhichSheet)<br />

Else<br />

17


If nSheetsUsed > oSheets.Count() - 1 Then<br />

nSheetsUsed = oSheets.Count() - 1<br />

oSheets.insertNewByName("Sheet"&CStr(oSheets.Count()+1), _<br />

nSheetsUsed)<br />

End If<br />

oSheet = oSheets.getByIndex(nSheetsUsed)<br />

nSheetsUsed = nSheetsUsed + 1<br />

End If<br />

oSheet.Name = sSheetName<br />

End Sub<br />

18


4 Ejemplos misceláneos<br />

19


4.1 Desplegar texto en la barra de estado<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

'Hay dos métodos que se pueden usar <strong>para</strong> obtener<br />

'el indcador de estado<br />

Function ProgressBar<br />

ProgressBar = ThisComponent.CurrentController.StatusIndicator<br />

'o también<br />

'ProgressBar = StarDesktop.getCurrentComponent.StatusIndicator<br />

End Function<br />

REM Despliega texto en la barra de estado<br />

Sub StatusText(sInformation)<br />

Dim sSpaces As String<br />

Dim iLen,iRest As Integer<br />

'sSpaces=SPACE(270)<br />

iLen=Len(sInformation)<br />

iRest=270-iLen<br />

ProgressBar.start(sInformation+SPACE(iRest),0)<br />

End Sub<br />

20


4.2 Despliega todos los estilos en el documento actual<br />

Esto no es tan grato como parece. Los siguientes estilos existen en un documento de texto:<br />

CharacterStyles, FrameStyles, NumberingStyles, PageStyles, y ParagraphStyles.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub DisplayAllStyles<br />

Dim mFamilyNames As Variant<br />

Dim mStyleNames As Variant<br />

Dim sMsg As String<br />

Dim oFamilies As Object<br />

Dim oStyle As Object<br />

Dim oStyles As Object<br />

oFamilies = ThisComponent.StyleFamilies<br />

mFamilyNames = oFamilies.getElementNames()<br />

For n = LBound(mFamilyNames) To UBound(mFamilyNames)<br />

sMsg = ""<br />

oStyles = oFamilies.getByName(mFamilyNames(n))<br />

mStyleNames = oStyles.getElementNames()<br />

For i = LBound(mStyleNames) To UBound (mStyleNames)<br />

sMsg=sMsg + i + " : " + mStyleNames(i) + Chr(13)<br />

If ((i + 1) Mod 20 = 0) Then<br />

MsgBox sMsg,0,mFamilyNames(n)<br />

sMsg = ""<br />

End If<br />

Next i<br />

MsgBox sMsg,0,mFamilyNames(n)<br />

Next n<br />

End Sub<br />

4.3 Cambiar entre los documentos abiertos<br />

Sub Main<br />

Dim oDesktop As Object, oDocs As Object<br />

Dim oDoc As Object, oComponents As Object<br />

'The hasMoreElements() will fail with the oDesktop,<br />

'I do not know why!<br />

'oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />

oComponents = StarDesktop.getComponents()<br />

oDocs = oComponents.createEnumeration()<br />

Do While oDocs.hasMoreElements()<br />

oDoc = oDocs.nextElement()<br />

Loop<br />

End Sub<br />

4.4 Listar fuentes (Quebrado, no funciona)<br />

Esto no funciona... solo <strong>para</strong> que lo sepan<br />

21


Sub ListFonts<br />

Dim document As Object<br />

Dim Cursor<br />

Dim oText As Object<br />

Dim mySelection As Object<br />

Dim displayString As String<br />

document=ThisComponent<br />

displayString = ""<br />

oStyleFamilies = document.StyleFamilies<br />

'CharacterStyles, ParagraphStyles, FrameStyles, PageStyles<br />

'NumberingStyles, CellStyles, ShapeStyles<br />

oStyles = oStyleFamilies.getByName("CharacterStyles")<br />

For n = 0 to oStyles.Count - 1<br />

oStyle = oStyles(n)<br />

displayString = displayString & "name = (" & oStyle.Name & ") Font = (" & oStyle.CharFontName<br />

& ") Style = (" & CharStyleName & ")" & chr(13)<br />

Next n<br />

Msgbox(displayString, 64, "Styles")<br />

End Sub<br />

22


4.5 Imprimir el documento actual<br />

La ejecuto y puedo imprimir. Me detuve cuando traté de ver como imprimir un documento<br />

A4 en mi impresora Letter! Deseo hacerlo por defecto, pero decidí que eso no merece mi<br />

tiempo por ahora.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub PrintCurrentDocument<br />

Dim mPrintopts1(), x as Variant<br />

'Dimensioned at 0, if you set any other properties, be certain to set this to a higher value....<br />

Dim mPrintopts2(0) As New com.sun.star.beans.PropertyValue<br />

Dim oDocument As Object, oPrinter As Object<br />

oDocument = ThisComponent<br />

'***********************************<br />

'Do you want to choose a certain printer<br />

'Dim mPrinter(0) As New com.sun.star.beans.PropertyValue<br />

'mPrinter(0).Name="Name"<br />

'mPrinter(0).value="Other printer"<br />

'oDocument.Printer = mPrinter()<br />

'***********************************<br />

'To simply print the document do the following:<br />

'oDocument.Print(mPrintopts1())<br />

'***********************************<br />

'To print pages 1-3, 7, and 9<br />

'mPrintopts2(0).Name="Pages"<br />

'mPrintopts2(0).Value="1-3; 7; 9"<br />

'oDocument.Printer.PaperFormat=com.sun.star.view.PaperFormat.LETTER<br />

'DisplayMethods(oDocument, "propr")<br />

'DisplayMethods(oDocument, "")<br />

oPrinter = oDocument.getPrinter()<br />

MsgBox "printer is from " + LBound(oPrinter) + " to " + UBound(oPrinter)<br />

sMsg = ""<br />

For n = LBound(oPrinter) To UBound(oPrinter)<br />

sMsg = sMsg + oPrinter(n).Name + Chr(13)<br />

Next n<br />

MsgBox sMsg,0,"Print Settings"<br />

'DisplayMethods(oPrinter, "propr")<br />

'DisplayMethods(oPrinter, "")<br />

'mPrintopts2(0).Name="PaperFormat"<br />

'mPrintopts2(0).Value=com.sun.star.view.PaperFormat.LETTER<br />

'oDocument.Print(mPrintopts2())<br />

End Sub<br />

23


Algo como esto imprime la página actual!<br />

dim aPrintOps(0) as new com.sun.star.beans.PropertyValue<br />

oDoc = ThisComponent<br />

oViewCursor = oDoc.CurrentController.getViewCursor()<br />

aPrintOps(0).Name = "Pages"<br />

aPrintOps(0).Value = trim(str(oViewCursor.getPage()))<br />

oDoc.print(aPrintOps())<br />

24


4.6 Cambiando el tamaño de una lista<br />

Comentario desde el sitio Web.<br />

Bueno, use la macro. Mientras este error no sea corregido, necesitará “terminar<br />

la tarea” después de aplicar la macro, como un apagado corriente, los valores<br />

escritos por la macro serán <strong>sobre</strong>escritos.<br />

Hay algunas otras maneras <strong>para</strong> lograr lo mismo, pero involucra meterse con<br />

archivos locales que son una implementación detallada de la configuración del<br />

“backend”, que no voy a mencionar aqui :).<br />

Para mi, esta macro no lo es.<br />

'******************************************************************<br />

'Author: Unknown<br />

'email: http://ui.openoffice.org/howto/index.html<br />

Option Explicit<br />

Sub SetPickListTen<br />

ChangePickListSize( 10 )<br />

End Sub<br />

Sub ChangePickListSize( nSize As Integer )<br />

' access the global configuration provider<br />

Dim aConfigProvider As Object<br />

aConfigProvider = createUnoService( "com.sun.star.configuration.ConfigurationProvider" )<br />

' create an access object for the history node<br />

Dim aHistorySettings As Object<br />

Dim aParams(0) As new com.sun.star.beans.PropertyValue<br />

aParams(0).Name = "nodepath"<br />

aParams(0).Value = "/org.openoffice.Office.Common/History"<br />

aHistorySettings = aConfigProvider.createInstanceWithArguments<br />

( "com.sun.star.configuration.ConfigurationUpdateAccess", aParams() )<br />

' set the pick list size<br />

aHistorySettings.replaceByName( "PickListSize", nSize )<br />

' commit the changes done<br />

aHistorySettings.commitChanges<br />

End Sub<br />

Si desea hacerlo manualmente, aqui está la forma “dificil” de hacerlo<br />

1. Haga una o dos copias completas de los archivos apropiados antes de empezar<br />

~/staroffice6.0/user/config/registry/instance/org/openoffice/Office/common.xml<br />

~/openoffice/user/config/registry/instance/org/openoffice/Office/common.xml<br />

2. Inicie TextPad (www.textpad.com) o cualquier otro editor de texto que maneje archivos<br />

XML bien. No use el Block de Notas (Notepad de windows); este obtiene cientos de<br />

cuadritos curiosos y mientras se intenta tecnicamente de estar OK, es rrrrrrealmente dificil<br />

de leer archivos XML en él.<br />

3. Abra el siguiente archivo, <strong>para</strong> StarOffice o <strong>OpenOffice</strong>, cualquiera que esté usando:<br />

25


~/staroffice6.0/user/config/registry/instance/org/openoffice/Office/common.xml<br />

~/openoffice/user/config/registry/instance/org/openoffice/Office/common.xml<br />

4. Busque la etiqueta ; las entradas son alfabéticas. Verá algo como lo siguiente:<br />

<br />

<br />

<br />

StarOffice XML (Writer)<br />

<br />

4. file:///C:/docs/newdocs/story.sxw<br />

file:///C:/docs/newdocs/story.sxw<br />

<br />

[y luego, un poco más entradas ...]<br />

<br />

<br />

<br />

StarOffice XML (Writer)<br />

<br />

file:///C:/docs/newdocs/story.sxw<br />

file:///C:/docs/newdocs/story.sxw<br />

<br />

[y luego, con tres entradas más; esta es la lista de archivos recientes<br />

desplegada bajo el menú archivo...]<br />

<br />

<br />

5. Reemplace en contenido entero de la etiqueta , es decir desde a<br />

inclusive, con el siguiente texto. El ejemplo cambia StarOffice <strong>para</strong> desplegar<br />

los 9 archivos más recientes; digite el número que desee. Imagino que no es buena idea<br />

hacerlo muy grande, pero no conozco si existe un límite de archivos, si hay alguno.<br />

<br />

9<br />

<br />

4.7 Open And Close Documents (And The Desktop)<br />

4.7.1 Cerrar documentos <strong>OpenOffice</strong><br />

Todos los documentos <strong>OpenOffice</strong> y los objetos en marcos (servicios) soportan la interface<br />

Xcerrable. Para cerrar estos objetos deberá llamar close(bForce As Boolean). Si bForce es<br />

falso, entonces el objeto puede rehusar a cerrarse. Si bForce es verdadero, entonces el objeto<br />

no puede rehusarse a cerrarse.<br />

El escritorio no soporta la interface Xcerrable por razones de herencia. El método terminate()<br />

es usado <strong>para</strong> esto. Este método causa un evento-terminación que será transmitido a todos los<br />

que escuchen. Si no se devuelve TerminationVetoException, una notificación de evento-<br />

26


terminación es transmitido y se devuelve un valor verdadero. De lo contrario, se transmite un<br />

aborte-evento-terminación y se devuelve un valor falso. Para citar a Mathias Bauer, “el<br />

método terminate() estuvo ahi por mucho tiempo, mucho antes que descubrimos que no es la<br />

manera correcta de manejar el cierre de documentos o ventanas. Si este no hubiera estado<br />

ahí, podríamos haber usado Xcerrable <strong>para</strong> el escritorio también.”[Bauer001]<br />

If HasUnoInterfaces(oDoc, "com.sun.star.util.XCloseable") Then<br />

oDoc.close(true)<br />

Else<br />

oDoc.dispose<br />

End If<br />

Obtuve los siguientes metodos de Sasa Kelecevic [scat@teol.net] que no he probado??<br />

'------------- salvar_y_cerrar --------------<br />

'Use uno de estos métodos<br />

'oDocClose=StarDesktop.CurrentFrame.Close<br />

'oDocClose=StarDesktop.ActiveFrame.Close<br />

'------------- cerrar_no_salvar ---------------------<br />

'Use uno de estos métodos<br />

'oDocClose=ThisComponent.Dispose<br />

'oDocClose=StarDesktop.ActiveFrame.Dispose<br />

4.7.2 Cargar un documento desde una URL<br />

Para cargar un documento desde una URL, use el método LoadComponentFromURL() del<br />

escritorio. Esto carga un componente dentro de un marco, nuevo o existente.<br />

Sintaxis:<br />

loadComponentFromURL(<br />

string aURL,<br />

string aTargetFrameName,<br />

long nSearchFlags,<br />

sequence< com::sun::star::beans::PropertyValue > aArgs)<br />

Returna:<br />

com::sun::star::lang::XComponent<br />

Parámetros:<br />

aURL: URL <strong>para</strong> el documento a cargar. Para crear un nuevo documento, use<br />

"private:factory/scalc", "private:factory/swriter", etc.<br />

aTargetFrameName: Nombre del marco que contendrá el documento. Si el nombre delmarco<br />

existe, será usado , de lo contrario será creado. "_blank" crea un nuevo marco, "_self"<br />

usa el marco actual, "_parent" usa el marco padre, y "_top" usa el primer marco de la<br />

ruta actual en el árbol.<br />

nSearchFlags: Usa los valores de FrameSearchFlag <strong>para</strong> especificar cómo encontrar el<br />

nombre del marco destino (aTargetFrameName). Normalmente, simplemente use 0.<br />

http://api.openoffice.org/common/ref/com/sun/star/frame/FrameSearchFlag.html<br />

27


# Nombre Descripción<br />

0 Auto SELF+CHILDREN<br />

1 PARENT Incluye el marco padre<br />

2 SELF Incluye el marco inicial<br />

4 CHILDREN Incluye los marcos hijos del marco inicial<br />

8 CREATE Será creado un marco, si no existe<br />

16 SIBLINGS Incluye otros marcos hijos del marco inicial<br />

32 TASKS<br />

23 ALL<br />

55 GLOBAL<br />

Incluye todos los marcos en todas las tareas de la actual<br />

jerarquía de marcos.<br />

Incluye todos los marcos de las otras tareas. 23 =<br />

1+2+4+16 = PARENT + SELF + CHILDREN +<br />

SIBLINGS.<br />

Busca en toda la jerarquía de marcos. 55 = 1+2+4+16+32<br />

= PARENT + SELF + CHILDREN + SIBLINGS +<br />

TASKS.<br />

63 GLOBAL + CREATE<br />

aArgs: Especifica el comportamiento especifico del componente o filtro. "ReadOnly" con un<br />

valor boleano especifica que el documento está abierto en modo sólo lectura.<br />

"FilterName" especifica el tipo de componente <strong>para</strong> crear y el tipo de filtro a usar, por<br />

ejemplo: "scalc: Text - csv". Ver<br />

http://api.openoffice.org/common/ref/com/sun/star/document/MediaDescriptor.html<br />

Ejemplo:<br />

Rem Cargar dos documentos en el mismo marco!<br />

oDesk = createUnoService("com.sun.star.frame.Desktop")<br />

Dim NoArgs()<br />

Rem marco "MyName" será creado si no existe porque incluye "CREATE"<br />

oDoc1 = oDesk.LoadComponentFromUrl(sUrl_1, "MyName", 63, Noargs())<br />

Rem Usar el marco existente "MyName"<br />

oDoc2 = oDesk.LoadComponentFromUrl(sUrl_2, "MyName", 55, Noargs())<br />

Tip En 1.1 el marco implementa loadComponentFromURL por eso puede<br />

usar:<br />

oDoc = oDesk.LoadComponentFromUrl(sUrl_1, "_blank", 0, Noargs())<br />

oFrame = oDoc.CurrentController.Frame<br />

oDoc = oFrame.LoadComponentFromUrl(sUrl_2, "", 2, Noargs())<br />

Note the search flag arguments and the empty frame name argument.<br />

Advertencia En 1.1 solamente puede volver a usar un marco si conoce su nombre.<br />

Ejemplo:<br />

Sub insertDocumentAtCursor(sFileUrl As String, oText As Object, oDoc As Object)<br />

28


Dim oCur As Object<br />

Dim oProperties As Object<br />

oCur=oText.createTextCursorByRange(oDoc.getCurrentController().getViewCursor().getStart())<br />

oCur.insertDocumentFromURL(sFileURL,oProperties)<br />

End Sub<br />

Ejemplo:<br />

'------------- open_new --------------------<br />

'Dim NoArgs()<br />

'oDocNew=StarDesktop.loadComponentFromURL("private:factory/swriter","_blank",0,NoArgs())'<br />

------------- open_old_file ---------------<br />

'Dim NoArg()<br />

'oDocOldFile=StarDesktop.loadComponentFromURL(sUrl,"_blank",0,NoArg())<br />

4.8 Creando una tabla<br />

No tengo nada que hacer con estas <strong>macros</strong> de Kienlein??<br />

Sub InsertNextItem(what, oCursor, oTable)<br />

Dim oCelle As Object<br />

'name of the cell range that is selected by this cursor<br />

sName = oCursor.getRangeName()<br />

' The cell name will be something like D3<br />

oCelle = oTable.getCellByName(sName)<br />

oCelle.String = what<br />

oCursor.goRight(1,FALSE)<br />

End Sub<br />

Function CreateTable() As Object<br />

oDocument = StarDesktop.ActiveComponent<br />

oTextTable = oDocument.createInstance("com.sun.star.text.TextTable") CreateTable =<br />

oTextTable<br />

End Function<br />

29


4.9 Llamando un programa externo<br />

Este ejemplo de llamada de un programa externo y salvar la salida fue muy lento por el<br />

creador de la macro. Aun no lo he probado. El programa my_filter pone su salida en /<br />

tmp/output.txt. Pero el filtro es muy lento y debo esperar a que termine. Pero esta no es la mejor<br />

manera de hacerlo. Cómo puedo canalizar una cadena por medio de un programa externo?<br />

Algún ejemplo? ?? Pruebe esto!<br />

'******************************************************************<br />

'Author: Pavel Janík<br />

'email: Pavel@Janik.cz<br />

Sub CallExternalProgram ()<br />

Dim Document As Object<br />

Document = ThisComponent<br />

' Andrew says that this looks like an extra text<br />

<strong>para</strong> = Document.text.Text.getText()<br />

shell ("/home/pavel/my_filter", 2, "'" & <strong>para</strong>.getString() & "'", True) wait (9000)<br />

<strong>para</strong>.setString(ReturnContentsOfFile("/tmp/output.txt"))<br />

End Sub<br />

30


4.10 Leer y escribir en un archivo<br />

Este ejemplo lee un número desde un archivo de texto. Este valor es convertido en número e<br />

incrementado. El número es escrito de nuevo en el archivo como una cadena.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub Read_Write_Number_In_File<br />

DIM CountFileName As String, NumberString As String<br />

DIM LongNumber As Long, iNum As Integer<br />

Dim oDocument As Object<br />

CountFileName = "C:\Andy\My Documents\oo\NUMBER.TXT"<br />

NumberString = "00000000"<br />

LongNumber = 0<br />

'On Local Error Goto NoFile<br />

If FileExists(CountFileName) Then<br />

ON ERROR GOTO NoFile<br />

iNum = FreeFile<br />

OPEN CountFileName for input as #iNum<br />

LINE INPUT #iNum ,NumberString<br />

CLOSE #iNum<br />

MsgBox("Read " & NumberString, 64, "Read")<br />

NoFile:<br />

If Err 0 Then<br />

Msgbox("Can not read " & CountFileName, 64, "Error")<br />

NumberString = "00000001"<br />

End If<br />

On Local Error Goto 0<br />

Else<br />

Msgbox(CountFileName & " does NOT exists", 64, "Warning")<br />

NumberString = "00000001"<br />

End If<br />

ON ERROR GOTO BadNumber<br />

LongNumber = Int(NumberString)<br />

LongNumber = LongNumber + 1<br />

BadNumber:<br />

If Err 0 Then<br />

Msgbox(NumberString & " is not a number", 64, "Error")<br />

LongNumber = 1<br />

End If<br />

On Local Error Goto 0<br />

NumberString=Trim(Str(LongNumber))<br />

While LEN(NumberString) < 8<br />

NumberString="0"&NumberString<br />

Wend<br />

MsgBox("Number is (" & NumberString & ")", 64, "Information")<br />

iNum = FreeFile<br />

OPEN CountFileName for output as #iNum<br />

PRINT #iNum,NumberString<br />

31


CLOSE #iNum<br />

End Sub<br />

32


4.11 Creando un estilo de formato numérico<br />

Si desea un formato particular de número, entonces puede observar si existe y crearlo si no lo<br />

tiene. Para más información <strong>sobre</strong> fomatos validos, vea los contenidos de la ayuda en los<br />

tópicos “number formats; formats”. Estos pueden ser bastante complejos.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Function FindCreateNumberFormatStyle (_<br />

sFormat As String, Optional doc, Optional locale)<br />

Dim oDocument As Object<br />

Dim aLocale as new com.sun.star.lang.Locale<br />

Dim oFormats As Object<br />

oDocument = IIf(IsMissing(doc), ThisComponent, doc)<br />

oFormats = oDocument.getNumberFormats()<br />

'If you choose to query on types, you need to use the type<br />

'com.sun.star.util.NumberFormat.DATE<br />

'I could set the locale from values stored at<br />

'http://www.ics.uci.edu/pub/ietf/http/related/iso639.txt<br />

'http://www.chemie.fu-berlin.de/diverse/doc/ISO_3166.html<br />

'I use a NULL locale and let it use what ever it likes.<br />

'First, see if the number format exists<br />

If ( Not IsMissing(locale)) Then<br />

aLocale = locale<br />

End If<br />

formatNum = oFormats.queryKey (sFormat, aLocale, TRUE)<br />

MsgBox "Current Format number is" & formatNum<br />

'If the number format does not exist then add it<br />

If (formatNum = -1) Then<br />

formatNum = oFormats.addNew(sFormat, aLocale)<br />

If (formatNum = -1) Then formatNum = 0<br />

MsgBox "new Format number is " & formatNum<br />

End If<br />

FindCreateNumberFormatStyle = formatNum<br />

End Function<br />

33


4.12 Retorna una matriz Fibonnaci<br />

Esta función retorna una matriz con números Fibonnaci.<br />

'******************************************************************<br />

' http://disemia.com/software/openoffice/macro_arrays.html<br />

' Return the sequence of fibonnaci numbers<br />

' assume that count >=2 is to make this code simpler<br />

Function Fibonnaci( Count As Integer )<br />

Dim result( 1 to Count, 1 ) As Double<br />

result( 1, 1 ) = 0<br />

result( 2, 1 ) = 1<br />

For i = 3 to Count<br />

result( i, 1 ) = result( i - 2, 1 ) + result( i - 1, 1 )<br />

Next i<br />

Fibonnaci = result()<br />

End Function<br />

4.13 Insertar texto en un marcador<br />

oDoc.getBookmarks().getByName("").getAnchor.setString(<br />

"What you want to insert")<br />

4.14 Campos de usuario<br />

?? No he hecho nada con esto!<br />

Encontré datos de usuario en el documento -- de estos puede obtener algo como esto:<br />

oDoc = ThisComponent<br />

oInfo = oDoc.Document.Info<br />

oVal = oData.ElementNames<br />

iCount = oInfo.GetUserFieldCount()<br />

For iCount = 0 to oInfo.GetUserFieldCount() - 1<br />

sKey = oInfo.GetUserFieldName(iCount)<br />

sVal = oInfo.GetUserFieldValue(iCount)<br />

msgbox "Name: " & sKey & ", Value: " & sVal<br />

Next iCount<br />

La respuesta fue:<br />

> Conoce alguno como (si es posible) incrementar el número de campos de usuario a más de<br />

4?<br />

AFAIK no. Qué encontraste <strong>sobre</strong> campos de usuario de documento de información. AFAIK<br />

Ellos son fijados.<br />

> Y si esto no es posible – Creo que encontré un segundo juego de campos de usuario,<br />

> pero no estoy seguro exactamente si están en el objeto Odoc.<br />

Puede obtenerlos con el getTextFields() y getTextFieldMasters()<br />

34


DocInfo = ThisComponent.DocumentInfo<br />

nCount = DocInfo.getUserFieldCount()<br />

for i=0 to nCount-1<br />

DocInfo.setUserFieldName(i,name)<br />

DocInfo.setUserFieldValue(index,value)<br />

next i<br />

donde [name], [value] son cadenas que usted elije.<br />

También puede usar getUserFieldName(index) o getUserFieldValue(index) <strong>para</strong> leer estos<br />

campos.<br />

35


5 Macros de Calc<br />

5.1 Es este un libro de cálculo?<br />

Un libro de cálculo está compuesto de un conjunto de hojas. Antes de poder usar los métodos<br />

específicos del libro de cálculo, debe tener un documento libro de cálculo. Puede verificar<br />

esto de la siguiente manera:<br />

Function IsSpreadhsheetDoc(oDoc) As Boolean<br />

On Local Error GoTo NODOCUMENTTYPE<br />

IsSpreadhsheetDoc =oDoc.SupportsService(_<br />

"com.sun.star.sheet.SpreadsheetDocument")<br />

NODOCUMENTTYPE:<br />

If Err 0 Then<br />

IsSpreadhseetDoc = False<br />

Resume GOON<br />

GOON:<br />

End If<br />

End Function<br />

5.2 Imprimiendo el valor de una Celda, Cadena o Fórmula.<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub ExampleGetValue<br />

Dim oDocument As Object, oSheet As Object, oCell As Object<br />

oDocument=ThisComponent<br />

oSheet=oDocument.Sheets.getByName("Sheet1")<br />

oCell=oSheet.getCellByposition(0,0) 'A1<br />

print oCell.getValue<br />

'print oCell.getString<br />

'print oCell.getFormula<br />

End sub<br />

5.3 Estableciendo el valor de una Celda, Formato, Cadena o<br />

Fórmula.<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub ExampleSetValue<br />

Dim oDocument As Object, oSheet As Object, oCell As Object<br />

oDocument=ThisComponent<br />

oSheet=oDocument.Sheets.getByName("Sheet1")<br />

oCell=oSheet.getCellByPosition(0,0) 'A1<br />

oCell.setValue(23658)<br />

'oCell..NumberFormat=2 '23658.00<br />

'oCell.SetString("oops")<br />

'oCell.setFormula("=FUNCTION()")<br />

'oCell.IsCellBackgroundTransparent = TRUE<br />

'oCell.CellBackColor = RGB(255,141,56)<br />

37


End Sub<br />

5.4 Limpiar una celda<br />

Una lista de cosas que pueden ser limpiadas se encuentra en<br />

http://api.openoffice.org/5.2/reference/com/sun/star/sheet/CellFlags.html<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub ClearDefinedRange<br />

Dim oDocument As Object, oSheet As Object, oSheets As Object<br />

Dim oCellRange As Object<br />

Dim nSheets As Long<br />

oDocument = ThisComponent<br />

oSheets = oDocument.Sheets<br />

nSheets = oDocument.Sheets.Count<br />

oSheet = oSheets.getByIndex(2) Rem the range is from 0 to n-1<br />

oCellRange = oSheet.getCellRangeByName("range_you_set")<br />

oCellRange.clearContents(_<br />

com.sun.star.sheet.CellFlags.VALUE | _<br />

com.sun.star.sheet.CellFlags.DATETIME | _<br />

com.sun.star.sheet.CellFlags.STRING | _<br />

com.sun.star.sheet.CellFlags.ANNOTATION | _<br />

com.sun.star.sheet.CellFlags.FORMULA | _<br />

com.sun.star.sheet.CellFlags.HARDATTR | _<br />

com.sun.star.sheet.CellFlags.STYLES | _<br />

com.sun.star.sheet.CellFlags.OBJECTS | _<br />

com.sun.star.sheet.CellFlags.EDITATTR)<br />

End Sub<br />

5.5 Texto seleccionado, Qué es?<br />

Un texto seleccionado en una hoja de cálculo puede ser diferentes cosas; algunas las entiendo y<br />

otras no.<br />

1. Una celda seleccionada. Haga click en una celda y luego presione mayúsculas y haga click de<br />

nuevo.<br />

2. Texto parcialmente seleccionado en una celda. Haga doble click en una celda y selecciona una<br />

parte del texto.<br />

3. Nada seleccionado. Un click sencillo o tabulador entre celdas.<br />

4. Múltiples celdas seleccionadas. Click sencillo y arrastre el cursor.<br />

5. Selecciones múltiples no continuas. Seleccione algunas celdas. Presione la tecla control y<br />

seleccione otras.<br />

No sé como distinguir los primeros tres casos. Si me puedo imaginar cómo extraer el texto<br />

seleccionado del caso 2, entonces resolveré el problema.<br />

Function CalcIsAnythingSelected(oDoc As Object) As Boolean<br />

Dim oSelections As Object, oSel As Object, oText As Object, oCursor As Object<br />

IsAnythingSelected = False<br />

If IsNull(oDoc) Then Exit Function<br />

' The current selection in the current controller.<br />

38


'If there is no current controller, it returns NULL.<br />

oSelections = oDoc.getCurrentSelection()<br />

If IsNull(oSelections) Then Exit Function<br />

If oSelections.supportsService("com.sun.star.sheet.SheetCell") Then<br />

Print "One Cell selected = " & oSelections.getImplementationName()<br />

MsgBox "getString() = " & oSelections.getString()<br />

ElseIf oSelections.supportsService("com.sun.star.sheet.SheetCellRange") Then<br />

Print "One Cell Range selected = " & oSelections.getImplementationName()<br />

ElseIf oSelections.supportsService("com.sun.star.sheet.SheetCellRanges") Then<br />

Print "Multiple Cell Ranges selected = " & oSelections.getImplementationName()<br />

Print "Count = " & oSelections.getCount()<br />

Else<br />

Print "Somethine else selected = " & oSelections.getImplementationName()<br />

End If<br />

End Function<br />

39


5.6 Dirección imprimible de una Celda.<br />

'Given a cell, extract the normal looking address of a cell<br />

'First, the name of the containing sheet is extracted.<br />

'Second, the column number is obtained and turned into a letter<br />

'Lastly, the row is obtained. Rows start at 0 but are displayed as 1<br />

Function PrintableAddressOfCell(the_cell As Object) As String<br />

PrintableAddressOfCell = "Unknown"<br />

If Not IsNull(the_cell) Then<br />

PrintableAddressOfCell = the_cell.getSpreadSheet().getName + ":" + _<br />

ColumnNumberToString(the_cell.CellAddress.Column) + (the_cell.CellAddress.Row+1)<br />

End If<br />

End Function<br />

' Columns are numbered starting at 0 where 0 corresponds to A<br />

' They run as A-Z,AA-AZ,BA-BZ,...,IV<br />

' This is esentially a question of how do you convert a Base 10 number to<br />

' a base 26 number.<br />

' Note that the_column is passed by value!<br />

Function ColumnNumberToString(ByVal the_column As Long) As String<br />

Dim s$<br />

'Save this so I do NOT modify the <strong>para</strong>meter.<br />

'This was an icky bug that took me a while to find<br />

Do<br />

s$ = Chr(65 + the_column MOD 26) + s$<br />

the_column = the_column / 26<br />

Loop Until the_column = 0<br />

ColumnNumberToString = s$<br />

End Function<br />

40


5.7 Insertar fechas formateadas en una Celda<br />

Inserte la fecha en la celda actual. Da un mensaje de error si el documento actual no es una<br />

hoja de cálculo. El código provee la manera de formatear la fecha con el estilo que elija. Lolo<br />

necesita pero quitele el comentario.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'uses: FindCreateNumberFormatStyle<br />

Sub InsertDateIntoCell<br />

Dim oDesktop As Object, oController As Object, oSelection As Object<br />

Dim doc As Object<br />

oDesktop = createUnoService("com.sun.star.frame.Desktop")<br />

oController = oDesktop.CurrentFrame.Controller<br />

doc = oController.Model<br />

If doc.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Then<br />

oSelection = oController.Selection<br />

' set the date value<br />

oFunction = CreateUnoService("com.sun.star.sheet.FunctionAccess")<br />

oFunction.NullDate = doc.NullDate<br />

Dim aEmpty()<br />

oSelection.Value = oFunction.callFunction("NOW", aEmpty())<br />

' Set the date number format to default<br />

oFormats = doc.NumberFormats<br />

dim aLocale as new com.sun.star.lang.Locale<br />

oSelection.NumberFormat = oFormats.getStandardFormat(_<br />

com.sun.star.util.NumberFormat.DATETIME, aLocale)<br />

' Set the format to something completely different<br />

'oSelection.NumberFormat = FindCreateNumberFormatStyle(_<br />

' "YYYYMMDD.hhmmss", doc) Else<br />

MsgBox "This macro must be run in a spreadsheet document"<br />

End If<br />

End Sub<br />

5.8 Desplegar un rango seleccionado en un cuadro de diálogo<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

'This macro will take the current selection and print a message<br />

'box indicating the selected range and the number of selected<br />

'cells<br />

Sub SelectedCells<br />

oSelect=ThisComponent.CurrentSelection.getRangeAddress<br />

41


oSelectColumn=ThisComponent.CurrentSelection.Columns<br />

oSelectRow=ThisComponent.CurrentSelection.Rows<br />

CountColumn=oSelectColumn.getCount<br />

CountRow=oSelectRow.getCount<br />

oSelectSC=oSelectColumn.getByIndex(0).getName<br />

oSelectEC=oSelectColumn.getByIndex(CountColumn-1).getName<br />

oSelectSR=oSelect.StartRow+1<br />

oSelectER=oSelect.EndRow+1<br />

NoCell=(CountColumn*CountRow)<br />

If CountColumn=1 AND CountRow=1 Then<br />

MsgBox("Cell " + oSelectSC + oSelectSR + chr(13) + "Cell No = " + NoCell,,<br />

"SelectedCells")<br />

Else<br />

MsgBox("Range(" + oSelectSC + oSelectSR + ":" + oSelectEC + oSelectER + ")" + chr(13) +<br />

"Cell No = " + NoCell,, "SelectedCells")<br />

End If<br />

End Sub<br />

5.9 Rellenar un rango seleccionado con texto<br />

Esta simple macro cambia a través del texto seleccionado poniéndo el texto en “OOPS”.<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub FillCells<br />

oSelect=ThisComponent.CurrentSelection<br />

oColumn=oselect.Columns<br />

oRow=oSelect.Rows<br />

For nc= 0 To oColumn.getCount-1<br />

For nr = 0 To oRow.getCount-1<br />

oCell=oselect.getCellByPosition (nc,nr).setString ("OOOPS")<br />

Next nr<br />

Next nc<br />

End Sub<br />

42


5.10 Algunos estados del texto seleccionado<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

'Esta macro toma la selección actual e imprime un mensaje<br />

'indicando el rango seleccionado y el número de celdas<br />

'seleccionadas<br />

Sub Analize<br />

sSum="=SUM("+GetAddress+")"<br />

sAverage="=AVERAGE("+GetAddress+")"<br />

sMin="=MIN("+GetAddress+")"<br />

sMax="=MAX("+GetAddress+")"<br />

CellPos(7,6).setString(GetAddress)<br />

CellPos(7,8).setFormula(sSum)<br />

CellPos(7,8).NumberFormat=2<br />

CellPos(7,10).setFormula(sAverage)<br />

CellPos(7,10).NumberFormat=2<br />

CellPos(7,12).setFormula(sMin)<br />

CellPos(7,12).NumberFormat=2<br />

CellPos(7,14).setFormula(sMax)<br />

CellPos(7,14).NumberFormat=2<br />

End sub<br />

Function GetAddress 'selected cell(s)<br />

oSelect=ThisComponent.CurrentSelection.getRangeAddress<br />

oSelectColumn=ThisComponent.CurrentSelection.Columns<br />

oSelectRow=ThisComponent.CurrentSelection.Rows<br />

CountColumn=oSelectColumn.getCount<br />

CountRow=oSelectRow.getCount<br />

oSelectSC=oSelectColumn.getByIndex(0).getName<br />

oSelectEC=oSelectColumn.getByIndex(CountColumn-1).getName<br />

oSelectSR=oSelect.StartRow+1<br />

oSelectER=oSelect.EndRow+1<br />

NoCell=(CountColumn*CountRow)<br />

If CountColumn=1 AND CountRow=1 then<br />

GetAddress=oSelectSC+oSelectSR<br />

Else<br />

GetAddress=oSelectSC+oSelectSR+":"+oSelectEC+oSelectER<br />

End If<br />

End Function<br />

Function CellPos(lColumn As Long,lRow As Long)<br />

CellPos= ActiveSheet.getCellByPosition (lColumn,lRow)<br />

End Function<br />

Function ActiveSheet<br />

ActiveSheet=StarDesktop.CurrentComponent.CurrentController.ActiveSheet<br />

End Function<br />

Sub DeleteDbRange(sRangeName As String)<br />

43


oRange=ThisComponent.DatabaseRanges<br />

oRange.removeByName (sRangeName)<br />

End Sub<br />

5.11 Cambiar el rango seleccionado a un rango de Base de Datos<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub DefineDbRange(sRangeName As String) 'selected range<br />

On Error GoTo DUPLICATENAME<br />

oSelect=ThisComponent.CurrentSelection.RangeAddress<br />

oRange=ThisComponent.DatabaseRanges.addNewByName (sRangeName,oSelect )<br />

DUPLICATENAME:<br />

If Err 0 Then<br />

MsgBox("Duplicate name",,"INFORMATION")<br />

End If<br />

End Sub<br />

5.12 Borrar un rango de Base de Datos<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub DeleteDbRange(sRangeName As String)<br />

oRange=ThisComponent.DatabaseRanges<br />

oRange.removeByName (sRangeName)<br />

End Sub<br />

5.13 Rango bordes de línea<br />

?? Está modificando la estructura temporal aqui. Use algo como esto.<br />

'******************************************************************<br />

'Author: Niklas Nebel<br />

'email: niklas.nebel@sun.com<br />

' setting_borders_in_calc<br />

oRange = ThisComponent.Sheets(0).getCellRangeByPosition(0,1,0,63)<br />

aBorder = oRange.TableBorder<br />

aBorder.BottomLine = lHor<br />

oRange.TableBorder = aBorder<br />

He goes on to say that the following will not work because it modifies a temporary struct.<br />

lHor.Color = 0: lHor.InnerLineWidth = 0: lHor.OuterLineWidth = 150:<br />

dim lHor as New com.sun.star.table.BorderLinelHor.LineDistance = 0<br />

ThisComponent.Sheets(0).getCellRangeByPosition(0,1,0,63).TableBorder.BottomLine = lHor<br />

44


5.14 Ordenar un rango<br />

'******************************************************************<br />

'Author: Sasa Kelecevic<br />

'email: scat@teol.net<br />

Sub SortRange<br />

Dim oSheetDSC,oDSCRange As Object<br />

Dim aSortFields(0) as new com.sun.star.util.SortField<br />

Dim aSortDesc(0) as new com.sun.star.beans.PropertyValue<br />

'set your sheet name<br />

oSheetDSC = ThisComponent.Sheets.getByName("Sheet1")<br />

'set your range address<br />

oDSCRange = oSheetDSC.getCellRangeByName("A1:L16")<br />

ThisComponent.getCurrentController.select(oDSCRange)<br />

aSortFields(0).Field = 0<br />

aSortFields(0).SortAscending = FALSE<br />

aSortDesc(0).Name = "SortFields"<br />

aSortDesc(0).Value = aSortFields()<br />

oDSCRange.Sort(aSortDesc())<br />

End sub<br />

45


5.15 Imprimir todos los datos en una columna<br />

Mientras cambiaba la celda y los valores a imprimir, quería imprimir información <strong>sobre</strong> las<br />

celdas. He aqui cómo lo hice.<br />

Sub PrintDataInColumn (a_column As Integer)<br />

Dim oCells As Object, aCell As Object, oDocument As Object<br />

Dim oColumn As Object, oRanges As Object<br />

oDocument = ThisComponent<br />

oColumn = oDocument.Sheets(0).Columns(a_column)<br />

Print "Using column " + oColumn.getName<br />

oRanges = oDocument.createInstance("com.sun.star.sheet.SheetCellRanges")<br />

oRanges.insertByName("", oColumn)<br />

oCells = oRanges.Cells.createEnumeration<br />

If Not oCells.hasMoreElements Then Print "Sorry, no text to display"<br />

While oCells.hasMoreElements<br />

aCell = oCells.nextElement<br />

'This next Function is defined elsewhere in this document!<br />

MsgBox PrintableAddressOfCell(aCell) + " = " + aCell.String<br />

Wend<br />

End Sub<br />

5.16 Usando métodos de bordes (agrupamiento)<br />

Ryan Nelson [ryan@aurelius-mfg.com] me dijo <strong>sobre</strong> la capacidad de bordes y luego me<br />

contó cómo hacer esta macro. Hay dos cosas que debe tener en mente. La primera es que es<br />

la hoja que agrega y remueve el arupamiento, y la segunda es que los parámetros deben ser<br />

los correctos.<br />

http://api.openoffice.org/common/ref/com/sun/star/sheet/XSheetOutline.html<br />

http://api.openoffice.org/common/ref/com/sun/star/table/TableOrientation.html<br />

Option Explicit<br />

Sub CalcGroupingExample<br />

Dim oDoc As Object, oRange As Object, oSheet As Object<br />

oDoc = ThisComponent<br />

If Not oDoc.SupportsService("com.sun.star.sheet.SpreadsheetDocument") Then<br />

MsgBox "This macro must be run from a spreadsheet document", 64, "Error"<br />

End If<br />

oSheet=oDoc.Sheets.getByName("Sheet1")<br />

' Parms are (left, top, right, bottom)<br />

oRange = oSheet.getCellRangeByPosition(2,1,3,2)<br />

'Could also use COLUMNS<br />

oSheet.group(oRange.getRangeAddress(), com.sun.star.table.TableOrientation.ROWS)<br />

Print "I just grouped the range"<br />

oSheet.unGroup(oRange.getRangeAddress(), com.sun.star.table.TableOrientation.ROWS)<br />

Print "I just ungrouped the range"<br />

End Sub<br />

46


5.17 Protegiendo sus datos<br />

Es fácil proteger sus hojas de cálculo, solamente tiene que llamar su hoja y protegerla. Mi<br />

experimento indica que sin embargo no genera un error cuando elige proteger un documento<br />

entero, pero no protegerá el documento entero.<br />

Sub ProtectSpreadsheet<br />

dim oDoc As Object, oSheet As Object<br />

oDoc = ThisComponent<br />

oSheet=oDoc.Sheets.getByName("Sheet1")<br />

oSheet.protect("password")<br />

Print "Protect value = " & oSheet.isProtected()<br />

oSheet.unprotect("password")<br />

Print "Protect value = " & oSheet.isProtected()<br />

End Sub<br />

47


6 Macros de Write<br />

6.1 Texto seleccionado, qué es?<br />

Texto seleccionado es esencialmente un rango de texto, nada más. Después de que la<br />

selección es obtenida. Es posible obtener el texto [getString()] y cambiar el texto [setString<br />

()]. Mientras las cadenas están limitadas a 64K de tamaño, las selecciones no. Hay algunas<br />

instancias, sin embargo, con los resultados de los métodos getString() y setString() que no<br />

entiendo. Sin embargo, es probablemente mejor usar un cursor <strong>para</strong> cambiar el texto<br />

seleccionado y después usar los métodos insertString() y insertControlCharacter() del objeto<br />

de texto. La documentación específicamente indica que los siguientes caracteres “blancos”<br />

son soportados por el método insertString(): blank, tab, cr (que inserta un cambio de parráfo),<br />

y lf (que inserta una nueva línea).<br />

El texto puede ser manualmente seleccionado mientras el cursor esta a la derecha o a la<br />

izquierda de la selección. Una selección tiene un punto de inicio y punto final y no se puede<br />

saber cual esta a la izquierda y cual está a la derecha del texto seleccionado. Un método<br />

mostrado abajo corrige este problema.<br />

Ver también:<br />

http://api.openoffice.org/common/ref/com/sun/star/text/TextRange.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XTextRange.html<br />

6.2 Cursores de texto, qué son?<br />

Un cursor de texto es un rango de texto que puede ser movido dentro de un objeto de texto.<br />

Los movimientos standars incluyen goLeft, goRight, goUp, y goDown. El primer <strong>para</strong>metro<br />

es un entero indicando cuántos caracteres o lineas se moverán. El segundo parámetro es un<br />

valor boleano <strong>para</strong> indicar si el texto seleccionado se puede expandir (true) o no. El valor de<br />

True (verdadero) es retornado mientras ocurre el movimiento. Si un cursor ha seleccionado<br />

texto por el movimiento izquierdo y desea moverlo a la derecha, probablemente quiera usar<br />

oCursor.goRight(0, False) <strong>para</strong> indicar al cursor que empiece a moverse a la derecha y no<br />

seleccione texto. Esto dejará el texto sin seleccionarse.<br />

Un cursor de texto tiene un inicio y un final. Si la posición inicial es la misma que la posición<br />

final entonces no hay texto seleccionado y la propiedad IsCollapsed será verdadera.<br />

Un cursor de texto implementa interfaces que permite movimientos y reconocimiento de<br />

posiciones específicas a palabras, oraciones, y párafos. Esto puede ahorrar bastante tiempo.<br />

Advertencia Cursor.gotoStart() y Cursor.gotoEnd() va al inicio o al final del<br />

documento aun si el cursor está creado <strong>sobre</strong> un rango.<br />

Ver también:<br />

http://api.openoffice.org/common/ref/com/sun/star/view/XViewCursor.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/TextCursor.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XWordCursor.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XSentenceCursor.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XParagraphCursor.html<br />

49


http://api.openoffice.org/common/ref/com/sun/star/text/TextRange.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XTextRange.html<br />

6.3 Andrew's Selected Text Framework<br />

Muchos problemas al usar texto seleccionado se ven en un nivel abstracto.<br />

If nothing is selected then<br />

do work on entire document<br />

else<br />

for each selected area<br />

do work on selected area<br />

The difficult part that will change each time is writing a worker macro that will iterate over a<br />

selection or between two cursors.<br />

6.3.1 Hay texto seleccionado?<br />

Los estados del documentación son si no hay controlador actual, entonces<br />

getCurrentSelection() regresará un valor nulo que cuando hay selecciones. Tengo un<br />

conocimiento limitado de esto pero trataré de explicarlo y verificarlo.<br />

Si la selección es cero, nada está seleccionado. Nunca he vista un conteo de selección de<br />

cero, pero chequeelo de cualquier manera. Si no hay texto seleccionado, Tengo una selección<br />

de tamaño cero. He visto ejemplos donde la selección es cero y se determina de la siguiente<br />

manera:<br />

If Len(oSel.getString()) = 0 Then nothing is selected<br />

El problema con esto es que es posible que el texto seleccionado pueda contener más de 64K<br />

en caracteres y una cadena no puede contener más de 64 caracteres. Yo considero que esto no<br />

es seguro. La mejor solución es crear un cursor de texto del rango seleccionado y luego<br />

chequearlo <strong>para</strong> ver si las posiciones de inicio y final son iguales.<br />

oCursor = oDoc.Text.CreateTextCursorByRange(oSel)<br />

If oCursor.IsCollapsed() Then nothing is selected<br />

Aqui hay una función que hará la verificación completa:<br />

Function IsAnythingSelected(oDoc As Object) As Boolean<br />

Dim oSelections As Object, oSel As Object, oText As Object, oCursor As Object<br />

IsAnythingSelected = False<br />

If IsNull(oDoc) Then Exit Function<br />

' The current selection in the current controller.<br />

'If there is no current controller, it returns NULL.<br />

oSelections = oDoc.getCurrentSelection()<br />

If IsNull(oSelections) Then Exit Function<br />

If oSelections.getCount() = 0 Then Exit Function<br />

If oSelections.getCount() > 1 Then<br />

IsAnythingSelected = True<br />

Else<br />

oSel = oSelections.getByIndex(0)<br />

oCursor = oDoc.Text.CreateTextCursorByRange(oSel)<br />

If Not oCursor.IsCollapsed() Then IsAnythingSelected = True<br />

50


End If<br />

End Function<br />

6.3.2 Cómo obtener una selección<br />

Obtener una selección es complicado porque es posible que tenga multiples selecciones no<br />

contiguas o adyacentes. Algunas selecciones son vacías y algunas no. El código está escrito<br />

<strong>para</strong> manejar todos estos casos. El siguiente ejemplo cambia dentro de todas las secciones<br />

seleccionadas y las imprime.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub MultipleTextSelectionExample<br />

Dim oSelections As Object, oSel As Object, oText As Object<br />

Dim lSelCount As Long, lWhichSelection As Long<br />

' The current selection in the current controller.<br />

'If there is no current controller, it returns NULL.<br />

oSelections = ThisComponent.getCurrentSelection()<br />

If Not IsNull(oSelections) Then<br />

oText = ThisComponent.Text<br />

lSelCount = oSelections.getCount()<br />

For lWhichSelection = 0 To lSelCount - 1<br />

oSel = oSelections.getByIndex(lWhichSelection)<br />

MsgBox oSel.getString()<br />

Next<br />

End If<br />

End Sub<br />

See Also:<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XTextRange.html<br />

6.3.3 Selected Text, Which End Is Which<br />

Selecciones son esencialmente rangos de texto con un inicio y un final. Como las selecciones<br />

tienen ambas un inicio y un final, que lado de la selección es cuál se determina por el método<br />

de selección. El objeto de texto provee métodos <strong>para</strong> com<strong>para</strong>r las posiciones de inicio y<br />

final de los rangos de texto. El método “short compareRegionStarts (XTextRange R1,<br />

XTextRange R2)” regresar 1 si R1 inicia antes de R2 , 0 si R1 inicia en la misma posición<br />

que R2 y -1 si R1 inicia después de R2. El método “short compareRegionEnds (XTextRange<br />

R1, XTextRange R2)” retorna 1, si R1 finaliza antes de R2 , 0, si R1 finaliza en la misma<br />

posición que R2 y -1, si R1 finaliza detrás de R2. Yo uso los siguientes dos métodos <strong>para</strong><br />

encontrar la posición más a la izquierda o más a la derecha del cursor del texto seleccionado.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'oSelection is a text selection or cursor range<br />

51


'oText is the text object<br />

Function GetLeftMostCursor(oSel As Object, oText As Object) As Object<br />

Dim oRange As Object, oCursor As Object<br />

If oText.compareRegionStarts(oSel.getEnd(), oSel) >= 0 Then<br />

oRange = oSel.getEnd()<br />

Else<br />

oRange = oSel.getStart()<br />

End If<br />

oCursor = oText.CreateTextCursorByRange(oRange)<br />

oCursor.goRight(0, False)<br />

GetLeftMostCursor = oCursor<br />

End Function<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'oSelection is a text selection or cursor range<br />

'oText is the text object<br />

Function GetRightMostCursor(oSel As Object, oText As Object) As Object<br />

Dim oRange As Object, oCursor As Object<br />

If oText.compareRegionStarts(oSel.getEnd(), oSel) >= 0 Then<br />

oRange = oSel.getStart()<br />

Else<br />

oRange = oSel.getEnd()<br />

End If<br />

oCursor = oText.CreateTextCursorByRange(oRange)<br />

oCursor.goLeft(0, False)<br />

GetRightMostCursor = oCursor<br />

End Function<br />

See Also:<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XTextCursor.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XSimpleText.html<br />

http://api.openoffice.org/common/ref/com/sun/star/text/XTextRangeCompare.html<br />

6.3.4 Sistema Macro de texto seleccionado<br />

Me tomó mucho tiempo entender como interactuar <strong>sobre</strong> el texto seleccionado usando los<br />

cursores, por eso tuve que escribir muchas <strong>macros</strong> que hacen cosas que considero<br />

equivocadas. Ahora uso sistemas de alto nivel <strong>para</strong> hacerlas. La idea es que si no hay texto<br />

seleccionado, entonces pregunta a la macro si se debe ejecutar contra todo el documento. Si<br />

la pregunta es si, entonces el cursor es creado al inicio y al final del documento, y luego la<br />

macro es ejecutada. Si hay texto seleccionado, entonces cada selección es traida, un cursor es<br />

obtenido al inicio y final de la selección, y la macro es ejecutada <strong>para</strong> cada una de estas<br />

selecciones.<br />

52


El sistema rechazado<br />

Ultimamente rechacé el siguiente sistema porque es muy largo y dificil de manejar y repetir<br />

cada vez que deseo interactuar contra el texto. Sin embargo es aceptable. Puede ser que<br />

prefiera este sistema y escoja usarlo.<br />

Sub IterateOverSelectedTextFramework<br />

Dim oSelections As Object, oSel As Object, oText As Object<br />

Dim lSelCount As Long, lWhichSelection As Long<br />

Dim oLCursor As Object, oRCursor As Object<br />

oText = ThisComponent.Text<br />

If Not IsAnythingSelected(ThisComponent) Then<br />

Dim i%<br />

i% = MsgBox("No text selected!" + Chr(13) + _<br />

"Call worker for the ENTIRE document?", _<br />

1 OR 32 OR 256, "Warning")<br />

If i% 1 Then Exit Sub<br />

oLCursor = oText.createTextCursor()<br />

oLCursor.gotoStart(False)<br />

oRCursor = oText.createTextCursor()<br />

oRCursor.gotoEnd(False)<br />

CallYourWorkerMacroHere(oLCursor, oRCursor, oText)<br />

Else<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

For lWhichSelection = 0 To lSelCount - 1<br />

oSel = oSelections.getByIndex(lWhichSelection)<br />

'If I want to know if NO text is selected, I could<br />

'do the following:<br />

'oLCursor = oText.CreateTextCursorByRange(oSel)<br />

'If oLCursor.isCollapsed() Then ...<br />

oLCursor = GetLeftMostCursor(oSel, oText)<br />

oRCursor = GetRightMostCursor(oSel, oText)<br />

CallYourWorkerMacroHere(oLCursor, oRCursor, oText)<br />

Next<br />

End If<br />

End Sub<br />

El sistema aceptable<br />

Opté por crear el siguiente sistema. Devuelve un arreglo bidimensional de los cursores de<br />

inicio y final <strong>sobre</strong> las cuales interactuar. Esto permite usar un mínimo código base <strong>para</strong><br />

interactuar <strong>sobre</strong> el texto seleccionado o <strong>sobre</strong> el documento entero.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'sPrompt : how to ask if should iterate over the entire text<br />

'oCursors() : Has the return cursors<br />

'Returns true if should iterate and false if should not<br />

Function CreateSelectedTextIterator(oDoc As Object, sPrompt As String, oCursors()) As Boolean<br />

53


Dim oSelections As Object, oSel As Object, oText As Object<br />

Dim lSelCount As Long, lWhichSelection As Long<br />

Dim oLCursor As Object, oRCursor As Object<br />

CreateSelectedTextIterator = True<br />

oText = oDoc.Text<br />

If Not IsAnythingSelected(ThisComponent) Then<br />

Dim i%<br />

i% = MsgBox("No text selected!" + Chr(13) + sPrompt, _<br />

1 OR 32 OR 256, "Warning")<br />

If i% = 1 Then<br />

oLCursor = oText.createTextCursor()<br />

oLCursor.gotoStart(False)<br />

oRCursor = oText.createTextCursor()<br />

oRCursor.gotoEnd(False)<br />

oCursors = DimArray(0, 1)<br />

oCursors(0, 0) = oLCursor<br />

oCursors(0, 1) = oRCursor<br />

Else<br />

oCursors = DimArray()<br />

CreateSelectedTextIterator = False<br />

End If<br />

Else<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

oCursors = DimArray(lSelCount - 1, 1)<br />

For lWhichSelection = 0 To lSelCount - 1<br />

oSel = oSelections.getByIndex(lWhichSelection)<br />

'If I want to know if NO text is selected, I could<br />

'do the following:<br />

'oLCursor = oText.CreateTextCursorByRange(oSel)<br />

'If oLCursor.isCollapsed() Then ...<br />

oLCursor = GetLeftMostCursor(oSel, oText)<br />

oRCursor = GetRightMostCursor(oSel, oText)<br />

oCursors(lWhichSelection, 0) = oLCursor<br />

oCursors(lWhichSelection, 1) = oRCursor<br />

Next<br />

End If<br />

End Function<br />

El trabajo principal<br />

Este es un ejemplo que llama a la rutina del trabajo principal.<br />

Sub PrintExample<br />

Dim oCursors(), i%<br />

If Not CreateSelectedTextIterator(ThisComponent, _<br />

"Print characters for the entire document?", oCursors()) Then Exit Sub<br />

For i% = LBOUND(oCursors()) To UBOUND(oCursors())<br />

PrintEachCharacterWorker(oCursors(i%, 0), oCursors(i%, 1), ThisComponent.Text)<br />

Next i%<br />

End Sub<br />

54


6.3.5 Desplegando caracteres, un ejemplo simple.<br />

Este simple ejemplo puede ser usado con el sistema anterior.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub PrintEachCharacterWorker(oLCursor As Object, oRCursor As Object, oText As Object)<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor) = 0<br />

Print "Character = '" & oLCursor.getString() & "'"<br />

Rem This will cause the currently selected text to become<br />

Rem no longer selected<br />

oLCursor.goRight(0, False)<br />

Loop<br />

End Sub<br />

6.3.6 Remover espacios y líneas vacíos, un gran ejemplo.<br />

Este grupo de <strong>macros</strong> remueve todos los espacios en blanco con un espacio sencillo. Es fácil<br />

de modificar <strong>para</strong> borrar diferentes tipos de espacios en blanco. Los diferentes tipos de<br />

espacios en blanco están ordenados por importancia de manera que puede tener un espacio<br />

regular seguido de un párrafo nuevo, el nuevo párrafo se mantiene y el espacio es removido.<br />

Esto causará que los espacios iniciales y finales de las líneas son removidos.<br />

Qué es un espacio en blanco?<br />

Para resolver este problema, mi primera tarea es determinar cuales caracteres son espacios en<br />

blanco. Puede trivialmente cambiar la definición de espacio en blanco <strong>para</strong> ignorar ciertos<br />

caracteres.<br />

'Usually, this is done with an array lookup which would probably be<br />

'faster, but I do not know how to use static initializers in basic.<br />

Function IsWhiteSpace(iChar As Integer) As Boolean<br />

Select Case iChar<br />

Case 9, 10, 13, 32, 160<br />

IsWhiteSpace = True<br />

Case Else<br />

IsWhiteSpace = False<br />

End Select<br />

End Function<br />

Rangos de caracteres <strong>para</strong> borrar<br />

Luego, necesito definir que remover y que debo dejar. Opté por hacer esto con la siguiente<br />

rutina.<br />

'-1 means delete the previous character<br />

' 0 means ignore this character<br />

55


' 1 means delete this character<br />

' Rank from highest to lowest is: 0, 13, 10, 9, 160, 32<br />

Function RankChar(iPrevChar, iCurChar) As Integer<br />

If Not IsWhiteSpace(iCurChar) Then 'The current char is not white space, ignore it<br />

RankChar = 0<br />

ElseIf iPrevChar = 0 Then 'Start of a line and current char is white space<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf Not IsWhiteSpace(iPrevChar) Then 'Current char is white space but previous is not<br />

RankChar = 0 ' so ignore the current charcter.<br />

ElseIf iPrevChar = 13 Then 'Previous char is highest ranked white space<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf iCurChar = 13 Then 'Current character is highest ranked white space<br />

RankChar = -1 ' so delete the previous character.<br />

ElseIf iPrevChar = 10 Then 'No new Pars so see if the previous char is new line<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf iCurChar = 10 Then 'No new Pars so see if the current char is new line<br />

RankChar = -1 ' so delete the previous character.<br />

ElseIf iPrevChar = 9 Then 'No new Lines so see if the previous char is tab<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf iCurChar = 9 Then 'No new Lines so see if the current char is a tab<br />

RankChar = -1 ' so delete the previous character.<br />

ElseIf iPrevChar = 160 Then 'No Tabs so check previous char for a hard<br />

space<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf iCurChar = 160 Then 'No Tabs so check current char for a hard space<br />

RankChar = -1 ' so delete the previous character.<br />

ElseIf iPrevChar = 32 Then 'No hard spaces so check previous for a space<br />

RankChar = 1 ' so delete the current character.<br />

ElseIf iCurChar = 32 Then 'No hard spaces so check current for a space<br />

RankChar = -1 ' so delete the previous character.<br />

Else 'Should probably not get here<br />

RankChar = 0 ' so simply ignore it!<br />

End If<br />

End Function<br />

El interativo seleccionador de texto<br />

Esto es el formato estandar <strong>para</strong> decidir si debe hacerlo <strong>sobre</strong> todo el documento o <strong>sobre</strong> una<br />

porción.<br />

'Remove all runs of empty space!<br />

'If text is selected, then it will only be removed from the selected region.<br />

Sub RemoveEmptySpace<br />

Dim oCursors(), i%<br />

If Not CreateSelectedTextIterator(ThisComponent, _<br />

"ALL empty space will be removed from the ENTIRE document?", oCursors()) Then Exit Sub<br />

For i% = LBOUND(oCursors()) To UBOUND(oCursors())<br />

RemoveEmptySpaceWorker (oCursors(i%, 0), oCursors(i%, 1), ThisComponent.Text)<br />

Next i%<br />

End Sub<br />

56


La macro principal<br />

Esto es donde el trabajo real sucede.<br />

Sub RemoveEmptySpaceWorker(oLCursor As Object, oRCursor As Object, oText As Object)<br />

Dim sParText As String, i As Integer<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor)


párrafos en blanco serán removidos.<br />

Si desea remover párrafos vacíos de una selección, entonces necesitará ejecutar esta macro.<br />

Si el texto está seleccionado, entonces los párrafos vacíos son removidos dentro del texto<br />

seleccionado. Si no hay texto seleccionado, se removerá del documento entero. Esta primera<br />

macro iteracciona <strong>sobre</strong> el texto seleccionado. Si no hay texto seleccionado, crea un cursor al<br />

inicio y al final del documento. La primera cosa que ve esta macro es como atravesar por los<br />

párrafos basados en texto. La macro <strong>para</strong> remover espacios es más segura porque esta no<br />

necesita extraer una cadena <strong>para</strong> trabajar.<br />

Sub RemoveEmptyParsWorker(oLCursor As Object, oRCursor As Object, oText As Object)<br />

Dim sParText As String, i As Integer<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor) 0<br />

'Yes, I know, limited to 64K here<br />

'If we have one <strong>para</strong>graph that is over 64K<br />

'Then I am in trouble!<br />

sParText = oLCursor.getString()<br />

i = Len(sParText)<br />

'We do not have short circuit logical. Drat!<br />

Do While i > 0<br />

If (Mid(sParText,i,1) = Chr(10)) OR (Mid(sParText,i,1) = Chr(13)) Then<br />

i = i - 1<br />

Else<br />

i = -1<br />

End If<br />

Loop<br />

If i = 0 Then<br />

oLCursor.setString("")<br />

Else<br />

oLCursor.goLeft(0,FALSE)<br />

End If<br />

loop<br />

End Sub<br />

6.4 Reemplazando espacios seleccionados usando cadenas.<br />

En general, no se debería remover espacios extra al leer el texto seleccionado y volviéndo a<br />

escribir los nuevos valores de nuevo. Una razón es porque las cadenas están limitadas a 64K<br />

de tamaño, y la otra es que es posible perder información de formateo. Dejé estos ejemplos<br />

porque trabajan con problemas que fueron escritos antes de que aprendiera cómo hacer lo<br />

mismo con cursores., y porque demuestran tecnicas de insertado de caracteres especiales. La<br />

primera macro reemplaza todos los nuevos párrafos y nuevas líneas con caracteres de<br />

espacios. Este ejemplo también demuestra cómo insertar caracteres de control (nuevos<br />

párrafos, cambios de línea, etc.) dentro del texto.<br />

Sub SelectedNewLinesToSpaces<br />

58


Dim lSelCount&, oSelections As Object<br />

Dim iWhichSelection As Integer, lIndex As Long<br />

Dim s$, bSomethingChanged As Boolean<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

For iWhichSelection = 0 To lSelCount - 1<br />

bSomethingChanged = False<br />

Rem What if the string is bigger than 64K? Oops<br />

s = oSelections.getByIndex(iWhichSelection).getString()<br />

lIndex = 1<br />

Do While lIndex < Len(s)<br />

Select Case Asc(Mid(s, lIndex, 1))<br />

Case 13<br />

'We found a new <strong>para</strong>graph marker.<br />

'The next character will be a 10!<br />

If lIndex < Len(s) And Asc(Mid(s, lIndex+1, 1)) = 10 Then<br />

Mid(s, lIndex, 2, " ")<br />

Else<br />

Mid(s, lIndex, 1, " ")<br />

End If<br />

lIndex = lIndex + 1<br />

bSomethingChanged = True<br />

Case 10<br />

'New line unless the previous charcter is a 13<br />

'Remove this entire case statement to ignore only new lines!<br />

If lIndex > 1 And Asc(Mid(s, lIndex-1, 1)) 13 Then<br />

'This really is a new line and NOT a new <strong>para</strong>graph.<br />

Mid(s, lIndex, 1, " ")<br />

lIndex = lIndex + 1<br />

bSomethingChanged = True<br />

Else<br />

'Nope, this one really was a new <strong>para</strong>graph!<br />

lIndex = lIndex + 1<br />

End If<br />

Case Else<br />

'Do nothing if we do not match something else<br />

lIndex = lIndex + 1<br />

End Select<br />

Loop<br />

If bSomethingChanged Then<br />

oSelections.getByIndex(iWhichSelection).setString(s)<br />

End If<br />

Next<br />

End Sub<br />

También se debe preguntar cómo convertir nuevos párrafos en nuevas líneas. Usar cursores<br />

es claramente una mejor idea, pero no sé como hacerlo. Pienso que este ejemplo es aún<br />

instructivo, por eso lo dejé. Primero borré el texto seleccionado y después empezar a agregar<br />

el texto de nuevo.<br />

Sub SelectedNewParagraphsToNewLines<br />

59


Dim lSelCount&, oSelections As Object, oSelection As Object<br />

Dim iWhichSelection As Integer, lIndex As Long<br />

Dim oText As Object, oCursor As Object<br />

Dim s$, lLastCR As Long, lLastNL As Long<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

oText=ThisComponent.Text<br />

For iWhichSelection = 0 To lSelCount - 1<br />

oSelection = oSelections.getByIndex(iWhichSelection)<br />

oCursor=oText.createTextCursorByRange(oSelection)<br />

s = oSelection.getString()<br />

'Delete the selected text!<br />

oCursor.setString("")<br />

lIndex = 1<br />

Do While lIndex


document?"<br />

If Not CreateSelectedTextIterator(ThisComponent, sPrompt$, oCursors())<br />

Then Exit Sub<br />

For i% = LBOUND(oCursors()) To UBOUND(oCursors())<br />

CRToNLWorker(oCursors(i%, 0), oCursors(i%, 1), ThisComponent.Text)<br />

Next i%<br />

End Sub<br />

Sub CRToNLWorker(oLCursor As Object, oRCursor As Object, oText As Object)<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor) = 0<br />

oLCursor.goLeft(1, True)<br />

oLCursor.setString("")<br />

oLCursor.goRight(0, False)<br />

oText.insertControlCharacter(oLCursor,_<br />

com.sun.star.text.ControlCharacter.LINE_BREAK, True)<br />

Loop<br />

End Sub<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'The real purpose of this macro is to make it easier to use the TextTable<br />

'method which wants trailing and leading white space removed.<br />

'It also wants new <strong>para</strong>graphs and NOT new lines!<br />

Sub SpaceToTabsInWordsMain<br />

Dim oCursors(), i%, sPrompt$<br />

sPrompt$ = "Convert Spaces to TABS for the ENTIRE document?"<br />

If Not CreateSelectedTextIterator(ThisComponent, sPrompt$, oCursors())<br />

Then Exit Sub<br />

For i% = LBOUND(oCursors()) To UBOUND(oCursors())<br />

SpaceToTabsInWordsWorker(oCursors(i%, 0), oCursors(i%, 1),<br />

ThisComponent.Text)<br />

Next i%<br />

End Sub<br />

Sub SpaceToTabsInWordsWorker(oLCursor As Object, oRCursor As Object, oText<br />

As Object)<br />

Dim iCurrentState As Integer, iChar As Integer, bChanged As Boolean<br />

Const StartLineState = 0<br />

Const InWordState = 1<br />

Const BetweenWordState = 2<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor) = 0<br />

iChar = Asc(oLCursor.getString())<br />

If iCurrentState = StartLineState Then<br />

If IsWhiteSpace(iChar) Then<br />

oLCursor.setString("")<br />

Else<br />

iCurrentState = InWordState<br />

End If<br />

ElseIf iCurrentState = InWordState Then<br />

61


it<br />

bChanged = True<br />

Select Case iChar<br />

Case 9<br />

Rem It is already a tab, ignore it<br />

iCurrentState = BetweenWordState<br />

Case 32, 160<br />

Rem Convert the space to a tab<br />

oLCursor.setString(Chr(9))<br />

oLCursor.goRight(1, False)<br />

iCurrentState = BetweenWordState<br />

Case 10<br />

Rem Remove the new line and insert a new <strong>para</strong>graph<br />

oText.insertControlCharacter(oLCursor,_<br />

com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, True)<br />

oLCursor.goRight(1, False)<br />

iCurrentState = StartLineState<br />

Case 13<br />

iCurrentState = StartLineState<br />

Case Else<br />

oLCursor.gotoEndOfWord(True)<br />

End Select<br />

ElseIf iCurrentState = BetweenWordState Then<br />

Select Case iChar<br />

Case 9, 32, 160<br />

Rem We already added a tab, this is extra stuff!<br />

oLCursor.setString("")<br />

Case 10<br />

Rem Remove the new line and insert a new <strong>para</strong>graph<br />

Rem and be sure to delete the leading TAB that we already<br />

Rem added in and that should come out!<br />

oText.insertControlCharacter(oLCursor,_<br />

com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, True)<br />

oLCursor.goLeft(0, False)<br />

Rem and over the TAB for deletion<br />

oLCursor.goLeft(1, True)<br />

oLCursor.setString("")<br />

oLCursor.goRight(1, False)<br />

iCurrentState = StartLineState<br />

Case 13<br />

Rem first, backup over the CR, then select the TAB and delete<br />

oLCursor.goLeft(0, False)<br />

oLCursor.goLeft(1, False)<br />

oLCursor.goLeft(1, True)<br />

oLCursor.setString("")<br />

Rem finally, move back over the CR that we will ignore<br />

oLCursor.goRight(1, True)<br />

iCurrentState = StartLineState<br />

Case Else<br />

iCurrentState = InWordState<br />

oLCursor.gotoEndOfWord(False)<br />

End Select<br />

End If<br />

oLCursor.goRight(0, False)<br />

Loop<br />

If bChanged Then<br />

Rem To get here, we went one character too far right<br />

oLCursor.goLeft(1, False)<br />

oLCursor.goLeft(1, True)<br />

62


If Asc(oLCursor.getString()) = 9 Then oLCursor.setString("")<br />

End If<br />

End Sub<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub TabsToSpacesMain<br />

Dim oCursors(), i%, sPrompt$<br />

sPrompt$ = "Convert TABS to Spaces for the ENTIRE document?"<br />

If Not CreateSelectedTextIterator(ThisComponent, sPrompt$, oCursors())<br />

Then Exit Sub<br />

For i% = LBOUND(oCursors()) To UBOUND(oCursors())<br />

TabsToSpacesWorker(oCursors(i%, 0), oCursors(i%, 1),<br />

ThisComponent.Text)<br />

Next i%<br />

End Sub<br />

Sub TabsToSpacesWorker(oLCursor As Object, oRCursor As Object, oText As<br />

Object)<br />

If IsNull(oLCursor) Or IsNull(oRCursor) Or IsNull(oText) Then Exit Sub<br />

If oText.compareRegionEnds(oLCursor, oRCursor) = 0<br />

If Asc(oLCursor.getString()) = 9 Then<br />

oLCursor.setString(" ") 'Change a tab into 4 spaces<br />

End If<br />

oLCursor.goRight(0, False)<br />

Loop<br />

End Sub<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'sPrompt : how to ask if should iterate over the entire text<br />

'oCursors() : Has the return cursors<br />

'Returns true if should iterate and false if should not<br />

Function CreateSelectedTextIterator(oDoc As Object, sPrompt As String,<br />

oCursors()) As Boolean<br />

Dim oSelections As Object, oSel As Object, oText As Object<br />

Dim lSelCount As Long, lWhichSelection As Long<br />

Dim oLCursor As Object, oRCursor As Object<br />

CreateSelectedTextIterator = True<br />

oText = oDoc.Text<br />

If Not IsAnythingSelected(ThisComponent) Then<br />

Dim i%<br />

i% = MsgBox("No text selected!" + Chr(13) + sPrompt, _<br />

1 OR 32 OR 256, "Warning")<br />

If i% = 1 Then<br />

oLCursor = oText.createTextCursor()<br />

oLCursor.gotoStart(False)<br />

oRCursor = oText.createTextCursor()<br />

oRCursor.gotoEnd(False)<br />

oCursors = DimArray(0, 1)<br />

oCursors(0, 0) = oLCursor<br />

oCursors(0, 1) = oRCursor<br />

Else oCursors = DimArray()<br />

CreateSelectedTextIterator = False<br />

End If<br />

63


Else oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

oCursors = DimArray(lSelCount - 1, 1)<br />

For lWhichSelection = 0 To lSelCount - 1<br />

oSel = oSelections.getByIndex(lWhichSelection)<br />

'If I want to know if NO text is selected, I could<br />

'do the following:<br />

'oLCursor = oText.CreateTextCursorByRange(oSel)<br />

'If oLCursor.isCollapsed() Then ...<br />

oLCursor = GetLeftMostCursor(oSel, oText)<br />

oRCursor = GetRightMostCursor(oSel, oText)<br />

oCursors(lWhichSelection, 0) = oLCursor<br />

oCursors(lWhichSelection, 1) = oRCursor<br />

Next<br />

End If<br />

End Function<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'oDoc is a writer object<br />

Function IsAnythingSelected(oDoc As Object) As Boolean<br />

Dim oSelections As Object, oSel As Object, oText As Object, oCursor As<br />

Object<br />

IsAnythingSelected = False<br />

If IsNull(oDoc) Then Exit Function<br />

' The current selection in the current controller.<br />

'If there is no current controller, it returns NULL.<br />

oSelections = oDoc.getCurrentSelection()<br />

If IsNull(oSelections) Then Exit Function<br />

If oSelections.getCount() = 0 Then Exit Function<br />

If oSelections.getCount() > 1 Then<br />

IsAnythingSelected = True<br />

Else oSel = oSelections.getByIndex(0)<br />

oCursor = oDoc.Text.CreateTextCursorByRange(oSel)<br />

If Not oCursor.IsCollapsed() Then IsAnythingSelected = True<br />

End If<br />

End Function<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'oSelection is a text selection or cursor range<br />

'oText is the text object<br />

Function GetLeftMostCursor(oSel As Object, oText As Object) As Object<br />

Dim oRange As Object, oCursor As Object<br />

If oText.compareRegionStarts(oSel.getEnd(), oSel) >= 0 Then<br />

oRange = oSel.getEnd()<br />

Else<br />

oRange = oSel.getStart()<br />

End If<br />

oCursor = oText.CreateTextCursorByRange(oRange)<br />

oCursor.goRight(0, False)<br />

GetLeftMostCursor = oCursor<br />

End Function<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

64


'oSelection is a text selection or cursor range<br />

'oText is the text object<br />

Function GetRightMostCursor(oSel As Object, oText As Object) As Object<br />

Dim oRange As Object, oCursor As Object<br />

If oText.compareRegionStarts(oSel.getEnd(), oSel) >= 0 Then<br />

oRange = oSel.getStart()<br />

Else<br />

oRange = oSel.getEnd()<br />

End If<br />

oCursor = oText.CreateTextCursorByRange(oRange)<br />

oCursor.goLeft(0, False)<br />

GetRightMostCursor = oCursor<br />

End Function<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'oSelection is a text selection or cursor range<br />

'oText is the text object<br />

Function IsWhiteSpace(iChar As Integer) As Boolean<br />

Select Case iChar<br />

Case 9, 10, 13, 32, 160<br />

IsWhiteSpace = True<br />

Case Else<br />

IsWhiteSpace = False<br />

End Select<br />

End Function<br />

'******************************************************************<br />

'Here starts the OLD <strong>macros</strong>!<br />

'Author: Andrew Pitonyak<br />

Sub ConvertSelectedNewParagraphToNewLine<br />

Dim lSelCount&, oSelections As Object, oSelection As Object<br />

Dim iWhichSelection As Integer, lIndex As Long<br />

Dim oText As Object, oCursor As Object<br />

Dim s$, lLastCR As Long, lLastNL As Long<br />

'There may be multiple selections present!<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

oText=ThisComponent.Text<br />

For iWhichSelection = 0 To lSelCount - 1<br />

oSelection = oSelections.getByIndex(iWhichSelection)<br />

oCursor=oText.createTextCursorByRange(oSelection)<br />

s = oSelection.getString()<br />

oCursor.setString("")<br />

lLastCR = -1<br />

lLastNL = -1<br />

lIndex = 1<br />

Do While lIndex


'always will be but I can not verify this<br />

If (lIndex < Len(s)) Then<br />

If Asc(Mid(s, lIndex+1, 1)) = 10 Then lIndex = lIndex + 1<br />

End If<br />

Case 10<br />

oText.insertControlCharacter(oCursor,_<br />

com.sun.star.text.ControlCharacter.LINE_BREAK, False)<br />

Case Else<br />

oCursor.setString(Mid(s, lIndex, 1))<br />

oCursor.GoRight(1, False)<br />

End Select<br />

lIndex = lIndex + 1<br />

Loop<br />

Next<br />

End Sub<br />

'I decided to write this as a finite state machine<br />

'Finite state machines are a wonderful thing :-)<br />

Sub ConvertSelectedSpaceToTabsBetweenWords<br />

Dim lSelCount&, oSelections As Object, oSelection As Object<br />

Dim iWhichSelection As Integer, lIndex As Long<br />

Dim oText As Object, oCursor As Object<br />

Dim s$, lLastCR As Long, lLastNL As Long<br />

Rem What states are supported<br />

Dim iCurrentState As Integer<br />

Const StartLineState = 0<br />

Const InWordState = 1<br />

Const BetweenWordState = 2<br />

Rem Transition Points<br />

Dim iWhatFound As Integer<br />

Const FoundWhiteSpace = 0<br />

Const FoundNewLine = 1<br />

Const FoundOther = 2<br />

Const ActionIgnoreChr = 0<br />

Const ActionDeleteChr = 1<br />

Const ActionInsertTab = 2<br />

Rem Define the state transitions<br />

Dim iNextState(0 To 2, 0 To 2, 0 To 1) As Integer<br />

iNextState(StartLineState, FoundWhiteSpace, 0) = StartLineState<br />

iNextState(StartLineState, FoundNewLine, 0) = StartLineState<br />

iNextState(StartLineState, FoundOther, 0) = InWordState<br />

iNextState(InWordState, FoundWhiteSpace, 0) = BetweenWordState<br />

iNextState(InWordState, FoundNewLine, 0) = StartLineState<br />

iNextState(InWordState, FoundOther, 0) = InWordState<br />

iNextState(BetweenWordState, FoundWhiteSpace, 0)= BetweenWordState<br />

iNextState(BetweenWordState, FoundNewLine, 0) = StartLineState<br />

iNextState(BetweenWordState, FoundOther, 0) = InWordState<br />

Rem Define the state actions<br />

iNextState(StartLineState, FoundWhiteSpace, 1) = ActionDeleteChr<br />

iNextState(StartLineState, FoundNewLine, 1) = ActionIgnoreChr<br />

iNextState(StartLineState, FoundOther, 1) = ActionIgnoreChr<br />

iNextState(InWordState, FoundWhiteSpace, 1) = ActionDeleteChr<br />

iNextState(InWordState, FoundNewLine, 1) = ActionIgnoreChr<br />

66


iNextState(InWordState, FoundOther, 1) = ActionIgnoreChr<br />

iNextState(BetweenWordState, FoundWhiteSpace, 1)= ActionDeleteChr<br />

iNextState(BetweenWordState, FoundNewLine, 1) = ActionIgnoreChr<br />

iNextState(BetweenWordState, FoundOther, 1) = ActionInsertTab<br />

'There may be multiple selections present!<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

oText=ThisComponent.Text<br />

For iWhichSelection = 0 To lSelCount - 1<br />

oSelection = oSelections.getByIndex(iWhichSelection)<br />

oCursor=oText.createTextCursorByRange(oSelection)<br />

s = oSelection.getString()<br />

oCursor.setString("")<br />

lLastCR = -1<br />

lLastNL = -1<br />

lIndex = 1<br />

iCurrentState = StartLineState<br />

Do While lIndex


Else oCursor.setString(Mid(s, lIndex, 1))<br />

oCursor.GoRight(1, False)<br />

'Print "Inserted Something"<br />

End If<br />

Case ActionInsertTab<br />

oCursor.setString(Chr$(9) + Mid(s, lIndex, 1))<br />

oCursor.GoRight(2, False)<br />

'Print "Inserted a tab"<br />

End Select<br />

lIndex = lIndex + 1<br />

'MsgBox "index = " + lIndex + Chr(13) + s<br />

iCurrentState = iNextState(iCurrentState, iWhatFound, 0)<br />

Loop<br />

Next<br />

End Sub<br />

Sub ConvertAllTabsToSpace<br />

DIM oCursor As Object, oText As Object<br />

Dim nSpace%, nTab%, nPar%, nRet%, nTot%<br />

Dim justStarting As Boolean<br />

oText=ThisComponent.Text 'Get the Text component<br />

oCursor=oText.createTextCursor() 'Create a cursor in the text<br />

oCursor.gotoStart(FALSE) 'Goto the start but do NOT select the<br />

text as you go<br />

Do While oCursor.GoRight(1, True) 'Move right one chracter and select<br />

it<br />

If Asc(oCursor.getString()) = 9 Then<br />

oCursor.setString(" ") 'Change a tab into 4 spaces<br />

End If<br />

oCursor.goRight(0,FALSE) 'Deselect text!<br />

Loop<br />

End Sub<br />

Sub ConvertSelectedTabsToSpaces<br />

Dim lSelCount&, oSelections As Object<br />

Dim iWhichSelection As Integer, lIndex As Long<br />

Dim s$, bSomethingChanged As Boolean<br />

'There may be multiple selections present!<br />

'There will probably be one more than expected because<br />

'it will count the current cursor location as one piece<br />

'of selected text, just so you know!<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

'Print "total selected = " + lSelCount<br />

For iWhichSelection = 0 To lSelCount - 1<br />

bSomethingChanged = False<br />

s = oSelections.getByIndex(iWhichSelection).getString()<br />

'Print "Text group " + iWhichSelection + " is of length " + Len(s)<br />

lIndex = 1<br />

Do While lIndex < Len(s)<br />

'Print "ascii at " + lIndex + " = " + Asc(Mid(s, lIndex, 1))<br />

If Asc(Mid(s, lIndex, 1)) = 9 Then<br />

s = ReplaceInString(s, lIndex, 1, " ")<br />

68


SomethingChanged = True<br />

lIndex = lIndex + 3<br />

End If<br />

lIndex = lIndex + 1<br />

'Print ":" + lIndex + "(" + s + ")"<br />

Loop<br />

If bSomethingChanged Then<br />

oSelections.getByIndex(iWhichSelection).setString(s)<br />

End If<br />

Next<br />

End Sub<br />

Function ReplaceInString(s$, index&, num&, replaces$) As String<br />

If index


mySelection = oText.createTextCursorByRange(Cursor.getStart())<br />

mySelection.gotoStartOfParagraph(false)<br />

mySelection.gotoEndOfParagraph(true)<br />

mySelection.CharFontName="Courier New"<br />

mySelection.Charheight="10"<br />

'Time to set Italic or NOT italic as the case with<br />

'NONE, OBLIQUE, ITALIC, DONTKNOW, REVERSE_OBLIQUE, REVERSE_ITALIC<br />

mySelection.CharPosture = com.sun.star.awt.FontSlant.ITALIC<br />

'So you want BOLD text?<br />

'DONTKNOW, THIN, ULTRALIGHT, LIGHT, SEMILIGHT,<br />

'NORMAL, SEMIBOLD, BOLD, ULTRABOLD, BLACK<br />

'These are really only constants where THIN is 50, NORMAL is 100<br />

' BOLD is 150, and BLACK is 200.<br />

mySelection.CharWeight = com.sun.star.awt.FontWeight.BOLD<br />

'If underlining is your thing<br />

'NONE, SINGLE, DOUBLE, DOTTED, DONTKNOW, DASH, LONGDASH,<br />

'DASHDOT, DASHDOTDOT, SMALLWAVE, WAVE, DOUBLEWAVE, BOLD,<br />

'BOLDDOTTED, BOLDDASH, BOLDLONGDASH, BOLDDASHDOT,<br />

'BOLDDASHDOTDOT, BOLDWAVE<br />

mySelection.CharUnderline = com.sun.star.awt.FontUnderline.SINGLE<br />

'I have not experimented with this enough to know what the true<br />

'implications of this really is, but I do know that it seems to set<br />

'the character locale to German.<br />

Dim aLanguage As New com.sun.star.lang.Locale<br />

aLanguage.Country = "de"<br />

aLanguage.Language = "de"<br />

mySelection.CharLocale = aLanguage<br />

6.6 End Sub Insertar texto<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

Sub InsertSimpleText<br />

Dim oDocument As Object<br />

Dim oText As Object<br />

Dim oViewCursor As Object<br />

Dim oTextCursor As Object<br />

oDocument = ThisComponent<br />

oText = oDocument.Text<br />

oViewCursor = oDocument.CurrentController.getViewCursor()<br />

oTextCursor = oText.createTextCursorByRange(oViewCursor.getStart())<br />

' Place the text to insert here<br />

oText.insertString(oTextCursor, "—", FALSE)<br />

End Sub<br />

70


6.7 Insertar fecha formateada dentro de un documento de texto<br />

Esto insertará el texto “Today is ” donde la fecha es formateada como “DD. MMM<br />

AAAA”. Esto creará el formato de fecha si no existe. Para más información <strong>sobre</strong> formatos<br />

válidos, vea el contenido de la ayuda en el tópico “formato de número; formatos”.<br />

'******************************************************************<br />

'Author: Andrew Pitonyak<br />

'email: andrew@pitonyak.org<br />

'uses: FindCreateNumberFormatStyle<br />

Sub InsertDateField<br />

Dim oDocument As Object<br />

Dim oText As Object<br />

Dim oViewCursor As Object<br />

Dim oTextCursor As Object<br />

Dim oDateTime As Object<br />

oDocument = ThisComponent<br />

If oDocument.SupportsService("com.sun.star.text.TextDocument") Then<br />

oText = oDocument.Text<br />

oViewCursor = oDocument.CurrentController.getViewCursor()<br />

oTextCursor = oText.createTextCursorByRange(oViewCursor.getStart())<br />

oText.insertString(oTextCursor, "Today is ", FALSE)<br />

' Create the DateTime type.<br />

ODateTime = oDocument.createInstance("com.sun.star.text.TextField.DateTime")<br />

oDateTime.IsFixed = TRUE<br />

oDateTime.NumberFormat = FindCreateNumberFormatStyle(_<br />

"DD. MMMM YYYY", oDocument)<br />

oText.insertTextContent(oTextCursor,oDateTime,FALSE)<br />

oText.insertString(oTextCursor," ",FALSE) Else<br />

MsgBox "Sorry, this macro requires a TextDocument"<br />

End If<br />

End Sub<br />

6.8 Insertar una nueva página<br />

6.8.1 La solución<br />

En mi investigación <strong>sobre</strong> cómo insertar una página nueva en un documento, tropecé con el<br />

siguiente vínculo:<br />

http://api.openoffice.org/common/ref/com/sun/star/style/ParagraphProperties.html<br />

el cual menciona dos propiedades. El estado PageNumberOffset: “Si una propiedad de salto<br />

de página es puesta en un párrafo, esta propiedad contiene el nuevo valor <strong>para</strong> el número de<br />

página.” El estado de la propiedad PageDescName: “Si esta propiedad es activada, creará un<br />

salto de página después del párrafo al que pertenece y asigna el valor del nombre del estilo<br />

que la nueva página usa.” Razoné que si activo PageDescName, entonces puedo crear una<br />

nueva página y ponerle un número de página. Lo que no se dijo es que PageDescName es el<br />

71


nombre del nuevo estilo de página que se usa después del salto de página. Si no usa un estilo<br />

de página existente, entonces fallará!<br />

Sub ExampleNewPage<br />

Dim oSelections As Object, oSel As Object, oText As Object<br />

Dim lSelCount As Long, lWhichSelection As Long<br />

Dim oLCursor As Object, oRCursor As Object<br />

oText = ThisComponent.Text<br />

oSelections = ThisComponent.getCurrentSelection()<br />

lSelCount = oSelections.getCount()<br />

For lWhichSelection = 0 To lSelCount - 1<br />

oSel = oSelections.getByIndex(lWhichSelection)<br />

oLCursor = oText.CreateTextCursorByRange(oSel)<br />

oLCursor.gotoStartOfParagraph(false)<br />

oLCursor.gotoEndOfParagraph(true)<br />

Rem Preserve the existing page style!<br />

oLCursor.PageDescName = oLCursor.PageStyleName<br />

oLCursor.PageNumberOffset = 7<br />

Next<br />

End Sub<br />

72


7 Ejemplo de inversión<br />

Estuve llevando mis inversiones, bien modestas, en una hoja de cálculo por algún tiempo.<br />

Pero decidí que es tiempo de cambiar.<br />

7.1 Página resumen<br />

Tengo un resumen con un renglón <strong>para</strong> cada inversión. Mi pensamiento inicial fue que<br />

deseaba la siguiente información:<br />

Columna Descripción<br />

Dueño A quien pertenece esta cuenta? A mi, a mi esposa, etc.<br />

NASDAQ Deseo automatizar la determinación del valor actual. Para hacer esto,<br />

requiero del símbolo NASDAQ symbol. Escribiré una macro <strong>para</strong> hacer<br />

esto.<br />

Fecha Cuándo fue la última vez que actualicé automáticamente el valor.<br />

Valor Valor actual en el NASDAQ.<br />

Acciones Número de acciones que tengo. Esto es tomado de la hoja de detalles.<br />

Valía El valor actual de la inversión. Este es el “precio*acciones”<br />

Tipo Mis valores actuales que uso incluyen “Capital Comercial”, “Fondos”, y<br />

“Banco”.<br />

Sub Tipo Actualmente tengo valores como “Capital medio” <strong>para</strong> dar un poco más<br />

de información acerca de la inversión.<br />

Que Cuando hice esta columna, estaba pensando en cosas como “Roth”,<br />

“IRA”, “inversión”, “401K”, “cheques”, etc.<br />

Apertura Fecha en que abrí la cuenta.<br />

Nombre El nombre que identifica la cuenta. Normalmente le pongo el nombre<br />

usado por la institución a que pertenece, algo como “Largo plazo,<br />

excenta de impuesto”.<br />

Compañía Ese es el nombre de la compañía a que pertenece, algo como<br />

“Vanguard”, “Thrivent”, o “T. Rowe Price”.<br />

Cuenta Mi número de cuenta<br />

Nombre de la hoja El nombre de la hoja que contiene los detalles de la cuenta.<br />

Beneficiario Que podrá ser el dueño de la cuenta en caso de que el dueño muera.<br />

7.2 Hoja de detalles<br />

Asumo que si cada hoja de detalle se ve igual, esto hará que sea fácil realizar operaciones<br />

automáticas en la hoja. No sé mucho de inversiones o finanzas por eso no prometo cuan<br />

útiles son mis elecciones. Yo decidí las siguientes columnas:<br />

73


Columna Descripción<br />

Valía Valor actual de la inversión. Esto es “Precio * Acciones”<br />

Acciones Número de acciones que tengo.<br />

$ agregé Cuánto gasté en esta transacción.<br />

# agregué Acciones compradas por mi contribución.<br />

# Igualaciones Acciones compradas por un programa de igualaciones como un 401K<br />

match.<br />

# Divididas Acciones agregadas como dividendos.<br />

# Honorarios Acciones removidas por honorarios de algún orden.<br />

Precio/Acción Monto pagado por cada acción.<br />

Fecha Fecha de la transacción.<br />

$ Gastado Monto acumulado que gasté en esta inversión.<br />

Rédito o producto Cuando abro una cuenta bancaria, normalmente está asociada un una<br />

tasa de interés. Busco como determinar cómo se ha comportado mi<br />

cuenta <strong>para</strong> poder calcular el promedio de réditos o productos.<br />

Comentario Agrego comentarios como “$2.50 por honorarios de mantenimiento”<br />

7.3 Chequear duplicados en una columna<br />

Para prevenir dos inversiones usando el mismo nombre de hoja, necesito una macro <strong>para</strong><br />

buscar en la columna “nombre de la hoja” <strong>para</strong> prevenir entradas duplicadas. Unos pocos<br />

utilitarios de <strong>macros</strong> se requerien <strong>para</strong> hacer esto.<br />

'Given a cell, extract the normal looking address of a cell<br />

'First, the name of the containing sheet is extracted.<br />

'Second, the column number is obtained and turned into a letter<br />

'Lastly, the row is obtained. Rows start at 0 but are displayed as 1<br />

Function PrintableAddressOfCell(the_cell As Object) As String<br />

PrintableAddressOfCell = "Unknown"<br />

If Not IsNull(the_cell) Then<br />

PrintableAddressOfCell = the_cell.getSpreadSheet().getName + _<br />

":" + ColumnNumberToString(the_cell.CellAddress.Column) + _<br />

(the_cell.CellAddress.Row + 1)<br />

End If<br />

End Function<br />

7.3.1 Dirección imprimible de una celda<br />

Problemas de seguimiento son mejor reportados en un formato diario sencillo. Internamente,<br />

las columnas son numeradas de 0 a 255. Las columnas son reportadas desde 'A' a 'IV'. Por<br />

efectos matemáticos, el problema es convertir de la base 10 a la base 26, donde 0 significa A<br />

74


y 25 significa Z.<br />

' Columns are numbered 0 to 255, and shows from 'A' to 'IV'<br />

' How do you convert Base 10 numbers to Base 26?<br />

Function ColumnNumberToString(the_column As Long) As String<br />

Dim s$<br />

Do<br />

s$ = Chr(65 + the_column MOD 26) + s$<br />

'If I don't use Int, then it seems to round<br />

'the result rather than truncating.<br />

the_column = Int(the_column / 26)<br />

Loop Until the_column = 0<br />

ColumnNumberToString = s$<br />

End Function<br />

Para imprimir la dirección completa de una celda, un poquito más de trabajo se requiere. El<br />

nombre de la hoja se obtiene fácil. El nombre de la columna es descrito abajo. Las filas son<br />

representadas internamente iniciando en 0 y externamente iniciando en 1.<br />

'Return a normal looking cell address as 'Sheetname'.ColumnRow.<br />

'Rows start at 0 but are displayed as 1<br />

Function PrintableCellAddress(the_cell As Object) As String<br />

PrintableAddressOfCell = "Unknown"<br />

If Not IsNull(the_cell) Then<br />

PrintableAddressOfCell = "'" + the_cell.getSpreadSheet().getName + _<br />

"'." + ColumnNumberToString(the_cell.CellAddress.Column) + _<br />

(the_cell.CellAddress.Row + 1)<br />

End If<br />

End Function<br />

7.3.2 Conteo de entradas no vacías en una columna<br />

'oSheet Spreadsheet containing the column<br />

'lCol Column to check<br />

'l_min Ignore rows before this<br />

'l_max Ignore columns after this<br />

'Return the number of non-blank cells in the column<br />

'I used the variant type in the <strong>para</strong>meter to avoid a bug in version 1.0.2<br />

'That fails to properly detect Optional <strong>para</strong>meters with non-variant types.<br />

Function NonBlankCellsInColumn (oSheet As Object, lCol&, _<br />

Optional l_min As Variant, Optional l_max As Variant) As Long<br />

Dim oCells As Object, oCell As Object, oColumn As Object<br />

Dim oAddr As Object, oRanges As Object<br />

Dim n&, lMin&, lMax&<br />

n = 0<br />

lMin = 0<br />

lMax = 2147483647<br />

If Not IsMissing(l_min) Then lMin = l_min<br />

If Not IsMissing(l_max) Then lMax = l_max<br />

oColumn = oSheet.Columns(lCol)<br />

75


oRanges = ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges")<br />

oRanges.insertByName("", oColumn)<br />

oCells = oRanges.Cells.createEnumeration<br />

Do While oCells.hasMoreElements<br />

oCell = oCells.nextElement<br />

oAddr = oCell.CellAddress<br />

If oAddr.Row > lMax Then Exit Do<br />

If oAddr.Row >= lMin And Len(oCell.String) > 0 Then n=n+1<br />

Loop<br />

NonBlankCellsInColumn = n<br />

End Function<br />

7.3.3 Arreglo ordenado<br />

No estoy muy convencido de su eficiencia, porque el número de elementos en mis arreglos es<br />

pequeño. Por eso, usé el ordenamiento de burbuja modificado.<br />

'sArray holds the sorted array<br />

'oSheet Spreadsheet containing the column<br />

'lCol Column to check<br />

'l_min Ignore rows before this<br />

'l_max Ignore columns after this<br />

Sub BuildSortedArray (sArray() As String, oSheet As Object, lCol&, _<br />

Optional l_min As Variant, Optional l_max As Variant)<br />

Dim oCells As Object, oCell As Object, oColumn As Object<br />

Dim oAddr As Object, oRanges As Object<br />

Dim n&, i&, j&, lMin&, lMax&<br />

n = NonBlankCellsInColumn (oSheet, lCol&,l_min,l_max)<br />

If n = 0 Then<br />

ReDim sArray() As String<br />

Else<br />

ReDim sArray(n-1) As String<br />

lMin = 0<br />

lMax = 2147483647<br />

If Not IsMissing(l_min) Then lMin = l_min<br />

If Not IsMissing(l_max) Then lMax = l_max<br />

oColumn = oSheet.Columns(lCol)<br />

oRanges = ThisComponent.createInstance("com.sun.star.sheet.SheetCellRanges")<br />

oRanges.insertByName("", oColumn)<br />

oCells = oRanges.Cells.createEnumeration<br />

i = 0<br />

Do While oCells.hasMoreElements<br />

oCell = oCells.nextElement<br />

oAddr = oCell.CellAddress<br />

If oAddr.Row > lMax Then Exit Do<br />

If oAddr.Row >= lMin And Len(oCell.String) > 0 Then<br />

sArray(i) = oCell.String<br />

76


i = i + 1<br />

End If<br />

Loop<br />

Dim bSomethingChanged As Boolean<br />

Dim sTemp$<br />

For i = LBound(sArray()) To UBound(sArray()) - 2<br />

bSomethingChanged = False<br />

For j = n-1 To i+1 Step -1<br />

If sArray(j) < sArray(j-1) Then<br />

sTemp$ = sArray(j)<br />

sArray(j) = sArray(j-1)<br />

sArray(j-1) = sTemp$<br />

bSomethingChanged = True<br />

End If<br />

Next<br />

If Not bSomethingChanged Then Exit For<br />

Next<br />

End If<br />

End Sub<br />

7.3.4 Encontrar el duplicado<br />

Con un arreglo ordenado, es fácil encontrar una entrada duplicada! Busco la primera y<br />

regreso el valor.<br />

Function FirstDuplicate(sArray() As String) As String<br />

Dim i&<br />

FirstDuplicate = ""<br />

For i = LBound(sArray()) To UBound(sArray()) - 1<br />

If sArray(i) = sArray(i+1) Then<br />

FirstDuplicate = sArray(i)<br />

Exit For<br />

End If<br />

Next<br />

End Function<br />

77


8 Lenguaje<br />

8.1 Comentarios<br />

Es siempre una buena práctica comentar libremente su código. Lo que es claro hoy, puede no<br />

serlo mañana. La comilla sencilla y REM, ambos indican que un comentario va a iniciar.<br />

Todo el texto posteriosr será ignorado.<br />

REM This is a comment<br />

REM And this is another comment<br />

' And yet another comment<br />

' I could do this all day long<br />

Dim i As IntegerRem i is used as in index variable in loops<br />

Print i REM This will print the value of i<br />

8.2 Variables<br />

8.2.1 Nombres<br />

Los nombres de variables están limitados a 255 caracteres, pueden iniciar con cualquier<br />

caracter del alfabeto estándar y pueden contener números. El “underscore” (subrayado) y los<br />

espacios también son carácteres válidos. No hay distinción entre mayúsculas y minúsculas.<br />

Los nombres de variables con espacios deben estar encerrados entre paréntesis cuadrados<br />

“[]”.<br />

8.2.2 Declaración<br />

Es considerado una buena práctica declarar las variables antes de usarlas. La instrucción<br />

“Option Explicit” fuerza a hacer esto. Esta línea debe existir en su código antes de cualquier<br />

otra. Si no usa “Option Explicit”, entonces es posible que un nombre de variable mal escrito<br />

regrese <strong>para</strong> asustarlo con errores.<br />

Para declarar variables use “Dim”. La sintaxis de “Dim” es la siguiente:<br />

[ReDim]Dim Nombre1 [(inicio To final)] [As Tipo][, Nombre2 [(inicio To final)] [As Tipo]<br />

[,...]]<br />

Esto permite declarar un número de variables al mismo tiempo. Nombre es cualquier variable<br />

o arreglo variable. Las valores inicio and final pueden estar dentro del rango -32768 a<br />

32767. Esto define un número de elementos (inclusive) mientras Nombre1(inicio) y<br />

Nombre1(final) sean valores válidos. Si se usa ReDim, entonces los valores inicio y final<br />

pueden ser expresiones numéricas. Los valores válidos <strong>para</strong> tipo incluyen Bool, Currency,<br />

Date, Double, Integer, Long, Object, Single, String, y Variant.<br />

Las varibles Object 4 pueden ser seguidas por un set subsecuente. Uso esto cuando necesito un<br />

objeto que retorne valores.<br />

El tipo por defecto es Single si tipo no es especificado. A menos que se usen los comandos<br />

DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, o DefVar. Estos comandos le permiten<br />

especificar el tipo de datos basados en la primera letra del nombre de una variable.<br />

4 Estas variables se usan <strong>para</strong> definir objetos, como hojas de cálculo, cursores, etc. Como en VBA.<br />

79


Los objetos de cadena están limitados a 64000 carateres.<br />

Los objetos Variant pueden contener todos los tipos y se determinan por definición.<br />

Advertencia El tipo de variable debe ser declarado individualmente <strong>para</strong> cada<br />

variable, o por defecto será de tipo variant. “Dim a, b As Integer”<br />

declara “a” como tipo Variant y “b” como tipo Integer (entero).<br />

Sub MultipleDeclaration<br />

Dim a, b As Integer<br />

Dim c As Long, d As String<br />

Dim e As Variant, f As Float<br />

Print TypeName(a) Rem Empty, Variant by default<br />

Print TypeName(b) Rem Integer, Declared Integer<br />

Print TypeName(c) Rem Long, Declared Long<br />

Print TypeName(d) Rem String, Declared String<br />

Print TypeName(e) Rem Empty, Variant as declared<br />

Print TypeName(f) Rem Object, Float is unknown type<br />

Print TypeName(g) Rem Object, because NOT declared<br />

End Sub<br />

8.2.3 Variables globales malas y estáticas<br />

Las variables globales usualmente no se usan porque pueden ser modificadas por cualquier<br />

rutina y en cualquier momento donde sea, y es dificil saber cuales métodos modifican cuales<br />

variables que está usando. Por eso inicie poniéndo el modificador “malas” después de<br />

“Variables Globales” mientras enseñaba en Ohio State University. Lo usé como una<br />

herramienta <strong>para</strong> recordar a mis estudiantes que hay un tiempo y un lugar <strong>para</strong> las variables<br />

globales, y que debe pensar antes de usarlas.<br />

Una global puede ser declarada fuera de un procedimiento. Puede usar las palabras claves<br />

Public 5 y Private <strong>para</strong> especificar si esta variable es global <strong>para</strong> todos los módulos o<br />

solamente <strong>para</strong> este. Si no se especifica Public o Private explicitamente, se asume Private. La<br />

sintaxis es la misma que las instrucciones Dim y ReDim.<br />

Aunque las variables son pasadas por referencia, a menos que se indique lo contrario, las<br />

variables globales aparentemente son pasadas por valor. Esto ha causado más de un error en<br />

mi código.<br />

Cada vez que un procedimiento es llamado, las variables locales en el procedimiento son<br />

vueltas a crear. Si usted declara una variable Static 6 , esta retendrá su valor. En el ejemplo de<br />

abajo, la subrutina Worker cuenta el número de veces que ha sido llamada. Recuerde que las<br />

variables numéricas son iniciadas en cero y las cadenas son iniciadas con una cadena vacía.<br />

Option Explicit<br />

Public Author As String REM Global to ALL Modules<br />

5 N.T: Esta palabra clave define una variable pública. Esta sería la palabra clave que el autor recomienda no<br />

usar.<br />

6 N.T: Esta palabra clave declara una variable estática. Este tipo de variable se mantiene durante todo el<br />

tiempo de ejecución. No se destruye después de salir de la función o subrutina, sin embargo no es global.<br />

80


Private PrivateOne$ REM Global to THIS Module only<br />

Dim PrivateTwo$ REM Global to THIS Module only<br />

Sub PublicPrivateTest<br />

Author = "Andrew Pitonyak"<br />

PrivateOne = "Hello"<br />

Worker()<br />

Worker()<br />

End Sub<br />

Sub Worker()<br />

Static Counter As Long REM retains its value between calls<br />

Counter = Counter + 1 REM count each time Worker is called<br />

Print "Counter = " + Counter<br />

Print "Author = " + Author<br />

End Sub<br />

8.2.4 Tipos<br />

Abstractamente hablando, <strong>OpenOffice</strong>.org Basic soporta los tipos numéricos, cadenas,<br />

booleanos, y objectos variables. Los objetos son usados principalmente usados <strong>para</strong> referirse<br />

a los internos como documentos, tablas, etc. Con un objeto, puede usar sus correspondientes<br />

métodos y propiedades. Los tipos numéricos son inicializados en cero y las cadenas con una<br />

cadena vacía “”.<br />

Si necesita saber el tipo de una variable en tiempo de ejecución, la función TypeName<br />

regresa una representación de cadena del tipo de variable. Si necesita saber un tipo de<br />

variable en tiempo de ejecución, la función VarType regresa un entero que corresponde al<br />

tipo de variable.<br />

Palabra<br />

Clave<br />

Tipo de variable No. tipo<br />

variable<br />

Auto Tipo Defxxx<br />

Boolean Booleano 11 DefBool<br />

Currency Moneda con cuatro decimales 6 @<br />

Date Fecha 7 DefDate<br />

Double Doble con punto flotante 5 # DefDbl<br />

Integer Entero 2 % DefInt<br />

Long Largo 3 & DefLng<br />

Object Objeto 9 DefObj<br />

Single Sencillo con punto flotante 4 !<br />

String Cadena 8 $<br />

Variant Puede contener todos los tipos<br />

especificados en la definición 12<br />

81<br />

DefVar


Palabra<br />

Clave<br />

Tipo de variable No. tipo<br />

variable<br />

Empty Variable no inicializada 0<br />

Null No tiene valores válidos 1<br />

Sub ExampleTypes<br />

Dim b As Boolean<br />

Dim c As Currency<br />

Dim t As Date<br />

Dim d As Double<br />

Dim i As Integer<br />

Dim l As Long<br />

Dim o As Object<br />

Dim f As Single<br />

Dim s As String<br />

Dim v As Variant<br />

Dim n As Variant<br />

Dim x As Variant<br />

n = null<br />

x = f<br />

Print TypeName(b) + " " + VarType(b) Rem Boolean 11<br />

Print TypeName(c) + " " + VarType(c) Rem Currency 6<br />

Print TypeName(t) + " " + VarType(t) Rem Date 7<br />

Print TypeName(d) + " " + VarType(d) Rem Double 5<br />

Print TypeName(i) + " " + VarType(i) Rem Integer 2<br />

Print TypeName(l) + " " + VarType(l) Rem Long 3<br />

Print TypeName(o) + " " + VarType(o) Rem Object 9<br />

Print TypeName(f) + " " + VarType(f) Rem Single 4<br />

Print TypeName(s) + " " + VarType(s) Rem String 8<br />

Print TypeName(v) + " " + VarType(v) Rem Empty 0<br />

Print TypeName(n) + " " + VarType(n) Rem Null 1<br />

Print TypeName(x) + " " + VarType(x) Rem Single 4<br />

End Sub<br />

Variables Booleanas<br />

Auto Tipo Defxxx<br />

Las variables booleanas usan los valores “Verdadero” o “Falso”, y son internamente<br />

representadas por los valores enteros “-1” y “0” respectivamente. Si asigna cualquier cosa a<br />

una variable booleana, y no puede ser precisamente evaluada como “-1”, entonces el valor<br />

“Falso” es guardado en la variable. Normalmente se usa de la siguiente manera:<br />

Dim b as Boolean<br />

b = True<br />

b = False<br />

b = (5 = 3) 'Set to False<br />

Print b 'Prints 0<br />

b = (5 < 7) 'Set to True<br />

Print b 'Prints -1<br />

b = 7 'Sets to False<br />

82


Variables enteras<br />

Las variables enteras son números de 16-bits dentro de un rango de -32768 a 32767. Asignar<br />

un valor desde un número de punto flotante causa que se trunquen los decimales. Poniendo<br />

después del nombre de la variable un caracter “%” causa que se defina como entero.<br />

Dim Age%<br />

Dim Dogs As Integer<br />

Variables Entero largo<br />

Las variables de entero largo son números de 32-bits en un rango de -2,147,483,648 a<br />

2,147,483,647. Asignar un valor desde un número de punto flotante causa que se trunquen<br />

los decimales. Poniendo después del nombre de la variable un caracter “&” causa que se<br />

defina como entero largo.<br />

Dim Age&<br />

Dim Dogs As Long<br />

Variables de moneda<br />

Las variables de moneda son números de 64-bits con cuatro decimales y cincuenta números<br />

no decimales. Su rango va desde -922,337,203,658,477.5808 a +922,337,203, 658,477.5807.<br />

Poniéndo después del nombre de la variable un caracter “@” causa que se defina como<br />

moneda.<br />

Dim Income@<br />

Dim Cost As Currency<br />

Variables de Sencillos<br />

Las variables de Sencillos son números de 32-bits. El número más grande es<br />

3.402823 x 10E38. El número más pequeño es 1.401298 x 10E-45. Poniendo después del<br />

nombre de la variable un caracter “!” causa que se defina como de Sencillo.<br />

Dim Weight!<br />

Dim Height As Single<br />

Variables de Dobles<br />

Las variables de Dobles Double son números de 64-bits. El valor más grande <strong>para</strong> una<br />

variable de dobles es 1.79769313486232 x 10E308. El número más pequeño <strong>para</strong> una<br />

variable de Dobles es 4.94065645841247 x 10E-324. Poniendo después del nombre de la<br />

variable un caracter “#” causa que se defina como de Doble.<br />

Dim Weight#<br />

Dim Height As Double<br />

Variables de Cadena<br />

Variables de Cadena usan un byte ASCII <strong>para</strong> cada caracter y están limitados a un tamaño de<br />

64Kbytes. Poniendo después del nombre de la variable el caracter “$” causa que se defina<br />

83


como de Cadena.<br />

Dim FirstName$<br />

Dim LastName As String<br />

8.2.5 Constantes<br />

<strong>OpenOffice</strong>.org Basic también conoce los valores “Verdadero”, “Falso”, y “PI”. Puede<br />

también definir sus propias constantes. Cada constante debe ser definida una vez, y sólo una<br />

vez. Las constantes no se les define un tipo, simplemente se insertan como son digitadas.<br />

Const Gravity = 9.81<br />

8.2.6 Areglos o matrices.<br />

Una matriz permite guardar diferentes valores en una sola variable. Por defecto, el primer<br />

item de la matriz está en la dirección 0. Usted puede, sin embargo, especificar los valores<br />

iniciales y finales. Aqui hay algunos ejemplos.<br />

Dim a(5) As Integer REM 6 elements from 0 to 5 inclusive<br />

Dim b$(5 to 10) As String REM 6 elements from 5 to 10 inclusive<br />

Dim c(-5 to 5) As String REM 11 elements from -5 to 5 inclusive<br />

Dim d(5 To 10, 20 To 25) As Long<br />

Option Base<br />

Usted puede cambiar el valor inicial de una matriz entre 1 y cero. Esto debe ser hecho antes<br />

de cualquier instrucción en el programa.<br />

Sintaxis: Option Base { 0 | 1 }<br />

LBound(NombreMatriz[,Dimensión])<br />

Regresa el item más bajo de un arreglo. El segundo parámetro es opcional, y es la dimensión<br />

de la matriz de la cual desea el item más bajo basado en 1 (no en cero).<br />

LBound(a()) REM 0<br />

LBound(b()) REM 5<br />

LBound(c()) REM -5<br />

LBound(d()) REM 5<br />

LBound(d(), 1) REM 5<br />

LBound(d(), 2) REM 20<br />

UBound(NombreMatriz[,Dimensión])<br />

Regresa el item más alto de un arreglo. El segundo parámetro es opcional, y es la dimensión<br />

de la matriz de la cual desea el item más alto basado en 1 (no en cero).<br />

LBound(a()) REM 5<br />

LBound(b()) REM 10<br />

LBound(c()) REM 5<br />

LBound(d()) REM 10<br />

LBound(d(), 1) REM 10<br />

84


LBound(d(), 2) REM 25<br />

Está esta matriz definida<br />

Si una matriz es una lista vacía, entonces el item más bajo será más grande que el item más<br />

alto.<br />

Listas de matrices y ReDim<br />

Una matriz de items variables es regresada con el uso del constructor Array. Este es el<br />

método más fácil de regresar una lista de valores.<br />

Dim a()<br />

a = Array(0, 1, 2)<br />

Para crear una matriz de dimensiones vacías, use el constructor DimArray. DimArray( 2, 2, 4<br />

) es lo mismo que DIM a( 2, 2, 4 ).<br />

Puede cambiar el tamaño de una matriz en tiempo de ejecución si lo desea.<br />

Dim e() As Integer REM I did not specify the size<br />

ReDim e(5) As Integer REM 0 to 5 is valid<br />

ReDim e(10) As Integer REM 0 to 10 is valid<br />

La palabra clave Preserve puede ser usada con la instrucción ReDim <strong>para</strong> preservar el<br />

contenido de la matriz cuando es redimensionada.<br />

Sub ReDimExample<br />

Dim a(5) As Integer<br />

Dim b()<br />

Dim c() As Integer<br />

a(0) = 0<br />

a(1) = 1<br />

a(2) = 2<br />

a(3) = 3<br />

a(4) = 4<br />

a(5) = 5<br />

Rem a is dimensioned from 0 to 5 where a(i) = i<br />

PrintArray("a at start", a())<br />

Rem a is dimensioned from 1 to 3 where a(i) = i<br />

ReDim Preserve a(1 To 3) As Integer<br />

PrintArray("a after ReDim", a())<br />

Rem Array() returns a variant type<br />

Rem b is dimensioned from 0 to 9 where b(i) = i-1<br />

b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)<br />

PrintArray("b at initial assignment", b())<br />

Rem b is dimensioned from 1 to 3 where b(i) = i-1<br />

ReDim Preserve b(1 To 3)<br />

PrintArray("b after ReDim", b())<br />

Rem The following is NOT valid because the array is already dimensioned<br />

Rem to a different size<br />

Rem a = Array(0, 1, 2, 3, 4, 5)<br />

Rem c is dimensioned from 0 to 5 where a(i) = i<br />

85


Rem If a "ReDim" had been done on c, then this would NOT work<br />

c = Array(0, 1, 2, 3, 4, 5)<br />

PrintArray("c, of type Integer after assignment", c())<br />

Rem Ironically, this allowed but c will contain no data!<br />

ReDim Preserve c(1 To 3) As Integer<br />

PrintArray("c after ReDim", c())<br />

End Sub<br />

Sub PrintArray (lead$, a() As Variant)<br />

Dim i%, s$<br />

s$ = lead$ + Chr(13) + LBound(a()) + " to " + UBound(a()) + ":" + Chr(13)<br />

For i% = LBound(a()) To UBound(a())<br />

s$ = s$ + a(i%) + " "<br />

Next<br />

MsgBox s$<br />

End Sub<br />

8.2.7 Probando objetos.<br />

Para determinar el tipo de variable, puede usar las funciones booleanas IsArray, IsDate,<br />

IsEmpty, IsMissing, IsNull, IsNumeric, IsObject, y IsUnoStruct. La función IsArray retorna<br />

un valor verdadero si el parámetro es una matriz. La función IsDate retorna un verdadero si<br />

es posible convertir el objeto en una fecha. Una cadena con un formato apropiado podrá<br />

retornar un valor verdadero desde la función IsDate. El método IsEmpty se usa <strong>para</strong> probar si<br />

un objeto del tipo variante ha sido inicializado. La función IsMissing indica si un parámetro<br />

opcional está perdido. El método IsNull prueba cuando una variable del tipo variante<br />

contiene el valor especial Null, indicándo que la variable no contiene datos. IsNumeric es<br />

usado <strong>para</strong> probar si una cadena contiene números. La función IsUnoStruct toma una cadena<br />

del nombre de una estructura uno y retorna verdadero o falso si está es un nombre válido.<br />

8.2.8 Condicionales<br />

Los condicionales generalmente trabajan como se esperan pero no hacen evaluaciones de<br />

cortos circuitos. Estos son los condicionales más comúnmente usados<br />

Símbolo Significado<br />

= Igual<br />

< Menor que<br />

> Mayor que<br />

= Mayor o igual que<br />

No igual a<br />

Is Son el mismo Objeto<br />

86


El operador And realiza operaciones lógicas en tipos boleanos y operaciones <strong>sobre</strong> bits en<br />

tipos numéricos. El operador OR realiza operaciones lógicas en tipos boleanos y operaciones<br />

<strong>sobre</strong> bits en tipos numéricos. El operador XOR realiza operaciones lógicas en tipos boleanos<br />

y operaciones <strong>sobre</strong> bits en tipos numéricos. Recuerde que es un “Exclusive OR” 7 . El<br />

operador NOT realiza operaciones lógicas en tipos boleanos y operaciones <strong>sobre</strong> bits en tipos<br />

numéricos. Una simple prueba muestra la precedencia standar que existe entre los roles, es<br />

decir que AND tiene más precedencia que los operadores OR.<br />

Option Explicit<br />

Sub ConditionTest<br />

Dim msg As String<br />

msg = "AND has "<br />

msg = msg & IIf(False OR True AND False, "equal", "greater")<br />

msg = msg & " precedence than OR" & Chr(13) & "OR does "<br />

msg = msg + IIF(True XOR True OR True, "", "not ")<br />

msg = msg + "have greater precedence than XOR" + Chr(13)<br />

msg = msg & "XOR does "<br />

msg = msg + IIF(True OR True XOR True, "", "not ")<br />

msg = msg + "have greater precedence than OR"<br />

MsgBox msg<br />

End Sub<br />

8.3 Funciones y SubProcedimientos<br />

Una función es un procedimiento Sub que puede retornar un valor. Esto permite que sea<br />

usado como parte de una expresión. Sub y Function inician como sigue:<br />

Sintaxis: Function NombreFunción [(Var1 [As Tipo][, Var2 [As Tipo][,...]]]) [As Tipo]<br />

Sintaxis: Sub NombreSub[(Var1 [As Tipo][, Var2 [As Tipo][,...]]])<br />

Las funciones declaran un valor de retorno porque ellas devuelven un valor. Para asignar el<br />

valor de retorno, use una instrucción de la siguiente forma “NombreFunción =<br />

valor_de_retorno”. Aunque puede realizar la asignación de esta instrucción muchas veces,<br />

solamente el último valor asignado será devuelto.<br />

Para dejar inmediatamente el procedimiento use una instrucción Exit.<br />

8.3.1 Parametros opcionales.<br />

Un parámetro puede ser declarado opcional usando la palabra clave Optional. El método<br />

IsMissing es usado <strong>para</strong> determinar si un parámetro ha sido pasado.<br />

Sub testOptionalParameters()<br />

Print TestOpt() Rem MMM<br />

Print TestOpt(,) Rem MMM<br />

Print TestOpt(,,) Rem MMM<br />

Print TestOpt(1) Rem 1MM<br />

Print TestOpt(1,) Rem 1MM<br />

7 N.T. O exclusivo.<br />

87


Print TestOpt(1,,) Rem 1MM<br />

Print TestOpt(1,2) Rem 12M<br />

Print TestOpt(1,2,) Rem 12M<br />

Print TestOpt(1,2,3) Rem 123<br />

Print TestOpt(1,,3) Rem 1M3<br />

Print TestOpt(,2,3) Rem M23<br />

Print TestOpt(,,3) Rem MM3<br />

Print TestOptI() Rem MMM<br />

Print TestOptI(,) Rem 488MM (Error)<br />

Print TestOptI(,,) Rem 488488M (Error)<br />

Print TestOptI(1) Rem 1MM<br />

Print TestOptI(1,) Rem 1MM<br />

Print TestOptI(1,,) Rem 1488M (Error)<br />

Print TestOptI(1,2) Rem 12M<br />

Print TestOptI(1,2,) Rem 12M<br />

Print TestOptI(1,2,3)Rem 123<br />

Print TestOptI(1,,3) Rem 14883 (Error)<br />

Print TestOptI(,2,3) Rem 48823 (Error)<br />

Print TestOptI(,,3) Rem 4884883 (Error)<br />

End Sub<br />

Function TestOpt(Optional v1 As Variant, Optional v2 As Variant, Optional v3 As Variant) As String<br />

Dim s As String<br />

s = "" & IIF(IsMissing(v1), "M", Str(v1))<br />

s = s & IIF(IsMissing(v2), "M", Str(v2))<br />

s = s & IIF(IsMissing(v3), "M", Str(v3))<br />

TestOpt = s<br />

End Function<br />

Function TestOptI(Optional i1 As Integer, Optional i2 As Integer, Optional i3 As Integer) As String<br />

Dim s As String<br />

s = "" & IIF(IsMissing(i1), "M", Str(i1))<br />

s = s & IIF(IsMissing(i2), "M", Str(i2))<br />

s = s & IIF(IsMissing(i3), "M", Str(i3))<br />

TestOptI = s<br />

End Function<br />

Advertencia En la versión 1.0.3.1, IsMissing fallará con Optional si el tipo no es<br />

Variant y el parámetro opcional perdido está representado por dos comas<br />

consecutivas. Primero investigué este comportamiento después de hablar<br />

con Christian Anderson [ca@ofs.no]. Esto es un issue 11678 en las<br />

issuezillas.<br />

8.3.2 Parámetros por referencia o valor.<br />

Si una variable es pasada por valor, puedo cambiar el parámetro en el procedimiento llamado<br />

y el valor original no cambiará. En cambio si es pasado por referencia, si cambio el<br />

parámetro también cambio el valor original. El comportamiento por defecto es pasar por<br />

referencia. Para pasar por valor, use la palabra clave ByVal antes de la declaración de los<br />

parámetros. Si el parámetro es una constante como “4” y lo modifica en el procedimiento<br />

este podrá o no realmente cambiarse. De acuerdo con Andreas Bregas (ab@openoffice.org)<br />

88


esto es un error por eso abrí un issue en issuezilla<br />

(http://www.openoffice.org/project/www/issues/show_bug.cgi?id=12272).<br />

Option Explicit<br />

Sub LoopForever<br />

Dim l As Long<br />

l = 4<br />

LoopWorker(l)<br />

Print "Passed l by value and it is still " + l<br />

LoopForeverWorker(l)<br />

' l is now 1 so this will print 1.<br />

Print "Passed l by reference and it now is " + l<br />

' This will loop forever because 4 is a constant<br />

' and you can NOT change it.<br />

Print "Passing a constant <strong>para</strong>meter by reference, this will be fun"<br />

Print LoopForeverWorker(4)<br />

End Sub<br />

Sub LoopWorker(ByVal n As Long)<br />

Do While n > 1<br />

Print n<br />

n = n - 1<br />

Loop<br />

End Sub<br />

Sub LoopForeverWorker(n As Long)<br />

Do While n > 1<br />

' This is fun when n is a constant.<br />

Print n<br />

n = n - 1<br />

Loop<br />

End Sub<br />

8.3.3 Recursividad<br />

Sus funciones no pueden ser recursivas. Cuando digo no pueden, realmente quiero decir que<br />

no puede porque no obtendrá los resultados que espera.<br />

Option Explicit<br />

Sub DoFact<br />

Print "Recursive = " + RecursiveFactorial(4)<br />

Print "Normal Factorial = " + Factorial(4)<br />

End Sub<br />

Function Factorial(n As Long) As Long<br />

Dim answer As Long<br />

Dim i As Long<br />

i = n<br />

answer = 1<br />

Do While i > 1<br />

answer = answer * i<br />

89


i = i - 1<br />

Loop<br />

Factorial = answer<br />

End Function<br />

' This will fail because you can not use recursion<br />

Function RecursiveFactorial(n As Long) As Long<br />

If n > 2 Then<br />

RecursiveFactorial = n * RecursiveFactorial(n-1)<br />

Else<br />

RecursiveFactorial = 1<br />

End If<br />

End Function<br />

8.4 Control de flujo<br />

8.4.1 If ... Then ... Else<br />

El constructor If es usado <strong>para</strong> ejecutar un bloque de código basado en una expresión.<br />

Mientras puede usar GoTo o GoSub <strong>para</strong> saltar fuera de un bloque If, no podrá saltar dentro<br />

de un bloque If.<br />

Sintaxis: If condición Then Bloque [ElseIf condición Then] Bloque [Else] Bloque End<br />

If<br />

If x < 0 Then<br />

MsgBox "The number is negative"<br />

ElseIf x > 0 Then<br />

MsgBox "The number is positive"<br />

Else<br />

MsgBox "The number is zero"<br />

End If<br />

8.4.2 IIF<br />

El constructor IIF es usada <strong>para</strong> devolver una expresión basados en una condición. Es similar<br />

a la sintaxis de “?” en C 8 .<br />

Sintaxis: IIf (Condición, Expresión_si_verdadero, Expresión_si_falso)<br />

Es muy similar al siguiente código.<br />

If (Condition) Then<br />

object = TrueExpression<br />

Else<br />

object = FalseExpression<br />

End If<br />

max_age = IIf(johns_age > bills_age, johns_age, bills_age)<br />

8 N.T. En Visual Fox también existe esta misma función son una sintaxis igual.<br />

90


8.4.3 Choose<br />

La instrucción choose permite seleccionar desde una lista de valores basados en un índice.<br />

Sintaxis: Choose (índice, Selección1[, Selección2, ... [,Selección_n]])<br />

Si el índice es 1, entonces el primer item es regresado. Si el índice es 2, entonces el segundo<br />

item es retornado. Se podrá imaginar el resto!<br />

8.4.4 For....Next<br />

Esto repetirá un bloque de instrucciones un número específico de veces.<br />

Sintaxis:<br />

For contador=inicio To final [Step paso]<br />

bloque de instrucciones<br />

[Exit For]<br />

bloque de instrucciones<br />

Next [contador]<br />

El numérico “contador” es inicialmente asignado al valor “inicio”. El valor de “paso” no es<br />

dado, entonces el contador es incrementado en uno hasta que pase el valor “final”. El bloque<br />

de instrucciones es ejecutado una vez por cada incremento.<br />

El “contador” es opcional en la instrucción “Next”, Y automáticamente se refiere a la más<br />

reciente instrucción “For”.<br />

Puede dejar prematuramente una instrucción For al usar la instrucción Exit For. Esto hará<br />

que salga de la instrucción “For” más reciente.<br />

Ejemplo:<br />

El siguiente ejemplo usa dos ciclos anidados <strong>para</strong> ordenar un arreglo de cadena con diez<br />

elementos ( sEntry() ), el cual es primero llenado con varios contenidos:<br />

Sub ForNextExampleSort<br />

Dim iEntry(10) As Integer<br />

Dim iCount As Integer, iCount2 As Integer, iTemp As Integer<br />

Dim bSomethingChanged As Boolean<br />

' Fill the array with the integers between -10 and 10<br />

For iCount = LBound(iEntry()) To Ubound(iEntry())<br />

iEntry(iCount) = Int((20 * Rnd) -10)<br />

Next iCount<br />

' Sort the array<br />

For iCount = LBound(iEntry()) To Ubound(iEntry())<br />

'Assume that the array is sorted<br />

bSomethingChanged = False<br />

For iCount2 = iCount + 1 To Ubound(iEntry())<br />

If iEntry(iCount) > iEntry(iCount2) Then<br />

iTemp = iEntry(iCount)<br />

91


iEntry(iCount) = iEntry(iCount2)<br />

iEntry(iCount2) = iTemp<br />

bSomethingChanged = True<br />

End If<br />

Next iCount2<br />

'If the array is already sorted then stop looping!<br />

If Not bSomethingChanged Then Exit For<br />

Next iCount<br />

For iCount = 1 To 10<br />

Print iEntry(iCount)<br />

Next iCount<br />

End Sub<br />

8.4.5 Do ... Loop<br />

El constructor Loop tiene algunas diferentes formas y es usado <strong>para</strong> continuar ejecutando un<br />

bloque de código mientras una condición sea verdadera. La forma más común verifica la<br />

condición antes de que inicie el ciclo y hasta que la condición sea verdadera ejecutará<br />

repetidamente el bloque de código. Si la condición es falsa, entonces el ciclo nunca será<br />

ejecutado.<br />

Do While condition<br />

Block<br />

Loop<br />

Una forma similar, pero menos común verifica la condición antes que el ciclo inicie y<br />

mientras la condición sea falsa ejecutará repetidamente el bloque de código. Si la condición<br />

se evalue en verdadero inmediatamente, entonces el cilco nunca se ejecutará.<br />

Do Until condition<br />

Block<br />

Loop<br />

Puede también poner la verificación al final del ciclo en cuyo caso el bloque de código se<br />

ejecutará al menos una vez. Para siempre ejecutar el ciclo al menos una vez y luego continuar<br />

si la condición es verdadera, use la siguiente construcción:<br />

Do<br />

Block<br />

Loop While condition<br />

Para ejecutar el ciclo al menos una vez y luego continuar mientras la condición sea falsa, use<br />

la siguiente construcción:<br />

Do<br />

Block<br />

Loop Until condition<br />

En un “Do Loop”, puede forzar a salir inmediatamente del ciclo con la instrucción “Exit Do”.<br />

8.4.6 Select ... Case<br />

La instrucción Select Case es similar al “case” y “switch” de otros lenguajes. Esto imita<br />

92


multiples bloques de “Else If” en una instrucción “If”. Una sola expresión de condición es<br />

especificada y com<strong>para</strong>da contra múltiples valores <strong>para</strong> verificar como sigue:<br />

Select Case expresión_de_condición<br />

Case caso_expresión1<br />

Bloque_de_instrucciones1<br />

Case caso_expresión2<br />

Bloque_de_instrucciones1<br />

Case Else<br />

Bloque_de_instrucciones1<br />

End Select<br />

La expresión_de_condición es la expresión que será com<strong>para</strong>da en cada instrucción Case. No<br />

extoy enterado acerca de algún tipo de limitación de tipos de datos más que los que sea<br />

compatible con los tipos de expresión. El primer bloque de instrucciones en cumplir la<br />

condición será ejecutado. Si ninguna condición se cumple, entonces el opcional Case Else se<br />

ejecutará.<br />

8.4.7 Expresiones Case<br />

Una expresión case es usualmente una constante de código como “Case 4” o Case “"Case<br />

hello"”. Múltiples valores pueden ser epecificados al se<strong>para</strong>rlos con comas: “Case 3, 5, 7”. Si<br />

desea verificar un rango de valores, hay una palabra clave “To” “Case 5 To 10”. Rangos sin<br />

valor inicial pueden ser verificados como “Case < 10” o con la palabra clave “Is” “Case Is <<br />

10”.<br />

La ayuda en línea incluye un ejemplo que tiene un error. Muestra como verificar un rango de<br />

números como “Case i > 2 And i < 10”. Lo que realmente evalúa es “i > 2 AND i < 10”, lo<br />

cual es boleano, y entonces lo com<strong>para</strong> con el parámetro seleccionado (presuntamente “i” en<br />

este ejemplo). Es como decir que “i (i>2 AND i 2 And i% < 10, %i, %i+1)”.<br />

Select Case i%<br />

'Correct method because it returns %i when it is true<br />

'and %i = %i. It returns %i+1 when it is false and<br />

'%i+1 %i<br />

Case IIf(i% > 2 And i% < 10, %i, %i+1)<br />

'WRONG because %i (i% > 2 And i% < 10)<br />

Case i% > 2 And i% < 10<br />

'Even better yet because these are integers<br />

Case 2 To 10<br />

Todavía se puede ver natural escribir algo como “Case Is > 2 AND i < 10”, y lo que<br />

realmente quiere decir es “Case Is > (2 AND i < 10)” lo cual definitivamente no es lo que se<br />

desea.<br />

Sub DemoSelectCase<br />

Dim i%<br />

i% = Int((15 * Rnd) -2)<br />

Select Case i%<br />

Case 1 To 5<br />

Print "Number from 1 to 5"<br />

93


Case 6, 7, 8<br />

Print "Number from 6 to 8"<br />

Case IIf(i% > 8 And i% < 11, %i, %i+1)<br />

Print "Greater than 8"<br />

Case Else<br />

Print "Out of range 1 to 10"<br />

End Select<br />

End Sub<br />

8.4.8 While...Wend<br />

No hay nada de especial en el constructor While...Wend, tiene la siguiente forma:<br />

While Condition<br />

Código<br />

Wend<br />

Tip Este constructor tiene limitaciones que no existen en el constructor Do<br />

While...Loop y no ofrece beneficios particulares. No puede usar el<br />

constructor Exit, o puede salir con un GoTo.<br />

8.4.9 GoSub<br />

La instrucción GoSub causa que la ejecución salte a una etiqueta de subrutina definida en la<br />

actual subrutina. No puede saltar fuera de la actual subrutina. Cuando se encuentra la<br />

instrucción Return, la ejecución continuará desde le punto de donde fue originalmente<br />

llamada. Si una instrucción Return es encontrada y no se hizo un previo GoSub, ocurre un<br />

error. En otras palabras, Return no es un substituto de un Exit Sub o Exit Function. Es<br />

generalmente aceptado que el uso de funciones y subrutinas produce un código más<br />

inteligible que el que el uso de GoSub y GoTo.<br />

Option Explicit<br />

Sub GoSubExample<br />

Dim i As Integer<br />

GoSub Line2<br />

GoSub Line1<br />

MsgBox "i = " + i, 0, "GoSub Example"<br />

Exit Sub<br />

Line1:<br />

i = i + 1<br />

Return<br />

Line2:<br />

i = 1<br />

Return<br />

End Sub<br />

Tip GoSub y Return son remanentes persistentes de dialectos viejos de<br />

BASIC, retenidos solamente por razones de compatibilidad. Su uso no es<br />

recomendable porque tiende a producir código ilegible. Subs o Functions<br />

son preferibles.<br />

94


8.4.10 GoTo<br />

La instrucción GoTo causa que la ejecución salte a una etiqueta definida en la actual<br />

subrutina. No puede saltar fuera de la actual subrutina. La instrucción GoTo es generalmente<br />

considerada que produce código pobremente escrito porque hace más dificil seguir la lógica 9 .<br />

No recomiendo su uso en general.<br />

Option Explicit<br />

Sub GoToExample<br />

Dim i As Integer<br />

GoTo Line2<br />

Line1:<br />

i = i + 1<br />

GoTo TheEnd<br />

Line2:<br />

i = 1<br />

GoTo Line1<br />

TheEnd:<br />

MsgBox "i = " + i, 0, "GoTo Example"<br />

End Sub<br />

8.4.11 On GoTo<br />

Sintaxis: On N GoSub Etiqueta1[, Etiqueta2[, Etiqueta3[,...]]]<br />

Sintaxis: On N GoTo Etiqueta1[, Etiqueta2[, Etiqueta3[,...]]]<br />

Esto causa que la ejecución se bifurque a una etiqueta basados en una expresión numérica N.<br />

If (N=0) then no ocurre bifurcación. La expresión numérica N debe estar dentro del rango de<br />

0 y 255. Esto es similar a las instrucciones “computed goto,” “case,” y “switch,” de otros<br />

lenguajes. No trate de saltar fuera de la actual subrutina o función.<br />

Option Explicit<br />

Sub OnGoToExample<br />

Dim i As Integer<br />

Dim s As String<br />

i = 1<br />

On i+1 GoSub Sub1, Sub2<br />

s = s & Chr(13)<br />

On i GoTo Line1, Line2<br />

REM The exit causes us to exit if we do not continue execution<br />

Exit Sub<br />

Sub1:<br />

s = s & "In Sub 1" : Return<br />

Sub2:<br />

s = s & "In Sub 2" : Return<br />

Line1:<br />

s = s & "At Label 1" : GoTo TheEnd<br />

Line2:<br />

9 N.T. Se <strong>sobre</strong>entiende que la lógica del código.<br />

95


s = s & "At Label 2"<br />

TheEnd:<br />

MsgBox s, 0, "On GoTo Example"<br />

End Sub<br />

8.4.12 Exit<br />

La instrucción Exit es usada <strong>para</strong> salir de un Do Loop, For Next, Function, o un Sub. Tratar<br />

de salir (exit) desde alguna parte del código no causará error. Las fomas son las siguientes:<br />

• Exit DO Continua la instrucción siguiente al Loop.<br />

• Exit For Continua la instrucción siguiente al Next.<br />

• Exit Function Inmediatamente saldrá de la función actual.<br />

• Exit Sub Inmediatamente saldrá de la subrutina actual.<br />

Option Explicit<br />

Sub ExitExample<br />

Dim a%(100)<br />

Dim i%<br />

REM Fill the array with 100, 99, 98, ..., 0<br />

For i = LBound(a()) To UBound(a())<br />

a(i) = 100 - i<br />

Next i<br />

Print SearchIntegerArray(a(), 0 )<br />

Print SearchIntegerArray(a(), 10 )<br />

Print SearchIntegerArray(a(), 100)<br />

Print SearchIntegerArray(a(), 200)<br />

End Sub<br />

Function SearchIntegerArray( list(), num%) As Integer<br />

Dim i As Integer<br />

SearchIntegerArray = -1<br />

For i = LBound(list) To UBound(list)<br />

If list(i) = num Then<br />

SearchIntegerArray = i<br />

Exit For<br />

End If<br />

Next i<br />

End Function<br />

8.4.13Manejo de errores<br />

Para atrapar los errores en las <strong>macros</strong>, use la instrucción “On Error”.<br />

On [Local] {Error GoTo Etiqueta | GoTo 0 | Resume Next}<br />

La foma “On Error GoTo Label”, causa que la macro salte a la etiqueta especificada si ocurre<br />

un error. Si la forma “On Error Resume Next” está activada y ocurre un error, la ejecución<br />

continua en la línea siguiente a la que causó el error. Considero que es una instrucción<br />

“ignore el error”. La instrucción “On Error” está deshabilitada por medio de el uso de la<br />

forma “On Error GoTo 0”.<br />

96


Una instrucción que inicie con “On Error” es válida <strong>para</strong> el módulo entero. Si se usa “Local”,<br />

entonces esto define que el manejo de errores es local al contenido de la subrutina o función.<br />

Si no se usa “Local” el manejo de errores afecta el módulo entero.<br />

8.5 Misceláneos<br />

Esta sección contiene pequeñeces y piezas que yo solo sé porque las he visto en ejemplos<br />

pero no he encontrado ejemplos <strong>para</strong> aplicar.<br />

*********<br />

Muchas instrucciones pueden existir en la misma línea si están se<strong>para</strong>das por dos puntos “:” .<br />

*********<br />

Para una línea sencilla de instrucciones, la construcción If Then no requiere que se cierre con<br />

End If.<br />

Sub SimpleIf<br />

If 4 = 4 Then Print "4 = 4" : Print " Hello you"Rem This prints<br />

If 3 = 2 Then Print "3 = 2" Rem This does not<br />

End Sub<br />

*********<br />

Librerias, dialogos, IDE, importar y exportar <strong>macros</strong>.<br />

With objeto ... End With<br />

*********<br />

Cómo iniciarlo desde la línea de comandos?<br />

El parámetro <strong>para</strong> llamar <strong>macros</strong> se lee así:<br />

soffice.exe macro:/Librería módulo macro<br />

Ejemplo:<br />

soffice.exe macro:///standard.module1.macro1<br />

Pero note! Si la macro no hace o no abre nada dentro del documento, la macro se implementa<br />

y cierra StarOffice de nuevo.<br />

*********<br />

Copiar un objeto simplemente copiará la referencia. Copiar una estructura hará una nueva<br />

copia. Ver EqualUnoObjects <strong>para</strong> un ejemplo.<br />

*********<br />

Los nombres con espacios pueden ser un problema. Puede manejarse de dos maneras<br />

Sub ExampleShell<br />

Shell("file:///C|/Andy/My%20Documents/oo/tmp/h.bat",2)<br />

Shell("C:\Andy\My%20Documents\oo\tmp\h.bat",2)<br />

End Sub<br />

97


******<br />

Poner el fondo de página<br />

Sub Main<br />

' First get the Style Families<br />

oStyleFamilies= ThisComponent.getStyleFamilies()<br />

' then get the PageStyles<br />

oPageStyles= oStyleFamilies.getByName("PageStyles")<br />

' then get YOUR page's style<br />

oMyPageStyle= oPageStyles.getByName("Standard")<br />

' then set your background<br />

with oMyPageStyle<br />

.BackGraphicUrl= _<br />

convertToUrl( )<br />

.BackGraphicLocation= _<br />

com.sun.star.style.GraphicLocation.AREA<br />

end with<br />

End Sub<br />

*******<br />

Todo el código <strong>para</strong> “Events” está mostrado en la ayuda.<br />

******<br />

La forma usual de cerrar OOo completamente es llamar el método terminate() en el objeto<br />

desktop. Esto se ejecutará si no hay abierta una ventana de documentos o una ventana no<br />

cerrable y no está registrado el visor de terminación que objeta contra las llamadas a<br />

teminaciones (tal y como lo hace el quickstarter).<br />

La interface "XCloseable" se refiere a cerrar documentos sencillos o marcos, y sólo trabaja<br />

en OOo 1.1, no en Ooo1.0, por eso deberá preguntar esto si desea escribir código que corra<br />

en OOo1.0 y OOo1.1 (Como se describe en la guía del desarrollador).<br />

Buena suerte,<br />

Mathias Bauer<br />

*******<br />

98


9 Operadores y precedencia<br />

<strong>OpenOffice</strong>.org Basic soporta los operadores numéricos básicos. -, +, /, *, y ^. Los<br />

operadores usan el orden de precedencia standard, pero de todos modos los indicaremos aqui.<br />

Los operadores lógicos devuelven 0 <strong>para</strong> falso (ningún bit activado) y -1 <strong>para</strong> verdadero<br />

(todos los bits activados). Para una descripción completa, vea la sección que lista los<br />

operadores y funciones.<br />

Precedence Operator Description<br />

0 AND Opera bits en numéricos y boleanos lógicos<br />

0 OR Opera bits en numéricos y boleanos lógicos<br />

0 XOR Opera bits en numéricos y boleanos lógicos<br />

0 EQV Equvalencia lógica o en bits<br />

1 = Lógico<br />

1 < Lógico<br />

1 > Lógico<br />

1 = Lógico<br />

1 Lógico<br />

2 - Resta numérica<br />

2<br />

+ Suma numérica y concatenación de<br />

caracteres.<br />

2 & Concatenación de caracteres<br />

3 * Multiplicación numérica<br />

3 / División numérica<br />

3 MOD Residuo numérico después de la división<br />

4 ^ Exponenciación numérica<br />

5 Is (operator) ??No verificado, ver “Select Case”<br />

Sub TestPrecedence<br />

Dim i%<br />

Print 1 + 2 OR 1 REM Prints 3<br />

Print 1 + (2 OR 1) REM Prints 4<br />

Print 1 + 2 AND 1 REM Prints 1<br />

Print 1 + 2 * 3 REM Prints 7<br />

Print 1 + 2 * 3 ^2 REM Prints 19<br />

Print 1 = 2 OR 4 REM Prints 4<br />

Print 4 AND 1 = 1 REM Prints 4<br />

End Sub<br />

99


Advertencia Los valores boleanos son guardados internamente como enteros donde<br />

falso = 0 y verdadero = -1. Esto permite usar operaciones numéricas con<br />

los valores boleanos pero cuidado esto (1 + Verdadero = Falso). Mejor<br />

use operadores boleanos.<br />

100


10 Operadores, Instrucciones y Funciones.<br />

10.1 Operador -<br />

Resumen:<br />

Resta dos valores numéricos. La precedencia matemática se explica en la página 99.<br />

Sintaxis:<br />

Resultado = Expresión1 - Expresión2<br />

Parámetros:<br />

Resultado : Resultado de la resta.<br />

Expresión1, Expresión2 : Cualquier expresión numérica.<br />

Ejemplo:<br />

Sub SubtractionExample<br />

Print 4 – 3 '1<br />

Print 1.23e2 – 23 '100<br />

End Sub<br />

10.2 Operador *<br />

Sumario:<br />

Multiplica dos valores numéricos. La precedencia matemática se explica en la página 99.<br />

Sintaxis:<br />

Resultado = Expresión1 * Expresión2<br />

Parámetros:<br />

Resultado: Resultado de la multiplicación.<br />

Expresión1, Expresión2 : Cualquier expresión numérica.<br />

Ejemplo:<br />

Sub MultiplictionExample<br />

Print 4 * 3 '12<br />

Print 1.23e2 * 23 '2829<br />

End Sub<br />

10.3 Operador +<br />

Sumario:<br />

Suma dos valores numéricos. Sin embargo trabaja con valores boleanos porque son<br />

representados como enteros pero no recomiendo su uso. Experimentalmente, imita el<br />

resultado del operador OR pero no recomiendo su uso, porque la conversión puede tener<br />

algunos problemas. Las operaciones son hechas en el dominio de los enteros y vueltos a<br />

convertir a boleanos. Esto puede acarrear problemas. La precedencia matemática se explica<br />

en la página 99.<br />

Sintaxis:<br />

Resultado = Expresión1 + Expresión2<br />

101


Parámetros:<br />

Resultado: Resultado de la suma<br />

Expresión1, Expresión2 : Cualquier expresión numérica.<br />

Ejemplo:<br />

Sub SubtractionExample<br />

Print 4 – 3 '1<br />

Print 1.23e2 – 23 '100<br />

End Sub<br />

10.4 Operador ^<br />

Sumario:<br />

Eleva un numéro a una potencia. En la equación x=y z<br />

representa el operador. Si z es un<br />

entero, entonces x es el resultado de multiplicar y por el mismo z veces. La precedencia<br />

matemática se explica en la página 99.<br />

Sintaxis:<br />

Resultado = Expresión ^ Exponente<br />

Parámetros:<br />

Resultado : Resultado de la exponenciación<br />

Expresión: Cualquier expresión numérica<br />

Exponent: Cualquier expresión numérica<br />

Ejemplo:<br />

Sub ExponentiationExample<br />

Print 2 ^ 3 '8<br />

Print 2.2 ^ 2 '4.84<br />

Print 4 ^ 0.5 '2<br />

End Sub<br />

10.5 Operador /<br />

Sumario:<br />

Divide dos valores numéricos. Tenga cuidado porque una división puede que no produzca un<br />

entero cuando usted esté esperando uno. Es <strong>importante</strong> el uso de la función Int(). La<br />

precedencia matemática se explica en la página 99.<br />

Sintaxis:<br />

Resultado = Expresión1 / Expresión2<br />

Paramétros:<br />

Resultado : Resultado de la división<br />

Expresión1, Expresión2 : Cualquier expresión numérica<br />

Ejemplo:<br />

Sub DivisionExample<br />

102


Print 4 /2 '2<br />

Print 11/2 '5.5<br />

End Sub<br />

10.6 Operador AND<br />

Sumario:<br />

Realiza AND lógicos en valores boleanos y operación de bits AND en valores numéricos.<br />

Una operación de bits AND en un número doble, aparentemente causa una conversión en un<br />

tipo entero. Es posible un desbordamiento numérico. La precedencia matemática se explica<br />

en la página 99 y la tabla de operaciones es mostrada abajo.<br />

x y x AND y<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO FALSO FALSO<br />

FALSO<br />

VERDAD<br />

ERO FALSO<br />

FALSO FALSO FALSO<br />

1 1 1<br />

1 0 0<br />

0 1 0<br />

0 0 0<br />

Sintaxis:<br />

Resultado = Expresión1 AND Expresión2<br />

Parámetros:<br />

Resultado: Resultado de la operación.<br />

Expresión1, Expresión2 : expresiones numéricas o boleanas<br />

Ejemplo:<br />

Sub AndExample<br />

Print (3 And 1) 'Prints 1<br />

Print (True And True) 'Prints -1<br />

Print (True And False) 'Prints 0<br />

End Sub<br />

10.7 Función Abs<br />

Sumario:<br />

Retorna el valor absoluto de una expresión numérica. Si el parámetro es una cadena, primero<br />

103


es convertida a número, probablemente usando la función Val. Si el número no es negativo,<br />

entonces, es retornado, en otro caso, el negativo del número es retornado.<br />

Sintaxis:<br />

Abs (Número)<br />

Valor de retorno:<br />

Doble<br />

Parámetro:<br />

Número: Cualquier expresión numérica.<br />

Ejemplo:<br />

Sub AbsExample<br />

Print Abs(3) '3<br />

Print Abs(-4) '4<br />

Print Abs("-123") '123<br />

End Sub<br />

10.8 Función Array<br />

Sumario:<br />

Crea una matriz de una lista de parámetros. Es el método más rápido <strong>para</strong> crear una matriz de<br />

constantes.<br />

Advertencia Si asigna el valor de una matriz Variant a una matriz no-Variant, no<br />

podrá preservar los datos si redimensiona el arreglo. Lo considero un<br />

error que pueda asignar matrices Variantes a matrices no-Variantes.<br />

Ver también la función DimArray.<br />

Sintaxis:<br />

Array ( lista de argumentos)<br />

Valor de retorno:<br />

Arreglo Variant conteniendo la lista de argumentos.<br />

Parámetros:<br />

Lista de argumentos: Lista de valores se<strong>para</strong>dos por comas desde las cuales es creada la lista.<br />

Ejemplo:<br />

Sub ArrayExample<br />

Dim a(5) As Integer<br />

Dim b() As Variant<br />

Dim c() As Integer<br />

Rem Array() returns a variant type<br />

Rem b is dimensioned from 0 to 9 where b(i) = i-1<br />

b = Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)<br />

PrintArray("b at initial assignment", b())<br />

Rem b is dimensioned from 1 to 3 where b(i) = i-1<br />

ReDim Preserve b(1 To 3)<br />

104


PrintArray("b after ReDim", b())<br />

Rem The following is NOT valid because the array is already dimensioned<br />

Rem to a different size, but you can ReDim it, go figure!<br />

Rem a = Array(0, 1, 2, 3, 4, 5)<br />

Rem c is dimensioned from 0 to 5.<br />

Rem This concerns me because "Hello" is a String value, but<br />

Rem it is allowed as of 1.0.2<br />

c = Array(0, 1, 2, "Hello", 4, 5)<br />

PrintArray("c, Variant assigned to an Integer array", c())<br />

Rem Ironically, this allowed but c will contain no data!<br />

ReDim Preserve c(1 To 3) As Integer<br />

PrintArray("c after ReDim", c())<br />

End Sub<br />

Sub PrintArray (lead$, a() As Variant)<br />

Dim i%, s$<br />

s$ = lead$ + Chr(13) + LBound(a()) + " to " + UBound(a()) + ":" + Chr(13)<br />

For i% = LBound(a()) To UBound(a())<br />

s$ = s$ + a(i%) + " "<br />

Next<br />

Rem I MsgBox rather than Print because I have an embeded Chr(13)<br />

MsgBox s$<br />

End Sub<br />

10.9 Función Asc<br />

Sumario:<br />

Retorna el valor ASCII (American Standard Code for Information Interchange) del primer<br />

caracter de la cadena, el resto es ignorado. Un error en tiempo de ejecución es reportado si la<br />

cadena tiene un tamaño de cero. Caracteres 16 bit unicode son permitidos. Esta es<br />

esencialmente inversa a la función Chr$.<br />

Sintaxis:<br />

Asc (Texto como cadena)<br />

Valor de retorno:<br />

entero<br />

Parámetro:<br />

Texto: Cualquier expresión caracter válida.<br />

Ejemplo:<br />

Sub AscExample<br />

Print Asc("ABC") '65<br />

End Sub<br />

10.10 Función ATN<br />

Sumario:<br />

105


Devuelve el Arcotangente de una expresión numérica dentro del rango -?/2 to ?/2 (radianes).<br />

Esta es inversa a la función de la tangente (Tan). Para los que no saben mucho de<br />

matemática, esta función es trigonométrica.<br />

Sintaxis:<br />

ATN(número)<br />

Valor de retorno:<br />

Doble<br />

Parametros:<br />

Número: cualquier expresión numérica<br />

Ejemplo:<br />

Sub ExampleATN<br />

Dim dLeg1 As Double, dLeg2 As Double<br />

dLeg1 = InputBox("Enter the length of the adjacent leg: ","Adjacent")<br />

dLeg2 = InputBox("Enter the length of the opposite leg: ","Opposite")<br />

MsgBox "The Angle is " + Format(ATN(dLeg2/dLeg1), "##0.0000") _<br />

+ " radians" + Chr(13) + "The Angle is " _<br />

+ Format(ATN(dLeg2/dLeg1) * 180 / Pi, "##0.0000") + " degrees"<br />

End Sub<br />

10.11 Instrucción Beep<br />

Sumario:<br />

Genera un beep del sistema (sonido)<br />

Sintaxis:<br />

Beep<br />

Ejemplo:<br />

Sub ExampleBeep<br />

Beep<br />

Beep<br />

End Sub<br />

10.12 Función Blue<br />

Sumario:<br />

Los colores son representados por enteros largos. Devuelve el componente azul de un código<br />

de colores específico. Ver también RGB, Red, y Green.<br />

Sintaxis:<br />

Blue (Color como entero largo)<br />

Valor de retorno:<br />

Entero en el rango de 0 a 255.<br />

Parámetros:<br />

106


Valor del color: es una expresión de entero largo que representa un color.<br />

Ejemplo:<br />

Sub ExampleColor<br />

Dim lColor As Long<br />

lColor = RGB(255,10,128)<br />

MsgBox "The color " & lColor & " consists of:" & Chr(13) &_<br />

"Red = " & Red(lColor) & Chr(13)&_<br />

"Green= " & Green(lColor) & Chr(13)&_<br />

"Blue= " & Blue(lColor) & Chr(13) , 64,"Colors"<br />

End Sub<br />

10.13 Palabra clave ByVal<br />

Sumario:<br />

Los parámetros de las funciones y subrutinas definidas por el usuario son pasados por<br />

referencia. Si la subrutina o la función modifica el parámetro, también es modificado en el<br />

programa que lo llamó. Esto puede causar resultados extraños si el parámetro de llamada es<br />

una constante o si el que está llamando no lo está esperando. La palabra clave ByVal<br />

especifica que el parámetro debe ser pasado por valor y no por referencia.<br />

Sintaxis:<br />

Sub Nombre(ByVal Parámetro As TipoParámetro)<br />

Ejemplo:<br />

Sub ExampleByVal<br />

Dim j As Integer<br />

j = 10<br />

ModifyParam(j)<br />

Print j Rem 9<br />

DoNotModifyParam(j)<br />

Print j Rem 9<br />

End Sub<br />

Sub ModifyParam(i As Integer)<br />

i = i - 1<br />

End Sub<br />

Sub DoNotModifyParam(ByVal i As Integer)<br />

i = i - 1<br />

End Sub<br />

10.14 Palabra clave Call<br />

Sumario:<br />

Transfiere el control del programa a una subrutina, una función o un procedimiento de un<br />

DLL. La palabra Call es opcional a menos que llame un DLL en cuyo caso este debe ser<br />

definido de primero. Los parámetros pueden estar encerrados en paréntesis y deben ser<br />

encerrados en paréntesis si una función es ejecutada como una expresión.<br />

Sintaxis:<br />

107


[Call] Nombre [Parámetros]<br />

Parámetros:<br />

Nombre: Nombre de la subrutina, función o DLL a llamar.<br />

Parámetros: El tipo y número de parámetros depende de la rutina que se está llamando.<br />

Ejemplo:<br />

Sub ExampleCall<br />

Call CallMe "This text will be displayed"<br />

End Sub<br />

Sub CallMe(s As String)<br />

Print s<br />

End Sub<br />

10.15 Función CBool<br />

Sumario:<br />

Convierte el parámetro a boleano. Si la expresión es un número, 0 será falso y cualquier otro<br />

número será verdadero. Si la expresión evalúa una cadena, entonces “true” y “false” (sensible<br />

a mayúsculas) se convierten a Verdadero y Falso respectivamente. Cadenas con cualquier<br />

otro valor genera un error en tiempo de ejecución. Esto es útil <strong>para</strong> forzar a que el resultado<br />

sea boleano. Si llamo una función y retorna un número, como en InStr, puedo escribir “If<br />

CBool(InStr(s1, s2)) Then” en lugar de “If InStr(s1, s2) 0 Then”.<br />

Sintaxis:<br />

CBool (Expresión)<br />

Valor de retorno:<br />

Booleano<br />

Parámetros:<br />

Expresión: Numérico, Booleano,<br />

Ejemplo:<br />

Sub ExampleCBool<br />

Print CBool(1.334e-2) 'True<br />

Print CBool("TRUE") 'True<br />

Print CBool(-10 + 2*5) 'False<br />

Print CBool("John" "Fred") 'True<br />

End Sub<br />

10.16 Función CByte<br />

Sumario:<br />

Convierte una expresión de cadena o numérica en el tipo Byte. Las expresiones de cadena<br />

son convertidas a números y los dobles son redondeados. Si la expresión es muy larga o<br />

negativa, se genera un error.<br />

Sintaxis:<br />

108


Cbyte(expresión)<br />

Valor de retorno:<br />

Byte<br />

Parámetros:<br />

Expresión : Una expresión de cadena o numérica.<br />

Ejemplo:<br />

Sub ExampleCByte<br />

Print Int(CByte(133)) '133<br />

Print Int(CByte("AB")) '0<br />

'Print Int(CByte(-11 + 2*5)) 'Error, out of range<br />

Print Int(CByte(1.445532e2)) '145<br />

Print CByte(64.9) 'A<br />

Print CByte(65) 'A<br />

Print Int(CByte("12")) '12<br />

End Sub<br />

10.17 Función CDate<br />

Sumario:<br />

Convierte a fecha. Las expresiones numéricas conteniendo fechas, empezando desde el 31 de<br />

diciembre de 1899 a la izquierda del decimal y la hora a la derecha del decimal. Las<br />

expresiones de cadena deben ser formateadas por las funciones convensionales de DateValue<br />

y TimeValue. En otras palabras, la el formato de la cadena depende del locale.<br />

CDateFromIso no depende de su locale y es más seguro si desea un código más global.<br />

Sintaxis:<br />

CDate (Expresión)<br />

Valor de retorno:<br />

Date<br />

Parámetros:<br />

Expresión: Cualquier expresión numérica o de cadena a ser convertida.<br />

Ejemplo:<br />

sub ExampleCDate<br />

MsgBox cDate(1000.25) REM 09.26.1902 06:00:00<br />

MsgBox cDate(1001.26) REM 09.27.1902 06:14:24<br />

Print DateValue("06/08/2002")<br />

MsgBox cDate("06/08/2002 15:12:00")<br />

end sub<br />

10.18 Función CDateFromIso<br />

Sumario:<br />

Retorna el número de fecha interno de una cadena conteniendo una fecha en formato ISO.<br />

109


Sintaxis:<br />

CDateFromIso(cadena)<br />

Valor de retorno:<br />

Número de fecha interno.<br />

Parámetros:<br />

Cadena: Una cadena conteniendo una fecha ISO. El año puede contener dos o cuatro dígitos.<br />

Ejemplo:<br />

sub ExampleCDateFromIso<br />

MsgBox cDate(37415.70) Rem 08 June 2002 16:48:00<br />

Print CDateFromIso("20020608") Rem 08 June 2002<br />

Print CDateFromIso("020608") Rem 08 June 1902<br />

Print Int(CDateFromIso("20020608")) Rem 37415<br />

end sub<br />

10.19 Función CDateToIso<br />

Sumario:<br />

Retorna la fecha en formato ISO de una serie de números generados con DateSerial o<br />

DateValue.<br />

Sintaxis:<br />

CDateToIso(Número)<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Número: Entero que contiene la serie de número de fecha.<br />

Ejemplo:<br />

Sub ExampleCDateToIso<br />

MsgBox "" & CDateToIso(Now) ,64,"ISO Date"<br />

End Sub<br />

10.20 Función CDbl<br />

Sumario:<br />

Convierte cualquier expresión numérica o de cadena en el tipo double. Las cadenas deben ser<br />

formateadas en el estilo locale. En USA, “12.34” funcionará, pero podría fallar en otros<br />

lugares.<br />

Sintaxis:<br />

CDbl (Expresión)<br />

Valor de retorno:<br />

Double<br />

110


Parámetros:<br />

Expresión: Cualquier expresión de cadena o numérica a ser convertida.<br />

Ejemplo:<br />

Sub ExampleCDbl<br />

Msgbox CDbl(1234.5678)<br />

Msgbox CDbl("1234.5678")<br />

End Sub<br />

10.21 Instrucción ChDir<br />

Sumario:<br />

Cambia el directorio actual o la unidad. Si sólo quiere cambiar la unidad actual, digite la letra<br />

de la unidad, seguida de dos puntos. ?? Cómo trabajará esto en mi computadora ! ??<br />

Cómo trabajará en Linux o en Mac.<br />

Sintaxis:<br />

ChDir Texto As String<br />

Parámetro:<br />

Texto: Cualquier expresión de cadena que especifica una ruta de directorio o unidad.<br />

Ejemplo:<br />

Sub ExampleChDir<br />

Dim sDir as String<br />

sDir = CurDir<br />

ChDir( "C:\temp" )<br />

msgbox CurDir<br />

ChDir( sDir )<br />

msgbox CurDir<br />

End Sub<br />

10.22 Instrucción ChDrive<br />

Sumario:<br />

Cambia la unidad actual. La letra de la unidad debe ser escrita como una letra mayúscula.<br />

Puede usar la instrucción OnError <strong>para</strong> capturar los errores. Esto se ve muy pequeño en mi<br />

computadora ??<br />

Sintaxis:<br />

ChDrive Texto As String<br />

Parámetros:<br />

Texto: Expresión de cadena que contenga una letra de unidad. Se acepta notación URL.<br />

Ejemplo:<br />

Sub ExampleCHDrive<br />

On Local Error Goto NoDrive<br />

ChDrive "Z" REM Only possible if a drive 'Z' exists.<br />

Print "Completed"<br />

111


Exit Sub<br />

NoDrive:<br />

Print "Sorry, the drive does not exist"<br />

Resume Next<br />

End Sub<br />

10.23 Función Choose<br />

Sumario:<br />

Retorna un valor seleccionado de una lista de argumentos. Este es un método rápido <strong>para</strong><br />

seleccionar un valor de una lista. Si el indice está fuera de los límites (menor a 1 o mayor que<br />

n), entonces es retornado un nulo.<br />

Sintaxis:<br />

Choose (Index, Selección_1[, Selección_2, ... [,Selección_n]])<br />

Valor de retorno:<br />

El tipo dependerá del que contenga Selección_i.<br />

Parámetros:<br />

Index: Una expresión numérica que especifique el valor de retorno.<br />

Selection_i: Un valor a retornar.<br />

Ejemplo:<br />

En este ejemplo, la variable “o” no tiene un tipo de valor dado de manera que toma el tipo de<br />

Selección_i. Selección_1 es del tipo “cadena” y Selección_2 es del tipo Double. Si define<br />

que “o” tenga un tipo de datos, entonces el valor de retorno será convertido a ese tipo de<br />

datos.<br />

Sub ExampleChoose<br />

Dim sReturn As String<br />

Dim sText As String<br />

Dim i As Integer<br />

Dim o<br />

sText = InputBox ("Enter a number (1-3):","Example")<br />

i = Int(sText)<br />

o = Choose(i, "One", 2.2, "Three")<br />

If IsNull(o) Then<br />

Print "Sorry, '" + sText + "' is not valid"<br />

Else<br />

Print "Obtained '" + o + "' of type " + TypeName(o)<br />

End If<br />

end Sub<br />

10.24 Función Chr<br />

Sumario:<br />

Retorna el caracter correspondiente al código de caracter específico (ASCII o Unicode)<br />

Esto es usado <strong>para</strong> crear secuencias especiales de cadenas, como secuencias de control <strong>para</strong><br />

112


impresoras, tabuladores, nuevas líneas, retornos de carro, etc. Esto también provee un<br />

método <strong>para</strong> insertar comillas dobles dentro de una cadena. Esto es escrito como “Chr$()”.<br />

Ver también la Función Asc<br />

Sintaxis:<br />

Chr(Expresión As Integer)<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Expresión: Variables numéricas que representan un valor ASCII de 8 bits válido (0-255) o un<br />

valor unicode de 16 bits.<br />

Ejemplo:<br />

Ejemplo:<br />

sub ExampleChr<br />

REM Show "Line 1" and "Line 2" on se<strong>para</strong>te lines.<br />

MsgBox "Line 1" + Chr$(13) + "Line 2"<br />

End Sub<br />

10.25 Función CInt<br />

Sumario:<br />

Convierte cualquier expresion numérica o de cadena en un tipo Integer (entero). La cadena<br />

debe ser formateada en base al tipo local. En EEUU, trabajará “12.34”.<br />

Ver también: Fix<br />

Sintaxis:<br />

CInt(Expresión)<br />

Valor de retorno:<br />

Entero (Integer)<br />

Parámetros:<br />

Expresión : Cualquier cadena o expresión numérica a ser convertida.<br />

Ejemplo:<br />

Sub ExampleCInt<br />

Msgbox CInt(1234.5678)<br />

Msgbox CInt("1234.5678")<br />

End Sub<br />

10.26 Función CLng<br />

Sumario:<br />

Convierte cualquier expresión numérica o de cadena en un tipo Largo (Long). Las cadenas<br />

deben ser formateadas en base al tipo local. En EEUU, trabajará “12.34”.<br />

Sintaxis:<br />

113


CLong(Expresión)<br />

Valor de retorno:<br />

Entero Largo (Long)<br />

Parámetros:<br />

Expresión : Cualquier cadena o expresión numérica a ser convertida.<br />

Ejemplo:<br />

Sub ExampleCLng<br />

Msgbox CLng(1234.5678)<br />

Msgbox CLng("1234.5678")<br />

End Sub<br />

10.27 Instrucción Close<br />

Sumario:<br />

Cierra archivos abiertos previamente con la instrucción Open. Multiples archivos pueden ser<br />

cerrados simultáneamente.<br />

Ver también, EOF, Kill, y FreeFile<br />

Sintaxis:<br />

Close NuméroArchivo As Integer[, NúmeroArchivo2 As Integer[,...]]<br />

Parámetros:<br />

NúmeroArchivo : Expresión entera que especifica un archivo abierto anteriormente.<br />

Ejemplo:<br />

Sub ExampleCloseFile<br />

Dim iNum1 As Integer, iNum2 As Integer<br />

Dim sLine As String, sMsg As String<br />

'Next available file number!<br />

iNum1 = FreeFile<br />

Open "c:\data1.txt" For Output As #iNum1<br />

iNum2 = FreeFile<br />

Open "c:\data2.txt" For Output As #iNum2<br />

Print #iNum1, "Text in file one for number " + iNum1<br />

Print #iNum2, "Text in file two for number " + iNum2<br />

Close #iNum1, #iNum2<br />

Open "c:\data1.txt" For Input As #iNum1<br />

iNum2 = FreeFile<br />

Open "c:\data2.txt" For Input As #iNum2<br />

sMsg = ""<br />

Do While not EOF(iNum1)<br />

Line Input #iNum1, sLine<br />

If sLine "" Then sMsg = sMsg+"File: "+iNum1+":"+sLine+Chr(13)<br />

Loop<br />

Close #iNum1<br />

Do While not EOF(iNum2)<br />

Line Input #iNum2, sLine<br />

If sLine "" Then sMsg = sMsg+"File: "+iNum2+":"+sLine+Chr(13)<br />

114


Loop<br />

Close #iNum2<br />

Msgbox sMsg<br />

End Sub<br />

10.28 Instrucción Const<br />

Sumario:<br />

Las Constantes mejora la lectura de los programas al asignar nombres a las contantes y<br />

también provee un solo punto de definición. Las constantes pueden incluir la definición de un<br />

tipo de datos pero no es requerido. Una constante es definida una vez y no puede ser<br />

modificada.<br />

Sintaxis:<br />

Const Texto [As tipo] = Expresión[, Texto2 [As tipo] = Expresión2[, ...]]<br />

Parámetros:<br />

Texto: Cualquier nombre de constante que siga los estándares de nombres de variables.<br />

Ejemplo:<br />

Sub ExampleConst<br />

Const iVar As String = 1964<br />

Const sVar = "Program", dVar As Double = 1.00<br />

Msgbox iVar & " " & sVar & " " & dVar<br />

End Sub<br />

10.29 Función ConvertFromURL<br />

Sumario:<br />

Convierte un URL de archivo en un nombre de archivo de sistema.<br />

Sintaxis:<br />

ConvertFromURL(NombreArchivo)<br />

Valor de retorno:<br />

Cadena (String)<br />

Parámetros:<br />

NombreArchivo: Nombre del archivo como un URL<br />

Ejemplo:<br />

Sub ExampleUrl<br />

Dim sUrl As String, sName As String<br />

sName = "c:\temp\file.txt"<br />

sUrl = ConvertToURL(sName)<br />

MsgBox "Original File:" + sName + Chr(13) + "URL: " + sURL + Chr(13) + _<br />

"And Back:" + ConvertFromURL(sUrl)<br />

End Sub<br />

115


10.30 Función ConvertToURL<br />

Sumario:<br />

Convierte un archivo de un URL a un nombre de archivo del sistema.<br />

Sintaxis:<br />

ConvertToURL(NombreArchivo)<br />

Valor de retorno:<br />

Cadena (String)<br />

Parámetros:<br />

NombreArchivo: Nombre del archivo como un nombre del sistema.<br />

Ejemplo:<br />

Sub ExampleUrl<br />

Dim sUrl As String, sName As String<br />

sName = "c:\temp\file.txt"<br />

sUrl = ConvertToURL(sName)<br />

MsgBox "Original File:" + sName + Chr(13) + _<br />

"URL: " + sURL + Chr(13) + _<br />

"And Back:" + ConvertFromURL(sUrl)<br />

End Sub<br />

10.31 Función Cos<br />

Sumario:<br />

El coseno de una expresión numérica con un valor de retorno en el rango de 1 y -1. Para las<br />

mentes no matemáticas, esta es una función trigonométrica.<br />

Sintaxis:<br />

Cos(Número)<br />

Valor de retorno:<br />

Doble (Double)<br />

Parámetros:<br />

Número:<br />

Ejemplo:<br />

Sub ExampleCos<br />

Dim dLeg1 As Double, dLeg2 As Double, dHyp As Double<br />

Dim dAngle As Double<br />

dLeg1 = InputBox("Enter the length of the adjacent leg: ","Adjacent")<br />

dLeg2 = InputBox("Enter the length of the opposite leg: ","Opposite")<br />

dHyp = Sqr(dLeg1 * dLeg1 + dLeg2 * dLeg2)<br />

dAngle = Atn(dLeg2 / dLeg1)<br />

MsgBox "Adjacent Leg = " + dLeg1 + Chr(13) + _<br />

"Opposite Leg = " + dLeg2 + Chr(13) + _<br />

"Hypotenuse = " + Format(dHyp, "##0.0000") + Chr(13) + _<br />

"Angle = "+Format(dAngle*180/Pi, "##0.0000")+" degrees"+Chr(13)+_<br />

116


End Sub<br />

"Cos = " + Format(dLeg1 / dHyp, "##0.0000") + Chr(13) + _<br />

"Cos = " + Format(Cos(dAngle), "##0.0000")<br />

10.32 Función CreateUnoDialog<br />

Sumario:<br />

Crea un objeto Basic Uno que representa un dialogo de control Uno durante el tiempo de<br />

ejecución de Basic.<br />

Los diálogos están definidos en las librerías de diálogos. Para desplegar un dialogo, un<br />

diálogo “vivo” debe ser creado en la librería.<br />

Sintaxis:<br />

CreateUnoDialog( oDlgDesc )<br />

Valor de retorno:<br />

Objeto: Diálogo a ejecutar!<br />

Parámetros:<br />

oDlgDesc : Descripción del dialogo previamente definido en la librería.<br />

Ejemplo:<br />

?? Warning, I have not made this work at all! Work on this!<br />

Sub ExampleCreateDialog<br />

Dim oDlgDesc As Object, oDlgControl As Object<br />

DialogLibraries.LoadLibrary("Standard")<br />

' Get dialog description from the dialog library<br />

oDlgDesc = DialogLibraries.Standard<br />

Dim oNames(), i%<br />

oNames = DialogLibraries.Standard.getElementNames()<br />

i = lBound( oNames() )<br />

while( i


oService = CreateUnoService( Nombre del servicio Uno )<br />

Valor de retorno:<br />

??<br />

Parámetros:<br />

??<br />

Ejemplo:<br />

oIntrospection = CreateUnoService( "com.sun.star.beans.Introspection" )<br />

10.34 Función CreateUnoStruct<br />

Sumario:<br />

Crea una instancia de un tipo de estructura Uno.<br />

Es mejor usar el siguiente constructor.!<br />

Dim oStruct as new com.sun.star.beans.Property<br />

Sintaxis:<br />

oStruct = CreateUnoStruct( Nombre del tipo Uno )<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

oStruct = CreateUnoStruct("com.sun.star.beans.Property")<br />

'***********************************<br />

'Do you want to choose a certain printer<br />

'Dim mPrinter(0) As New com.sun.star.beans.PropertyValue<br />

'mPrinter(0).Name="Name"<br />

'mPrinter(0).value="Other printer"<br />

'oDocument.Printer = mPrinter()<br />

'You could have done it this way after it was defined!<br />

'mPrinter(0) = CreateUnoStruct("com.sun.star.beans.PropertyValue")<br />

10.35 Función CSng<br />

Sumario:<br />

Convierte una expresión numérica o de cadena en un tipo sencillo (Single). Las cadenas<br />

deben ser formateadas en base al tipo local. En EEUU, trabajará “12.34”.<br />

Sintaxis:<br />

CSng(Expresión)<br />

Valor de retorno:<br />

Entero Sencillo (Single)<br />

118


Parámetros:<br />

Expresión : Cualquier cadena o expresión numérica a ser convertida.<br />

Ejemplo:<br />

Sub ExampleCLng<br />

Msgbox CSng(1234.5678)<br />

Msgbox CSng("1234.5678")<br />

End Sub<br />

10.36 Función CStr<br />

Sumario:<br />

Converte cualquier expresión en una cadena. Esto se usa <strong>para</strong> convertir un número en una<br />

cadena.<br />

Tipo entrada Valor de salida<br />

Booleano “True” o “False”<br />

Fecha (Date) Cadena con la fecha y la hora.<br />

Null Error en tiempo de ejecución.<br />

Vacío (Empty) Cadena vacía “”<br />

Cualquier<br />

número<br />

El número como una cadena. Los ceros a la<br />

derecha del decimal son cortados.<br />

Sintaxis:<br />

CStr (Expresión)<br />

Valor de retorno:<br />

Cadena (String)<br />

Parámetros:<br />

Expresión: Cualquier cadena válida o expresión numérica a ser convertida.<br />

Ejemplo:<br />

Sub ExampleCSTR<br />

Dim sVar As String<br />

Msgbox CDbl(1234.5678)<br />

Msgbox CInt(1234.5678)<br />

Msgbox CLng(1234.5678)<br />

Msgbox CSng(1234.5678)<br />

sVar = CStr(1234.5678)<br />

MsgBox sVar<br />

end sub<br />

10.37 Función CurDir<br />

Sumario:<br />

119


etorna la cadena representando la ruta actual de la unidad especificada. Si el parámetro no es<br />

dado o de tamaño cero, entonces la ruta de la unidad actual es retornado.<br />

Sintaxis:<br />

CurDir [(Texto As String)]<br />

Valor de retorno:<br />

Cadena (String)<br />

Parámetros:<br />

Texto: Cadena no sensible a mayúsculas especificando una unidad <strong>para</strong> retornar la ruta<br />

actual. Debe ser un solo caracter. ?? Chequear esto en linux.<br />

Ejemplo:<br />

Sub ExampleCurDir<br />

MsgBox CurDir("c")<br />

MsgBox CurDir("p")<br />

MsgBox CurDir()<br />

end sub<br />

10.38 Función Date<br />

Sumario:<br />

Retorna o cambia el sistema actual. El formato de fecha depende del local.<br />

Sintaxis:<br />

Fecha<br />

Date = Texto As String<br />

Valor de retorno:<br />

Cadena (String)<br />

Parámetros:<br />

Texto: Nueva fecha del sistema como se define en su configuración local.<br />

Ejemplo:<br />

Sub ExampleDate<br />

MsgBox "The date is " & Date<br />

End Sub<br />

10.39 Función DateSerial<br />

Sumario:<br />

Convierte un año, mes, y día en un objeto Fecha (Date). La representación interna es un<br />

doble (Double) donde 0 es Diciembre 30,1899. Ver este doble como el número de días desde<br />

esta fecha base. Los números negativos son antes y los positivos después.<br />

Ver también DateValue, Date, y Day.<br />

120


Advertencia Los años de dos dígitos son consderados como 19xx. Esto no es<br />

consistente con la función DateValue.<br />

Sintaxis:<br />

DateSerial (año, mes, día)<br />

Valor de retorno:<br />

Fecha<br />

Parámetros:<br />

Año: valor entero de año. Valores entre 0 y 99 son representados como los años 1900 a 1999.<br />

todos los demás años deberán contener cuatro dígitos.<br />

Mes: Entero indicando el mes. Los valores válidos van de 1 a 12.<br />

Día: Entero indicando el día. Los valores válidos van de 1 a 28, 29, 30 o 31 (Depende del<br />

mes).<br />

Ejemplo:<br />

Sub ExampleDateSerial<br />

Dim lDate as Long, sDate as String, lNumDays As Long<br />

lDate = DateSerial(2002, 6, 8)<br />

sDate = DateSerial(2002, 6, 8)<br />

MsgBox lDate REM returns 37415<br />

MsgBox sDate REM returns 06/08/2002<br />

lDate = DateSerial(02, 6, 8)<br />

sDate = DateSerial(02, 6, 8)<br />

MsgBox lDate REM returns 890<br />

MsgBox sDate REM returns 06/08/1902<br />

end sub<br />

10.40 Función DateValue<br />

Sumario:<br />

Convierte una cadena de fecha en un valor númerico que puede ser usado <strong>para</strong> determinar el<br />

número de días entre dos fechas.<br />

Ver también DateSerial, Date, y Day<br />

Advertencia Los años de dos dígitos son considerados 20xx. Esto no es consistente<br />

con la función DateSerial.<br />

Sintaxis:<br />

DateValue [(fecha)]<br />

Valor de retorno:<br />

Largo<br />

Parámetros:<br />

Fecha: Cadena representando la fecha.<br />

Ejemplo:<br />

121


Sub ExampleDateValue<br />

Dim s(), i%, sMsg$, l1&, l2&<br />

Rem These all map to June 8, 2002.<br />

s = Array("06.08.2002", "6.08.02", "6.08.2002", "June 08, 2002", _<br />

"Jun 08 02", "Jun 08, 2002", "Jun 08, 02", "06/08/2002")<br />

Rem If you use these values, it will generate an error<br />

Rem which contradicts the included help<br />

Rem s = Array("6.08, 2002", "06.08, 2002", "06,08.02", "6,08.2002", "Jun/08/02")<br />

sMsg = ""<br />

For i = LBound(s()) To UBound(s())<br />

sMsg = sMsg + DateValue(s(i)) + "


Basic.<br />

Aliasname: Nombre de la subrutina tal y como está definida en la DLL.<br />

Libname: Archivo o nombre de sistema de la DLL. Esta librería es automáticamente cargada<br />

la primera vez que la función es usada.<br />

Argumentlist: Lista de parámetros representando los argumentos que son pasados al<br />

procedimiento cuando este es llamado. El tipo y número de parámetros depende del<br />

procedimiento que se está ejecutando.<br />

Type: Define el tipo de datos de el valor retornado por el procedimiento Función. Esto puede<br />

ser excluido si un caracter de tipo de declaración es ingresado despues del nombre.<br />

Ejemplo:<br />

Declare Sub MyMessageBeep Lib "user32.dll" Alias "MessageBeep" ( long )<br />

Sub ExampleDeclare<br />

Dim lValue As Long<br />

lValue = 5000<br />

MyMessageBeep( lValue )<br />

FreeLibrary("user32.dll" )<br />

End Sub<br />

10.43 Instrucción DefBool<br />

Sumario:<br />

Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “b”, por ejemplo, sean automáticamente del tipo boleanos.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefBool Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

REM Prefix definition for variable types:<br />

DefBool b<br />

DefDate t<br />

DefDbL d<br />

DefInt i<br />

DefLng l<br />

DefObj o<br />

DefVar v<br />

DefBool b-d,q<br />

Sub ExampleDefBool<br />

cOK = 2.003<br />

zOK = 2.003<br />

Print cOK Rem True<br />

123


Print zOK Rem 2.003<br />

End Sub<br />

10.44 Instrucción DefDate<br />

Summary<br />

Define el tipo de variable por defecto, de acuerdo a un rango de letras, si no es declarado el<br />

tipo mediante un caracter de definición o una palabra clave. Permite que todas las variables<br />

que inician con una “t”, por ejemplo, sean automaticamente del tipo fecha.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefDate Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

ver ejemplo DefBool<br />

10.45 Instrucción DefDbl<br />

Sumario:<br />

Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “d”, por ejemplo, sean automáticamente del tipo Doble.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefDbl Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

ver ejemplo DefBool<br />

10.46 Instrucción DefInt<br />

Sumario:<br />

Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “i”, por ejemplo, sean automáticamente del tipo Entero.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

124


DefInt Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

Ver ejemplo DefBool<br />

10.47DefLng Statement<br />

Sumario:<br />

Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “l”, por ejemplo, sean automáticamente del tipo Largo.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefLng Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

Ver ejemplo DefBool<br />

10.48 Instrucción DefObj<br />

Sumario:<br />

Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “o”, por ejemplo, sean automáticamente del tipo Objeto.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefObj Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

Ver ejemplo DefBool<br />

10.49 Instrucción DefVar<br />

Sumario:<br />

125


Define el tipo por defecto de las variables, de acuerdo a un rango de letras, si no se define un<br />

caracter de tipo de declaración o palabra clave. Puede permitir que todas las variables que<br />

inician con “v”, por ejemplo, sean automáticamente del tipo Variante.<br />

Ver también: DefBool, DefDate, DefDbL, DefInt, DefLng, DefObj, y DefVar.<br />

Sintaxis:<br />

DefVar Rango1[, Rango2[,...]]<br />

Parámetros:<br />

Rango: Letras especificando el rango de variables a las que se les va a definir el tipo de datos<br />

por defecto.<br />

Ejemplo:<br />

Ver ejemplo DefBool<br />

10.50 Instrucción Dim<br />

Sumario:<br />

Declara variables. El tipo de cada variable es declarado se<strong>para</strong>damente y el tipo por defecto<br />

es Variante. La siguiente instrucción define a, b, y c del tipo Variante y d del tipo Fecha.<br />

Dim a, b, c, d As Date<br />

Los tipos de variables también pueden ser definidos mediante el uso de un caracter al final.<br />

Esto es mencionado en la sección de tipos de variables.<br />

Dim es usada <strong>para</strong> declarar variables locales dentro de las subrutinas. Las variables globales<br />

fuera de las Subrutinas son declaradas con las instrucciones PUBLIC o PRIVATE.<br />

A menos que la instrucción “Option Explicit” esté presente, las variables que no sean matriz<br />

pueden ser usadas sin declaración y su tipo por defecto será variante.<br />

Son soportadas matrices sencillas y multi-dimensionales.<br />

Ver también: Public, Private, ReDim<br />

Sintaxis:<br />

[ReDim]Dim Nombre_1 [(inicio To fin)] [As Tipo][, Nombre_2 [(inicio To fin)] [As Tipo]<br />

[,...]]<br />

Parámetros/Palabras clave:<br />

Name_i: Nombre de la variable o de la matriz.<br />

Inicio, fin: Constante entero desde -32768 a 32767 del rango de la matriz o arreglo. A nivle<br />

de procedimiento, ReDim permite expresiones numéricas de manera que puede ser reiniciado<br />

en tiempo de ejecución.<br />

Tipo: Palabra clave usada <strong>para</strong> declarar el tipo de datos de una variable. Los tipos soportados<br />

son Boolean (Boleano), Currency (Moneda), Date (Fecha), Double (Doble), Integer (Entero),<br />

Long (Largo), Object (Objeto), Single (Sencillo), String (Cadena), o Variant (Variante).<br />

Ejemplo:<br />

Sub ExampleDim<br />

126


Dim s1 As String, i1 As Integer, i2%<br />

Dim a1(5) As String Rem 0 to 6<br />

Dim a2(3, -1 To 1) As String Rem (0 to 3, -1 to 1)<br />

Const sDim as String = " Dimension:"<br />

For i1 = LBound(a2(), 1) To UBound(a2(), 1)<br />

For i2 = LBound(a2(), 2) To UBound(a2(), 2)<br />

a2(i1, i2) = Str(i1) & ":" & Str(i2)<br />

Next<br />

Next<br />

For i1 = LBound(a2(), 1) To UBound(a2(), 1)<br />

For i2 = LBound(a2(), 2) To UBound(a2(), 2)<br />

Print a2(i1, i2)<br />

Next<br />

Next<br />

End Sub<br />

10.51 Función DimArray<br />

Sumario:<br />

Crea una matriz del tipo Variante. Esto trabaja igual que Dim(Lista de argumentos). Si no<br />

hay argumentos, una matriz vacía es creada. Si hay parámetros, una dimensión es creada por<br />

cada parámetro.<br />

Ver también: Array<br />

Sintaxis:<br />

DimArray ( Lista de argumentos)<br />

Valor de retorno:<br />

Matriz Variant<br />

Parámetros:<br />

Lista de argumentos: De manera opcional son enteros se<strong>para</strong>dos por comas.<br />

Ejemplo:<br />

DimArray( 2, 2, 4 ) es lo mismo que DIM a( 2, 2, 4 )<br />

10.52 Función Dir<br />

Sumario:<br />

Retorna el nombre de un archivo, directorio, o todos los archivos y directorios de una unidad<br />

o directorio que concuerde con la ruta de busqueda especificada. Un posible uso es verificar<br />

que exista un archivo o directorio, o listar los archivos y directorios de un directorio<br />

especifico.<br />

Si no concuerda ningún archivo o directorio, se retorna una cadena de tamaño cero. Llamar<br />

repetidamente la función Dir hasta que una cadena de tamaño cero sea retornada <strong>para</strong> iterate<br />

a traves de todos los valores retornados.<br />

Los atributos de Volumen y Directorio tienen significado exclusivamente si pide uno de estos<br />

127


y es la única cosa que obtiene. No puedo determinar cual tiene más precedencia, porque la<br />

versión 1.0.3, el atributo del volumen no hace nada.<br />

Los atributos son un subconjunto de estos disponibles en GetAttr.<br />

Ver también: GetAttr<br />

Sintaxis:<br />

Dir [(Texto As String[, Atributo As Integer])]<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Texto: Cadena que especifica la ruta de búsqueda, directorio o archivo. Notación URL es<br />

aceptada.<br />

Atributo: Entero <strong>para</strong> los atributos de los archivos. La función Dir retornará solo los archivos<br />

o directorios que concuerden con los atributos especificos. Sume los atributos <strong>para</strong><br />

combinarlos.<br />

Atributo Descripción<br />

0 Archivo normal.<br />

2 Archivo oculto.<br />

4 Archivo de sistema.<br />

8 Retorna el nombre del volumen (Exclusivo).<br />

16 Retorna directorios (Exclusivo).<br />

Ejemplo:<br />

Sub ExampleDir<br />

REM Displays all files and directories<br />

Dim sFile as String, sPath As String<br />

Dim sDir as String, sValue as String<br />

Dim iFIle as Integer<br />

sFile= "Files: "<br />

sDir="Directories:"<br />

iFile = 0<br />

sPath = CurDir<br />

Rem 0 : Normal files.<br />

Rem 2 : Hidden files.<br />

Rem 4 : System files.<br />

Rem 8 : Returns the name of the volume<br />

Rem 16 : Returns the name of the directory only.<br />

Rem This example will ONLY return directories because the 16 is included!<br />

Rem Remove the 16 and you will receive the files<br />

sValue = Dir$(sPath, 0 + 2 + 4 + 16)<br />

Do<br />

If sValue "." and sValue ".." Then<br />

128


If (GetAttr( sPath + getPathSe<strong>para</strong>tor() + sValue) AND 16) > 0 Then<br />

REM here the directories<br />

sDir = sDir & chr(13) & sValue<br />

Else<br />

REM here the files<br />

If iFile Mod 3 = 0 Then sFile = sFile + Chr(13)<br />

iFile = iFile + 1<br />

sFile = sFile + sValue &"; "<br />

End If<br />

End If<br />

sValue = Dir$<br />

Loop Until sValue = ""<br />

MsgBox sDir,0,sPath<br />

MsgBox "" & iFile & " " & sFile,0,sPath<br />

End Sub<br />

Tip El método getPathSe<strong>para</strong>tor() es incluido sin embargo no aparece en la<br />

lista de ayuda. No ha encontrado aun donde está definido, pero es usado<br />

en las herramientas distribuidas y en la ayuda.<br />

Advertencia Algunos sistemas operativos incluyen los directorios “.” y “..” que se<br />

refieren al directorio actual y al directorio padre respectivamente. Si<br />

escribe código que barra un directorio, probablemente no desee seguirlos<br />

o caerá en un ciclo infinito.<br />

Advertencia Cuando obtenga una lista de directorios, los archivos no serán retornados,<br />

aun cuando la ayuda en línea parezca indicar que si lo hace.<br />

10.53 Instrucción Do...Loop<br />

Sumario:<br />

Construye una repetición de instrucciones.<br />

Ver también: Control Loop Página 92.<br />

Sintaxis:<br />

Do [{While | Until} Condición = True]<br />

Block de instrucciones<br />

[Exit Do]<br />

Block de instrucciones<br />

Loop<br />

Sintaxis:<br />

Do<br />

Block de instrucciones<br />

[Exit Do]<br />

Block de instrucciones<br />

129


Loop [{While | Until} condición = True]<br />

10.54 Instrucción End<br />

Sumario:<br />

Marca el final de un procedimiento o bloque.<br />

Ver también: Exit<br />

Sintaxis:<br />

Forma Función<br />

End Por sí mismo termina la ejecución del<br />

programa. Puede estar en cualquier parte. Es<br />

opcional.<br />

End Function Marca el final de una función.<br />

End If Marca el final de un bloque If...Then...Else.<br />

End Select Marca el final de un bloque Select Case.<br />

End Sub Marca el final de una subrutina.<br />

Ejemplo:<br />

Sub ExampleEnd<br />

Dim s As String<br />

s = InputBox ("Enter an integer :","White Space Checker")<br />

If IsWhiteSpace(Val(s)) Then<br />

Print "ASCII " + s + " is white space"<br />

Else<br />

Print "ASCII " + s + " is not white space"<br />

End If<br />

End<br />

Print "I will never get here"<br />

End Sub<br />

Function IsWhiteSpace(iChar As Integer) As Boolean<br />

Select Case iChar<br />

Case 9, 10, 13, 32, 160<br />

IsWhiteSpace = True<br />

Case Else<br />

IsWhiteSpace = False<br />

End Select<br />

End Function<br />

10.55 Función Environ<br />

Sumario:<br />

Retorna el valor de una variable de ambiente. Las variables de ambiente dependen del<br />

sistema operativo. En una Macintosh esta función retorna una cadena vacía.<br />

Sintaxis:<br />

130


Environ (Ambiente As String)<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Ambiente: Variable de ambiente, de la cual se quiere extraer el valor que contiene.<br />

Ejemplo:<br />

Sub ExampleEnviron<br />

MsgBox "Path = " & Environ("PATH")<br />

End Sub<br />

10.56 Función EOF<br />

Sumario:<br />

Use EOF <strong>para</strong> evitar tratar de leer más allá del final del archivo. Cuando el final del archivo<br />

es encontrado, EOF retorna Verdadero (-1).<br />

Ver también Open, Close, Kill, y FreeFile<br />

Sintaxis:<br />

EOF (ValorEntero As Integer)<br />

Valor de retorno:<br />

Boleano<br />

Parámetros:<br />

ValorEntero: Expresión Entera que evalúa el número correspondiente de un archivo abierto.<br />

Ejemplo:<br />

Rem Este ejemplo está modificado de la ayuda en línea.<br />

Rem El ejemplo de la ayuda en línea no funciona.<br />

Sub ExampleEof<br />

Dim iNumber As Integer<br />

Dim aFile As String<br />

Dim sMsg as String, sLine As String<br />

aFile = "c:\DeleteMe.txt"<br />

iNumber = Freefile<br />

Open aFile For Output As #iNumber<br />

Print #iNumber, "First line of text"<br />

Print #iNumber, "Another line of text"<br />

Close #iNumber<br />

iNumber = Freefile<br />

Open aFile For Input As iNumber<br />

While Not Eof(iNumber)<br />

Line Input #iNumber, sLine<br />

If sLine "" Then<br />

sMsg = sMsg & sLine & chr(13)<br />

End If<br />

Wend<br />

Close #iNumber<br />

131


Msgbox sMsg<br />

End Sub<br />

10.57 Función EqualUnoObjects<br />

Sumario:<br />

Verifica si dos objetos Uno representan la misma instancia del objeto Uno.<br />

Sintaxis:<br />

EqualUnoObjects( oObj1, oObj2 )<br />

Valor de retorno:<br />

Boleano<br />

Ejemplo:<br />

Sub ExampleEqualUnoObjects<br />

Dim oIntrospection, oIntro2, Struct2<br />

Rem Copy of objects -> same instance<br />

oIntrospection = CreateUnoService( "com.sun.star.beans.Introspection" )<br />

oIntro2 = oIntrospection<br />

print EqualUnoObjects( oIntrospection, oIntro2 )<br />

Rem Copy of structs as value -> new instance<br />

Dim Struct1 as new com.sun.star.beans.Property<br />

Struct2 = Struct1<br />

print EqualUnoObjects( Struct1, Struct2 )<br />

End Sub<br />

10.58 Operador EQV<br />

Sumario:<br />

Calcula la equivalencia lógica de doe expresiones. En una com<strong>para</strong>ción de bit-a-bit, el<br />

operador EQV activa el bit correspondiente en el resultado solamente si un bit es activado en<br />

ambas expresiones o en ninguna expresión. La precedencia matemática usada está mostrada<br />

en la página 99 y la tabla de operaciones es mostrada a continuación:<br />

x y x EQV y<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO<br />

VERDAD<br />

ERO FALSO FALSO<br />

FALSO<br />

FALSO FALSO<br />

VERDAD<br />

ERO FALSO<br />

VERDAD<br />

ERO<br />

1 1 1<br />

132


x y x EQV y<br />

1 0 0<br />

0 1 0<br />

0 0 1<br />

Sintaxis:<br />

Resultado = Expresión1 EQV Expresión2<br />

Parámetros:<br />

Resultado: Variable numérica que contiene el resultado de la com<strong>para</strong>ción.<br />

Expresión1, expresión2 : Expresiones a com<strong>para</strong>r.<br />

Ejemplo:<br />

Sub ExampleEQV<br />

Dim vA as Variant, vB as Variant, vC as Variant, vD as Variant<br />

Dim vOut as Variant<br />

vA = 10: vB = 8: vC = 6: vD = Null<br />

vOut = vA > vB EQV vB > vC REM returns -1<br />

Print vOut<br />

vOut = vB > vA EQV vB > vC REM returns -1<br />

Print vOut<br />

vOut = vA > vB EQV vB > vD REM returns 0<br />

Print vOut<br />

vOut = (vB > vD EQV vB > vA) REM returns -1<br />

Print vOut<br />

vOut = vB EQV vA REM returns -1<br />

End Sub<br />

10.59 Función Erl<br />

Sumario:<br />

Retorna el número de línea en la que ha ocurrido un error durante el tiempo de ejecución.<br />

Ver también: Err<br />

Sintaxis:<br />

Erl<br />

Valor de retorno:<br />

Entero<br />

Ejemplo:<br />

Sub ExampleErl<br />

On Error GoTo ErrorHandler<br />

Dim iVar as Integer<br />

iVar = 0<br />

iVar = 4 / iVar<br />

133


Exit Sub<br />

ErrorHandler:<br />

Rem Error 11 : Division by Zero<br />

Rem In line: 8<br />

Rem ....<br />

MsgBox "Error " & err & ": " & error$ + chr(13) + _<br />

"In line : " + Erl + chr(13) + Now , 16 ,"An error occured"<br />

End Sub<br />

10.60 Función Err<br />

Sumario:<br />

Retorna el número de error del último error.<br />

Ver también: Erl<br />

Sintaxis:<br />

Err<br />

Valor de retorno:<br />

Entero<br />

Ejemplo:<br />

Sub ExampleErr<br />

On Error GoTo ErrorHandler<br />

Dim iVar as Integer<br />

iVar = 0<br />

iVar = 4 / iVar<br />

Exit Sub<br />

ErrorHandler:<br />

Rem Error 11 : Division by Zero<br />

Rem In line: 8<br />

Rem ....<br />

MsgBox "Error " & err & ": " & error$ + chr(13) + _<br />

"In line : " + Erl + chr(13) + Now , 16 ,"An error occured"<br />

End Sub<br />

10.61 Función Error<br />

Sumario:<br />

Simula la ocurrencia de un error durante la ejecución de un programa.<br />

Sintaxis:<br />

Error NumeroError As Integer<br />

Parámetros:<br />

NumeroError: Expresión Entera que especifica el número de error a ser simulado.<br />

La instrucción Error simula la ocurrencia de un error durante la ejecución de un programa.<br />

Un error interceptado por una rutina de manejo de errores no será reportada, a menos que sea<br />

tomada una acción correctiva o no. La instrucción Error es usada <strong>para</strong> reportar un error<br />

134


cuando no hay rutina de manejo de errores, y detener la ejecución del programa.<br />

Ejemplo:<br />

?? This does NOT work!<br />

Sintaxis:<br />

Error NumeroError As Integer<br />

Valor de retorno:<br />

Entero<br />

Parámetros:<br />

Ejemplo:<br />

10.62 Función Error<br />

Sumario:<br />

Retorna el mensaje de error correspondiente a un código de error dado.<br />

Sintaxis:<br />

Error (Expresión)<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Expresión: Entero opcional conteniendo el mensaje de error <strong>para</strong> un número de error. Si este<br />

no está presente, el mensaje de error más reciente es regresado.<br />

Ejemplo:<br />

Sub ExampleError<br />

On Error GoTo ErrorHandler<br />

Dim iVar as Integer<br />

iVar = 0<br />

iVar = 4 / iVar<br />

Exit Sub<br />

ErrorHandler:<br />

Rem Error 11 : Division by Zero<br />

Rem In line: 8<br />

Rem ....<br />

MsgBox "Error " & err & ": " & error$ + chr(13) + _<br />

"In line : " + Erl + chr(13) + Now , 16 ,"An error occured"<br />

End Sub<br />

10.63 Instrucción Exit<br />

Sumario:<br />

La instrucción Exit es usada <strong>para</strong> dejar una estructura Do...Loop, For...Next, Función o<br />

135


Subroutina. En otras palabras, puedo inmediatamente salir de cualquiera de estas estructuras.<br />

Si estoy dentro de una subrutina y determino que los argumentos están mal, puedo dejar<br />

inmediatamente la subrutina.<br />

Ver también: End<br />

Sintaxis:<br />

Forma Function<br />

Exit Do Sale del Do...Loop más cercano.<br />

Exit For Sale del For...Next más cercano.<br />

Exit Function Sale de una función y continua la ejecución<br />

siguiente a la llamada a la función.<br />

Exit Sub Sale de la subrutina y continua la ejecución<br />

siguiente a la llamada a la subrutina.<br />

Ejemplo:<br />

Sub ExampleExit<br />

Dim sReturn As String<br />

Dim sListArray(10) as String<br />

Dim siStep as Single<br />

Rem Build array ("B", "C", ..., "L")<br />

For siStep = 0 To 10 REM Fill array with test data<br />

sListArray(siStep) = chr(siStep + 66)<br />

Next siStep<br />

sReturn = LinSearch(sListArray(), "M")<br />

Print sReturn<br />

Exit Sub Rem This really is a useless statement!<br />

End Sub<br />

REM Returns the index of the entry or (LBound(sList()) - 1) if not found<br />

Function LinSearch( sList(), sItem As String ) as integer<br />

Dim iCount As Integer<br />

REM LinSearch searches a TextArray:sList() for a TextEntry:<br />

For iCount=LBound(sList()) To UBound(sList())<br />

If sList(iCount) = sItem Then<br />

LinSearch = iCount<br />

Exit Function Rem Probably a good use of Exit here!<br />

End If<br />

Next<br />

LinSearch = LBound(sList()) - 1<br />

End Function<br />

10.64 Función Exp<br />

Sumario:<br />

Retorna la base del logaritmo natural (e = 2.718282) elevado a una potencia.<br />

Ver también: Log<br />

136


Sintaxis:<br />

Exp (Número)<br />

Valor de retorno:<br />

Doble<br />

Parámetros:<br />

Número: Cualquier expresión numérica.<br />

Ejemplo:<br />

Sub ExampleExp<br />

Dim d as Double, e As Double<br />

e = Exp(1)<br />

Print "e = " & e<br />

Print "ln(e) = " & Log(e)<br />

Print "2*3 = " & Exp(Log(2.0) + Log(3.0))<br />

Print "2^3 = " & Exp(Log(2.0) * 3.0)<br />

end sub<br />

10.65 Función FileAttr<br />

Sumario:<br />

El primer propósito de la función FileAttr es determinar el modo de acceso de un archivo<br />

abierto con la instrucción Open. Poniéndo el segundo parámetro en 1, recupera este valor.<br />

Valor Descrición del modo de acceso<br />

1 INPUT (Archivo abierto <strong>para</strong> entrada)<br />

2 OUTPUT (Archivo abierto <strong>para</strong> salida)<br />

4<br />

RANDOM (Archvo abierto <strong>para</strong> acceso<br />

aleatorio)<br />

8 APPEND (Archivo abierto <strong>para</strong> añadir)<br />

32<br />

BINARY (Archivo abierto en modo<br />

binario)<br />

El segundo propósito de la función FileAttr es determinar el atributo de un archivo MS-DOS<br />

que ha sido abierto con la instrucción Open. Este valor depende del sistema operativo.<br />

Poniéndo el segundo <strong>para</strong>metro en 2, recupera este valor.<br />

Advertencia El atributo de archivos depende del sistema operativo. Si el sistema<br />

operativo es una versión 32-bit, no es posible usar la función FileAttr<br />

<strong>para</strong> determinar al atributo del archivo MS-Dos file de manera que es<br />

regresado un cero.<br />

Ver también: Open<br />

Sintaxis:<br />

FileAttr (NumeroArchivo As Integer, Atributo As Integer)<br />

137


Valor de retorno:<br />

Entero<br />

Parámetros:<br />

NumeroArchivo: Número usado en la instrucción Open.<br />

Atributo: Entero indicando que información retornar. 1 recupera el modo de acceso y 2<br />

recupera el número de acceso del archivo.<br />

Ejemplo:<br />

Sub ExampleFileAttr<br />

Dim iNumber As Integer<br />

iNumber = Freefile<br />

Open "file:///c|/data.txt" For Output As #iNumber<br />

Print #iNumber, "Random Text"<br />

MsgBox AccessModes(FileAttr(#iNumber, 1 )),0,"Access mode"<br />

MsgBox FileAttr(#iNumber, 2 ),0,"File attribute"<br />

Close #iNumber<br />

End Sub<br />

Function AccessModes(x As Integer) As String<br />

Dim s As String<br />

s = ""<br />

If (x AND 1) 0 Then s = "INPUT"<br />

If (x AND 2) 0 Then s = "OUTPUT"<br />

If (x AND 4) 0 Then s = s & " RANDOM"<br />

If (x AND 8) 0 Then s = s & " APPEND"<br />

If (x AND 32) 0 Then s = s & " BINARY"<br />

AccessModes = s<br />

End Function<br />

10.66 Instrucción FileCopy<br />

Sumario:<br />

Copia un archivo. No puede copiar un archivo que esté abierto.<br />

Sintaxis:<br />

FileCopy TextoDesde As String, TextoA As String<br />

Parámetros:<br />

TextoDesde: Cadena especificando el nombre del archivo origen.<br />

TextoA: Cadena especificando el nombre de archivo destino.<br />

Ejemplo:<br />

Sub ExampleFilecopy<br />

Filecopy "c:\Data.txt", "c:\Temp\Data.sav"<br />

End Sub<br />

10.67 Función FileDateTime<br />

Sumario:<br />

138


Retorna una cadena cona la fecha y hora en que un archivo ha sido creado o modificado por<br />

última vez, retornado en un formato que depende del sistema."MM/DD/YYYY HH:MM:SS"<br />

en mi computadora. Considere el uso de la función DateValue function con esta cadena.<br />

Sintaxis:<br />

FileDateTime(Texto As String)<br />

Valor de retorno:<br />

Cadena<br />

Parámetros:<br />

Texto: Especificación del archivo (no se permiten comodines). Notación URL es permitida.<br />

Ejemplo:<br />

Sub ExampleFileDateTime<br />

Rem 04/23/2003 19:30:03<br />

MsgBox FileDateTime("file://localhost/C|/macro.txt")<br />

End Sub<br />

10.68 Función FileExists<br />

Sumario:<br />

Determina si un archivo o directorio existe.<br />

Sintaxis:<br />

FileExists(NombreArchivo As String | NombreDirectorio As String)<br />

Valor de retorno:<br />

Boleano<br />

Parámetros:<br />

NombreArchivo | NombreDirectorio: Archivo o directorio especificado (No se permiten<br />

comodines).<br />

Ejemplo:<br />

Sub ExampleFileExists<br />

MsgBox FileExists("C:\autoexec.bat")<br />

MsgBox FileExists("file://localhost/c|/macro.txt")<br />

MsgBox FileExists("file:///d|/private")<br />

End Sub<br />

10.69 Función FileLen<br />

Sumario:<br />

Determina el tamaño de un archivo. Si el archivo está actualmente abierto, el tamaño antes de<br />

que fue abierto será retornado. Para determinar el largo del archivo de un archivo abierto, en<br />

su lugar use la función Lof.<br />

Sintaxis:<br />

FileExists(NombreArchivo As String)<br />

139


Valor de retorno:<br />

Largo.<br />

Parámetros:<br />

NombreArchivo: Especificación del archivo (No se permiten comodines).<br />

Ejemplo:<br />

Sub ExampleFileExists<br />

MsgBox FileLen("C:\autoexec.bat")<br />

MsgBox FileLen("file://localhost/c|/macro.txt")<br />

End Sub<br />

10.70 Función FindObject<br />

Sumario:<br />

?? No tengo idea 10<br />

Sintaxis:<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

10.71 Función FindPropertyObject<br />

Sumario:<br />

?? No tengo idea 11<br />

Sintaxis:<br />

10 El siguiente texto está tomado de la ayuda en línea:<br />

Permite que los objetos sean referenciados en tiempo de ejecución como un parámetro de cadena de caracteres<br />

por medio del nombre del objeto.<br />

Sintaxis: FindObject(NombreObjeto As String)<br />

Parámetro: NombreObjeto: Cadena que especifica el nombre del objeto que debe ser referenciado en tiempo de<br />

ejecución.<br />

Ejemplo:<br />

Dim ObjVar as Object<br />

Dim ObjProp as Object<br />

ObjName As String = "MyObj"<br />

ObjVar = FindObject( ObjName As String )<br />

PropName As String = "Prop1"<br />

ObjProp = FindPropertyObject( ObjVar, PropName As String )<br />

ObjProp.Command = 5<br />

11 La ayuda en línea de este tópico es igual a la anterior.<br />

140


Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

10.72 Función Fix<br />

Sumario:<br />

Retorna la porción entera de una expresión numérica removiendo la fracción.<br />

Ver también: CInt<br />

Sintaxis:<br />

Fix(Expresión)<br />

Valor de retorno:<br />

Doble<br />

Parámetros:<br />

Expresión: Número del cual se retornará la parte entera.<br />

Ejemplo:<br />

sub ExampleFix<br />

Print Fix(3.14159) REM returns 3.<br />

Print Fix(0) REM eturns 0.<br />

Print Fix(-3.14159) REM returns -3.<br />

End Sub<br />

10.73For...Next Statement<br />

Sumario:<br />

Construye una repetición de instrucciones con un contador que se autoincrementa.<br />

Ver también: For....Next en la página 91.<br />

Sintaxis:<br />

For contador=inicio To end [Step paso]<br />

block de instrucciones<br />

[Exit For]<br />

block de instrucciones<br />

Next [contador]<br />

141


10.74 Función Format<br />

Sumario:<br />

Convierte un número en una cadena formateada de acuerdo al formado de cadena opcional.<br />

Formatos múltiples pueden ser incluidos en una sola cadena de formato. Cada formato<br />

individual está se<strong>para</strong>do por un “;”. El primer formato es usado <strong>para</strong> los números positivos, el<br />

segundo <strong>para</strong> los negativos y el tercero <strong>para</strong> el cero. Si sólo un código de formato está<br />

presente, se aplica <strong>para</strong> todos los números.<br />

Código Descripción<br />

0<br />

#<br />

.<br />

%<br />

E-<br />

E+<br />

ee+<br />

,<br />

- + $ ( ) space<br />

Si un número tiene un dígito en la posición del cero en el código del<br />

formato, el dígito es desplegado; de lo contrario aparecerá un cero. Esto<br />

significa que los cero al inicio y al final son despegados, los digitos al<br />

inicio no serán truncados y los decimales al final serán redondeados.<br />

Esto trabaja como el 0, pero los ceros al inicio y al final no son<br />

desplegados.<br />

El punto decimal determina el número de posiciones decimales a la<br />

derecha y a la izquierda del se<strong>para</strong>dor decimal.<br />

Multiplica el número por 100 e inserta el signo porcentual (%) en donde<br />

aparezca en el código del formato.<br />

Si el código de formato contiene al menos una posición <strong>para</strong> digitos a la<br />

derecha del simbolo, el número será formateado en notación científica.<br />

La letra E o e es insertada entre el número y el exponente. El número de<br />

posiciones <strong>para</strong> los dígitos a la derecha del símbolo determina el número<br />

de dígitos en el exponente. Si el exponente es negativo, un signo de<br />

menos es desplegado directamente antes del exponente. Si el exponente<br />

es positivo, un signo de más solamente será desplegado antes con E+ o<br />

e+.<br />

La coma es un indicador <strong>para</strong> el se<strong>para</strong>dor de miles. Se<strong>para</strong> los miles de<br />

los cientos en un número de al menos cuatro dígitos.<br />

El delimitador de miles es desplegado si el formato contiene el<br />

delimitador rodeado de los indicadores de dígitos (0 o #).<br />

Más (+), menos (-), dólar ($), espacio, o paréntesis entradas directamente<br />

en el formato son desplegadas como caracteres literales.<br />

142


Código Descripción<br />

\<br />

Números en<br />

general<br />

Moneda<br />

Fijo<br />

Standard<br />

Científico<br />

El “backslash” despliega el siguiente caracter en el formato del codigo.<br />

En otras palabras, previene que el siguiente caracter se lea como un<br />

caracter especial. El “backslash” no es desplegado, a menos que<br />

introduzca un doble “backslash” (\\) en el código de formato.<br />

Los caracteres que pueden ser precedidos por un “backslash” en el<br />

código de formato <strong>para</strong> que sean desplegados como caracteres literales<br />

son los caracteres de formato de fecha-hora (a, c, d, h, m, n, p, q, s, t, w,<br />

y, /, :), caracteres de formateo de números (#, 0, %, E, e, coma, punto) y<br />

caracteres de formatero de cadenas (@, &, , !). Puede encerrar los<br />

caracteres en comillas dobles.<br />

Los números se despliegan tal y como se introducen.<br />

Un signo de dólar es colocado al frente del número; los números<br />

negativos son encerrados en paréntesis. Se despliegan dos decimales.<br />

(Actualmente, esto es especifico de la localización)<br />

Al menos un digito es desplegado al frente del se<strong>para</strong>dor decimal. Se<br />

despliegan dos decimales.<br />

Despliega los números con el se<strong>para</strong>dor de miles específico de la<br />

localización. Se despliegan dos decimales.<br />

Despliego los números en notación científica. Se despliegan dos<br />

decimales.<br />

Advertencia No se hace ninguna conversión si el parámetro no es un número (como<br />

cuando es una cadena) y una cadena vacía es devuelta.<br />

Advertencia La versión 1.0.3.1, Format(123.555, “.##”) produce “.12356” lo que<br />

considero un problema. Cambiando el formato a “#.##” resuelve el<br />

problema. Use siempre un “#” o “0” adelante según sea lo apropiado.<br />

La notación científica actualmente está mala (quebrada)<br />

Moneda es colocando el signo de dólar a la derecha.<br />

Actualmente no es posible realizar caracteres especiales de escape.<br />

Sintaxis:<br />

Format (Número [, Formato As String])<br />

Valor de retorno:<br />

Cadena<br />

143


Parámetros:<br />

Número: Expresión numérica a ser convertida a una cadena formateada.<br />

Formato: El formato deseado. Si es omitido, la función Format trabajará como la función Str.<br />

Ejemplo:<br />

Sub ExampleFormat<br />

MsgBox Format(6328.2, "##,##0.00") REM = 6,328.20<br />

MsgBox Format(123456789.5555, "##,##0.00") REM = 123,456,789.56<br />

MsgBox Format(0.555, ".##") Rem .56<br />

MsgBox Format(123.555, "#.##") Rem 123.56<br />

MsgBox Format(0.555, "0.##") Rem 0.56<br />

MsgBox Format(0.1255555, "%#.##") Rem %12.56<br />

MsgBox Format(123.45678, "##E-####") Rem 12E1<br />

MsgBox Format(.0012345678, "0.0E-####") Rem 1.2E3 (broken)<br />

MsgBox Format(123.45678, "#.e-###") Rem 1e2<br />

MsgBox Format(.0012345678, "#.e-###") Rem 1e3 (broken)<br />

MsgBox Format(123.456789, "#.## is ###") Rem 123.45 is 679 (strange)<br />

MsgBox Format(8123.456789, "General Number")Rem 8123.456789<br />

MsgBox Format(8123.456789, "Fixed") Rem 8123.46<br />

MsgBox Format(8123.456789, "Currency") Rem 8,123.46$ (broken)<br />

MsgBox Format(8123.456789, "Standard") Rem 8,123.46<br />

MsgBox Format(8123.456789, "Scientific") Rem 8.12E03<br />

MsgBox Format(0.00123456789, "Scientific") Rem 1.23E03 (broken)<br />

End Sub<br />

10.75 Función FreeFile<br />

Sumario:<br />

Retorna el siguiente número de archivo disponible <strong>para</strong> abrir un archivo. Esto asegura que<br />

nunca use un número de archivo que esté actualmente en uso.<br />

Ver también Open, EOF, Kill, y Close.<br />

Sintaxis:<br />

FreeFile<br />

Valor de retorno:<br />

Entero<br />

Ejemplo:<br />

Ver el ejemplo <strong>para</strong> Close.<br />

10.76FreeLibrary Function<br />

Sumario:<br />

Libera una DLL que ha sido cargada por una instrucción Declare. La DLL será<br />

automaticamente recargada si una de sus funciones es llamada. Solamente las DLLs cargadas<br />

durante el tiempo de ejecución de Basic pueden ser liberadas.<br />

Ver también: Declare<br />

144


Sintaxis:<br />

FreeLibrary (NombreLib As String)<br />

Parámetros:<br />

NombreLib: Nombre de la DLL.<br />

Ejemplo:<br />

Declare Sub MyMessageBeep Lib "user32.dll" Alias "MessageBeep" ( long )<br />

Sub ExampleDeclare<br />

Dim lValue As Long<br />

lValue = 5000<br />

MyMessageBeep( lValue )<br />

FreeLibrary("user32.dll" )<br />

End Sub<br />

10.77 Instrucción Function<br />

Sumario:<br />

Define una función definida por el usuario, en oposición a una subrutina.<br />

Ver también: Sub<br />

Sintaxis:<br />

Function Nombre[(Variable1 [As Tipo][, Variable2 [As Tipo][,...]]]) [As Tipo]<br />

bloque de instrucciones<br />

[Exit Function]<br />

bloque de instrucciones<br />

End Function<br />

Valor de retorno:<br />

Cualquier tipo que haya sido declarado.<br />

Ejemplo:<br />

Function IsWhiteSpace(iChar As Integer) As Boolean<br />

Select Case iChar<br />

Case 9, 10, 13, 32, 160<br />

IsWhiteSpace = True<br />

Case Else<br />

IsWhiteSpace = False<br />

End Select<br />

End Function<br />

10.78 Instrucción Get<br />

Sumario:<br />

Lee un registro de un archivo relativo, o una secuencia de bytes de un archivo binario, dentro<br />

de una variable. Si el parámetro de posición es omitido, los datos son leidos de la posición<br />

actual en el archivo. Para los archivos abiertos en modo binario, la posición es la posición del<br />

145


yte en el archivo.<br />

Ver también: PUT<br />

Sintaxis:<br />

Get [#] NúmeroArchivo As Integer, [Posición], Variable<br />

Parámetros:<br />

NúmeroArchivo: expresión entera que determina el número de archivo. Yo uso FreeFile <strong>para</strong><br />

obtenerlo.<br />

Posición: Para los archivos abiertos en modo aleatorio, este es el número de registro a ser<br />

leido.<br />

Variable: Variable a leer. El objeto Variable puede no ser usado aqui.<br />

Ejemplo:<br />

'?? This is broken!<br />

Sub ExampleRandomAccess2<br />

Dim iNumber As Integer, aFile As String<br />

Dim sText As Variant REM Must be a variant<br />

aFile = "c:\data1.txt"<br />

iNumber = Freefile<br />

Open aFile For Random As #iNumber Len=5<br />

Seek #iNumber,1 REM Position at beginning<br />

Put #iNumber,, "1234567890" REM Fill line with text<br />

Put #iNumber,, "ABCDEFGHIJ"<br />

Put #iNumber,, "abcdefghij"<br />

Rem This is how the file looks now!<br />

Rem 08 00 0A 00 31 32 33 34 35 36 37 38 39 30 08 00 ....1234567890..<br />

Rem 0A 00 41 42 43 44 45 46 47 48 49 4A 08 00 0A 00 ..ABCDEFGHIJ....<br />

Rem 61 62 63 64 65 66 67 68 69 6A 00 00 00 00 00 00 abcdefghij<br />

Rem<br />

Seek #iNumber,1<br />

Get #iNumber,,sText<br />

Print "on open:" & sText<br />

Close #iNumber<br />

iNumber = Freefile<br />

Open aFile For Random As #iNumber Len=5<br />

Get #iNumber,,sText<br />

Print "reopened: " & sText<br />

Put #iNumber,,"ZZZZZ"<br />

Get #iNumber,1,sText<br />

Print "anoter get "& sText<br />

Get #iNumber,1,sText<br />

Put #iNumber,20,"This is the text in record 20"<br />

Print Lof(#iNumber)<br />

Close #iNumber<br />

End Sub<br />

146


10.79 Función GetAttr<br />

Sumario:<br />

Retorna un máscara de bits <strong>para</strong> el tipo de archivo. Los atributos son el tipo usado en la<br />

función Dir.<br />

Ver también: Dir<br />

Atributo Descripción<br />

0 Archivo Normal.<br />

1 Archivo de Sólo-Lectura<br />

2 Archivo oculto.<br />

4 Archivo de sistema.<br />

8 Nombre del Volumen.<br />

16 Directorio.<br />

32<br />

Bit de archivado (el archivo cambio desde el<br />

último backup)<br />

Advertencia No sirve en 1.0.3.1. Pruebe con la versión que usted usa.<br />

Sintaxis:<br />

GetAttr (Texto As String)<br />

Valor de retorno:<br />

Entero<br />

Parámetros:<br />

Texto: Expresión de cadena que contiene una especificación única de archivo. Es válida la<br />

notación URL.<br />

Ejemplo:<br />

Sub ExampleGetAttr<br />

Rem Should say " Read-Only Hidden System Archive"<br />

Rem says " Read-Only"<br />

Print FileAttributeString(GetAttr("C:\IO.SYS"))<br />

Rem Should say " Archive" says "Normal"<br />

Print FileAttributeString(GetAttr("C:\AUTOEXEC.BAT"))<br />

Rem "Directory"<br />

Print FileAttributeString(GetAttr("C:\WINDOWS"))<br />

End Sub<br />

Function FileAttributeString(x As Integer) As String<br />

Dim s As String<br />

If (x = 0) Then<br />

s = "Normal"<br />

Else<br />

s = ""<br />

147


If (x AND 16) 0 Then s = "Directory"<br />

If (x AND 1) 0 Then s = s & " Read-Only"<br />

If (x AND 2) 0 Then s = " Hidden"<br />

If (x AND 4) 0 Then s = s & " System"<br />

If (x AND 8) 0 Then s = s & " Volume"<br />

If (x AND 32) 0 Then s = s & " Archive"<br />

End If<br />

FileAttributeString = s<br />

End Function<br />

10.80 Función GetProcessServiceManager<br />

Sumario:<br />

Obtiene el administrador Uno central. Esto es requerido cuando debe iniciar un servicio<br />

usando CreateInstance con argumentos.<br />

?? Encontrar un mejor ejemplo que este! Mostrar un ejemplo que toma un argumento!<br />

Sintaxis:<br />

oServiceManager = GetProcessServiceManager()<br />

Valor de retorno:<br />

Ejemplo:<br />

oServiceManager = GetProcessServiceManager()<br />

oIntrospection = oServiceManager.createInstance("com.sun.star.beans.Introspection");<br />

this is the same as the following statement:<br />

oIntrospection = CreateUnoService("com.sun.star.beans.Introspection")<br />

10.81 Función GetSolarVersion<br />

Sumario:<br />

Retorna el número interno de la versión actual de <strong>OpenOffice</strong>.org. Puede escribir sus <strong>macros</strong><br />

de manera que trabajen alrededor de problemas conocidos en las diferentes versiones.<br />

Sintaxis:<br />

s = GetSolarVersion()<br />

Valor de retorno:<br />

Cadena<br />

Ejemplo:<br />

Sub ExampleGetSolarVersion<br />

Rem as of 1.0.3.1, this is "641"<br />

Print GetSolarVersion()<br />

End Sub<br />

148


10.82 Función GetSystemTicks<br />

Sumario:<br />

Retorna los tiempos del sistema provistos por el sistema operativo. El número de tiempos de<br />

reloj del sistema retornados dentro de ciertos marcos de tiempo, dependen del sistema<br />

operativo.<br />

Sintaxis:<br />

GetSystemTicks()<br />

Valor de retorno:<br />

Largo<br />

Ejemplo:<br />

Este ejemplo intentará medir cuantos tiempos de reloj hay por segundo. En Windows XP y la<br />

versión 1.0.3.1 de <strong>OpenOffice</strong>.org, veo 1000 tiempos de reloj por segundo.<br />

Sub ExampleGetSystemTicks<br />

Dim lTick As Long, lMillisToWait As Long<br />

Dim lSecsToWait As Long, lTicksPerSec As Long<br />

lSecsToWait = 60<br />

lMillisToWait = lSecsToWait * 1000<br />

lTick = GetSystemTicks()<br />

wait(lMillisToWait)<br />

lTick = (GetSystemTicks() - lTick)<br />

lTicksPerSec = lTick / lSecsToWait<br />

MsgBox "Each second has about " & lTicksPerSec & " Ticks Per Second"<br />

End Sub<br />

10.83 Instrucción GlobalScope<br />

Sumario:<br />

Los <strong>macros</strong> de y diálogos están organizados en librerias. Una librería puede contener<br />

módulos y/o diálogos. En Basic, el contenedor de librerías es llamado “BasicLibraries” y el<br />

contenedor de dialogos es llamado “DialogLibraries”. De esta forma ambos contenedores de<br />

librerías existen en el nivel de aplicación y de documento, en basic estas son cargadas<br />

automáticamente pero no en el doumento. Para llamar estos contenedores de librerías<br />

globales dentro de un documento, debe usar la palabra clave GlobalScope.<br />

Sintaxis:<br />

GlobalScope<br />

Ejemplo:<br />

' calling Dialog1 in the document library Standard<br />

oDlgDesc = DialogLibraries.Standard.Dialog1<br />

' calling Dialog2 in the application library Library1<br />

oDlgDesc = GlobalScope.DialogLibraries.Library1.Dialog2<br />

149


10.84 Function<br />

Sumario:<br />

Sintaxis:<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

10.85 Function<br />

Sumario:<br />

Sintaxis:<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

10.86 Function<br />

Sumario:<br />

Sintaxis:<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

150


???????<br />

10.87 Function<br />

Sumario:<br />

Sintaxis:<br />

Valor de retorno:<br />

Parámetros:<br />

Ejemplo:<br />

10.88 Función Green<br />

Sumario:<br />

Los colores son representados por un entero largo. Retorna el componente verde del código<br />

de colores específico. Ver también RGB, Red, y Blue.<br />

Sintaxis:<br />

Green(Color As Long)<br />

Valor de retorno:<br />

Entero en el rango de 0 a 255.<br />

Parámetros:<br />

Color: Expresión de entero largo representando un color.<br />

Ejemplo:<br />

Sub ExampleColor<br />

Dim lColor As Long<br />

lColor = RGB(255,10,128)<br />

MsgBox "The color " & lColor & " consists of:" & Chr(13) &_<br />

"Red = " & Red(lColor) & Chr(13)&_<br />

"Green= " & Green(lColor) & Chr(13)&_<br />

"Blue= " & Blue(lColor) & Chr(13) , 64,"Colors"<br />

End Sub<br />

151


10.89 Palabra clave Private<br />

Sumario:<br />

La palabra clave Private es usado <strong>para</strong> declarar una variable fuera de una subrutina como<br />

privada. Si una variable es declarada usando la palabra clave Dim, es considerada privada.<br />

Ver también la descripción <strong>para</strong> las descripciones de la sintaxis de Dim.<br />

Ver también: Dim, Public<br />

Sintaxis:<br />

Private Nombre_1 [(inicio To fin)] [As VarType][, Nombre_2 [(inicio To fin)] [As VarType]<br />

[,...]]<br />

Ejemplo:<br />

Private iPriv As Integer<br />

Sub ExamplePublic<br />

iPriv = 1<br />

Call CalledSub<br />

End Sub<br />

Sub CalledSub<br />

Print iPriv Rem 1<br />

End Sub<br />

10.90 Palabra clave Public<br />

Sumario:<br />

La palabra clave Public es usada <strong>para</strong> declarar una variable fuera de una subrutina como<br />

pública <strong>para</strong> todos los módulos. Si una variable es declarada usando la palabra clave Dim, es<br />

considerada privada. Vea la descripción en Dim <strong>para</strong> la sintaxis.<br />

Ver también: Dim, Private<br />

Sintaxis:<br />

Public Nombre_1 [(inicio To fin)] [As VarType][, Nombre_2 [(inicio To fin)] [As VarType]<br />

[,...]]<br />

Ejemplo:<br />

Public iPub As Integer<br />

Sub ExamplePublic<br />

iPub = 1<br />

Call CalledSub<br />

End Sub<br />

Sub CalledSub<br />

Print iPub Rem 1<br />

End Sub<br />

152


10.91 Función Red<br />

Sumario:<br />

Los colores son representados por un entero largo. Retorna el componente rojo del código de<br />

colores específico. Ver también RGB, Green, y Blue.<br />

Sintaxis:<br />

Red(Color As Long)<br />

Valor de retorno:<br />

Entero en el rango de 0 a 255.<br />

Parámetros:<br />

Color: Expresión de entero largo representando un color.<br />

Ejemplo:<br />

Sub ExampleColor<br />

Dim lColor As Long<br />

lColor = RGB(255,10,128)<br />

MsgBox "The color " & lColor & " consists of:" & Chr(13) &_<br />

"Red = " & Red(lColor) & Chr(13)&_<br />

"Green= " & Green(lColor) & Chr(13)&_<br />

"Blue= " & Blue(lColor) & Chr(13) , 64,"Colors"<br />

End Sub<br />

10.92 Notación y nombres de archivo URL<br />

10.92.1 Notación URL<br />

En una computadora con windows, “c:\autoexec.bat” es un típico método <strong>para</strong> referenciar un<br />

archivo. Esto también puede ser referenciado en notación URL como “file:///c|/autoexec.bat”.<br />

Una idea general cuando realice conversiones es iniciar el URL con “file:///”, cambiar “:” por<br />

“|”, y reemplazar “\” con “/”. Si desea insertar el nombre de una computadora o una dirección<br />

IP, insértelo entre el segundo y tercer caracter “/” como en “file://localhost/c|/autoexec.bat/”.<br />

10.92.2 Rutas con espacios y otros caracteres especiales.<br />

Los espacios y caracteres especiales pueden ser cambiados en las URLs como notación<br />

estandar de archivos usando la secuencia de escape standar de URL. Tome el valor ASCII<br />

que intenta cambiar, conviertalo en hex, ponga el caracter “%” antes, y coloquelo donde<br />

desea el caracter especial. Considere el cambio por un espacio en la ruta. “c:\My%<br />

20Documents\info.sxw” y “file///c|/My%20Documents/info.sxw”.<br />

153


154


11Index<br />

/ 86p., 90, 101, 103p.<br />

Abs 106<br />

And 87, 101, 105<br />

Array 85p.<br />

Asc 107<br />

ATN 108<br />

AVERAGE 41<br />

Beep 108<br />

Blue 109<br />

Bool 79<br />

BottomLine 42<br />

ByVal 89, 109<br />

Call 110<br />

case 93, 95<br />

Case Else 93<br />

CBool 110<br />

Cbyte 111<br />

CDate 111<br />

CDateFromIso 111p.<br />

CDateToIso 112<br />

CDbl 113<br />

Cell<br />

CellAddress 38, 74p.<br />

CellBackColor 35<br />

getFormula 35<br />

getSpreadSheet 38, 74p.<br />

getString 35<br />

getValue 35<br />

IsCellBackgroundTransparent 35<br />

NumberFormat 35, 41<br />

setFormula 35, 41<br />

setString 35, 41<br />

setValue 35<br />

String 29<br />

CellAddress<br />

Column 38, 74p.<br />

Row 38, 74p.<br />

CharacterProperties<br />

CharFontName 69<br />

Charheight 69<br />

CharLocale 69<br />

CharPosture 69<br />

FontSlant 69<br />

CharUnderline 69<br />

CharWeight 69<br />

FontWeight 69<br />

FontSlant<br />

DONTKNOW 69<br />

ITALIC 69<br />

NONE 69<br />

OBLIQUE 69<br />

REVERSE_ITALIC 69<br />

REVERSE_OBLIQUE 69<br />

FontUnderline<br />

BOLD 69<br />

BOLDDASH 69<br />

BOLDDASHDOT 69<br />

BOLDDASHDOTDOT 69<br />

BOLDDOTTED 69<br />

BOLDLONGDASH 69<br />

BOLDWAVE 69<br />

DASH 69<br />

DASHDOT 69<br />

DASHDOTDOT 69<br />

DONTKNOW 69<br />

DOTTED 69<br />

DOUBLE 69<br />

DOUBLEWAVE 69<br />

LONGDASH 69<br />

NONE 69<br />

SINGLE 69<br />

SMALLWAVE 69<br />

WAVE 69<br />

FontWeight<br />

BLACK 69<br />

BOLD 69<br />

DONTKNOW 69<br />

LIGHT 69<br />

NORMAL 69<br />

SEMIBOLD 69<br />

SEMILIGHT 69<br />

THIN 69<br />

ULTRABOLD 69<br />

ULTRALIGHT 69<br />

ChDir 113<br />

ChDrive 114<br />

Choose 114<br />

Chr 107, 115<br />

Christian Anderson 88<br />

CInt 115<br />

155


CLong 116<br />

Close 31, 116, 134, 147<br />

Component<br />

CurrentController 41<br />

CurrentSelection 41<br />

DatabaseRanges 41<br />

getCurrentController 43<br />

removeByName 42<br />

StatusIndicator 20<br />

Text 1<br />

computed goto 95<br />

Config<br />

commitChanges 25<br />

ConfigurationUpdateAccess 25<br />

createInstanceWithArguments 25<br />

PickListSize 25<br />

replaceByName 25<br />

ConfigurationProvider 25<br />

Const 117<br />

Controller<br />

ActiveSheet 41<br />

getViewCursor() 69<br />

select 43<br />

StatusIndicator 20<br />

ConvertFromURL 117<br />

ConvertToURL 118<br />

Cos 118<br />

CreateUnoDialog 119<br />

CreateUnoService 25, 120<br />

CreateUnoStruct 120<br />

CSng 121<br />

CStr 121<br />

CurDir 122<br />

Currency 79<br />

CurrentController 20<br />

Cursor<br />

getRangeName 29<br />

getStart() 69<br />

goRight 29<br />

gotoEndOfParagraph() 69<br />

gotoStartOfParagraph() 69<br />

Date 79, 122<br />

DateSerial 112, 123<br />

DateValue 111p., 124<br />

Day 124<br />

DBG_methods 8<br />

DBG_Properties 8<br />

Declare 125<br />

DefBool 79, 126<br />

DefDate 79, 126<br />

DefDbl 79, 127<br />

DefInt 79, 127<br />

DefLng 79, 127<br />

DefObj 79, 128<br />

DefVar 79, 128<br />

Desktop<br />

CurrentComponent 41<br />

LoadComponentFromURL() 27<br />

Dim 79pp., 84p., 129<br />

Dim” 79<br />

DimArray 85, 130<br />

DimArray. 85, 106<br />

Dir 130, 150<br />

Do...Loop más cercano 138<br />

Double 79<br />

Else 90<br />

ElseIf 90<br />

El tipo por defecto es Single 79<br />

End 132p.<br />

End Function 132p.<br />

End If 133<br />

End Select 133<br />

End Sub 133<br />

Environ 133<br />

EOF 116, 134, 147<br />

EqualUnoObjects 134<br />

EQV 101, 135<br />

Erl 136<br />

Err 136<br />

Error 137<br />

Exit 96<br />

Exit DO 96<br />

Exit For 96<br />

Exit Function 96<br />

Exit Sub 96<br />

Exit. 87<br />

Exit Do 93, 138<br />

Exit For 91, 138<br />

Exit Function 139<br />

Exit Sub 139<br />

Exp 139<br />

False 87<br />

156


Fecha 122<br />

Fibonnaci 33<br />

File<br />

CLOSE 31<br />

FileExists 31<br />

LINE INPUT 31<br />

OPEN 31<br />

FileAttr 140<br />

FileCopy 141<br />

FileDateTime 141<br />

FileExists 142<br />

Fix 144<br />

For 91<br />

For...Next 138<br />

Format 146<br />

FreeFile 116, 134, 147<br />

Function 87<br />

Get 149<br />

GetAttr 130, 150<br />

getCurrentComponent 20<br />

getNumberFormats() 32<br />

getPathSe<strong>para</strong>tor() 131<br />

GetProcessServiceManager() 151<br />

GetSolarVersion() 151<br />

GetSystemTicks() 152<br />

GlobalScope 152<br />

GoSub 90, 94<br />

GoTo 31, 90, 94p.<br />

Green 154<br />

If 90<br />

If. 90<br />

IIf 87, 90p.<br />

Int 31<br />

Integer 79<br />

Is 87, 93<br />

IsArray 86<br />

IsDate 86<br />

IsEmpty 86<br />

IsMissing 32, 86, 88<br />

IsNull 74, 86<br />

IsNumeric 86<br />

IsObject 86<br />

IsUnoStruct 86<br />

Kelecevic, Sasa 27<br />

Kill 116, 134, 147<br />

Las variables enteras son números de 16-bits<br />

dentro de un rango de 83<br />

Las varibles Object4 79<br />

LBound 21, 23, 84p.<br />

LEN 20, 31<br />

LineDistance 42<br />

Locale<br />

Country 69<br />

Language 69<br />

Long 79<br />

Loop 92<br />

Do 92<br />

Do Until 92<br />

Do While 92<br />

Loop Until 93<br />

Loop While 92<br />

Los objetos de cadena están limitados a 80<br />

Los objetos Variant 80<br />

Macro Author<br />

Andrew Pitonyak<br />

AccessModes 141<br />

BuildSortedArray 76<br />

CalcGroupingExample 44<br />

ClearDefinedRange 36<br />

ColumnNumberToString 38, 75<br />

CreateSelectedTextIterator 52<br />

DisplayAllStyles 21<br />

ExampleNewPage 72<br />

FileAttributeString 151<br />

FindCreateNumberFormatStyle 32<br />

FirstDuplicate 77<br />

ForNextExampleSort 91<br />

GetLeftMostCursor 50<br />

GetRightMostCursor 50<br />

GoToExample 95<br />

InsertDateField 71<br />

InsertDateIntoCell 39<br />

InsertSimpleText 69<br />

IsAnythingSelected 48<br />

IsSpreadhsheetDoc 35<br />

IsWhiteSpace 53, 148<br />

IterateOverSelectedTextFramework 51<br />

MultipleTextSelectionExample 49<br />

NonBlankCellsInColumn 75<br />

OnGoToExample 95<br />

PrintableAddressOfCell 38, 74<br />

PrintableCellAddress 75<br />

157


PrintAscii 7<br />

PrintDataInColumn 44<br />

PrintEachCharacterWorker 53<br />

ProtectSpreadsheet 45<br />

RankChar 54<br />

Read_Write_Number_In_File 31<br />

RemoveEmptyParsWorker 56<br />

RemoveFromString 6<br />

ReplaceInString 6<br />

SelectedNewLinesToSpaces 56<br />

SelectedNewParagraphsToNewLines<br />

57<br />

SetTextAttributes 68<br />

testOptionalParameters 88<br />

edA-qa mort-ora-y<br />

Fibonnaci 33<br />

Hermann Kienlein<br />

CreateTable 29<br />

InsertNextItem 29<br />

Niklas Nebel<br />

setting_borders_in_calc 42<br />

<strong>OpenOffice</strong><br />

GetDocumentType 7<br />

Pavel Janík<br />

CallExternalProgram 30<br />

Sasa Kelecvic<br />

_no_salvar 27<br />

ActiveSheet 41<br />

Analize 41<br />

CellPos 41<br />

DefineDbRange 42<br />

DeleteDbRange 41p.<br />

ExampleGetValue 35<br />

ExampleSetValue 35<br />

FillCells 40<br />

GetAddress 41<br />

open_new 29<br />

open_old_file 29<br />

ProgressBar 20<br />

salvar_y_cerrar 27<br />

SelectedCells 39<br />

SortRange 43<br />

StatusText 20<br />

Tony Bloomfield<br />

DisplayMethods 8<br />

Unknown<br />

ChangePickListSize 25<br />

MAX 41<br />

MIN 41<br />

MOD 21, 101<br />

NOT 87<br />

Null 86<br />

NumberFormat 32<br />

addNew 32<br />

DATE 32<br />

FindCreateNumberFormatStyle 39, 71<br />

queryKey 32<br />

Object 79<br />

On Error 97<br />

Local 97<br />

On Error 97<br />

On Error GoTo 0 97<br />

On Error GoTo Label 97<br />

On Error Resume Next 97<br />

ON ERROR 31<br />

On Local Error Goto 0 31<br />

On N GoSub 95<br />

On N GoTo 95<br />

Open 31, 134, 147<br />

Option<br />

Explicit 25<br />

Option 25<br />

Optional 32, 88<br />

Option Base 84<br />

Option Explicit 9, 79<br />

OR 87, 101<br />

PageDescName 71<br />

PageDescName es el nombre del nuevo estilo<br />

de página que se usa después del salto de<br />

página. Si no usa un estilo de página existente,<br />

entonces fallará 71<br />

PageNumberOffset 71<br />

PI 84<br />

PRINT 31<br />

printdbgInfo 3<br />

Private 80p., 155<br />

PropertyValue 25, 43<br />

Name 25, 43<br />

Value 25, 43<br />

Public 80p., 155<br />

Public5 80<br />

Red 156<br />

158


ReDim 79, 129<br />

ReDim<br />

Preserve 85p.<br />

ReDim 85p.<br />

ReDimExample 85<br />

ReDim. 80<br />

Return 94<br />

Select Case 93<br />

Selection<br />

Columns 41<br />

getRangeAddress 41<br />

Rows 41<br />

shell 30<br />

Single 79<br />

Sort 43<br />

SortField 43<br />

Field 43<br />

SortAscending 43<br />

SPACE 20<br />

SpreadsheetDocument<br />

BottomLine 42<br />

Column<br />

Columns 39p.<br />

getByIndex 40p.<br />

getCount 40p.<br />

getName 40, 44<br />

Columns 39, 44<br />

Count 36<br />

CurrentSelection 39p.<br />

getByName 35, 43<br />

getCellByPosition 35, 40<br />

getCellRangeByName 43<br />

getCellRangeByPosition 42<br />

getCount 40<br />

getName 38, 74p.<br />

getRangeAddress 39<br />

Row<br />

EndRow 40p.<br />

getCount 40p.<br />

Rows 40<br />

StartRow 40p.<br />

Rows 40<br />

setString 40<br />

Sheets 35p., 42pp.<br />

SpreadsheetDocument 35<br />

SupportsService 35<br />

TableBorder 42<br />

StarDesktop” respectivamente 1<br />

Static 81<br />

Static6 80<br />

StatusIndicator<br />

start 20<br />

Str 31<br />

String 79<br />

Styles<br />

CharacterStyles 21<br />

FrameStyles 21<br />

getByName 21<br />

getElementNames() 21<br />

NumberingStyles 21<br />

PageStyles 21<br />

ParagraphStyles 21<br />

StyleFamilies 21<br />

Sub 87<br />

switch 93, 95<br />

TableBorder 42<br />

Tan 108<br />

TextCursor<br />

goRight() 47<br />

gotoEnd() 47<br />

gotoStart() 47<br />

IsCollapsed 47<br />

IsCollapsed() 48p.<br />

TextDocument<br />

compareRegionEnds() 49<br />

compareRegionStarts() 49p.<br />

createTextCursorByRange 69<br />

createTextCursorByRange() 48pp., 69<br />

CurrentController 69<br />

getCurrentSelection<br />

getCount() 49<br />

getCurrentSelection() 48p.<br />

getByIndex() 49<br />

getCount() 48<br />

getString() 30<br />

getText() 30<br />

insertControlCharacter 58<br />

insertString 69<br />

setString 30<br />

Text 30, 69<br />

TextTable<br />

getCellByName 29<br />

159


ThisComponent” 1<br />

TimeValue 111<br />

To 93<br />

Trim 31<br />

True 87<br />

UBound 21<br />

Variant 79<br />

wait 30<br />

While...Wend 94<br />

WritedbgInfo 3<br />

XOR 87, 101<br />

160

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!