For Schleifen zu langsam, alternative?

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

Moderator: Moderatoren

vitalinka
Beiträge: 9
Registriert: Fr, 27.05.2011 13:57

For Schleifen zu langsam, alternative?

Beitrag von vitalinka »

Hallo Profis!
Folgendes Problem:
Ein Neuer und alter Katalog sollen vergleichen werden. Katalog besteht aus Artikelnummer, Artikelname, Preis.
Katalog = Tabelle. Und erhält über 30 000 Artikel.
Es ist so aufgebaut:
In Tabelle1 wird ermittelt wie viel Artikel drin sind und an diese Function übergeben. GesamtTab1.
Gleiche mit Tabelle2.
In erster For Schleife wird Artikelnummer 1 genommen und in 2ter Schleife in Tabelle2 gesucht. So bald gefunden weitere Manipulationen. Es lauft gut so lange Artikelnummern sortiert und da sind. So bald ein Artikel in Tabelle2 fehlt läuft die gesamte Tabelle2 durch und das dauert viel zu lange.
Kann man das anders lösen? Eine Schnelle Möglichkeit? Suchen Function ist nicht optimal, weil Artikelnummern müßen exakt passen. Artikel nummern sind unterschiedlicher Länge.
z.B. 1234 und der nächster 12345 und 12349 und alle mit 1234 werden gefunden. Das darf nicht sein. 1234 = 1234.

Code: Alles auswählen

Function Vergleichen (GesamtTab1, GesamtTab2)
TabelleNeu = thiscomponent.Sheets().getByName("Neue")
TabelleAlt = thiscomponent.Sheets().getByName("Alte")
Dim Color
Dim Ergebnis
Grosser = 0
Kleiner = 0
Gleich = 0

For i=0 To GesamtTab1 Step 1
Prefiks1 = TabelleNeu.getCellByPosition(0,i).getValue
Preis1 = TabelleNeu.getCellByPosition(2,i).getValue
	For j=0 To GesamtTab2 Step 1

		Prefiks2 = TabelleAlt.getCellByPosition(0,j).getValue
		
		If Prefiks1 = Prefiks2 Then
		Preis2 = TabelleAlt.getCellByPosition(2,j).getValue
		
			If Preis1 < Preis2 Then
			Color = 1832967
			Kleiner = Kleiner + 1
			Elseif Preis1 > Preis2 Then
			Color = 16667675
			Grosser = Grosser + 1
			Elseif Preis1 = Preis2 Then
			Color = 16251661
			Gleich = Gleich + 1
			Else
			Color = 0
			End If
			
			TabelleVergleich = thiscomponent.Sheets().getByName("Vergleich")
			TabelleVergleich.getCellByPosition(0,j).setValue(Prefiks1) 
			TabelleVergleich.getCellByPosition(1,j).setString(TabelleNeu.getCellByPosition(1,i).getString) 
			TabelleVergleich.getCellByPosition(2,j).setValue(Preis1) 
			TabelleVergleich.getCellByPosition(2,j).CellBackColor = Color
			TabelleVergleich.getCellByPosition(3,j).setValue(Preis2)
			TabelleVergleich.getCellByPosition(4,0).setValue(j)
			GoTo weiter
		End If
				
		If GesamtTab2 < j Then
		Preis2 = 0
		TabelleVergleich = thiscomponent.Sheets().getByName("Vergleich")
		TabelleVergleich.getCellByPosition(0,j).setValue(Prefiks1) 
		TabelleVergleich.getCellByPosition(1,j).setString(TabelleNeu.getCellByPosition(1,i).getString) 
		TabelleVergleich.getCellByPosition(2,j).setValue(Preis1) 
		TabelleVergleich.getCellByPosition(2,j).CellBackColor = Color
		TabelleVergleich.getCellByPosition(3,j).setValue(Preis2)
		GoTo weiter
		End If

	Next j
	weiter:
Next i

If Kleiner > Grosser AND Kleiner > Gleich Then
Ergebnis = "Billiger"
Elseif Grosser > Kleiner AND Grosser > Gleich Then
Ergebnis = "Teuerer"
Elseif Gleich > Kleiner AND Gleich > Grosser Then
Ergebnis = "Gleich"
Else
Ergebnis = "Unverstaendlich"
End If

Ausgabe = "Ergebnis: " & Ergebnis & CHR$(10)
Ausgabe = Ausgabe & "Kleiner: " & Kleiner & CHR$(10)
Ausgabe = Ausgabe & "Grosser: " & Grosser & CHR$(10)
Ausgabe = Ausgabe & "Gleich: " & Gleich & CHR$(10)
MsgBox Ausgabe

End Function


Moderation,4: verschoben in BASIC-Unterbereich, wo alle Makro-Fragen hin gehören
Karolus
********
Beiträge: 7535
Registriert: Mo, 02.01.2006 19:48

