[erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

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

Moderator: Moderatoren

Benutzeravatar
balu
********
Beiträge: 3649
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

[erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von balu » Do, 31.05.2018 23:11

Hallo liebe Gemeinde.

Ich stecke im Treibsand, und je mehr ich tu und mach, umso mehr versinke ich.
Das ich so nebenbei den Wald vor lauter Bäume nicht mehr sehe kommt auch noch dazu.
Ich qäule mich nun seit mittlerweile 4 Tagen mit folgendem Problem herum.

Eins vorweg: Beispieldatei ist im Anhang.

Beispielsweise lese ich aus einem Tabellenblatt den Bereich A1 bis B69 in ein Array ein, Spalte A = Datum und Spaltze B = Namen. Okay, kein Problem.
Den eingelesenen "Datenbereich" durchsuche ich nach einem bstimmten Datumsbereich.

Code: Alles auswählen

if aDatenArray(iAz)(0) >= dQuartalVon AND aDatenArray(iAz)(0) <= dQuartalBis then
Ist quasi so etwas wie eine SUMMENPRODUKT, vereinfacht dargestellt:

Code: Alles auswählen

SUMMENPRODUKT(B3>=QuartalVon;B3<=QuartalBis)
Das funktioniert auch so weit. Durch diverse vorgenommene Test konnte ich mich auch davon überzeugen das die gesuchten Datume vom Makro gefunden werden. Also bis hier kein Problem.

Jetzt kann ich mir natürlich die Ergebnisse auf simple und einfache Art und Weise ausgeben lassen.

Code: Alles auswählen

	for iAz = LBound(aDatenArray()) to UBound(aDatenArray())
		if aDatenArray(iAz)(0) >= dQuartalVon AND aDatenArray(iAz)(0) <= dQuartalBis then
		oBlatt2.getCellRangeByName("A" & iAz+1).FormulaLocal = aDatenArray(iAz)(0)
		oBlatt2.getCellRangeByName("A" & iAz+1).Numberformat = 36
		oBlatt2.getCellRangeByName("B" & iAz+1).string = aDatenArray(iAz)(1)
		end if
   	next iAz
Klar ersichtlich das dies eine "Schneckentempo Angelegenheit" wird, wenn es sich um beispielsweise 100 Treffer oder noch viel mehr handeln würde.

Und genau an dieser Stelle stecke ich im Treibsand fest!
Denn ich suche jetzt eine Methode das Ergebniss schnellst möglich in das Tabellenblatt einzutragen.
Meine bisherigen Informationsquellen sind da leider nicht sehr hilfreich:
- Dannenhöfer
- Die deutsche Version von Andrew Pitonyak "OpenOffice.org Macros Explained, 3. ed." stand Februar 2018
- Dieses Forum

Ein Hauptproblem bei den Infoquellen ist, da werden einerseits Beispiele gezeigt die mit sehr vielen Abkürzungen arbeiten, wie z.B. in der Art von

Code: Alles auswählen

for i=0 to ubound(oData())
	t = oData(i)
	for j=0 to ubound(t)
		Ausgabe(i,j) = t(j)
	next
next
Dies Beispiel stammt von hier: viewtopic.php?t=19294 (ist nicht in meiner Beispieldatei)
I, t, und j sind irgendwelche Variablen die wohl funktionieren, aber leider nicht sehr viel sagen. Und dabei ist das ja noch relativ Harmlos. Wenn man sich die deutsche oder Amerikanische Version von Andrew anschaut, dann wird es erst recht ungemütlich. Da wird beim Thema ARRAY das so gesehen auf die Spitze getrieben.

Ja ich weiss!
Auch ich arbeite mit teilweise solchen oder solch ähnlichen Abkürzungen.
Aber bei dem gezeigten Beispiel kommts dann zum "Wald ... Bäume"-Effekt, aus dem ich nicht mehr herausfinde. Dieses Problem liegt also nicht beim Autor solcher Beispiele, sondern bei mir.

Kommen wir aber zu dem nächsten Problem, welches dann auch mein Hauptproblem ist.
Viele, oder fast alle Beispiel bei dem Thema ARRAY in dem eben genannten PDF (Andrew) geben etwas in einer PRINT oder aber in einer MSGBOX aus. Damit ist das Ergebniss aber leider noch nicht aufm Papier (Tabellenblatt). Und selbst wenn ich XRAY bemühe, bekomme ich wohl etwas aufm Bildschirm angezeigt, was dadurch aber auch noch nicht ins Papier rüber gebracht ist.

Sorry, das ich jetzt etwas weit ausgeholt habe, aber das musste sein damit ihr in ungefähr versteht wie es mir momentan geht (Treibsand).


Jetzt habe ich hier im Forum etwas gefunden was wohl theoretisch und auch teilweise praktisch funktioniert, aber leider nicht so wie erhofft.
Hier der Link dazu: viewtopic.php?t=64222
Und das habe ich dann bei mir wie folgt eingearbeitet (ein kurzer Auszug hier, aber vollsändig in der Beispieldstei)

Code: Alles auswählen

for iAz2 = LBound(aDatenArray2()) to UBound(aDatenArray2())
	if aDatenArray2(iAz2)(0) >= dQuartalVon AND aDatenArray2(iAz2)(0) <= dQuartalBis then
		aFilterArray(0, iAz2) = aDatenArray2(iAz2)(0) : aFilterArray(1, iAz2) = aDatenArray2(iAz2)(1)			
		iAT = iAT +1
			If iAT = iArrayTreffer THEN
				goto Ende
			end if
	end if
next iAz2
	   	Ende: 
'
'*************************************************************************************
' Inspiriert durch: http://de.openoffice.info/viewtopic.php?t=64222
'	
	oStartZelle = oBlatt2.getCellRangeByName("A1")
	
	StartSpalte = oStartZelle.RangeAddress.StartColumn
	StartReihe = oStartZelle.RangeAddress.StartRow

	EndSpalte = StartSpalte + UBound(aFilterArray,2)
	EndReihe = StartReihe + UBound(aFilterArray,1)
	
	oBlatt2.getCellRangeByPosition(StartSpalte, StartReihe, EndSpalte, EndReihe).setDataArray(aFilterArray)
Positiv dabei ist, hier werden "sprechende" Variablen genommen.
Wenn ich das Makro laufen lasse, dann werden auch rasend schnell die Ergebnisse ausgeben. Und jetzt kommt das dicke fette

ABER!!
die Ausgabe ist Horizontal. Und ich will das Vertikal haben.
Also anstatt nur 2 Zeilen und sehr viele Spalten, soll es 2 Spalten und sehr viele Zeilen haben.

Ich habe wirklich lange daran rumgedoktert um mein Ziel zu erreichen, aber es geht nicht so wie ich es mir vorgestellt habe. Es hatt auch sehr lange gedauert bis das ich das Problem wohl so einigermaßen verstanden habe, es aber dadurch nicht beseitigt bekomme.

Mein ARRAY ist ein 2 Dimensionales Array wo erst die Zeilen und dann erst die Spalten abgearbeitet werden. Es ist so gesehen (lapidar ausgedrückt) Transponiert.

Ich weiss das mein Betreff eigentlich nicht ganz korrekrt ist, von wegen 2 Spalten, aber deshalb habe ich das ja auch in Gänsefüßchen gesetzt: "2-Spaltiges"
Es ist ein ARRAY in einem ARRAY.

Also hatte ich versucht das ganze irgendwie so zu Transponieren, das die Ausgabe wie gewünscht ist, also 2 Spalten mit vielen Zeilen. Jedoch da komm ich einfach nicht weiter. Ich dachte mir, vielleicht hilft ja SPLIT irgendwie, wenn ich das auszugebende ARRAY anders erstelle, was so z.B. aussah.

Code: Alles auswählen

aFilterArray(iAz) = aDatenArray(iAz)(0) & "-" & aDatenArray(iAz)(1)
(Nicht in der Beispieldatei)
Damit bekomme ich wohl auch nachweislich ein ARRAY, aber ich krieg das nicht "Gesplitet", weil mir dafür das nötige Wissen fehlt.


Mein Problem ist jetzt wie folgt.
Wie kriege ich das eingelesene ARRAY, welches gefiltert wurde, 2 Spaltig mit vielen Zeilen ins Tabellenblatt geschrieben?

Vielen dank für die aufgebrachte Zeit um meinen Beitrag zu lesen.

Ich freue mich auf Eure Antworten.


Gruß
balu
Dateianhänge
ARRAY_schreiben_0.ods
(9.81 KiB) 58-mal heruntergeladen
Zuletzt geändert von balu am Fr, 01.06.2018 08:57, insgesamt 1-mal geändert.
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Stephan
********
Beiträge: 10590
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von Stephan » Fr, 01.06.2018 00:50

z.B.

Code: Alles auswählen

Sub Quartal_Filtern_2
	Dim aDatenArray	
		
	aDatenArray = oQuellBereich.getDataArray()
	
	Dim aFilterArray()
	Dim akt_array(1)
	Dim aktuelle_Arraygroesse

	for iAz = LBound(aDatenArray()) to UBound(aDatenArray())
		if aDatenArray(iAz)(0) >= dQuartalVon AND aDatenArray(iAz)(0) <= dQuartalBis then
		aktuelle_Arraygroesse = UBOUND(aFilterArray())
		Redim Preserve aFilterArray(aktuelle_Arraygroesse + 1)
		Redim akt_array(1)
		
		akt_array(0) = aDatenArray(iAz)(0)
		akt_array(1) = aDatenArray(iAz)(1)
		aFilterArray(aktuelle_Arraygroesse + 1) = akt_array()
		
		end if
   	next iAz
   		
   	oStartZelle = oBlatt2.getCellRangeByName("A1")
	
	StartSpalte = oStartZelle.RangeAddress.StartColumn
	StartReihe = oStartZelle.RangeAddress.StartRow

	EndSpalte = StartSpalte + 1
	EndReihe = StartReihe + UBound(aFilterArray())
	
	oBlatt2.getCellRangeByPosition(StartSpalte, StartReihe, EndSpalte, EndReihe).setDataArray(aFilterArray)
	oBlatt2.getCellRangeByPosition(StartSpalte, StartReihe, StartSpalte, EndReihe).Numberformat = 36	
   			
   			PRINT "F Ä D I S C H ! ! ! Quartal_Filtern_2"
end Sub

Für eine Fehleranalyse Deines Makros bin ich zu müde.

Gruß
Stephan

Benutzeravatar
balu
********
Beiträge: 3649
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von balu » Fr, 01.06.2018 08:42

Moin moin Stephan,

ich hoffe Du konntest ausschlafen.
Für eine Fehleranalyse Deines Makros bin ich zu müde.
Das verlange ich doch gar nicht von dir.

Ich habe deinen Code in meine Beispieldatei eingefügt, ausgeführt und jetzt bin ich absolut Häppy. Denn es funktioniert genau so wie ich es mir vorgestellt habe. Und das Sahnehäuptchen von dir oben drauf ist, die Datumsspalte wird auch gleich noch richtig formatiert. Damit hatte ich gar nicht gerechnet, ich hätte es auch gar nicht verlangt.

An 'Redim' und 'Redim Preserve' hatte ich wohl auch kurz gedacht, das hätte mich aber alleine nicht weitergebracht da mir der Sinn und Ablauf beim Umbau des Array einfach fehlte.


Wie auch immer. Das Ergebnis funktioniert, und ich bin nicht nur Glücklich, sondern auch erleichtert. Ich Danke dir vielmals. :D



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Stephan
********
Beiträge: 10590
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von Stephan » Fr, 01.06.2018 09:56

so, trotzdem noch nachgereicht:

Code: Alles auswählen

Sub Quartal_Filtern_1

	iArrayTreffer = 0
	
	Dim aDatenArray2(), aFilterArray()
	aDatenArray2 = oQuellBereich.getDataArray()

	for iAz = LBound(aDatenArray2()) to UBound(aDatenArray2())
		if aDatenArray2(iAz)(0) >= dQuartalVon AND aDatenArray2(iAz)(0) <= dQuartalBis then
		iArrayTreffer = iArrayTreffer + 1
		end if
   	next iAz
'-----------------------------------------------------------	
		iAT = 0 ' Ein kleiner Startzähler		
'-----------------------------------------------------------
	Redim aFilterArray(iArrayTreffer -1)

	for iAz2 = LBound(aDatenArray2()) to UBound(aDatenArray2())
		if aDatenArray2(iAz2)(0) >= dQuartalVon AND aDatenArray2(iAz2)(0) <= dQuartalBis then
			aFilterArray(iAz2) = aDatenArray2(iAz2) ': aFilterArray(iAz2)(1) = aDatenArray2(iAz2)(1)			
			iAT = iAT +1
				If iAT = iArrayTreffer THEN ' Wenn der Zähler den größten Wert von *iArrayTreffer* erreicht hat,
					goto Ende				' dann wird diese Routine beendet.
				end if
		end if
   	next iAz2
			   	Ende: 
'
'*************************************************************************************
' Inspiriert durch: http://de.openoffice.info/viewtopic.php?t=64222
'	
	oStartZelle = oBlatt2.getCellRangeByName("A1")
	
	StartSpalte = oStartZelle.RangeAddress.StartColumn
	StartReihe = oStartZelle.RangeAddress.StartRow

	EndSpalte = StartSpalte + UBOUND(aFilterArray(0))
	EndReihe = StartReihe + UBound(aFilterArray)
	
	oBlatt2.getCellRangeByPosition(StartSpalte, StartReihe, EndSpalte, EndReihe).setDataArray(aFilterArray)
	oBlatt2.getCellRangeByPosition(StartSpalte, StartReihe, StartSpalte, EndReihe).Numberformat = 36

'*************************************************************************************
   			PRINT "F Ä D I S C H ! ! ! Quartal_Filtern_1"
end Sub
Hinweise:

(a)
Das Array ist nur eindimensional, deshalb:

Code: Alles auswählen

Redim aFilterArray(iArrayTreffer -1)
(b)
folglich ist die Wertzuweisung so, denn es müssen nur bestehende Unterarrays unverändert übernommen werden:

Code: Alles auswählen

aFilterArray(iAz2) = aDatenArray2(iAz2)
mir ist leider nicht klar (da hing ich auch heute Nacht) warum Folgendes nicht geht:

Code: Alles auswählen

aFilterArray(iAz2) (0) = aDatenArray2(iAz2) (0)
aFilterArray(iAz2) (1) = aDatenArray2(iAz2) (1)
denn das läuft zwar zunächst ohne Fehlermeldung, aber das Array 'passt' dann beim Rückschreiben nicht. Das das nicht läuft ist hier kein Nachteil, denn es so zu lösen wäre unnötig kompliziert, ich würde aber trotzdem gerne verstehen warum das nicht läuft.


(c)
die eine Zeile, die auch in meinem Makro von heute Nacht war, ist so besser:
(aFilterArray(0) ist beliebig, der Index muss nur einem existenten Index entsprechen)

Code: Alles auswählen

EndSpalte = StartSpalte + UBOUND(aFilterArray(0))


Gruß
Stephan

Benutzeravatar
balu
********
Beiträge: 3649
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von balu » Fr, 01.06.2018 10:56

aFilterArray(0) ist beliebig, der Index muss nur einem existenten Index entsprechen
Ich hatte erst gedacht das der was mit den Zeilen- oder Spaltenindex im Array zu tun hatte, aber da ich ja das Array nicht richtig befüllt hatte, änderte sich die Schreibrichtung im Tabellenblatt ja nicht.

Das er existieren muss stellte ich dadurch fest, das bei der Eingabe von 3 eine Fehlermeldung ausgespuckt wurde.

mir ist leider nicht klar (da hing ich auch heute Nacht) warum Folgendes nicht geht:

Code: Alles auswählen

aFilterArray(iAz2) (0) = aDatenArray2(iAz2) (0)
aFilterArray(iAz2) (1) = aDatenArray2(iAz2) (1)
denn das läuft zwar zunächst ohne Fehlermeldung, aber das Array 'passt' dann beim Rückschreiben nicht. Das das nicht läuft ist hier kein Nachteil, denn es so zu lösen wäre unnötig kompliziert, ich würde aber trotzdem gerne verstehen warum das nicht läuft.
Damit hatte ich auch experimentiert, blos meine Schreibweise war anders.

Code: Alles auswählen

aFilterArray(iAz2) (0) = aDatenArray2(iAz2) (0) : aFilterArray(iAz2) (1) = aDatenArray2(iAz2) (1)
BASIC-Makros für OpenOffice und LibreOffice hat geschrieben: Im allgemeinen ist es am besten, die Daten auf eine Weise zu organi-
sieren, dass ein möglichst direkter, natürlicher und einprägsamer Bezug dazu besteht, wie sie erstellt,
verwendet und verarbeitet werden.
Zu finden im Kapitel "5. Array-Routinen" PDF-Seite 115. Und deshalb hatte ich mich auch für die leicht fremdartige Schreibweise entschieden. Aber das nur so am Rande.
... ich würde aber trotzdem gerne verstehen warum das nicht läuft.
Und darüber hatte ich mir auch den Kopf zerbrochen. Denn mein Gedanke war: Wenn ich auf diese Art und Weise ein Array auslesen kann, dann müsste ich doch auch eigentlich es so wieder befüllen können. Aber dann fiel mir irgendwann wieder ein, das es ja kein richtiges 2 Spaltiges Array ist, sondern ein Array in einem Array was anders aufgebaut ist. Doch irgendwann hats mir dann endgültig gereicht, und ich habe mich hier ans Forum gewendet.


Stephan ich danke dir noch mal für deine ganzen Bemühungen. Zumal ich ja jetzt gesehen habe das selbst Du damit ganz schön rumgekämpft hast. Und ich dachte mir heute morgen noch so naiv: "Typisch Stephan! Er schüttelt es einfach so ausm Ärmel." Aber weit gefehlt.


Wünsche dir noch einen schönen Tag.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Stephan
********
Beiträge: 10590
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von Stephan » Fr, 01.06.2018 12:41

Damit hatte ich auch experimentiert, blos meine Schreibweise war anders.

...

Und ich dachte mir heute morgen noch so naiv: "Typisch Stephan! Er schüttelt es einfach so ausm Ärmel." Aber weit gefehlt.

Unwichtig ist: Ich kann die eine Variante 'aus dem Ärmel', die ich zuerst gepostet hatte.
Wichtig ist hingegen: Bei der anderen Variante, die ich ursprünglich von Dir habe:
viewtopic.php?f=18&t=68341&hilit=getDataArray

bin ich immer unsicher und genau deshalb hatte ich jetzt die Gelegenheit genutzt mich wieder einmal damit zu beschäftigen.

Folgendes läuft einwandfrei für beliebige Zuweisungen im Sinne daten(x)(y) = <Wert>:

Code: Alles auswählen

Sub Main
	daten = ThisComponent.Sheets(0).getCellRangeByName("A1:B10").getDataArray()
	daten(1)(0) = 1234
	daten(1)(1) = 5678
	ThisComponent.Sheets(0).getCellRangeByName("A1:B10").setDataArray(daten)
End Sub
weswegen ich nicht kapiere das:

Code: Alles auswählen

aFilterArray(iAz2) (0) = aDatenArray2(iAz2) (0)
aFilterArray(iAz2) (1) = aDatenArray2(iAz2) (1)

nicht richtig funktioniert bzw. diese 2 Zeilen ansich funktionieren ja, nur lässt sich das Array "aFilterArray" hinterher nicht in die Tabelle zurückschreiben.


Gruß
Stephan

Benutzeravatar
balu
********
Beiträge: 3649
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von balu » Fr, 01.06.2018 14:07

Weisst Du was Stephan?
Ich gehöre verboten :lol:
Wichtig ist hingegen: Bei der anderen Variante, die ich ursprünglich von Dir habe:
viewtopic.php?f=18&t=68341&hilit=getDataArray

bin ich immer unsicher und genau deshalb hatte ich jetzt die Gelegenheit genutzt mich wieder einmal damit zu beschäftigen.
Ich wusste gar nicht das ich in dieser Hinsicht so einen bleibenden Eindruck hinterlassen habe. Nur mal so am Rande bemerkt, und auch nicht so Bier-Ernst nehmen ;-)

Aber davon abgesehen. In einem anderen Forum helfe ich momentan jemandem bei einem Makro Problem. Und als ich im groben verstand was ein Problem bei ihm ist, dachte ich mir nur noch folgendes:

"Das wäre doch eine prima Gelegenheit meinen damaligen Beitrag in die Tat umzusetzen und auch den Punkt *zurück ins Blatt schreiben* anzugehen."

Denn dann könnte ich auch gleichzeitig deiner Bitte nachkommen das hier in die FAQs zu schreiben. Nur das zu durchsuchen dort zu erklären wäre für mich einfach zu wenig. Es fehlt genau dieser Punkt, das zurückschreiben.

Wir beide stehen also genau vor dem gleichen Problem.


Joke Frage.
Wie oft wird es am Tag; Nacht?
Antwort.
Hier heute 2 mal.
Das erste mal wars um ca. 9 Uhr. Und das zweite mal kommt gleich. Thor lässt schön grüßen.
Fürs erste reichts mir damit. Ziehe mich vorläufig in meine "Brummel-Höhle" zurück.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

mikeleb
******
Beiträge: 723
Registriert: Fr, 09.12.2011 16:50

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von mikeleb » So, 03.06.2018 16:58

Hallo,
weswegen ich nicht kapiere das:

Code: Alles auswählen

aFilterArray(iAz2) (0) = aDatenArray2(iAz2) (0)
aFilterArray(iAz2) (1) = aDatenArray2(iAz2) (1)
nicht richtig funktioniert bzw. diese 2 Zeilen ansich funktionieren ja, nur lässt sich das Array "aFilterArray" hinterher nicht in die Tabelle zurückschreiben.
Die Frage lies mich nun auch nicht locker und daher habe ich ein bisschen herumexperimentiert. Herausgekommen ist folgendes:
a) .setDataArray ist offensichtlich recht genügsam. Während .getDataArray ein einddimensionales Array liefert (die Zeilen) und jedes Element dabei wiederum ein Array ist (die Spalten), darf man .setDataArray auch mit einem (echten) zweidimensionales Array füttern.
Die beiden folgenden Varianten funktionieren also:

