Commit 1f440ea3 authored by Mauricio Baeza's avatar Mauricio Baeza

Merge branch 'develop'

Ranges and data in Calc in Basic and Python
parents edd74624 111e8ba8
#!/usr/bin/env python3
import os
import zipfile
import click
def _join(*paths):
return os.path.join(*paths)
PATH_USER = '/home/mau/.temp/develop/user'
LANG = 'basic'
VERSION = '0.1.0'
EXT_NAME = 'EasyMacro'
EXT_ID = f'org.universolibre.{EXT_NAME}'
PATH_LIBRARY = _join(PATH_USER, LANG, EXT_NAME)
PATH_PROYECT = os.path.dirname(os.path.realpath(__file__))
PATH_EXT = _join(PATH_PROYECT, f'{EXT_NAME}_v{VERSION}.oxt')
PATH_ZIP = _join(PATH_PROYECT, f'{EXT_NAME}_v{VERSION}.zip')
PATH_UPDATE = _join(PATH_PROYECT, f'{EXT_NAME}.update.xml')
LANG_APP = {
'basic': 'basic-library',
}
DESC_LANG = {
'desc.en': 'Easy develop macros with Basic',
'desc.es': 'Desarrollo fácil de macros con Basic',
}
DESCRIPTION = """<?xml version="1.0" encoding="UTF-8"?>
<description xmlns="http://openoffice.org/extensions/description/2006" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:d="http://openoffice.org/extensions/description/2006">
<identifier value="{ext_id}" />
<version value="{version}" />
<update-information>
<src xlink:href="https://gitlab.com/mauriciobaeza/libreoffice-macros/raw/master/easy-macro/{ext_name}.update.xml" />
</update-information>
<publisher>
<name xlink:href="https://universolibre.org" lang="es">Universo Libre Mexico, A.C.</name>
</publisher>
<display-name>
<name lang="en">{ext_name}</name>
<name lang="es">{ext_name}</name>
</display-name>
<extension-description>
<src lang="en" xlink:href="descriptions/desc.en"/>
<src lang="es" xlink:href="descriptions/desc.es"/>
</extension-description>
</description>
"""
MANIFEST = """<?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest>
<manifest:file-entry manifest:full-path="{ext_name}/" manifest:media-type="application/vnd.sun.star.{lang}"/>
</manifest:manifest>
"""
UPDATE = """<?xml version="1.0" encoding="UTF-8"?>
<description xmlns="http://openoffice.org/extensions/update/2006"
xmlns:xlink="http://www.w3.org/1999/xlink">
<identifier value="{ext_id}"/>
<version value="{version}" />
<update-download>
<src xlink:href="https://gitlab.com/mauriciobaeza/libreoffice-macros/raw/master/easy-macro/{ext_name}_v{version}.oxt" />
</update-download>
</description>
"""
values_description = {
'ext_name': EXT_NAME,
'ext_id': EXT_ID,
'version': VERSION,
}
values_manifest = {
'ext_name': EXT_NAME,
'lang': LANG_APP[LANG],
}
data_description = DESCRIPTION.format(**values_description)
data_manifest = MANIFEST.format(**values_manifest)
data_update = UPDATE.format(**values_description)
def _to_zip(path, files, mode='w'):
with zipfile.ZipFile(path, mode, zipfile.ZIP_DEFLATED, False) as zip_file:
for path, file_name, data in files:
if path:
zip_file.write(path, file_name)
else:
zip_file.writestr(file_name, data)
return
def _get_files(path):
files = []
l = len(path) + 1
for root, dirs, names in os.walk(path):
for n in names:
p = _join(root, n)
files.append([p, p[l:], ''])
return files
def _zip_library():
msg = 'Zip library...'
click.echo(msg)
files = _get_files(PATH_LIBRARY)
_to_zip(PATH_ZIP, files)
msg = '\tLibrary ziped...'
click.echo(msg)
return files
def _add_files(files):
for f in files:
f[1] = f'{EXT_NAME}/{f[1]}'
files.append(['', 'description.xml', data_description])
files.append(['', 'META-INF/manifest.xml', data_manifest])
for k, v in DESC_LANG.items():
files.append(['', f'descriptions/{k}', v])
return files
def _zip_extension(files):
msg = 'Create extension...'
click.echo(msg)
files = _add_files(files)
_to_zip(PATH_EXT, files)
msg = '\tExtension created...'
click.echo(msg)
return
def main():
files = _zip_library()
_zip_extension(files)
with open(PATH_UPDATE, 'w') as f:
f.write(data_update)
return
if __name__ == '__main__':
main()
# Documentos
<BR>
### Documento activo
```
app = factory.createAppEasyMacro()
doc = app.doc
MsgBox doc.Title
```
<BR>
### Acceso a todos los documentos
```
For Each doc In app.docs
MsgBox doc.Title
Next
```
<BR>
### Nuevos documentos
Por default te crea un documento Calc
```
doc = app.docNew()
```
<BR>
Para los demás tipos de documentos usamos:
* Writer:
```
doc = app.docNew("writer")
```
* Impress:
```
doc = app.docNew("impress")
```
* Draw:
```
doc = app.docNew("draw")
```
* Math:
```
doc = app.docNew("math")
```
* Base
Para crear un documento de Base se usa otro método
```
ruta = "/home/mau/Mi_Base_Datos.odb"
doc = app.dbNew(ruta)
```
<BR>
### Abrir documentos
```
ruta = "/home/mau/archivo.ods"
doc = app.docOpen(ruta)
```
Si LibreOffice soporta el tipo de documento, lo abrirá con solo pasar la ruta.
```
ruta = "/home/mau/word.doc"
ruta = "/home/mau/web.htm"
ruta = "/home/mau/excel.xls"
```
<BR>
Se pueden pasar propiedades para modificar el comportamiento de apertura como:
* Abrir una plantilla para edición:
```
Dim args(0) As New com.sun.star.beans.PropertyValue
ruta = "/home/mau/plantilla.ots"
args(0).Name = "AsTemplate"
args(0).Value = False
doc = app.docOpen(ruta, args)
```
* Forzar abrir un documento como si fuera una plantilla:
```
Dim args(0) As New com.sun.star.beans.PropertyValue
ruta = "/home/mau/archivo.ods"
args(0).Name = "AsTemplate"
args(0).Value = True
doc = app.docOpen(ruta, args)
```
* Abrir como solo lectura
```
args(0).Name = "ReadOnly"
args(0).Value = True
```
* Si el documento tiene contraseña
```
args(0).Name = "Password"
args(0).Value = "letmein"
```
* Puedes usar varios argumentos, siempre y cuando no entren en conflicto.
```
Dim args(1) As New com.sun.star.beans.PropertyValue
args(0).Name = "ReadOnly"
args(0).Value = True
args(1).Name = "Password"
args(1).Value = "abrete"
```
* Por default, si un documento tiene macros, por código se abren desactivadas,
para abrirlo con las [macros activadas][1].
```
args(0).Name = "MacroExecutionMode"
args(0).Value = 4
```
* Iniciar una presentación al abrir.
```
args(0).Name = "StartPresentation"
args(0).Value = True
```
* Abrirlo como vista previa.
```
args(0).Name = "Preview"
args(0).Value = True
```
* Abrirlo de forma oculta
```
args(0).Name = "Hidden"
args(0).Value = True
```
TIP: Es buena practica, manipular un documento de forma oculta, y solo mostrarlo
cuando sea necesario.
<BR>
### Mostrar un documento, abierto de forma oculta
```
app.docVisible(doc)
```
Ocultar un documento abierto de forma visible
```
app.docVisible(doc, False)
```
<BR>
### Guardar documentos
* Para documentos abiertos.
```
doc.store()
```
* Para documentos nuevos o documentos abiertos que se vayan a guardar con un
nuevo nombre, **cuidado**, si existe **no te mostrará ninguna advertencia** y
será reemplazado.
```
ruta = "/home/mau/archivo.ods"
doc = app.docNew()
app.docSave(doc, ruta)
```
<BR>
### Cerrar documentos
```
doc.close(True)
```
<BR>
### Propiedades útiles para conocer el estado de un documento.
* Saber si el documento ya esta en disco
```
resultado = doc.hasLocation()
```
* Saber si es de solo lectura
```
resultado = doc.isReadOnly()
```
* Saber si ha sido modificado
```
resultado = doc.isModified()
```
<BR>
### Exportando documentos
* Para guardar como Word
```
args(0).Name = "FilterName"
args(0).Value = "MS Word 2007 XML"
ruta = "/home/mau/word.doc"
doc = app.docNew("writer")
app.docSave(doc, ruta, args)
```
* Para guardar como Excel
```
args(0).Name = "FilterName"
args(0).Value = "Calc MS Excel 2007 XML"
ruta = "/home/mau/excel.xlsx"
doc = app.docNew()
app.docSave(doc, ruta, args)
```
* Exportar a PDF documentos de Calc. Nota que cambia el método.
```
args(0).Name = "FilterName"
args(0).Value = "calc_pdf_Export"
ruta = ConvertToURL("/home/mau/archivo.pdf")
doc.storeToURL(ruta, args())
```
<BR>
Para los demás tipos de documentos.
* Writer:
```
args(0).Value = "writer_pdf_Export"
```
* Impress:
```
args(0).Value = "impress_pdf_Export"
```
* Draw:
```
args(0).Value = "draw_pdf_Export"
```
* Math:
```
args(0).Value = "math_pdf_Export"
```
<BR>
### Activar un documento
TIP: No es necesario activar o mostrar un documento para manipularlo.
```
ventana = doc.getCurrentController().getFrame().getComponentWindow()
ventana.setFocus()
```
<BR>
### Mostrar cuadro de diálogo de selección de archivo.
* Abrir un solo archivo
```
dlg_archivos = createUnoService("com.sun.star.ui.dialogs.FilePicker")
dlg_archivos.setTitle("Selecciona el archivo a abrir")
If dlg_archivos.execute() Then
ruta = dlg_archivos.getFiles()(0)
MsgBox ruta
Else
MsgBox "Cancelado"
End If
```
* Abrir varios archivos.
```
dlg_archivos = createUnoService("com.sun.star.ui.dialogs.FilePicker")
dlg_archivos.setTitle("Selecciona el archivo a abrir")
dlg_archivos.setMultiSelectionMode(True)
If dlg_archivos.execute() Then
rutas = dlg_archivos.getSelectedFiles()
For co1 = LBound(rutas) To UBound(rutas)
MsgBox ConvertFromUrl(rutas(co1))
Next
Else
MsgBox "Cancelado"
End If
```
TIP: Estos métodos solo devuelven la ruta o rutas seleccionadas por el usuario
* Puedes agregar un filtro para mostrar solo los archivos necesarios.
```
With dlg_archivos
.AppendFilter("Hoja de calculo ODF (.ods)", "*.ods")
.AppendFilter("Documento de Texto ODF (.odt)", "*.odt")
End With
```
<BR>
### Mostrar cuadro de diálogo para guardar archivos
```
dlg_guardar = createUnoService("com.sun.star.ui.dialogs.FilePicker")
With dlg_guardar
.Initialize(Array(1))
.AppendFilter("Documento de Texto ODF (.odt)", "*.odt")
.AppendFilter("Hoja de calculo ODF (.ods)", "*.ods")
End With
If dlg_guardar.Execute() Then
ruta = dlg_guardar.getFiles()(0)
MsgBox ruta
Else
MsgBox "Cancelado"
End If
```
Para inicializarlo (**Initialize**), puedes usar [estos valores][2]. Recuerda,
este diálogo solo le permite al usuario seleccionar una ruta y un nombre para
el archivo, debes de agregar el proceso de guardado real.
<BR>
### Saber el tipo de documento
```
Dim dt As String
dt = "unknown"
If doc.supportsService("com.sun.star.sheet.SpreadsheetDocument") Then
dt = "calc"
ElseIf doc.supportsService("com.sun.star.text.TextDocument") Then
dt= "writer"
ElseIf doc.supportsService("com.sun.star.presentation.PresentationDocument") Then
dt = "impress"
ElseIf doc.supportsService("com.sun.star.drawing.DrawingDocument") Then
dt = "draw"
ElseIf doc.supportsService("com.sun.star.sdb.OfficeDatabaseDocument") Then
dt = "base"
ElseIf doc.supportsService("com.sun.star.formula.FormulaProperties") Then
dt = "math"
ElseIf doc.supportsService("com.sun.star.script.BasicIDE") Then
dt = "basic"
End If
MsgBox dt
```
<BR>
### Controlando la barra de estado.
```
barra_estado = doc.getCurrentController().StatusIndicator
barra_estado.start("Procesando Líneas ", 10)
For co1 = 1 To 10
barra_estado.setValue(co1)
barra_estado.setText("Procesando la línea: " & co1)
Wait 1000
Next
barra_estado.end()
```
TIP: Es importante liberar la barra de estado al final (**end**). Puedes controlar
la barra de estado de todas las aplicaciones, excepto de Base.
[Regresar al índice][3]
[1]: https://www.openoffice.org/api/docs/common/ref/com/sun/star/document/MacroExecMode.html
[2]: https://www.openoffice.org/api/docs/common/ref/com/sun/star/ui/dialogs/TemplateDescription.html
[3]: index.md
<div style="text-align: right">
<BR><B>
He who receives an idea from me, <BR>
receives instruction himself without lessening mine;<BR>
as he who lights his taper at mine,<BR>
receives light without darkening me<BR>
</B><BR>
<div style="font-weight: bold">Thomas Jefferson</div>
<BR>
</div>
# Welcome to EasyMacro
Easy develop macros in LibreOffice.
[English][1] - [Spanish][2]
<div style="text-align: right">
<BR><B>
Quien recibe una idea de mí, <BR>
recibe instrucción sin disminuir la mía; <BR>
igual que quien enciende su vela con la mía, <BR>
recibe luz sin que yo quede a oscuras<BR>
</B><BR>
<div style="font-weight: bold">Thomas Jefferson</div>
<BR>
</div>
# Bienvenido a EasyMacro
Desarrollo fácil de macros en LibreOffice.
[Inglés][1] - [Español][2]
[1]: en/index.md
[2]: es/index.md
site_name: Easy Macro
nav:
- Home: index.md
[Regresar al índice][1]
## Calc - Manipulando datos
<BR>
### Tipo de dato en la celda
```
doc = ThisComponent
sel = doc.CurrentSelection
MsgBox sel.Type
```
* Valores devueltos
| Valor | Tipo |
|-------|------|
| 0 | Vacía |
| 1 | Texto |
| 2 | Número |
| 3 | Formula |
<BR>
### Leyendo
* Una celda como texto
```
doc = ThisComponent
sel = doc.CurrentSelection
MsgBox sel.String
```
* Una celda como valor, si la celda tiene texto, te devolverá cero.
```
sel = doc.CurrentSelection
MsgBox sel.Value
```
* La formula, si contiene funciones, las devuelve en ingles
```
sel = doc.CurrentSelection
MsgBox sel.Formula
```
* La formula, si contiene funciones, las devuelve en el lenguaje local
```
sel = doc.CurrentSelection
MsgBox sel.FormulaLocal
```
* Si la celda tiene formula y tiene error, se puede saber el número de error
```
sel = doc.CurrentSelection
MsgBox sel.Error
```
Si no hay error, siempre devuelve cero.
* Devolver los valores de un rango de celdas. **Ojo**, solo devuelve valores.
```
sel = doc.CurrentSelection
datos = sel.Data
For Each fila In datos
For Each col In fila
MsgBox col
Next
Next
```
* Devolver todos los valores de un rango de celdas
```
sel = doc.CurrentSelection
datos = sel.DataArray
For Each fila In datos
For Each col In fila
MsgBox col
Next
Next
```
* Devolver todos las formulas de un rango de celdas
```
sel = doc.CurrentSelection
datos = sel.FormulaArray
For Each fila In datos
For Each col In fila
MsgBox col
Next
Next
```
<BR>
### Escribiendo
* Texto en una celda
```
sel = doc.CurrentSelection
msg = "Todo lo que no podemos dar nos posee"
sel.setString(msg)
```
* Valor en una celda
```
sel.setValue(45)
```
**TIP**: Una fecha es un valor.
```
fecha = DateSerial(2019, 3, 31)
sel.setValue(fecha)
```
* Formula en una celda, debe ser una cadena con una formula válida
```
formula = "A1+B1"
sel.setFormula(formula)
```
* Si la formula tiene funciones, hay que escribirlas en ingles.
```
formula = "=SUM(A1:A10)"
sel.setFormula(formula)
```