Wie lösche ich eine ganze Zeile in Excel, wenn dieselbe Zelle in der vorhergehenden Zeile identisch ist? - Excel, Excel-VBA

Meine Excel-Tabelle enthält 11 Spalten und 500kReihen. Jede Zeile ist ein Abtastwert von einem digitalen 8-Kanal-Logikanalysator: Spalte A ist ein Zeitstempel; die Spalten B bis I sind Bitwerte (entweder 1 oder 0 in jeder Zelle); Spalte J ist ein binäres Byte, das mit CONCATENATE (B, C, D, E, F, G, H, I) erzeugt wird; und Spalte K ist das gleiche Byte in Hexadezimal, das mit BIN2HEX (J) erstellt wurde.

Der Logikanalysator hat die Daten überabgetastetwesentlich. Ich möchte Samples löschen, bei denen sich der Byte-Wert nicht geändert hat, wobei nur der erste Abtastwert in einer Folge von sequentiellen Duplikaten beibehalten wird. Mit anderen Worten, ich möchte das ändern:

A        B  C  D  E  F  G  H  I  J         K
0.67497  1  0  0  1  1  1  1  0  10011110  9E
0.67498  1  0  0  1  1  1  0  1  10011101  9D
0.67499  1  0  0  1  1  1  0  1  10011101  9D
0.67500  1  0  0  1  1  1  0  1  10011101  9D
0.67501  1  0  0  1  1  1  1  0  10011110  9E

zu diesem:

A        B  C  D  E  F  G  H  I  J         K
0.67497  1  0  0  1  1  1  1  0  10011110  9E
0.67498  1  0  0  1  1  1  0  1  10011101  9D
0.67501  1  0  0  1  1  1  1  0  10011110  9E

Wenn ich nach Auswahl von Zelle K1 den folgenden Code ausführe, löscht er die Überabtastungen nach Wunsch, aber er läuft sehr langsam. (Es würde einige Tage dauern, bis ich fertig bin.)

Sub DeleteOverSamples()
Do Until ActiveCell.Value = ""
If ActiveCell.Value = ActiveCell.Offset(-1, 0).Value Then
ActiveCell.EntireRow.Delete
ElseIf ActiveCell.Value <> ActiveCell.Offset(-1, 0).Value Then
ActiveCell.Offset(1, 0).Select
End If
Loop
End Sub

Wie kann ich das effizienter machen?Wenn EntireRow.Delete eine zeitaufwendige Funktion ist, kann ich mehrere Zeilen gleichzeitig löschen (manchmal wiederholt sich der wiederholte Wert für Hunderte von Samples)? Danke vielmals!

Antworten:

3 für die Antwort № 1

Delete-Methode ist langsam, und einzelne Eingabe / Ausgabe einer Zelle ist auch langsam. Verwendung einer Variant Array ist schnell.

Sub test()
Dim vDB As Variant, vR() As Variant
Dim r As Long, c As Integer, n As Long, j As Integer
Dim s As String

vDB = Range("a1").CurrentRegion
r = UBound(vDB, 1)
c = UBound(vDB, 2)

s = vDB(1, 11)

n = n + 1
ReDim Preserve vR(1 To r, 1 To c)
For j = 1 To c
vR(n, j) = vDB(1, j)
Next j

For i = 1 To r
If s <> vDB(i, 11) Then
n = n + 1
For j = 1 To c
vR(n, j) = vDB(i, j)
Next j
s = vDB(i, 11)
End If
Next i
Sheets.Add
Range("a1").Resize(n, c) = vR

End Sub

2 für die Antwort № 2

Der folgende Code erstellt ein neues Blatt und kopiert die relevanten Werte aus dem ersten Blatt:

Sub test()
Application.ScreenUpdating = False
Application.Calculation = xlCalculationManual
Dim ws0 As Worksheet
Dim ws1 As Worksheet
Dim r0 As Long
Dim r1 As Long
Dim c As Long
Dim startTime As Single
startTime = Timer

Set ws0 = ActiveSheet
Set ws1 = Worksheets.Add
r0 = 1
r1 = 1
Do While Not IsEmpty(ws0.Cells(r0, 1).Value)
If r0 = 1 Then
ws1.Rows(r1).Range("A1:I1").Value = ws0.Rows(r0).Range("A1:I1").Value
r1 = r1 + 1
Else
For c = 2 To 9
If ws0.Cells(r0, c).Value <> ws0.Cells(r0 - 1, c).Value Then
ws1.Rows(r1).Range("A1:I1").Value = ws0.Rows(r0).Range("A1:I1").Value
r1 = r1 + 1
End If
Exit For
Next
End If
r0 = r0 + 1
Loop

MsgBox "Finished in " & (Timer - startTime) & " seconds"
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
End Sub

Ich testete dies anhand der Daten, die Sie für die ersten paar Zeilen angegeben haben, und replizierte dann Ihre letzte Zeile für die nächsten 499995 Zeilen (außer dass Spalte B zufällig zwischen beiden Zeilen ausgewählt wurde) 0 oder 1) und es dauerte etwas mehr als 20 Sekunden, um zu kopierenungefähr 250.000 Datenzeilen. Ohne den zufälligen Effekt in Spalte B dauerte es nur 19 Sekunden, um die 3 Zeilen zu kopieren, die Sie erwarten würden. Ein zufälliger Effekt in Spalte I statt in Spalte B dauerte etwas mehr als 28 Sekunden - was wahrscheinlich am langsamsten ist.

(Es wäre schneller, wenn es Ihre benutztberechnete Spalte J oder K, da sie nur eine Zelle pro Zeile anstatt der 8 Zellen betrachten müsste, die sie gerade betrachtet, aber ich war mir nicht sicher, ob Sie diese Spalten wirklich brauchten oder ob Sie sie nur hinzufügten, um Ihr vorhandenes zu machen Code einfacher.)


Verwandte Fragen