Code: Alles auswählen

	dim a(2)
	a(0)=array(1,1)
	a(1)=array(2,2)
	a(2)=array(3,3)
	Thiscomponent.sheets(2).getcellrangebyName("A1:B3").setDataArray(a())
	dim b(4,3)
	for i=0 to ubound(b(),1)
		for k=0 to ubound(b(),2)
			b(i,k)=rnd
		next
	next
	Thiscomponent.sheets(2).getCellRangeByName("D1:G5").setDataArray(b())
b) Was passiert nun, wenn ich ein eindimensionales Array dimensioniere und folgendermaßen fülle:

Code: Alles auswählen

	Dim c(1)
	c(0)="erster"
	c(1)(0)="zwo 1"
	c(1)(1)="zwo 2"
Das erste Element des Arrays ist "erster" und das zweite Element ist ... "zwo 2" !!! Die Indizierung in der "zweiten Dimension" wird schlicht ignoriert - es wird kein Array erzeugt.
Um also die Elemente des Arrays c() mit Arrays zu füllen, wäre sowas nötig:

Code: Alles auswählen

	Dim c(1)
	c(0)="erster"
	c(1)=DimArray(1)
	c(1)(0)="zwo 1"
	c(1)(1)="zwo 2"
oder eben

Code: Alles auswählen

	Dim c(1)
	c(0)="erster"
	c(1)=Array("zwo 1","zwo 2")
