Què és el Programari Lliure? a la Viquipèdia hom pot trobar aquesta mapa conceptual que ho explica gràficament:
diumenge, 22 d’agost del 2010
Com invocar una funció de calc des d'una macro?
La idea central és invocar la funció a través del servei UNO com.sun.star.sheet.FunctionAccess. Cal passar dos arguments: el nom de la funció, en anglès, que volem executar; i un Array amb els paràmetres que demana la funció.
la llista de funcions en anglès la podem trobar a la wiki: http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_Functions_listed_by_category
la llista de funcions en anglès la podem trobar a la wiki: http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_Functions_listed_by_category
En l'exemple invocarem la funció BDEXTREU (DGET en anglès) que permet trobar en un rang de cel·les aquella que verifica unes determinades condicions. Els paràmetres de BDEXTREU (DGET) també els trobem a la wiki:
http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_DGET_function
http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_DGET_function
En una fulla de Calc posaré els següents valors en el rang B1:D22. Aquesta serà la taula de dades:
I en el rang B24:D25 hi poso les condicions de cerca. Els títols han de coincidir amb els de la taula de dades
Poso que em cerqui el valor ID=8
Aleshores, en una altre cel·la verifico que la funció troba el valor posant:
=BDEXTREU(B1:D22;C1;B24:D25)
Que ho llegeixo així, en el rang de dades B1:D22, obté el valor de la columna de títol C1, que verifica les condicions expressades al rang B24:D25.
Les condicions que hi ha a B24:D25 són (ID=8) i (NOM pot ser qualsevol valor) i (VALOR pot ser qualsevol valor).
La funció retorna "h" com era d'esperar.
Aquesta és una funció molt útil per a fer cerques en fulles. Com puc utilitzar-la en una macro? Primer de tot, creo un nou mòdul de macros i hi afegeixo el següent codi:
function MacroBDExtreu as String
Dim oFuncio As Object
Dim oFull As Object
Dim oRangTaula As Object
Dim oColumnaSelect As Object
Dim oColumnaCondicions as Object
Dim sRetorn As String
oFull = ThisComponent.Sheets.getByName("Full1")
oRangTaula = oFull.getCellRangeByName("B1:D22")
oColumnaSelect = oFull.getCellByPosition(2, 0)
oColumnaCondicions = oFull.getCellRangeByName("B24:D25")
oFuncio = createUnoService("com.sun.star.sheet.FunctionAccess")
' Invoca la funció pel seu nom en anglès: BDEXTREU --> DGET
sRetorn = oFuncio.callFunction("DGET", _
Array(oRangTaula, _
oColumnaSelect.String, _
oColumnaCondicions))
MsgBox(sRetorn)
MacroBDExtreu = sRetorn
End Function
I invoquem la macro que ens mostra un missatge amb la dada trobada.
id | nom | valor |
1 | a | aa |
2 | b | bb |
3 | c | cc |
4 | d | dd |
5 | e | ee |
6 | f | ff |
7 | g | gg |
8 | h | hh |
9 | i | ii |
10 | j | jj |
11 | k | kk |
12 | l | ll |
13 | m | mm |
14 | n | nn |
15 | o | oo |
16 | p | pp |
17 | q | |
18 | r | rr |
19 | s | ss |
20 | t | tt |
21 | u | uu |
I en el rang B24:D25 hi poso les condicions de cerca. Els títols han de coincidir amb els de la taula de dades
id | nom | valor |
8 |
Poso que em cerqui el valor ID=8
Aleshores, en una altre cel·la verifico que la funció troba el valor posant:
=BDEXTREU(B1:D22;C1;B24:D25)
Que ho llegeixo així, en el rang de dades B1:D22, obté el valor de la columna de títol C1, que verifica les condicions expressades al rang B24:D25.
Les condicions que hi ha a B24:D25 són (ID=8) i (NOM pot ser qualsevol valor) i (VALOR pot ser qualsevol valor).
La funció retorna "h" com era d'esperar.
Aquesta és una funció molt útil per a fer cerques en fulles. Com puc utilitzar-la en una macro? Primer de tot, creo un nou mòdul de macros i hi afegeixo el següent codi:
function MacroBDExtreu as String
Dim oFuncio As Object
Dim oFull As Object
Dim oRangTaula As Object
Dim oColumnaSelect As Object
Dim oColumnaCondicions as Object
Dim sRetorn As String
oFull = ThisComponent.Sheets.getByName("Full1")
oRangTaula = oFull.getCellRangeByName("B1:D22")
oColumnaSelect = oFull.getCellByPosition(2, 0)
oColumnaCondicions = oFull.getCellRangeByName("B24:D25")
oFuncio = createUnoService("com.sun.star.sheet.FunctionAccess")
' Invoca la funció pel seu nom en anglès: BDEXTREU --> DGET
sRetorn = oFuncio.callFunction("DGET", _
Array(oRangTaula, _
oColumnaSelect.String, _
oColumnaCondicions))
MsgBox(sRetorn)
MacroBDExtreu = sRetorn
End Function
I invoquem la macro que ens mostra un missatge amb la dada trobada.
Etiquetes de comentaris:
openoffice.org
divendres, 20 d’agost del 2010
Macros OOoBasic com funcions de Calc.
OpenOffice.org Calc aporta una llarga llista de funcions incorporades.
Aquesta llista, amb els noms de les funcions en anglès, la podem obtenir aquí:
http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_Functions_listed_by_category
En alguna ocasió ens interessarà poder fer servir alguna d'aquestes funcions dins del codi d'una macro. Igualment es pot donar el cas que ens interessi invocar una macro com si fos una funció icroporada del calc.
Comencem per això últim. Invocar una macro com si fos una funció de Calc.
Per a poder invocar una macro com si fos una funció de Calc és necessari, primer de tot, que la macro estigui carregada. Per defecte es carreguen les macros que estan a la biblioteca "Standard".
Si la macro que vull invocar es troba a un mòdul de la llibreria Standard (ja sigui del Document, o de l'usuari a "Les-meves-macros") aleshores es pot invocar directament.
A les macros del document, a la llibreria Standar, creo un mòdul nou Module1 i hi poso el següent codi:
Function HelloWorld()
HelloWorld = "macro invocada com una funció"
End Function
Aleshores, a qualsevol cel·la de la fulla de càlcul hi escric
=helloworld()
en invocar les funcions no és distingeix majúscules i minúscules
apareixerà immediatament
macro invocada com una funció
No té gaire ciència. La clau és que la macro es trobi a la llibreria "Standard".
Per a que quedi clar aquest punt, quan fem Eines-Macros-Organitza les macros-OpenOffice.org Basic obtenim això:
Veiem a la imatge com hi ha dues biblioteques Standard: una a "Les meves macros" i l'altre al document, que en aquest cas s'anomena "macro-funció-calc.ods".
En tot moment puc crear noves biblioteques de macros (libraries) fent click al botó "Organitzador...":
Aquesta llista, amb els noms de les funcions en anglès, la podem obtenir aquí:
http://wiki.services.openoffice.org/wiki/Documentation/How_Tos/Calc:_Functions_listed_by_category
En alguna ocasió ens interessarà poder fer servir alguna d'aquestes funcions dins del codi d'una macro. Igualment es pot donar el cas que ens interessi invocar una macro com si fos una funció icroporada del calc.
Comencem per això últim. Invocar una macro com si fos una funció de Calc.
Per a poder invocar una macro com si fos una funció de Calc és necessari, primer de tot, que la macro estigui carregada. Per defecte es carreguen les macros que estan a la biblioteca "Standard".
Si la macro que vull invocar es troba a un mòdul de la llibreria Standard (ja sigui del Document, o de l'usuari a "Les-meves-macros") aleshores es pot invocar directament.
A les macros del document, a la llibreria Standar, creo un mòdul nou Module1 i hi poso el següent codi:
Function HelloWorld()
HelloWorld = "macro invocada com una funció"
End Function
Aleshores, a qualsevol cel·la de la fulla de càlcul hi escric
=helloworld()
en invocar les funcions no és distingeix majúscules i minúscules
apareixerà immediatament
macro invocada com una funció
No té gaire ciència. La clau és que la macro es trobi a la llibreria "Standard".
Per a que quedi clar aquest punt, quan fem Eines-Macros-Organitza les macros-OpenOffice.org Basic obtenim això:
Veiem a la imatge com hi ha dues biblioteques Standard: una a "Les meves macros" i l'altre al document, que en aquest cas s'anomena "macro-funció-calc.ods".
En tot moment puc crear noves biblioteques de macros (libraries) fent click al botó "Organitzador...":
Des de la pestanya Biblioteques:
En la que puc triar on vull posar la biblioteca: De l'usuari, general, o del document:
En aquest document de la wiki de l'OpenOffice.org proposen la següent tècnica per al cas que en que tinguem moltes macros i molt de codi a les macros. En aquesta situació, en comptes de sobrecarregar la biblioteca estàndard amb molts mòduls molt grossos, el que proposen es crear biblioteques auxiliars, aleshores, en la biblioteca Standard el que posaríem serien funcions de pont que l'únic que farien seria carregar la llibreria corresponent i invocar a la funció d'utilitat desitjada.
Etiquetes de comentaris:
openoffice.org
dijous, 19 d’agost del 2010
Com dibuixar una escala semi-logarítmica amb OpenOffice.org Draw?
En aquest exercici dibuixo una escala semi-logarítmica. Aquesta mena de gràfiques es fan servir en tecnologia, per exemple a l'electrònica es fa servir per representar la resposta en freqüència dels circuits (els diagrames de Bode).
Aquest exercici ens servirà per aprendre com dibuixar línies amb macros de OOoBasic.
Primer de tot, creo un nou document de Draw. I amb l'organitzador de macros creo un mòdul al document.
Faig servir aquest codi
Sub DibuixaLinia
const cMarge = 1000
Dim oPagina as Object
Dim oLinea as Object
Dim oPosition as Object
Dim oSize as Object
Dim iPagWidth as Integer
Dim iPagHeight as Integer
Dim iWidth as Integer
Dim iHeight as Integer
Dim v as Double
Dim w as Double
Dim x as Double
Dim xx as Integer
Dim y as Double
Dim yy as Integer
Dim iNumDecades as Integer
Dim iNumVerticals as Integer
iNumDecades = 7
iNumVerticals = 10
' obté la pàgina de dibuix actual
oPagina = ThisComponent.getDrawPages().getByName("page1")
' dimensions de la pàgina
iPagWidth = oPagina.Width
iPagHeight = oPagina.Height
' dimensions de l'àrea de dibuix, amb un marge de 1000px
iWidth = oPagina.Width - (2 * cMarge)
iHeight = oPagina.Height - (2 * cMarge)
' pinta escala logarítmica
for w = 0 to (iNumDecades - 1)
for v = 1 to 10
x = log(v * (10 ^ w)) / log(10)
xx = ((iWidth / iNumDecades) * x) + cMarge
oLinea = ThisComponent.createInstance("com.sun.star.drawing.LineShape")
oLinea.LineColor = RGB(0, 0, 255)
oLinea.LineWidth = 2
oPosition = oLinea.Position
oPosition.X = xx
oPosition.Y = cMarge
oLinea.Position = oPosition
oSize = oLinea.Size
oSize.Width = 0
oSize.Height = iHeight
oLinea.Size = oSize
oPagina.add(oLinea)
next
next
' dibuixa les divisions verticals
for w=0 to iNumVerticals
oLinea = ThisComponent.createInstance("com.sun.star.drawing.LineShape")
oLinea.LineColor = RGB(0, 0, 255)
oLinea.LineWidth = 2
yy = ((iHeight / iNumVerticals) * w) + cMarge
oPosition = oLinea.Position
oPosition.X = cMarge
oPosition.Y = yy
oLinea.Position = oPosition
oSize = oLinea.Size
oSize.Width = iWidth
oSize.Height = 0
oLinea.Size = oSize
oPagina.add(oLinea)
next
End Sub
Si executem aquesta macro, obtindrem el paper semi-logarítmic.
Aquest exercici ens servirà per aprendre com dibuixar línies amb macros de OOoBasic.
Primer de tot, creo un nou document de Draw. I amb l'organitzador de macros creo un mòdul al document.
Faig servir aquest codi
Sub DibuixaLinia
const cMarge = 1000
Dim oPagina as Object
Dim oLinea as Object
Dim oPosition as Object
Dim oSize as Object
Dim iPagWidth as Integer
Dim iPagHeight as Integer
Dim iWidth as Integer
Dim iHeight as Integer
Dim v as Double
Dim w as Double
Dim x as Double
Dim xx as Integer
Dim y as Double
Dim yy as Integer
Dim iNumDecades as Integer
Dim iNumVerticals as Integer
iNumDecades = 7
iNumVerticals = 10
' obté la pàgina de dibuix actual
oPagina = ThisComponent.getDrawPages().getByName("page1")
' dimensions de la pàgina
iPagWidth = oPagina.Width
iPagHeight = oPagina.Height
' dimensions de l'àrea de dibuix, amb un marge de 1000px
iWidth = oPagina.Width - (2 * cMarge)
iHeight = oPagina.Height - (2 * cMarge)
' pinta escala logarítmica
for w = 0 to (iNumDecades - 1)
for v = 1 to 10
x = log(v * (10 ^ w)) / log(10)
xx = ((iWidth / iNumDecades) * x) + cMarge
oLinea = ThisComponent.createInstance("com.sun.star.drawing.LineShape")
oLinea.LineColor = RGB(0, 0, 255)
oLinea.LineWidth = 2
oPosition = oLinea.Position
oPosition.X = xx
oPosition.Y = cMarge
oLinea.Position = oPosition
oSize = oLinea.Size
oSize.Width = 0
oSize.Height = iHeight
oLinea.Size = oSize
oPagina.add(oLinea)
next
next
' dibuixa les divisions verticals
for w=0 to iNumVerticals
oLinea = ThisComponent.createInstance("com.sun.star.drawing.LineShape")
oLinea.LineColor = RGB(0, 0, 255)
oLinea.LineWidth = 2
yy = ((iHeight / iNumVerticals) * w) + cMarge
oPosition = oLinea.Position
oPosition.X = cMarge
oPosition.Y = yy
oLinea.Position = oPosition
oSize = oLinea.Size
oSize.Width = iWidth
oSize.Height = 0
oLinea.Size = oSize
oPagina.add(oLinea)
next
End Sub
Si executem aquesta macro, obtindrem el paper semi-logarítmic.
Una millora evident és factoritzar la funció que dibuixa la línia:
function Linea(int x, int y, int llarg, int ample, int vermell, int verd, int blau, int gruix)
dim oLinea as Object
dim oPosition as Object
dim oSize as Object
oLinea = ThisComponent.createInstance("com.sun.star.drawing.LineShape")
oLinea.LineColor = RGB(vermell, verd, blau)
oLinea.LineWidth = gruix
oPosition = oLinea.Position
oPosition.X = x
oPosition.Y = y
oLinea.Position = oPosition
oSize = oLinea.Size
oSize.Width = llarg
oSize.Height = ample
oLinea.Size = oSize
Linea = oLinea
end sub
El resultat del programa anterior és:
Etiquetes de comentaris:
openoffice.org
dimarts, 17 d’agost del 2010
ListBox a formulari de l'OpenOffice.org
El control listbox dels formularis de l'OpenOffice.org permet sel·leccionar un o diversos valors d'una llista. La llista de valors es pot carregar des d'una taula, o des d'una consulta SQL, o bé amb valors arbitraris.
Carregar la listbox des d'una taula o amb un SQL és tan senzill com ajustar les propietats corresponents del control. En canvi, per carregar valors arbitraris cal fer-ho amb BASIC.
Com sempre, estic parlant de OpenOffice 3.2 en català sobre Ubuntu Lucid Lynx 10.04.
Vet aquí l'exemple. Primer de tot obro un nou document del Writer. Hi poso els següents components:
Amb l'organitzador de macros creo una macro nova dins del document, l'edito i hi afegeixo el codi per respondre als diferents events.
En prémer el botó Afegeix>> el que faré serà que el text que està a la caixa de text Afegeix opció s'afegeixi a la listbox.
Això ho faig amb el codi següent que associo a l'event de fer click al botó.
sub AfegeixALlista
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim sLlista() as String
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oText = oDoc.getByName("Text1")
oLlista = oDoc.getByName("Llista1")
sLlista = oLlista.StringItemList
bas_PushArray(sLlista, oText.Text)
oLlista.StringItemList = sLlista
Deselecciona
End sub
La funció bas_pushArray redimensiona un array per incrementar-ne el nombre d'elements en u, i afegeix el nou element.
' La següent sub extreta de
' http://www.oooforum.org/forum/viewtopic.phtml?t=38721
' very simple routine appending a single element to an array which
' may be undimensioned (LBound > UBound)
Sub bas_PushArray(xArray(),vNextElement)
Dim iUB,iLB as Integer
iLB = lBound(xArray())
iUB = uBound(xArray())
If iLB > iUB then
iUB = iLB
redim xArray(iLB To iUB)
else
iUB = iUB +1
redim preserve xArray(iLB To iUB)
endif
xArray(iUB) = vNextElement
End Sub
Per associar la sub d'afegir element a la llista a l'event de picar Return sobre el botó, faig el següent, associo la següent sub a l'event de"en prémer una tecla", i faig que la sub rebi com argument l'event. De l'event puc determinar quina tecla s'ha premut. Si la tecla és Return, aleshores executa la sub d'afegir a la listbox.
Sub AfegeixALListaKeyPressed(Event as Object)
' si està fet amb return, Ok
if Event.KeyCode = com.sun.star.awt.Key.RETURN then
AfegeixALlista
end if
end sub
Un cop he afegit l'element a la listbox el que faig és deseleccionar elements. També hauria pogut fer que l'element afegit fos l'element actualment seleccionat.
Per deseleccionar faig:
Sub Deselecciona
Dim oDoc as object
Dim oLlista as Object
Dim oLlista2 as Object
Dim EmptyList()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista2 = oDoc.getByName("Llista2")
oLlista = oDoc.getByName("Llista1")
oLlista.SelectedItems = EmptyList()
oLLista2.SelectedItems = EmptyList()
End Sub
Per sel·leccionar un o molts valors (en aquest cas he de posar a true la propietat de múltiples valors) puc fer servir el següent codi. que he d'associar a l'event "L'estat de l'element ha canviat" de la listbox:
Sub ObteValors
Dim oDoc as object
Dim ollista2 as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim i as integer
Dim LlistaSeleccionades()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
ollista2 = oDoc.getByName("Llista2")
' obté els índexos de les seleccionades
iIndex = oLlista.SelectedItems
' buida la listbox de seleccionades
ollista2.StringItemList() = LlistaSeleccionades()
' Redimensiona l'array auxiliar per a poder encabir-hi els nous valors
Redim LlistaSeleccionades(uBound(iIndex()))
' El plena amb les noves seleccionades
for i=0 to uBound(iIndex())
LlistaSeleccionades(i) = oLlista.StringItemList(iIndex(i))
next i
' l'assigna a la listbox
ollista2.StringItemList = LlistaSeleccionades
End sub
Si vull eliminar algun dels valors de la llista, primer he de tenir-lo seleccionat. Si no hi ha res seleccionat, ignora la crida (Sí, hi ha un goto!). El que fa és redimensionar (redim) a un element menys, preservant-ne el contingut, i deseleccionant al final.
Sub EliminarValor
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim sValorObtingut as String
Dim iIndex() as Integer
Dim sNovaLlista() as String
Dim iDimInicial as Integer
Dim iDimFinal as Integer
Dim i,j as Integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
'xRay oLlista
iIndex = oLlista.SelectedItems
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
iDimInicial = UBound(oLlista.StringItemList())
iDimFinal = iDimInicial - 1
if iDimFinal < idimfinal =" 0" j="0" i="0"> iIndex(0) then
sNovaLlista(j) = oLlista.StringItemList(i)
j= j + 1
end if
next i
oLlista.StringItemList() = sNovaLlista()
iIndex = oLlista.SelectedItems
Deselecciona
SORTIR:
End sub
Per eliminar tots, Empty Array a tot arreu i deseleccionar.
Sub EliminaTots
Dim oDoc as object
Dim oLlista as Object
Dim oLlista2 as Object
Dim EmptyList()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
oLLista2 = oDoc.getByName("Llista2")
oLlista.StringItemList = EmptyList
oLLista2.StringItemList = EmptyList
Deselecciona
End sub
Finalment, puc ordenar (botons Puja i Baixa) la llista. Cal tenir un element selccionat, i si no, ignora la crida. Es tracta d'intercanviar les posicions dels elements de l'array que van seguits, i recarrregar l'array StringItemList amb el nou array reordenat.
Sub Puja
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim sAux as String
Dim EmptyList()
Dim i,j,k as Integer
Dim sNovaLlista() as String
dim sNovaLlistaSeleccionat(0) as Integer
Dim iDimLlista as integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
iIndex = oLlista.SelectedItems
' primer mira si té un element sel·leccionat
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
' si el té, mira que no sigui el primer
if iIndex(0) > 0 then
' prepara un Array auxiliar
iDimLlista = UBound(oLlista.StringItemList())
Redim sNovaLlista(iDimLlista)
' obté els índexos a intercanviar
i = iIndex(0)
j = i - 1
' itera per carregar l'array auxiliar
for k=0 to iDimLlista
sNovaLlista(k) = oLlista.StringItemList(k)
next k
' intercanvia les posicions en l'array auxiliar
sAux = sNovaLlista(j)
sNovaLlista(j) = sNovaLlista(i)
sNovaLlista(i) = sAux
' carrega la llista
oLlista.StringItemList() = sNovaLlista()
' selecciona l'anterior
sNovaLlistaSeleccionat(0) = j
oLlista.SelectedItems = sNovaLlistaSeleccionat
end if
oLlista.Refresh()
SORTIR:
End sub
Sub Baixa
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim sAux as String
Dim EmptyList()
Dim i,j,k as Integer
Dim sNovaLlista() as String
dim sNovaLlistaSeleccionat(0) as Integer
Dim iDimLlista as integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
iIndex = oLlista.SelectedItems
' primer mira si té un element sel·leccionat
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
' si el té, mira que no sigui l'últim
iDimLlista = UBound(oLlista.StringItemList())
if iIndex(0) < iDimLlista then ' prepara un Array auxiliar
Redim sNovaLlista(iDimLlista) ' obté els índexos a intercanviar
i = iIndex(0)
j = i + 1 ' itera per carregar l'array auxiliar
for k=0 to iDimLlista
sNovaLlista(k) = oLlista.StringItemList(k)
next k ' intercanvia les posicions en l'array auxiliar
sAux = sNovaLlista(j)
sNovaLlista(j) = sNovaLlista(i)
sNovaLlista(i) = sAux ' carrega la llista
oLlista.StringItemList() = sNovaLlista() ' selecciona l'anterior sNovaLlistaSeleccionat(0) = j
oLlista.SelectedItems = sNovaLlistaSeleccionat
end if oLlista.Refresh()
SORTIR:
End sub
Carregar la listbox des d'una taula o amb un SQL és tan senzill com ajustar les propietats corresponents del control. En canvi, per carregar valors arbitraris cal fer-ho amb BASIC.
Com sempre, estic parlant de OpenOffice 3.2 en català sobre Ubuntu Lucid Lynx 10.04.
Vet aquí l'exemple. Primer de tot obro un nou document del Writer. Hi poso els següents components:
Amb l'organitzador de macros creo una macro nova dins del document, l'edito i hi afegeixo el codi per respondre als diferents events.
En prémer el botó Afegeix>> el que faré serà que el text que està a la caixa de text Afegeix opció s'afegeixi a la listbox.
Això ho faig amb el codi següent que associo a l'event de fer click al botó.
sub AfegeixALlista
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim sLlista() as String
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oText = oDoc.getByName("Text1")
oLlista = oDoc.getByName("Llista1")
sLlista = oLlista.StringItemList
bas_PushArray(sLlista, oText.Text)
oLlista.StringItemList = sLlista
Deselecciona
End sub
La funció bas_pushArray redimensiona un array per incrementar-ne el nombre d'elements en u, i afegeix el nou element.
' La següent sub extreta de
' http://www.oooforum.org/forum/viewtopic.phtml?t=38721
' very simple routine appending a single element to an array which
' may be undimensioned (LBound > UBound)
Sub bas_PushArray(xArray(),vNextElement)
Dim iUB,iLB as Integer
iLB = lBound(xArray())
iUB = uBound(xArray())
If iLB > iUB then
iUB = iLB
redim xArray(iLB To iUB)
else
iUB = iUB +1
redim preserve xArray(iLB To iUB)
endif
xArray(iUB) = vNextElement
End Sub
Per associar la sub d'afegir element a la llista a l'event de picar Return sobre el botó, faig el següent, associo la següent sub a l'event de"en prémer una tecla", i faig que la sub rebi com argument l'event. De l'event puc determinar quina tecla s'ha premut. Si la tecla és Return, aleshores executa la sub d'afegir a la listbox.
Sub AfegeixALListaKeyPressed(Event as Object)
' si està fet amb return, Ok
if Event.KeyCode = com.sun.star.awt.Key.RETURN then
AfegeixALlista
end if
end sub
Un cop he afegit l'element a la listbox el que faig és deseleccionar elements. També hauria pogut fer que l'element afegit fos l'element actualment seleccionat.
Per deseleccionar faig:
Sub Deselecciona
Dim oDoc as object
Dim oLlista as Object
Dim oLlista2 as Object
Dim EmptyList()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista2 = oDoc.getByName("Llista2")
oLlista = oDoc.getByName("Llista1")
oLlista.SelectedItems = EmptyList()
oLLista2.SelectedItems = EmptyList()
End Sub
Per sel·leccionar un o molts valors (en aquest cas he de posar a true la propietat de múltiples valors) puc fer servir el següent codi. que he d'associar a l'event "L'estat de l'element ha canviat" de la listbox:
Sub ObteValors
Dim oDoc as object
Dim ollista2 as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim i as integer
Dim LlistaSeleccionades()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
ollista2 = oDoc.getByName("Llista2")
' obté els índexos de les seleccionades
iIndex = oLlista.SelectedItems
' buida la listbox de seleccionades
ollista2.StringItemList() = LlistaSeleccionades()
' Redimensiona l'array auxiliar per a poder encabir-hi els nous valors
Redim LlistaSeleccionades(uBound(iIndex()))
' El plena amb les noves seleccionades
for i=0 to uBound(iIndex())
LlistaSeleccionades(i) = oLlista.StringItemList(iIndex(i))
next i
' l'assigna a la listbox
ollista2.StringItemList = LlistaSeleccionades
End sub
Si vull eliminar algun dels valors de la llista, primer he de tenir-lo seleccionat. Si no hi ha res seleccionat, ignora la crida (Sí, hi ha un goto!). El que fa és redimensionar (redim) a un element menys, preservant-ne el contingut, i deseleccionant al final.
Sub EliminarValor
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim sValorObtingut as String
Dim iIndex() as Integer
Dim sNovaLlista() as String
Dim iDimInicial as Integer
Dim iDimFinal as Integer
Dim i,j as Integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
'xRay oLlista
iIndex = oLlista.SelectedItems
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
iDimInicial = UBound(oLlista.StringItemList())
iDimFinal = iDimInicial - 1
if iDimFinal < idimfinal =" 0" j="0" i="0"> iIndex(0) then
sNovaLlista(j) = oLlista.StringItemList(i)
j= j + 1
end if
next i
oLlista.StringItemList() = sNovaLlista()
iIndex = oLlista.SelectedItems
Deselecciona
SORTIR:
End sub
Per eliminar tots, Empty Array a tot arreu i deseleccionar.
Sub EliminaTots
Dim oDoc as object
Dim oLlista as Object
Dim oLlista2 as Object
Dim EmptyList()
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
oLLista2 = oDoc.getByName("Llista2")
oLlista.StringItemList = EmptyList
oLLista2.StringItemList = EmptyList
Deselecciona
End sub
Finalment, puc ordenar (botons Puja i Baixa) la llista. Cal tenir un element selccionat, i si no, ignora la crida. Es tracta d'intercanviar les posicions dels elements de l'array que van seguits, i recarrregar l'array StringItemList amb el nou array reordenat.
Sub Puja
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim sAux as String
Dim EmptyList()
Dim i,j,k as Integer
Dim sNovaLlista() as String
dim sNovaLlistaSeleccionat(0) as Integer
Dim iDimLlista as integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
iIndex = oLlista.SelectedItems
' primer mira si té un element sel·leccionat
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
' si el té, mira que no sigui el primer
if iIndex(0) > 0 then
' prepara un Array auxiliar
iDimLlista = UBound(oLlista.StringItemList())
Redim sNovaLlista(iDimLlista)
' obté els índexos a intercanviar
i = iIndex(0)
j = i - 1
' itera per carregar l'array auxiliar
for k=0 to iDimLlista
sNovaLlista(k) = oLlista.StringItemList(k)
next k
' intercanvia les posicions en l'array auxiliar
sAux = sNovaLlista(j)
sNovaLlista(j) = sNovaLlista(i)
sNovaLlista(i) = sAux
' carrega la llista
oLlista.StringItemList() = sNovaLlista()
' selecciona l'anterior
sNovaLlistaSeleccionat(0) = j
oLlista.SelectedItems = sNovaLlistaSeleccionat
end if
oLlista.Refresh()
SORTIR:
End sub
Sub Baixa
Dim oDoc as object
Dim oText as Object
Dim oLlista as Object
Dim iIndex() as Integer
Dim sAux as String
Dim EmptyList()
Dim i,j,k as Integer
Dim sNovaLlista() as String
dim sNovaLlistaSeleccionat(0) as Integer
Dim iDimLlista as integer
oDoc = ThisComponent.getDrawPage().Forms().getByIndex(0)
oLlista = oDoc.getByName("Llista1")
iIndex = oLlista.SelectedItems
' primer mira si té un element sel·leccionat
if UBound(iIndex()) = -1 and LBound(iIndex()) = 0 then goto SORTIR
' si el té, mira que no sigui l'últim
iDimLlista = UBound(oLlista.StringItemList())
if iIndex(0) < iDimLlista then ' prepara un Array auxiliar
Redim sNovaLlista(iDimLlista) ' obté els índexos a intercanviar
i = iIndex(0)
j = i + 1 ' itera per carregar l'array auxiliar
for k=0 to iDimLlista
sNovaLlista(k) = oLlista.StringItemList(k)
next k ' intercanvia les posicions en l'array auxiliar
sAux = sNovaLlista(j)
sNovaLlista(j) = sNovaLlista(i)
sNovaLlista(i) = sAux ' carrega la llista
oLlista.StringItemList() = sNovaLlista() ' selecciona l'anterior sNovaLlistaSeleccionat(0) = j
oLlista.SelectedItems = sNovaLlistaSeleccionat
end if oLlista.Refresh()
SORTIR:
End sub
Subscriure's a:
Missatges (Atom)