wie Array an Calc-Tabelle übergeben??

Programmierung unter AOO/LO (StarBasic, Python, Java, ...)

Moderator: Moderatoren

lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

wie Array an Calc-Tabelle übergeben??

Beitrag von lupolupp1 » Fr, 22.08.2008 15:12

Hallo zusammen,

ich habe zwischenzeitlich etwas herumgebastelt und habe herausgefunden, wie ich die Daten richtig abfrage.
Aber wie übergebe ich die Daten richtig an das Ausgabe-Array, damit dieses mittels setDataArray an eine Calc-Tabelle übergeben werden kann?
Das Daten-Array (oData), in das die Werte eingelesen werden, sieht nach getDataArray so aus: oData(0)(0), oData(0)(1) ...
Ich denke, dass das Ausgabe-Array das gleiche Format haben muss, aber wie bekomme ich das hin? -> habe ein Brett vorm Kopf!!!

Code: Alles auswählen

Sub schnell()
dim odata(5) ' Das Array wird nur einfach dimensioniert und zwar nach Anzahl der Zeilen.
'Durch den Befehl getDataArray bilden sich die Unterarrays mit den Angaben zur Spalte automatisch
dim Ausgabe(6) 'wie bilde ich hier Unterarrays?? Muss ich diese bereits hier dimensionieren? dim Ausgabe(6)(1) funktioniert nicht

for x=0 to 1
for y=0 to 6 'ansonsten erscheint der Fehler "Objektvariable nicht belegt"
'Ausgabe(x,y) ?????????????????? = ?????????? wie wäre es richtig, damit Ausgabe nachher Ausgabe (y)(x)="" ist?
next
next

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:B5")
oData()= oRange.getDataArray()

Zwischenwert = oData(1) ' Hier wird die Zeile der entsprechenden abzufragenden Zelle angegeben
Wert=Zwischenwert(0) ' Hier wird die Spalte der abzufragenden Zelle angegeben
Ergebnis=Wert/2
'Ausgabe(0,0)=Array(Ergebnis) ?????????????????? wie wäre es richtig, damit Ergebnis in Ausgabe(0)(0) geschrieben wird?

Wert=Zwischenwert(1)
Ergebnis=Wert/2
'Ausgabe(0,1)=Array(Ergebnis2) ??????????

Zwischenwert = oData(2)
Wert=Zwischenwert(0)
Ergebnis=Wert/2
'Ausgabe(1,0)=Array(Ergebnis) ??????????

Wert=Zwischenwert(1)
Ergebnis=Wert/2
'Ausgabe(1,1)=Array(Ergebnis2) ???????????

Zwischenwert = oData(3)
Wert=Zwischenwert(0)
Ergebnis=Wert/2
'Ausgabe(2,0)=Array(Ergebnis) ???????????????

Wert=Zwischenwert(1)
Ergebnis=Wert/2
'Ausgabe(2,1)=Array(Ergebnis2) ????????????

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("C1:D7")
oRange.setDataArray(Ausgabe())'Übertrag der im Array zwischengespeicherten Ergebnisse an den Ausgabebereich im Tabellenblatt

End Sub
Ich habe zu diesem Thema leider überhaupt nichts in den Dokumentationen oder auch hier im Forum gefunden.

Vielen Dank und viele Grüße

Lupo

hawe
****
Beiträge: 151
Registriert: Di, 05.08.2008 19:47

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von hawe » Mo, 25.08.2008 17:36

Hallo,

ich denke da haben die Entwickler vergessen den Safearray aus c++ für BASIC umzuschreiben. Das Problem tritt auch bei Worksheetfunction die einen Array zurückliefern. Hab das Probelm schon mal bei Herr Dannenhoefer abgestellt, aber keine Antwort erhalten. Hab das auch immer nur über einen Zwischenschritt gesehen, etwa

Code: Alles auswählen

Sub SafeArray()

dim Ausgabe

oRange = ThisComponent.Sheets(0).getCellRangeByName("A1:B5")

oData()= oRange.getDataArray()

Redim Ausgabe(ubound(oData),ubound(oData(0)))
for i=0 to ubound(oData())
	msgbox "(" & Join(oData(i), ",") & ")"
	t = oData(i)
	for j=0 to ubound(t)
		Ausgabe(i,j) = t(j)^2
	next
next

oRange = ThisComponent.Sheets(0).getCellRangeByName("C1:D5")
oRange.setDataArray(Ausgabe())


End Sub
Gruß HW
Hans W. Hofmann
Gruss HW
Win7/SuSe 11.2 - LO 3.3

lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von lupolupp1 » Mo, 25.08.2008 23:29

Hallo Hawe,