Gruß,
mikeleb

Stephan
********
Beiträge: 10590
Registriert: Mi, 30.06.2004 19:36
Wohnort: nahe Berlin

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von Stephan » So, 03.06.2018 19:24

Hallo mikeleb,

Danke, das war gute Detektivarbeit.

Ich bin sehr sehr erstaunt das das funktioniert:

Code: Alles auswählen

dim b(4,3)
for i=0 to ubound(b(),1)
	for k=0 to ubound(b(),2)
		b(i,k)=rnd
	next
next
Thiscomponent.sheets(2).getCellRangeByName("D1:G5").setDataArray(b())
Denn als StarBasic-Anfänger habe ich mich einst damit rumgeärgert überhaupt erst die Arrays in die Array-in-Array-Form bringen zu müssen und das habe ich doch nur getan weil es sonst nicht funktioniert hat. Auch jüngst (innerhalb der letzten 6 Monate) kam dazu hier wieder einmal eine Anfängerfrage im Forum wo es auch nicht klappte.
Ich sehe also das Dein Code funktioniert, aber ich bin überrascht.
b) Was passiert nun, wenn ich ein eindimensionales Array dimensioniere und folgendermaßen fülle:
[...]
WOW, das hast Du sehr gut aufgeklärt.

In der Tat scheint es genauso zu sein, denn das erklärt warum mein zweiter Code funktioniert (dort wird ein eingelesenes Array nur geändert) und der Erste Code von mir (von Balus Code abgeleitet) nicht (da wird das ganze Array neu erstellt).


