Live-Forum - Die aktuellen Beiträge
Datum
Titel
24.04.2024 19:29:30
24.04.2024 18:49:56
24.04.2024 17:19:09
Anzeige
Archiv - Navigation
692to696
Aktuelles Verzeichnis
Verzeichnis Index
Übersicht Verzeichnisse
Vorheriger Thread
Rückwärts Blättern
Nächster Thread
Vorwärts blättern
Anzeige
HERBERS
Excel-Forum (Archiv)
20+ Jahre Excel-Kompetenz: Von Anwendern, für Anwender
692to696
692to696
Aktuelles Verzeichnis
Verzeichnis Index
Verzeichnis Index
Übersicht Verzeichnisse
Inhaltsverzeichnis

Spalten-Einmaligkeitsprüfung zu langsam

Spalten-Einmaligkeitsprüfung zu langsam
09.11.2005 14:56:52
David
Hallo Zusammen
Ich komme gleich mal zu meinem Problem:
Ich habe eine Spalte in einem Sheet, deren Werte Einmalig sein müssen. Doppelte oder dreifache (oder x-fache) Werte sollen Rot markiert werden und auf derselben Zeile soll in Spalte I die Zeilennummer von dem/den Gegenstück/en geschrieben werden.
Das funktioniert an sich schon alles. Das Problem ist: es sind insgesamt 3557 Zeilen, aber es sollte so schnell wie Möglich durchlaufen (das Beste wäre innerhalb einer Minute, aber ich bin mir zu 90% sicher, dass das unmöglich ist).
Mein momentaner Code (s.u.) braucht aber rund 20 Minuten dafür. Ich habe schon alles optimiert, das mir möglich war (und so schon ca. 30 minuten eingespart) aber ich weiss nicht, ob und was man noch verbessern könnte.
Kann mir hier vieleicht jemand helfen oder mir zumindest sagen, dass eine weitere Verbesserung gar nicht Möglich ist? Danke im Voraus.
Mein Code sieht momentan so aus:

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim Cell As Range
Dim z As Range
Dim check As Long
check = 0
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
For Each z In ActiveSheet.UsedRange.Columns(2).Cells
' nur überprüfen, wenn die Zelle nicht leer ist
If Not z.Value = "" Then
' jede zeile von z aus überprüfen auf Wert in Spalte B
For Each Cell In ActiveSheet.Range(z, z.End(xlDown)).Cells
' Wert Vergleichen: Zelle vom 1. Loop und Zelle vom momentanen
If Range("B" & Cell.Row).Value = z.Value Then
check = check + 1
If Not Cell.Row = z.Row Then Range("I" & z.Row).Value = Range("I" & z.Row).Value & " " & Cell.Row
End If
Next
If check > 1 Then
z.Interior.ColorIndex = 3
ElseIf z.Interior.ColorIndex = 3 Then
z.Interior.ColorIndex = xlNone
End If
check = 0
Else
Exit For
End If
Next z
MsgBox "Überprüfung der Spalte B abgeschlossen!"
End Sub

15
Beiträge zum Forumthread
Beiträge zu diesem Forumthread

Betreff
Datum
Anwender
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
09.11.2005 15:15:37
Heiko
Hallo David,

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim Cell As Range
Dim z As Range
Dim check As Long
check = 0
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
For Each z In ActiveSheet.UsedRange.Columns(2).Cells
' nur überprüfen, wenn die Zelle nicht leer ist
If Not z.Value = "" Then
' jede zeile von z aus überprüfen auf Wert in Spalte B
For Each Cell In ActiveSheet.Range(z, z.End(xlDown)).Cells
' Wert Vergleichen: Zelle vom 1. Loop und Zelle vom momentanen
If Range("B" & Cell.Row).Value = z.Value Then
check = check + 1
If Not Cell.Row = z.Row Then Range("I" & z.Row).Value = Range("I" & z.Row).Value & " " & Cell.Row
End If
Next
If check > 1 Then
z.Interior.ColorIndex = 3
ElseIf z.Interior.ColorIndex = 3 Then
z.Interior.ColorIndex = xlNone
End If
check = 0
Else
Exit For
End If
Next z
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
MsgBox "Überprüfung der Spalte B abgeschlossen!"
End Sub

