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

Cap comentari:

Publica un comentari a l'entrada