GRuß
Stephan

Benutzeravatar
balu
********
Beiträge: 3649
Registriert: Fr, 24.08.2007 00:28
Wohnort: Warstein

Re: [erl.]CALC: "2-Spaltiges" Array einlesen, filtern und ausgeben in Calc

Beitrag von balu » So, 03.06.2018 21:51

Hallo mikeleb und Stephan,

ich danke dir, mikeleb, für deine Bemühungen.
Zu deinem Vorschlag kann ich momentan praktisch angewendet noch nichts sagen. Das wird vielleicht noch ein paar Tage dauern.

Ich habe heute den Lösungsvorschlag von Stephan am 'Fr, 01.06.2018 00:50' leicht abgewandelt praktisch eingesetzt.

An meine Bedingungen angepasst sah die dementsprechende Passage zu erst wie folgt aus.

Code: Alles auswählen

	Dim aDatenArray	
		
	aDatenArray = oQuellBereich.getDataArray()
	
	Dim aFilterArray()
	Dim akt_array(6)
	Dim aktuelle_Arraygroesse

	for iAz = LBound(aDatenArray()) to UBound(aDatenArray())
	
		if aDatenArray(iAz)(6) >= dQuartalVon AND aDatenArray(iAz)(6) <= dQuartalBis then
			aktuelle_Arraygroesse = UBOUND(aFilterArray())
			
				Redim Preserve aFilterArray(aktuelle_Arraygroesse + 1)
				Redim akt_array(6)
		
						akt_array(0) = aDatenArray(iAz)(0)
						akt_array(1) = aDatenArray(iAz)(1)
						akt_array(2) = aDatenArray(iAz)(2)
						akt_array(3) = aDatenArray(iAz)(3)
						akt_array(4) = aDatenArray(iAz)(4)
						akt_array(5) = aDatenArray(iAz)(5)
						akt_array(6) = aDatenArray(iAz)(6)
		
		aFilterArray(aktuelle_Arraygroesse + 1) = akt_array()
		
		end if