Bitte um Rückmeldung mit Zeitersparniss.
Gruß Heiko
Anzeige
Noch ein Tipp
09.11.2005 15:42:24
Heiko
Hallo
ich hab mal irgendwo gelernt das Vergleiche auf Ungleich schneller sind als auf Gleich.

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim Cell As Range
Dim z As Range
Dim check As Long
check = 0
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
For Each z In ActiveSheet.UsedRange.Columns(2).Cells
' nur überprüfen, wenn die Zelle nicht leer ist
If z.Value <> "" Then
' jede zeile von z aus überprüfen auf Wert in Spalte B
For Each Cell In ActiveSheet.Range(z, z.End(xlDown)).Cells
' Wert Vergleichen: Zelle vom 1. Loop und Zelle vom momentanen
If Range("B" & Cell.Row).Value = z.Value Then
check = check + 1
If Cell.Row <> z.Row Then Range("I" & z.Row).Value = Range("I" & z.Row).Value & " " & Cell.Row
End If
Next
If check > 1 Then
z.Interior.ColorIndex = 3
ElseIf z.Interior.ColorIndex = 3 Then
z.Interior.ColorIndex = xlNone
End If
check = 0
Else
Exit For
End If
Next z
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
MsgBox "Überprüfung der Spalte B abgeschlossen!"
End Sub

Würde mich mal interessieren ob das auch noch Zeitvorteile zu meiner 1. Version gebracht hat.
Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
09.11.2005 15:58:18
David
Ich hab's gerade mal ausprobiert.. Es dauerte 22 Minuten. Wiso auch immer, es scheint sogar langsamer zu sein.
Das mit dem ungleich habe ich allerdings noch nicht probiert.
Ich kam auf die Idee, die ganze Spalte in ein Array zu füllen, dieses zu Sortieren und doppelte herauszulöschen und dann die Länge mit der Länge der Spalte zu vergleichen. das würde sicher um einiges schneller ablaufen, aber ich hätte die doppelten nicht mehr markiert, was auch nicht so das Wahre wäre.
Danke jedenfalls für die Hilfe.
Das mit Ungleich werde ich testen.
AW: Spalten-Einmaligkeitsprüfung zu langsam
09.11.2005 16:06:55
Heiko
Hallo David,
das wundert mich nun, weil meistens hilft das. ;-)
Die Gleich Ungleich Sache wird da keine 21 Minuten rausholen.
Deinen Code habe ich mir nun noch nicht genau angeschaut, da läst sich vielleicht was tun, mit Arrays usw.
Um das dann zu testen wäre eine Beispielmappe ganz gut, um zu sehen was in der Tabelle überhaupt gemacht wird. Lade doch mal eine hoch (max 300kB) dann kann man viel besser schauen was zu optimieren geht.
Gruß Heiko
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
09.11.2005 16:18:00
David
Hallo Heiko,
Der Upload ist ziemlich langsam und leider muss ich los, um meinen Bus nicht zu verpassen. Werd es aber gleich Morgen Morgen hochladen (notfalls auf eigenen Server).
Bis dann
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 08:02:23
David
OK, der Upload funktioniert nicht wirklich.. also hier wäre es:
http://spaam.ath.cx/Tabelle.zip
Ich habe jetzt 1000 Zeilen davon 'reingenommen und ein paar Spalten gelöscht, um's kleiner zu machen. Meine Makros sollten noch enthalten sein. Die Funktion Einmaligkeit_Ueberpruefen_Spalte_B() ist die, mit dere ich das Problem habe. dort ist dein Verbesserungsvorschlag noch nicht drin.
Gruss David
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 08:16:42
Heiko
Moin david,
habe zwar noch nicht ganz verstanden was du machen willst, suchst irgendwie dopplte.
Hier mal ne neue Version: Teste mal, ich muss nu erstmal was tun bin nachher aber wieder am Ball.
GetTickCount ist nur zur zeitmessung in Millisekunden, kann später raus.
Option Explicit
Private Declare