vielen Dank für deine Antwort. Ich werden nun einfach pro Spalte ein eigenes Array anlegen, das ist für mich einfacher und übersichtlicher. So bastele ich mir quasi mein eigenes mehrdimensionales Array zusammen. Im Beispiel habe ich in der Spalte A einfach die Zahlen 1,2,3,4, ... und in Spalte B 11,12,13,14, ... als Daten eingegeben. Um einfach irgendeinen Beispielcode auszuprobieren, nehme ich jeweils abwechselnd den Wert aus Spalte A und B zum Rechnen - hier im Beispiel wird die Zahl halbiert - und das Ergebnis abwechselnd in den Spalten C und D ausgegeben. Nicht sehr einfallsreich, aber anschaulich.

Code: Alles auswählen

Sub schnell()
'option base 1 -> wenn das Array bei 1 beginnen soll
dim yEin(5) ' Das Array wird nur einfach dimensioniert und zwar nach Anzahl der einzulesenden Zeilen.
'Durch den Befehl getDataArray bilden sich die Unterarrays mit den Angaben zur Spalte automatisch
dim SpalteC(10) 'Alternativ kann das Ausgabe-Array von der Größe her auch an das Einlese-Array angepasst werden: 
'Ausgabe (LBound(yein()) To UBound(yein()))
dim SpalteD(10)

for y=0 to 10 'zunächst alle "virtuellen Zellen" mit "" füllen, ansonsten erscheint der Fehler "Objektvariable nicht belegt", 
'Anzahl der Durchläufe muss mit der Zellenanzahl des Ausgabebereiches übereinstimmen
SpalteC(y)=Array("")
SpalteD(y)=Array("")
next

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:B5")
yEin()= oRange.getDataArray()

x=1
For y=0 to 4
 ZwischenwertyEin = yein(y) ' Hier wird die Zeile der entsprechenden abzufragenden Zelle angegeben
 xEin=ZwischenwertyEin(x) ' Hier wird die Spalte der abzufragenden Zelle angegeben
 if x=0 then SpalteC(y)=Array(xEin/2): x=1: goto weiter
 if x=1 then SpalteD(y)=Array(xEin/2): x=0
weiter:
next

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("C1:C11")'Definition des Ausgabebereiches
oRange.setDataArray(SpalteC())'Übertrag der im Array zwischengespeicherten Ergebnisse an den Ausgabebereich im Tabellenblatt
oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("D1:D11")'Definition des Ausgabebereiches
oRange.setDataArray(SpalteD())'Übertrag der im Array zwischengespeicherten Ergebnisse an den Ausgabebereich im Tabellenblatt

End Sub
Viele Grüße

Lupo

hawe
****
Beiträge: 151
Registriert: Di, 05.08.2008 19:47

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von hawe » Di, 26.08.2008 09:20

Wie bring ich es Dir auf schonende Art und Weise bei. Ach was, ganz einfach und brutal

Code: Alles auswählen

option VBASupport 1

Sub VBARangeCopy
a=Range("A1:B9")
Range("F1:G9")=a
End Sub
Gruß HW
Hans W. Hofmann
Gruss HW
Win7/SuSe 11.2 - LO 3.3

lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von lupolupp1 » Di, 26.08.2008 14:05

Hallo HW,

vielen Dank für deine Hilfe.
Funktioniert Range("F1:G9") denn auch, wenn a ein selbst erstelltes Array, im besten Fall sogar ein zweidimensionales wie Ausgabe(x,y), ist?
Das wär super. Funktionieren bei option VBASupport 1 die Funktionen von OOBasic auch?

Viele Grüße

Lupo
hawe hat geschrieben:Wie bring ich es Dir auf schonende Art und Weise bei. Ach was, ganz einfach und brutal

Code: Alles auswählen

option VBASupport 1

Sub VBARangeCopy
a=Range("A1:B9")
Range("F1:G9")=a
End Sub
Gruß HW
Hans W. Hofmann

hawe
****
Beiträge: 151
Registriert: Di, 05.08.2008 19:47

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von hawe » Di, 26.08.2008 17:22

Also soweit ich im Debugger sehen kann gibt RANGE a ein original Array über
Dim a( 1 to 9, 1 to 2)
zurück. VBASupport schaltet ein paar VBA-Objekte zu. OOBasic ist davon nicht betroffen. Was genau unterstützt wird musst Du googeln oder ausprobieren. Es ist schon interessant, dass man über den VBASupport einige Haken und Ösen von OOBasic übertünchen kann. :-)

Gruß HW
Hans W. Hofmann
Gruss HW
Win7/SuSe 11.2 - LO 3.3

lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von lupolupp1 » Di, 26.08.2008 22:33

Hallo Hawe,

du hast vollkommen recht, dass das funktioniert. Ist auch von der Programmierung her wesentlich einfacher und kürzer (habe ich leider schon öfter im Vergleich VBA/OOBasic festgestellt), allerdings arbeitet der Code auch wesentlich langsamer.
Ich wollte ja gerade, um die lange Berechnungsdauer zu verkürzen, Arrays einsetzen, anstatt die Zellen jedesmal direkt anzusprechen.