Das schien mir aber irgendwie zu unelegant. Also habe ich das auf dies hier geändert.

Code: Alles auswählen

	Dim aDatenArray	
	Dim iZaehlerSpalten as Integer
	
	iZaehlerSpalten = oQuellBereich.getColumns.Count -1
	aDatenArray = oQuellBereich.getDataArray()
	
	Dim aFilterArray()
	Dim akt_array(iZaehlerSpalten)
	Dim aktuelle_Arraygroesse

	for iAz = LBound(aDatenArray()) to UBound(aDatenArray())
	
		if aDatenArray(iAz)(iZaehlerSpalten) >= dQuartalVon AND aDatenArray(iAz)(iZaehlerSpalten) <= dQuartalBis then
			aktuelle_Arraygroesse = UBOUND(aFilterArray())
			
				Redim Preserve aFilterArray(aktuelle_Arraygroesse + 1)
				Redim akt_array(iZaehlerSpalten)
		
					For iArrayIDX = 0 to iZaehlerSpalten
						akt_array(iArrayIDX) = aDatenArray(iAz)(iArrayIDX)
					next iArrayIDX
		
		aFilterArray(aktuelle_Arraygroesse + 1) = akt_array()
		
		end if
Auf diese Art und Weise musste ich das nicht so schreiben.

