get data array

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

Moderator: Moderatoren

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

get data array

Beitrag von lupolupp1 »

Hallo zusammen,

ich bin dabei, ein Zinsstaffelprogramm zu schreiben. Dies funktioniert auch soweit. Da ich allerdings bei jeder Buchung das Ergebnis sofort in das Tabellenblatt mit dem Ergebnis schreibe, dauert die Berechnung sehr lange. Ich habe nun den Tipp erhalten, mit get data array und set data array zu arbeiten.
Ich kenne mich damit jedoch nicht aus und bin leider auch aus dem Dokument und den Beispielen von Andrew Pitonyak nicht besonders schlau geworden.

Zunächst müsste die Daten aus einem Daten-Tabellenblatt in ein Array einlesen und mit diesen Daten weiterarbeiten (Zinssatz, zu buchende Beträge, etc.).
Die auszugebenden Daten haben aber natürlich ein ganz anderes Array-Raster als die Ursprungsdaten. Ich produziere ja neue Daten und verändere nicht nur die alten.

Ich habe es folgendermaßen versucht:

Sub mitarrayrechnen()
x = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
x2 = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10000")
Dim daten()
Dim z(10000)
daten() = x.getDataArray()
For i = LBound(daten()) To UBound(daten())
a = daten(i)
z(i)=a*2
Next
x2.setDataArray(z())
End Sub

Dabei bekomme ich die Fehlermeldung, dass die Objektvariable nicht belegt sei. Da Daten() anscheinend als Objekt behandelt wird, kann ich wohl nicht einfach mit der von mir verwendeten Zeile a=daten(i) den Wert auslesen.
Ich dachte, wenn ich das Array eingelesen habe muss ich statt beispielsweise dem Wert der Zelle(1,2) nur den Wert des Array(1,2) auslesen, um damit weiterrechnen zu können und würde dann Zeit sparen. Tja, falsch gedacht.

Wie muss ich denn nun vorgehen, um den Wert von Beispielsweise Daten(5) auszulesen und unabhängig vom Array mit einer "normalen" Variable damit weiterrechnen zu können? Und wie kann ich die Ergebnisse dann nachher in ein weiteres, neues Array schreiben und dieses in einem anderen Tabellenblatt ausgeben?

Vielen Dank

Lupo
turtle47
*******
Beiträge: 1849
Registriert: Mi, 04.01.2006 20:10
Wohnort: Rheinbach

Re: get data array

Beitrag von turtle47 »

Hi Lupo,

versuche mal folgenden Code:

Code: Alles auswählen

Global Daten(10000) as long
Sub mitarrayrechnen()
	on error goto weiter
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oRange1 = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10000")
	oData() = oRange.getDataArray()
	For i = LBound(oData()) To UBound(oData())
	oRow() = oData(i)
	For j = LBound(oRow()) To UBound(oRow())
	oRow(j) = oRow(j) * 5
	Next
	Next
	weiter:
	oRange1.setDataArray(oData())