Function GetTickCount Lib "kernel32" () As Long
Public lngTime As Long

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim Cell As Range
Dim z As Range
Dim check As Long, lngLastRow As Long
check = 0
lngTime = GetTickCount
lngLastRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
' For Each z In ActiveSheet.UsedRange.Columns(2).Cells
For Each z In ActiveSheet.Range("B1:B" & lngLastRow)
' nur überprüfen, wenn die Zelle nicht leer ist
If Not z.Value = "" Then
' jede zeile von z aus überprüfen auf Wert in Spalte B
'For Each Cell In ActiveSheet.Range(z, z.End(xlDown)).Cells
For Each Cell In ActiveSheet.Range("B" & z.Row & ":B" & lngLastRow)
' Wert Vergleichen: Zelle vom 1. Loop und Zelle vom momentanen
If Range("B" & Cell.Row).Value = z.Value Then
check = check + 1
If Not Cell.Row = z.Row Then Range("I" & z.Row).Value = Range("I" & z.Row).Value & " " & Cell.Row
End If
Next
If check > 1 Then
z.Interior.ColorIndex = 3
ElseIf z.Interior.ColorIndex = 3 Then
z.Interior.ColorIndex = xlNone
End If
check = 0
Else
Exit For
End If
Next z
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
MsgBox "Zeit = " & GetTickCount - lngTime
End Sub

Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 11:12:11
Heiko
Hallo David,
neuste Version und nu bist erstmal dran mit Rückmeldung !!!
Option Explicit
Private Declare

Function GetTickCount Lib "kernel32" () As Long
Public lngTime As Long

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim rngZ As Range, rngFind As Range, rngFirstAddress
Dim lngCheck As Long, lngLastRow As Long
lngCheck = 0
lngTime = GetTickCount
lngLastRow = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
' For Each rngZ In ActiveSheet.UsedRange.Columns(2).Cells
For Each rngZ In ActiveSheet.Range("B1:B" & lngLastRow)
' nur überprüfen, wenn die Zelle nicht leer ist
If rngZ.Value <> "" Then
Set rngFind = ActiveSheet.Range("B" & rngZ.Row & ":B" & lngLastRow).Find(rngZ.Value, LookAt:=xlWhole, LookIn:=xlValues)
If Not rngFind Is Nothing Then
rngFirstAddress = rngFind.Address
Do
lngCheck = lngCheck + 1
If rngFind.Row <> rngZ.Row Then ActiveSheet.Range("H" & rngZ.Row).Value = ActiveSheet.Range("H" & rngZ.Row).Value & " " & rngFind.Row
Set rngFind = ActiveSheet.Range("B" & rngZ.Row & ":B" & lngLastRow).FindNext(rngFind)
Loop While Not rngFind Is Nothing And rngFind.Address <> rngFirstAddress
End If
If lngCheck > 1 Then
rngZ.Interior.ColorIndex = 3
ElseIf rngZ.Interior.ColorIndex = 3 Then
rngZ.Interior.ColorIndex = xlNone
End If
lngCheck = 0
Else
Exit For
End If
Next rngZ
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
MsgBox "Zeit = " & GetTickCount - lngTime
End Sub

Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 11:37:02
David
Hi Heiko
seltsam.. ich bin sicher, dass ich ne Antwort geschrieben hab.
Womöglich hab ich die Antwort der falschen Person oder so geschrieben.. peinlich
Die neue Version ist nun 14 Minuten gelaufen. Hab es nun abgebrochen.
Denn inzwischen hab ich es anders gelöst, habe das eigentlich im "verschwundenen" Post schon geschrieben. Tut mir leid, dass du nun unnötigen Aufwand hattest. Meine neue Version liest die Spalte in ein Array ein, sortiert das Array, vegleicht jeden Index mit dem nächsten und wenn die gleich sind, wird das in ein zweites Array geschrieben. am Schluss geh ich nochmal die ganze Spalte durch und markiere jede Zelle rot, die mit einem Eintrag im 2. array übereinstimmt.
Auf diese Weise geht es viel schneller, nämlich nur ca. 10 Sekunden. Jetzt muss ich nur noch herausfinden, wie ich die Funktion automatisch beim speichern ausführen kann. (Da sollte sie schon nicht gerade 20 minuten haben ;))
Aber vielmals Danke für deine Mühe. Du warst, soweit ich mich erinnere, auch derjenige, der mir beim letzten VB-Problem geholfen hat.
Gruss David
noch mein neuer code, falls er dich interessieren sollte:

Sub Einmaligkeit_Ueberpruefen_Spalte_B()
Dim z As Range
Dim iRows As Integer
iRows = ActiveSheet.Columns(2).End(xlDown).Row
Dim bCheck As Boolean
bCheck = True
' Array mit Feldzahl = Zeilenzahl
Dim aSpalte() As String
ReDim Preserve aSpalte(iRows)
Dim sTemp As String
' Loop über alle Zellen der 2. Spalte (B) im aktiven Sheet
For Each z In ActiveSheet.UsedRange.Columns(2).Cells
'farben zurücksetzen
z.Interior.ColorIndex = xlNone
' nur überprüfen, wenn die Zelle nicht leer ist
If z.Value <> "" Then
' Zeile ins Array speichern
aSpalte(z.Row - 1) = z.Value
Else
Exit For
End If
Next z
Dim i As Integer
While bCheck
bCheck = False
For i = 0 To iRows - 1
If aSpalte(i) > aSpalte(i + 1) Then
sTemp = aSpalte(i)
aSpalte(i) = aSpalte(i + 1)
aSpalte(i + 1) = sTemp
bCheck = True
End If
Next
Wend
Dim sDouble As String
sDouble = ""
Dim aDouble() As String
Dim iSizeOfDoubleArray As Integer
iTemp = 0
' Doppelte in den String und in den Array füllen
For i = 0 To iRows - 1
If aSpalte(i) = aSpalte(i + 1) Then
' array vergrössern und doppelte Zahl hineinfüllen
iSizeOfDoubleArray = iSizeOfDoubleArray + 1
ReDim Preserve aDouble(iSizeOfDoubleArray)
aDouble(iSizeOfDoubleArray - 1) = aSpalte(i)
' doppelte zahl in string schreiben
If sDouble = "" Then
sDouble = aSpalte(i)
Else
sDouble = sDouble & ", " & aSpalte(i)
End If
End If
Next
' Den Markierdurchlauf der Spalte nur starten, wenn's überhaupt was zu Markieren gibt
If iTemp <> 0 Then
For Each z In ActiveSheet.UsedRange.Columns(2).Cells
For i = 0 To iSizeOfDoubleArray - 1
If z.Value = aDouble(i) Then
z.Interior.ColorIndex = 3
End If
Next i
Next z
If iSizeOfDoubleArray = 1 Then
MsgBox "Nummer " & sDouble & " doppelt. Siehe rote Markierung"
Else
MsgBox "Nummern " & sDouble & " doppelt. Siehe rote Markierung"
End If
Else
MsgBox "Überprüfung der Spalte B abgeschlossen: Keine Doppelten!"
End If
End Sub

Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 11:58:26
Heiko
Hallo David,
was hast du denn für einen Rechner und wieviele Zeilen durchsuchst du bei dir ?!
Mit deinem Code finde ich bei mir überhaupt keine Doppelungen.
Mit meinem Code findet es in 5000 Zeilen alle Doppelungen in ca 45 Sekunden.
Bist du sicher das alle Doppelungen mit deinem Code erkannt wurden ?!
Gruß Heiko
PS: Rückmeldung wäre nett !
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 12:55:03
David
Hallo Heiko
Doppelungen hat es noch keine, aber die Liste wird oft erweitert und umgeschrieben, und es darf da nie passieren, dass eine Doppelung auftritt.
mein pc hier ist nicht so der tollste:
win 2000, 256 mega ram, pentium 3 800Mhz
und ja, bin sicher, hab extra ein paar hinzugefügt ;)
Gruss David
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 14:20:08
Heiko
Hallo David,
habe noch mal ein bisschen rumgespielt, wenn du magst kannst du diese Version nochmal testen. Lehnt sich an deine letzte an, sollte nur schneller sein, hoffe ich ;-)

Sub Einmaligkeit_Spalte_B()
Dim arrDaten()
Dim lngRows As Long, lngI As Long, lngK As Long
Dim strDoppelt As String
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
lngRows = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
arrDaten = Application.WorksheetFunction.Transpose(ActiveSheet.Range("B1:B" & lngRows))
For lngI = LBound(arrDaten) To UBound(arrDaten)
For lngK = lngI + 1 To UBound(arrDaten)
If arrDaten(lngI) = arrDaten(lngK) Then
ActiveSheet.Cells(lngK, 2).Interior.ColorIndex = 3
If InStr(1, strDoppelt, " " & arrDaten(lngK) & " ") = 0 Then
strDoppelt = strDoppelt & " " & arrDaten(lngK) & " "
End If
End If
Next lngK
Next lngI
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
If strDoppelt <> "" Then
MsgBox "Nummer " & strDoppelt & " doppelt. Siehe rote Markierung", vbCritical
Else
MsgBox "Überprüfung der Spalte B abgeschlossen: Keine Doppelten!"
End If
End Sub

Gruß Heiko
PS: Rückmeldung wäre nett !
Anzeige
AW: Spalten-Einmaligkeitsprüfung zu langsam
10.11.2005 14:26:07
David
Hi Heiko
---------------------------
Microsoft Visual Basic
---------------------------
Fehler beim Kompilieren:
Keine Zuweisung an Datenfeld möglich
---------------------------
OK Hilfe
---------------------------
Zeile: arrDaten = Application.WorksheetFunction.Transpose(ActiveSheet.Range("B1:B" & lngRows))
Geht leider nicht. Liegt vieleicht an der alten office-version (97)
aber eigentlich bin ich ganz zufrieden mit der version jetzt. 10 sekunden sind ja nicht die welt :)
Gruss David
Letzter Versuch.
10.11.2005 15:08:45
Heiko
Hallo David,
lange nicht mehr soviel mit Arrays rumgespielt wie heute, jetzt kann ich es wieder.
Habe nochmal ne Version ohne Transpose gemacht, wenn die wieder nicht läuft liegt es wohl wirklich an der "alten" EXCEL Version.
Das einzige was du dann nochmal testen kannst in diese Zeile
Dim arrDaten
so zu verändern.
Dim arrDaten()
Denn einem Array einen Range in einem Rutsch zuzuweisen, spart enorm viel Rechenzeit.
Bei mir braucht die Version mit Transpose für 5000 Zeilen nun ca.3,5 Sekunden (Rechner 1,1 GHZ Laptop mit XP und EXCEL 2002) die ohne Transpose 9,5 Sekunden.
Habe mich heute also von mehreren Minuten auf ein paar Sekunden runtergekämpft :-)

Sub EinmaligkeitOhneTranspose()
Dim arrDaten
Dim lngRows As Long, lngI As Long, lngK As Long
Dim strDoppelt As String
lngTime = GetTickCount
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
lngRows = ActiveSheet.Cells(Rows.Count, 2).End(xlUp).Row
arrDaten = ActiveSheet.Range("B1:B" & lngRows)
For lngI = LBound(arrDaten) To UBound(arrDaten)
For lngK = lngI + 1 To UBound(arrDaten)
If arrDaten(lngI, 1) = arrDaten(lngK, 1) Then
ActiveSheet.Cells(lngK, 2).Interior.ColorIndex = 3
If InStr(1, strDoppelt, " " & arrDaten(lngK, 1) & " ") = 0 Then
strDoppelt = strDoppelt & " " & arrDaten(lngK, 1) & " "
End If
End If
Next lngK
Next lngI
Application.ScreenUpdating = True
Application.Calculation = xlCalculationAutomatic
Application.Calculate
MsgBox "Zeit = " & (GetTickCount - lngTime) / 1000
If strDoppelt <> "" Then
MsgBox "Nummer " & strDoppelt & " doppelt. Siehe rote Markierung", vbCritical
Else
MsgBox "Überprüfung der Spalte B abgeschlossen: Keine Doppelten!"
End If
End Sub

Gruß Heiko
PS: Rückmeldung wäre nett !
AW: Letzter Versuch.
10.11.2005 15:32:06
David
10 sekunden dauerte es hier. auch wenn office was anderes behauptet:
---------------------------
Microsoft Excel
---------------------------
Zeit = 0
---------------------------
OK
---------------------------
das problem bei der version ist nur: das erste auftreten der mehrfach vorhandenen zahl wird nicht markiert.
also 10 sek. was sagt uns das? genau, ich brauche einen schnelleren pc ;)
Danke nochmals
Gruss David

Beliebteste Forumthreads (12 Monate)

Anzeige

Beliebteste Forumthreads (12 Monate)

Anzeige
Anzeige
Anzeige