Code: Alles auswählen

		akt_array(0) = aDatenArray(iAz)(0)
		akt_array(1) = aDatenArray(iAz)(1)
		akt_array(2) = aDatenArray(iAz)(2)
		akt_array(3) = aDatenArray(iAz)(3)
		akt_array(4) = aDatenArray(iAz)(4)
		akt_array(5) = aDatenArray(iAz)(5)
		akt_array(6) = aDatenArray(iAz)(6)
		akt_array(7) = aDatenArray(iAz)(7)
		akt_array(8) = aDatenArray(iAz)(8)
Da es in wirklichkeit nämlich 9 Spaltem im Tabellenblatt sind.

Okay, also gings an den Praxistest.
Erstmal noch recht Harmlos mit nur insgesamt 760 Zeilen, die auch alle mit irgendwelchen Daten gefüttert waren, nebst Datum. Und in OO.o 3.2.1 funktionierte das auch echt schnell.

Dann habe ich die Datei in AOO 4.1.5 komplett neu aufgebaut. Und beim Makro hatte ich eine kleinigkeit geändert die mir anschließend die Suppe verhagelte, wo ich aber bei der "Fehleranalyse" nicht sofort dran gedacht hatte.
Denn mit fast der gleichen Datenmenge wie zuvor in OO.o dauerte jetzt der Filterprozess nicht mehr ca. 1 sekunde, sondern irgendetwas um die 10 sekunden.
Was war denn jetzt Los?
Ist AOO in der 4.1.5er Version so träge langsam geworden?
Ich wollte schon die Version verfluchen.
Bis das ich diese Datei in OO.o öffnete.
Und was soll ich sagen?
Das gleiche in Grün!