Ich habe aber zwischenzeitlich noch eine weitere Lösung gefunden, die auch wesentlich schneller rechnet.
Fülle in einem Calc-Tabellenblatt den Bereich A1:D5001 mit irgendwelchen Zahlen und lasse jeweils die beiden Codes drüber laufen. Die OOBasic-Variante ist zwar komplizierter und auch vom Code her wesentlich länger, dafür aber auch wesentlich schneller.

Schön wäre es natürlich, wenn es eine ähnlich einfache Funktion wie in VBA auch zukünftig in OOBasic geben würde, die dann auch genauso schnell arbeitet wie meine jetzige OOBasic-Variante. Hier die Frage an die Entwickler: ist so etwas umsetzbar und wird es so etwas mal geben?

Viele Grüße

Lupo

VBA-Variante

Code: Alles auswählen

option VBASupport 1

Sub schnell()
Dim Ausgabe(1 to 5000,1 to 3)
yEin= Range("A1:D7500")

For y=1 to 5000
for x=1 to 3 step 2
Ausgabe(y,x)=yEin(y,x)*2
next
next

Range("F1:H5000")=Ausgabe
msgbox("fertig")
Reine OOBasic-Variante

Code: Alles auswählen

Sub schnell()
dim Ausgabe(5000) 
dim f(5000)
dim g(5000)
dim h(5000)

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:D7500")
yEin()= oRange.getDataArray()


for y=0 to 5000 'zunächst alle "virtuellen Zellen" mit "" füllen, ansonsten erscheint der Fehler "Objektvariable nicht belegt", 
'Anzahl der Durchläufe muss mit der Zellenanzahl des Ausgabebereiches übereinstimmen
f(y)="":g(y)="":h(y)=""
next


'Mit folgendem Code werden die Spalten A und C jeweils verdoppelt (einfach um irgendetwas zu rechnen)
For y=0 to 5000
ZwischenwertyEin = yein(y) ' Hier wird die Zeile der entsprechenden abzufragenden Zelle angegeben
For x=1 to 3 step 2
xEin=ZwischenwertyEin(x)
Ergebnis=xEin*2

select case x
Case 1
f(y)=Ergebnis
Case 3
h(y)=Ergebnis
end select
next
next

'Ausgabe der Ergebnisse
For y=0 to 5000
Ausgabe(y)=Array(f(y),g(y),h(y))
next
oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("F1:H5001")'Definition des Ausgabebereiches
oRange.setDataArray(Ausgabe())'Übertrag der im Array zwischengespeicherten Ergebnisse an den Ausgabebereich im Tabellenblatt
msgbox("fertig")

End Sub

hawe hat geschrieben:Also soweit ich im Debugger sehen kann gibt RANGE a ein original Array über
Dim a( 1 to 9, 1 to 2)
zurück. VBASupport schaltet ein paar VBA-Objekte zu. OOBasic ist davon nicht betroffen. Was genau unterstützt wird musst Du googeln oder ausprobieren. Es ist schon interessant, dass man über den VBASupport einige Haken und Ösen von OOBasic übertünchen kann. :-)

Gruß HW
Hans W. Hofmann

lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: wie Array an Calc-Tabelle übergeben??

Beitrag von lupolupp1 » Di, 26.08.2008 22:58

Hallo noch einmal,

es funktioniert auch folgendermaßen und ist fast genauso schnell wie die oben angeführte OOBasic-Variante und das auch ohne "option VBASupport 1":

Code: Alles auswählen

Sub schnell()
dim Ausgabe(0 to 5000, 0 to 2) 

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:D7500")
yEin()= oRange.getDataArray()

'Muss nicht unbedingt sein, nicht belegte Felder werden aber in der Tabelle mit #NV ausgegeben
'for y=1 to 5000 
'for x=1 to 3
'Ausgabe(y,x)=""
'next
'next

'Mit folgendem Code werden die Spalten A und C jeweils verdoppelt (einfach um irgendetwas zu rechnen)
For y=0 to 5000
ZwischenwertyEin = yein(y) ' Hier wird die Zeile der entsprechenden abzufragenden Zelle angegeben
For x=0 to 2 step 2
xEin=ZwischenwertyEin(x)
Ergebnis=xEin*2
Ausgabe(y,x)=Ergebnis
next
next

oRange = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("F1:H5001")'Definition des Ausgabebereiches
oRange.setDataArray(Ausgabe())'Übertrag der im Array zwischengespeicherten Ergebnisse an den Ausgabebereich im Tabellenblatt
msgbox("fertig")

End Sub
Viele Grüße

Lupo

Antworten