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
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