Um es kurz zu machen, ich hatte das Problem doch noch entdeckt.
Der Datenbereich im Tabellenblatt ging ja nur, wie schon erwähnt, bis zur Zeile 760. Jedoch hatte ich den "Quellbereich" im Makro von A6:G1000 auf A6:I5000 geändert. Wobei die 2 zusätzlichen Spalten die Suppe auch nicht mehr Fett machte. Aber die Zeilenerhöhung von 1000 bis 5000, die war der Übeltäter. Und obendrein hatte ich weiterhin nur bis zur Zeile 760 Daten, und der Rest war Leer.

In dem Augenblick wo ich auf A6:I1000 die Zeilenzahl reduzierte, ging das wieder um die 1 sekunde flugs über die Bühne.

Also wars AOO nicht schuld, das ich vor einem Rätsel stand. Das Problem bin ich.

Jetzt war aber meine Neugierde geweckt, und ich wollte das System jetzt mal auf eine echte Bewährungsprobe stellen.
Also habe ich den schon vorhandenen Datenbereich (mit Daten) A6:I760 kopiert, und immer wieder unten am Ende eingefügt. Und irgendwann landete ich dann in der Zeile 36341 (mit dezimaltrenner: 36.341). Das sollte jetzt doch zum testen ausreichen.

Tja, wie soll ichs sagen?

Am besten kurz und schmerzlos.
Der Filterungsprozes mit der Ausgabe von ca. 8740 Zeilen dauert jetzt ca. 32 sekunden!

Mein angedachtes Experiment mit getDataArray und setDataArray scheint wohl unter dieser Datenmenge wohl nicht das Optimale zu sein.

Aber egal wie auch immer, ich habe was dazugelernt, und werde den Vorschlag von mikeleb demnächst noch Praktisch anwenden und ausprobieren. Werde dann auch davon Berichten.

Also bis bald.



Gruß
balu
Sei öfter mal ein Faultier, sag öfter mal "Ach was!" Dann kriegst du keinen Herzinfarkt, und hast ne menge Spass.

wehr rächtschraipfähler findet khan si behalden :D

Antworten