End Sub
Obiger Code ist auf meinem Läpppi 5 mal schneller als der nachfolgende:
[

Code: Alles auswählen

ub mitarrayrechnen1()
	odoc=thiscomponent
	oSheet = ThisComponent.Sheets().getByIndex(0)
	for i = 0 To 10000
	Value1 = osheet.getcellbyposition(0,i).value
	oCell2 = osheet.getcellbyposition(1,i)
	oCell2.value = Value1 * 5
	next i
End Sub
- der im Prinzip ja genau das Gleiche macht.

Wenn Du direkt Werte aus dem Array lesen willst kannst Du das wie folgt machen.
Zuertst folgenden Code laufen lassen:

Code: Alles auswählen

Global Daten(10000) as long
Sub mitarrayrechnen2()
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oData() = oRange.getDataArray()
End Sub
und dann die Position aufrufen mit:

Code: Alles auswählen

Sub Array_1_auslesen
	x0 = oData(1000) 'Stelle des Wertes im Array
	Wert1= x0(0) * 5
	msgbox Wert1
End Sub
Hilft das weiter oder habe ich Deine Frage falsch interpretiert?

Jürgen
Software hat keinen Verstand - benutze deinen eigenen...!

Win 7 SP1/ LibreOffice 3.4.2 OOO340m1 (Build:203) / Firefox 15.0.1 / Notebook ASUS K70IO 64 Bit-Betriebssytem
lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: get data array

Beitrag von lupolupp1 »

Hi Jürgen,

ich hab gerade mal ein bisschen mit deinem Code etwas ausprobiert und ich glaube, dass ich so weiterkomme.
Das war ne gute Idee, die beiden Codeteile voneinander zu trennen und die Verbindung über Global zu halten.

Super, vielen Dank!

Lupo
turtle47 hat geschrieben:Hi Lupo,

versuche mal folgenden Code:

Code: Alles auswählen

Global Daten(10000) as long
Sub mitarrayrechnen()
	on error goto weiter
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oRange1 = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10000")
	oData() = oRange.getDataArray()
	For i = LBound(oData()) To UBound(oData())
	oRow() = oData(i)
	For j = LBound(oRow()) To UBound(oRow())
	oRow(j) = oRow(j) * 5
	Next
	Next
	weiter:
	oRange1.setDataArray(oData())
End Sub
Obiger Code ist auf meinem Läpppi 5 mal schneller als der nachfolgende:
[[

Code: Alles auswählen

b mitarrayrechnen1()
	odoc=thiscomponent
	oSheet = ThisComponent.Sheets().getByIndex(0)
	for i = 0 To 10000
	Value1 = osheet.getcellbyposition(0,i).value
	oCell2 = osheet.getcellbyposition(1,i)
	oCell2.value = Value1 * 5
	next i
End Sub
- der im Prinzip ja genau das Gleiche macht.

Wenn Du direkt Werte aus dem Array lesen willst kannst Du das wie folgt machen.
Zuertst folgenden Code laufen lassen:

Code: Alles auswählen

Global Daten(10000) as long
Sub mitarrayrechnen2()
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oData() = oRange.getDataArray()
End Sub
und dann die Position aufrufen mit:

Code: Alles auswählen

Sub Array_1_auslesen
	x0 = oData(1000) 'Stelle des Wertes im Array
	Wert1= x0(0) * 5
	msgbox Wert1
End Sub
Hilft das weiter oder habe ich Deine Frage falsch interpretiert?

Jürgen[
lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: get data array

Beitrag von lupolupp1 »

Hallo Jürgen,

ich bin soweit gekommen, dass ich mit den eingelesenen Daten weiterrechnen und die Ergebnisse in einem neuen Ausgabe-Array ablegen kann.
Die Arrays habe ich zunächst eindimensional und die Anzahl der Array-Werte der Einfachheit halber beide mit 5 gewählt. Später werde ich jedoch mit zweidimensionalen Arrays arbeiten (um die Adresse der Zellen abbilden zu können) und die beiden Arrays bzw. die verwendeten "Zellen" werden sich voneinander unterscheiden, da ich ja mit dem Ausgabe-Array die neu produzierten Daten ausgebe.

Ich habe es bisher nóch nicht geschafft, das Array in die Tabelle zu übertragen.
Bei der Zeile

Code: Alles auswählen

oRange.setDataArray(Ausgabe())
kommt immer der Hinweis, dass die Objektvariable nicht belegt ist.
Was habe ich falsch gemacht? Was fehlt?

Hier der gesamte Code:

Code: Alles auswählen

Global odata(5) as long

Sub mitarrayrechnen2()' Daten aus Tabelle in Array lesen
   oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A5")
   oData() = oRange.getDataArray()
End Sub


Sub schnell()
dim Ausgabe(5)

mitarrayrechnen2 'zunächst Daten einlesen

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

For r=0 to 4
x = oData(r) 'Stelle des Wertes im Array
Ergebnis=x(0)*2
Ausgabe(r)=Ergebnis
next

oRange.setDataArray(Ausgabe())

End Sub[
Vielen herzlichen Dank und viele Grüße

Lupo
turtle47 hat geschrieben:Hi Lupo,

versuche mal folgenden Code:
[c

Code: Alles auswählen

obal Daten(10000) as long
Sub mitarrayrechnen()
	on error goto weiter
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oRange1 = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10000")
	oData() = oRange.getDataArray()
	For i = LBound(oData()) To UBound(oData())
	oRow() = oData(i)
	For j = LBound(oRow()) To UBound(oRow())
	oRow(j) = oRow(j) * 5
	Next
	Next
	weiter:
	oRange1.setDataArray(oData())
End Sub
Obiger Code ist auf meinem Läpppi 5 mal schneller als der nachfolgende:
[[

Code: Alles auswählen

b mitarrayrechnen1()
	odoc=thiscomponent
	oSheet = ThisComponent.Sheets().getByIndex(0)
	for i = 0 To 10000
	Value1 = osheet.getcellbyposition(0,i).value
	oCell2 = osheet.getcellbyposition(1,i)
	oCell2.value = Value1 * 5
	next i
End Sub
- der im Prinzip ja genau das Gleiche macht.

Wenn Du direkt Werte aus dem Array lesen willst kannst Du das wie folgt machen.
Zuertst folgenden Code laufen lassen:

Code: Alles auswählen

Global Daten(10000) as long
Sub mitarrayrechnen2()
	oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10000")
	oData() = oRange.getDataArray()
End Sub
und dann die Position aufrufen mit:

Code: Alles auswählen

Sub Array_1_auslesen
	x0 = oData(1000) 'Stelle des Wertes im Array
	Wert1= x0(0) * 5
	msgbox Wert1
End Sub
Hilft das weiter oder habe ich Deine Frage falsch interpretiert?

Jürgen[
turtle47
*******
Beiträge: 1849
Registriert: Mi, 04.01.2006 20:10
Wohnort: Rheinbach

Re: get data array

Beitrag von turtle47 »

Hi Lupo,
lupolupp1 hat geschrieben:Was habe ich falsch gemacht?
Dein "oRange.setDataArray(Ausgabe())"
ist kein Array und kann deshalb nicht verarbeitet werden!
lupolupp1 hat geschrieben:Was fehlt?
Na, das Array welches Du hiermit erzeugst:

Code: Alles auswählen

Sub schnell_1()
mitarrayrechnen3()
Dim  Ergebnis (LBound(oData()) To UBound(oData()))
	oDoc = ThisComponent
	oSheets = oDoc.Sheets
	oSheet = oSheets.getByIndex(0)
	oRange1  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10")
	mitarrayrechnen3 'zunächst Daten einlesen
	For r = LBound(oData()) To UBound(oData())
	x0 = oData(r) 'Zeile
	Berechneter_Wert = x0(0) * 2 
	Ausgabe(r) = Array(Berechneter_Wert)'Berechneter_Wert in Array schreiben	
	next
	oRange1.setDataArray(Ausgabe())
End Sub

Sub mitarrayrechnen3()' Daten aus Tabelle in Array lesen
   oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10")
   oData() = oRange.getDataArray()
End Sub
Jetzt alles klar?

Jürgen
Software hat keinen Verstand - benutze deinen eigenen...!

Win 7 SP1/ LibreOffice 3.4.2 OOO340m1 (Build:203) / Firefox 15.0.1 / Notebook ASUS K70IO 64 Bit-Betriebssytem
lupolupp1
**
Beiträge: 32
Registriert: Do, 28.06.2007 14:51

Re: get data array

Beitrag von lupolupp1 »

Hi Jürgen,

super! Vielen Dank, ich denke jetzt komm ich weiter. Ich habe

Code: Alles auswählen

Ausgabe(r)=BerechneterWert
statt

Code: Alles auswählen

Ausgabe(r) = Array(BerechneterWert)
verwendet. Daran lag's wohl.

Viele Grüße

Lupo
turtle47 hat geschrieben:Hi Lupo,
lupolupp1 hat geschrieben:Was habe ich falsch gemacht?
Dein "oRange.setDataArray(Ausgabe())"
ist kein Array und kann deshalb nicht verarbeitet werden!
lupolupp1 hat geschrieben:Was fehlt?
Na, das Array welches Du hiermit erzeugst:

Code: Alles auswählen

Sub schnell_1()
mitarrayrechnen3()
Dim  Ergebnis (LBound(oData()) To UBound(oData()))
	oDoc = ThisComponent
	oSheets = oDoc.Sheets
	oSheet = oSheets.getByIndex(0)
	oRange1  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10")
	mitarrayrechnen3 'zunächst Daten einlesen
	For r = LBound(oData()) To UBound(oData())
	x0 = oData(r) 'Zeile
	Berechneter_Wert = x0(0) * 2 
	Ausgabe(r) = Array(Berechneter_Wert)'Berechneter_Wert in Array schreiben	
	next
	oRange1.setDataArray(Ausgabe())
End Sub

Sub mitarrayrechnen3()' Daten aus Tabelle in Array lesen
   oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10")
   oData() = oRange.getDataArray()
End Sub
Jetzt alles klar?

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

Re: get data array

Beitrag von lupolupp1 »

Hallo zusammen,

ich habe den Code nun noch etwas optimiert. Ich habe festgestellt, dass es auch ohne Global funktioniert.
Ich habe aber noch zwei Fragen:

a) Mit den Zeilen

Code: Alles auswählen

x = oData(r) 
Ergebnis=x(0) 
werden die Daten aus dem Array gelöst.
Wenn ich direkt

Code: Alles auswählen

Ergebnis=oData(r)
schreibe und dann mit Ergebnis weiterrechnen möchte, bekomme ich einen Fehlerhinweis.
Ist das zu kompliziert programmiert oder geht es nicht anders?

b) Ich habe festgestellt, dass alle einzelnen Variablen des Ausgabearrays gefüllt sein müssen (und wenn es sich nur um "" handelt), damit eine Übergabe des Arrays an eine Calc-Tabelle erfolgen kann. Ansonsten erscheint der Fehlerhinweis "Objektvariable nicht belegt".
Da ich einige der Array-Positionen aber nicht benötige (die entsprechenden Zellen der Calc-Tabelle, an die das Array übergeben wird, sollen leer bleiben), möchte ich nach dem Dim des Arrays zunächst alle Einzelpositionen mit "" füllen und die von mir verwendeten im weiteren Programmverlauf dann einfach überschreiben. Somit wären alle Positionen wenigstens mit "" belegt.
Gibt es einen Befehl, mit dem ich allen Array-Positionen in einem Vorgang den gleichen Wert, hier also "", zuweisen kann?
Oder gibt es eine andere Lösung dafür bzw. um die Fehlermeldung "Objektvariable nicht belegt" zu vermeiden?

Hier noch mein kompletter optimierter Code:

Code: Alles auswählen

Sub schnell()
dim odata(5)
dim Ausgabe(0 to 7) 'Alternativ kann das Ausgabe-Array von der Größe her auch an das Einlese-Array angepasst werden: 
'Ausgabe (LBound(oData()) To UBound(oData()))

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

For r=0 to 4 'Alternative mit kleinstem und größtem Wert des Einlese-Arrays: For r = LBound(oData()) To UBound(oData())
x = oData(r) 'Stelle des Wertes im Array
Ergebnis=x(0) 
Ergebnis2=Ergebnis/2 
Ausgabe(r)=Array(Ergebnis2) ' Übergabe des Ergebnisses an das Ausgabe-Array
next

Ausgabe(5)=Array("test") 'zur Ausgabe müssen alle Array-Positionen wenigstens mit "" gefüllt werden, 
'ansonsten erscheint der Fehler "Objektvariable nicht belegt"
Ausgabe(6)=Array("")
Ausgabe(7)=Array("test2")

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

End Sub
Vielen Dank für eure Hilfe im Voraus!

Lupo
turtle47 hat geschrieben:Hi Lupo,
lupolupp1 hat geschrieben:Was habe ich falsch gemacht?
Dein "oRange.setDataArray(Ausgabe())"
ist kein Array und kann deshalb nicht verarbeitet werden!
lupolupp1 hat geschrieben:Was fehlt?
Na, das Array welches Du hiermit erzeugst:

Code: Alles auswählen

Sub schnell_1()
mitarrayrechnen3()
Dim  Ergebnis (LBound(oData()) To UBound(oData()))
	oDoc = ThisComponent
	oSheets = oDoc.Sheets
	oSheet = oSheets.getByIndex(0)
	oRange1  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("B1:B10")
	mitarrayrechnen3 'zunächst Daten einlesen
	For r = LBound(oData()) To UBound(oData())
	x0 = oData(r) 'Zeile
	Berechneter_Wert = x0(0) * 2 
	Ausgabe(r) = Array(Berechneter_Wert)'Berechneter_Wert in Array schreiben	
	next
	oRange1.setDataArray(Ausgabe())
End Sub

Sub mitarrayrechnen3()' Daten aus Tabelle in Array lesen
   oRange  = ThisComponent.Sheets().getByIndex(0).getCellRangeByName("A1:A10")
   oData() = oRange.getDataArray()
End Sub
Jetzt alles klar?

Jürgen
Antworten