Ho un foglio di lavoro Excel composto da due colonne, una delle quali è piena di stringhe e laltra è vuota. Vorrei utilizzare VBA per assegnare il valore delle celle nella colonna vuota in base al valore della stringa adiacente nellaltra colonna.

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 

Il il problema è che quando si utilizza questo ciclo per una grande quantità di dati, ci vuole troppo tempo per funzionare e, la maggior parte delle volte, si blocca semplicemente Excel.

Qualcuno conosce un modo migliore per farlo?

Risposta

La risposta breve è:

Non utilizzare , utilizza una formula. In particolare, una combinazione di IF e SEARCH .

=IF(SEARCH($A1,"Admin")>0,"Exploitation","") 

Ma questa è una revisione del codice, quindi facciamolo comunque.

  • Regex è lento. Sembra che tu lo stia usando solo per la sua insensibilità al maiuscolo / minuscolo. Detto questo, puoi confrontare direttamente i valori delle celle utilizzando StrComp con lopzione vbTextCompare. ( articolo utile su StrComp )

  • i e j sono in genere utilizzati per i contatori di loop, ma row e col ha più senso in questo caso.

Ecco come potrebbe apparire:

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 

Risposta

Penso che il semplice confronto tra stringhe sarebbe molto più veloce di Regex.

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 

Commenti

  • Questo codice non ‘ indirizza il confronto senza distinzione tra maiuscole e minuscole, ma ‘ è corretto. Lespressione regolare è eccessiva e in questo caso è preferibile il confronto delle stringhe. (Benvenuto in Code Review, comunque!)

Answer

Posso suggerire una riduzione del 50% del tempo di esecuzione /sforzo?

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 

Nessuno ha notato che lOP parla di “controllare UNA colonna, scrivere nella NEXT adiacente”, davvero? Perché allora le colonne in loop? Il secondo passaggio controllerebbe solo una cella vuota o una con “Exploitation” al suo interno.

Answer

Wow. La sola lettura delle prime due righe mi ha fatto pensare:

  • Perché lassociazione tardiva?
  • Perché usare una regex?

@ ckuhn203 ha già affrontato la denominazione nella sua risposta, ma trovo questo:

Dim i As Integer For i = 1 To 10 "let"s say there is 10 rows 

Si è trasformato in questo:

Dim row As Integer For row = 1 To 10 "let"s say there is 10 rows 

… non ha più bisogno del commento.


Vorrei utilizzare VBA per assegnare il valore delle celle nella colonna vuota in base al valore della stringa adiacente nellaltra colonna.

Penso che “s [mis | ab] usando VBA: Excel stesso sia molto bravo a gestire lassegnazione di valori di cella basati su altri celle “valori.


regexAdmin.Pattern = "Admin" 

Penso che “s [mis | ab] usi regex: se il tuo pattern è solo una parola semplice,” molto probabilmente stai cercando di uccidere una zanzara con un bazooka. Strumento sbagliato per t egli lavoro qui.

Risposta

Ogni volta che accedi alloggetto Range, dovrebbe essere fatto con una singola operazione di lettura / scrittura.

Prima di entrare nel ciclo for dovresti leggere lintero intervallo con cui stai cercando di lavorare.

data = Range(Cells(1,1), Cells(10,2)).Value 

Ora puoi lavorare con i dati:

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 

Infine riscrivi i dati in excel:

Range(Cells(1,1), Cells(10,2)).Value = data 

Risposta

In B1:

=if(upper(A1)="ADMIN","Exploitation","") 

Quindi riempilo. Non fa distinzione tra maiuscole e minuscole.

Questo riempimento automatico può essere eseguito in due modi, in modo interattivo nel foglio di lavoro o in modo programmatico:

Interattivo : Excel ha una funzione di compilazione automatica. Con B1 selezionato e la formula inserita, fai doppio clic sul quadratino di riempimento, che è il quadratino nellangolo inferiore destro della cella quando è selezionato. Excel copierà in modo intelligente la formula fino alla fine dellintervallo contiguo che ha dati. Significa che se A1-A256 ha dati senza spazi vuoti, verrà compilato automaticamente a B256. In alternativa, se ci sono spazi vuoti, scorri fino in fondo e seleziona B256 (o qualunque sia la fine). Quindi Ctrl + Maiusc + Freccia su per selezionare lintervallo che porta a B1 e Ctrl + D per copiarlo (pensa d = idem)

Uso di VBA … se devi farlo in modo programmatico: con la formula contenente la cella come selezione:

Selection.AutoFill Destination:=Range("B1:B19") 

Sono disponibili altre opzioni per la compilazione automatica per eseguire alcuni trucchi interessanti.Può copiare un valore letterale invece di una formula o anche riempire una serie in base a un modello. Puoi anche impostare modelli personalizzati da riconoscere, ad esempio linee di attività che ripeti comunemente in cose o città in cui hai punti vendita, ecc.

Commenti

  • Benvenuto in Code Review! Mi mancava completamente che OP ‘ non aveva bisogno di cercare nella colonna! ++ Soluzione migliore qui.

Risposta

La combinazione di tutte le altre risposte insieme, ha reso insensibile al maiuscolo / minuscolo come il regex nelloriginale, ha rimosso la necessità di specificare quante righe e dichiarare tutte le variabili perché Option Explicit evita così tanti errori 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 

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *