Ich habe ein Excel-Arbeitsblatt, das aus zwei Spalten besteht, von denen eine mit Zeichenfolgen gefüllt und die andere leer ist. Ich möchte VBA verwenden, um den Wert der Zellen in der leeren Spalte basierend auf dem Wert der benachbarten Zeichenfolge in der anderen Spalte zuzuweisen.
Dim regexAdmin As Object Set regexAdmin = CreateObject("VBScript.RegExp") regexAdmin.IgnoreCase = True regexAdmin.Pattern = "Admin" Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If regexAdmin.test(Cells(i, j).Value) Then Cells(i, j + 1).Value = "Exploitation" End If Next j Next i
Die Das Problem ist, dass die Verwendung dieser Schleife für eine große Datenmenge viel zu lange dauert und meistens nur Excel zum Absturz bringt.
Kennt jemand einen besseren Weg, dies zu tun?
Antwort
Die kurze Antwort lautet:
Verwenden Sie vba verwenden Sie eine Formel. Insbesondere eine Kombination aus IF
und SEARCH .
=IF(SEARCH($A1,"Admin")>0,"Exploitation","")
Aber dies ist eine Codeüberprüfung, also machen wir das trotzdem.
-
Regex ist langsam. Es scheint, dass Sie es „nur für die Groß- und Kleinschreibung verwenden“. Vor diesem Hintergrund können Sie Zellenwerte direkt vergleichen, indem Sie
StrComp
mit der OptionvbTextCompare
verwenden. ( nützlicher Artikel über StrComp ) -
i
undj
werden normalerweise für Schleifenzähler verwendet, aberrow
undcol
in diesem Fall sinnvoller.
So könnte dies aussehen:
Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows Dim col As Integer For col = 1 To 2 If StrComp("Admin",Cells(row, col).Value,vbTextCompare) Then Cells(row, col + 1).Value = "Exploitation" End If Next col Next row
Antwort
Ich würde denken, dass ein einfacher Zeichenfolgenvergleich viel schneller als Regex ist.
Dim pattern as string pattern = "Admin" Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If Cells(i, j) = pattern Then Cells(i, j + 1) = "Exploitation" End If Next j Next i
Kommentare
- Dieser Code ‚ adressiert den Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung nicht, aber Sie ‚ sind korrekt. Die Regex ist übertrieben und in diesem Fall wird ein Zeichenfolgenvergleich bevorzugt. (Willkommen übrigens bei Code Review!)
Antwort
Darf ich eine Reduzierung der Laufzeit um 50% vorschlagen? /Anstrengung?
Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows If StrComp("Admin",Cells(row, 1).Value,vbTextCompare) Then Cells(row, 2).Value = "Exploitation" End If Next row
Hat niemand bemerkt, dass das OP wirklich davon spricht, „EINE Spalte zu überprüfen und in den nächsten Nachbarn zu schreiben“? Warum dann Spalten schleifen? Der zweite Durchgang würde nur entweder eine leere Zelle oder eine Zelle mit „Ausnutzung“ überprüfen.
Antwort
Wow. Schon beim Lesen der ersten Zeilen habe ich mich gefragt:
- Warum die späte Bindung?
- Warum überhaupt eine Regex verwenden?
@ ckuhn203 hat die Benennung bereits in seiner Antwort angesprochen, aber ich finde Folgendes:
Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows
Daraus wurde Folgendes:
Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows
… Benötigt den Kommentar nicht mehr.
Ich möchte VBA verwenden, um den Wert der Zellen in der leeren Spalte basierend auf dem Wert der benachbarten Zeichenfolge in der anderen Spalte zuzuweisen.
Ich denke, dass „s [mis | ab] mit VBA: Excel selbst sehr gut mit der Zuweisung von Zellenwerten auf der Basis anderer umgehen kann Zellen „Werte.
regexAdmin.Pattern = "Admin"
Ich denke, dass „s [mis | ab] Regex verwendet: Wenn Ihr Muster nur ein einfaches Wort ist, versuchen Sie höchstwahrscheinlich, eine Mücke mit einer Panzerfaust zu töten. Falsches Werkzeug für t Der Job hier.
Antwort
Wenn Sie auf das Range-Objekt zugreifen, sollte dies mit einem einzigen Lese- / Schreibvorgang erfolgen.
Bevor Sie die for-Schleife eingeben, sollten Sie den gesamten Bereich lesen, mit dem Sie arbeiten möchten.
data = Range(Cells(1,1), Cells(10,2)).Value
Jetzt können Sie arbeiten mit den Daten:
For i = 1 To 10 "let"s say there is 10 rows Dim j As Integer For j = 1 To 2 If regexAdmin.test(data(i, j)) Then data(i, j + 1) = "Exploitation" End If Next j Next i
Schreiben Sie die Daten schließlich zurück, um sie zu übertreffen:
Range(Cells(1,1), Cells(10,2)).Value = data
Antwort
In B1:
=if(upper(A1)="ADMIN","Exploitation","")
Dann füllen Sie es einfach aus. Dies unterscheidet nicht zwischen Groß- und Kleinschreibung.
Diese automatische Füllung kann auf zwei Arten erfolgen, entweder interaktiv im Arbeitsblatt oder programmgesteuert:
Interaktiv : Excel verfügt über eine Funktion zum automatischen Ausfüllen. Wenn B1 ausgewählt und diese Formel eingegeben ist, doppelklicken Sie einfach auf den Füllpunkt. Dies ist das winzige Quadrat in der unteren rechten Ecke der Zelle, wenn es ausgewählt ist. Excel kopiert die Formel intelligent bis zum Ende des zusammenhängenden Bereichs Daten. Wenn A1-A256 Daten ohne Leerzeichen enthält, wird B256 automatisch ausgefüllt. Wenn Leerzeichen vorhanden sind, scrollen Sie alternativ nach unten und wählen Sie B256 (oder was auch immer das Ende ist). Dann Strg + Umschalt + Aufwärtspfeil, um den Bereich auszuwählen, der zu B1 führt, und Strg + D, um ihn nach unten zu kopieren (denken Sie an d = dito)
Verwenden von VBA … , wenn Sie dies programmgesteuert tun müssen: mit der Formel, die Zelle als Auswahl enthält:
Selection.AutoFill Destination:=Range("B1:B19")
Für das automatische Ausfüllen stehen weitere Optionen zur Verfügung, mit denen Sie einige coole Tricks ausführen können.Kann einen Literalwert anstelle einer Formel kopieren oder auch eine Reihe basierend auf einem Muster füllen. Sie können auch benutzerdefinierte Muster festlegen, die erkannt werden sollen, z. B. Geschäftsbereiche, die Sie häufig in Dingen oder Städten wiederholen, in denen Sie Einzelhandelsstandorte haben usw.
Kommentare
- Willkommen bei Code Review! Ich habe völlig übersehen, dass OP ‚ die Spalte nicht durchsuchen musste! ++ Beste Lösung hier.
Antwort
Durch die Kombination aller anderen Antworten wurde die Groß- und Kleinschreibung nicht berücksichtigt Regex im Original beseitigte die Notwendigkeit, die Anzahl der Zeilen anzugeben und alle Variablen zu deklarieren, da Option Explicit
so viele Fehler in vba
Option Explicit Sub checkForExploit() Dim row As Integer Dim data() As Variant Dim datarange As Range Set datarange = Range("A1:B10") data = datarange.Value For row = 1 To UBound(data, 1) If LCase(data(row, 1)) = "admin" Then data(row, 2) = "Exploitation" End If Next row datarange.Value = data End Sub