Re: For Schleifen zu langsam, alternative?

Beitrag von Karolus »

Hallo
Man kann das vmtl. mit "Bordmitteln" lösen und muss gar kein Makro bemühen - aber ich hab an der Stelle aufgegeben:

Code: Alles auswählen

If Kleiner > Grosser AND Kleiner > Gleich Then
Ergebnis = "Billiger"
Warum nimmt man solche bescheuerten Variablennamen ?

Karo
LO7.4.7.2 debian 12(bookworm) auf Raspberry5 8GB (ARM64)
LO25.2.3.2 flatpak debian 12(bookworm) auf Raspberry5 8GB (ARM64)
vitalinka
Beiträge: 9
Registriert: Fr, 27.05.2011 13:57

Re: For Schleifen zu langsam, alternative?

Beitrag von vitalinka »

Hallo!
Ihre Bemerkungen werde ich mir merken. Aber Lösung habe ich noch nicht.
Ich habe es umgebaut. Ich dachte, wenn ich Cellen einzel auslese und vergleiche dauert es viel zulange. Dann habe ich alles in Arrays eingelesen. Es hat schon geholfen, aber immer noch zu langsam. Dann ist mir eingefallen, gebrauchte Daten aus Array zu löschen um die Schleife zu verkürzen. Aber immer noch langsam. Es dauer über 2 Stunden.
Man kann natürlich auch ohne Makros lösen, aber makro muß sein. Gibt es eine schnellere Lösung? Base? MySql?
Ich habe gleiche im PHP geht viel schneller. Halbe stunde, aber die Lösung ist unbequem. Viel Vorbereitung.
Mit kleinen Datenmengen kein Problem, aber ich habe 30 000 Datensätze.

Code: Alles auswählen

Function Vergleichen (ArrayTabNeu, ArrayTabAlt)

Dim Color
Dim Ergebnis
Dim VergleichArray(0 to UBound(ArrayTabNeu))
Grosser = 0
Kleiner = 0
Gleich = 0

For i=0 To UBound(ArrayTabNeu) Step 1
Prefiks1 = ArrayTabNeu(i)(0)
Land1 = ArrayTabNeu(i)(1)
Preis1 = ArrayTabNeu(i)(2)

	For j=0 To UBound(ArrayTabAlt) Step 1
				
		Prefiks2 = ArrayTabAlt(j)(0)
		If Prefiks1 = Prefiks2 Then
		Preis2 = ArrayTabAlt(j)(2)
		
			If Preis1 < Preis2 Then
			Color = 1832967
			Kleiner = Kleiner + 1
			Elseif Preis1 > Preis2 Then
			Color = 16667675
			Grosser = Grosser + 1
			Elseif Preis1 = Preis2 Then
			Color = 16251661
			Gleich = Gleich + 1
			Else
			Color = 0
			End If
			
			Erase ArrayTabAlt(j)
			
		 GoTo weiter
		ElseIf UBound(ArrayTabAlt) <= j Then 
		Preis2 = 0
		Color = 0
		
		GoTo weiter
		End If

	Next j	
	weiter:
	ver = Array(Prefiks1, Land1, Preis1, Preis2, Color)
	VergleichArray(i) = ver
	TabelleVergleich = thiscomponent.Sheets().getByName("Vergleich")
	TabelleVergleich.getCellByPosition(4,0).setValue(i) 'um zu sehen dass alles noch läuft
Next i

For a=0 To UBount(VergleichArray) Step 1
TabelleVergleich = thiscomponent.Sheets().getByName("Vergleich")
TabelleVergleich.getCellByPosition(0,a).setValue(VergleichArray(a)(0)) 
TabelleVergleich.getCellByPosition(1,a).setString(VergleichArray(a)(1)) 
TabelleVergleich.getCellByPosition(2,a).setValue(VergleichArray(a)(2)) 
TabelleVergleich.getCellByPosition(2,a).CellBackColor = VergleichArray(a)(4)
TabelleVergleich.getCellByPosition(3,a).setValue(VergleichArray(a)(3))
Next a


If Kleiner > Grosser AND Kleiner > Gleich Then
Ergebnis = "Billiger"
Elseif Grosser > Kleiner AND Grosser > Gleich Then
Ergebnis = "Teuerer"
Elseif Gleich > Kleiner AND Gleich > Grosser Then
Ergebnis = "Gleich"
Else
Ergebnis = "Unverstaendlich"
End If

Ausgabe = "Ergebnis: " & Ergebnis & CHR$(10)
Ausgabe = Ausgabe & "Kleiner: " & Kleiner & CHR$(10)
Ausgabe = Ausgabe & "Grosser: " & Grosser & CHR$(10)
Ausgabe = Ausgabe & "Gleich: " & Gleich & CHR$(10)
MsgBox Ausgabe

End Function
Antworten