Jeg har et Excel-regneark som består av to kolonner, hvorav den ene er fylt med strenger og den andre er tom. Jeg vil bruke VBA til å tilordne verdien av cellene i den tomme kolonnen basert på verdien til den tilstøtende strengen i den andre kolonnen.

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 

problemet er at når det brukes denne sløyfen for store mengder data, tar det altfor lang tid å jobbe, og for det meste krasjer det ganske enkelt Excel.

Er det noen som vet en bedre måte å gjøre dette på?

Svar

Det korte svaret er:

Ikke bruk , bruk en formel. Spesielt en kombinasjon av IF og SØK .

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

Men dette er kodegjennomgang, så la oss gjøre det uansett.

  • Regex er treg. Det ser ut til at du bare bruker det til sakens ufølsomhet. Gitt det, kan du direkte sammenligne celleverdier ved å bruke StrComp med alternativet vbTextCompare. ( nyttig artikkel på StrComp )

  • i og j brukes vanligvis for loop-tellere, men row og col gi mer mening i dette tilfellet.

Slik kan dette se ut:

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 

Svar

Jeg vil tro at enkel strengesammenligning ville være mye raskere enn 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 

Kommentarer

  • Denne koden ‘ t adresserer ikke sakfølsom sammenligning, men du ‘ er riktig. Regex er overkill, og strengesammenligning foretrekkes i dette tilfellet. (Velkommen til Code Review forresten!)

Svar

Kan jeg foreslå en 50% reduksjon i kjøretid /innsats?

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 

Merket ingen at OP snakker om «å sjekke EN kolonne, skrive til NESTE tilstøtende», egentlig? Hvorfor sløyfekolonner da? Det andre passet ville bare sjekke enten en tom celle eller en med «Utnyttelse» i den.

Svar

Wow. Bare det å lese gjennom de første par linjene fikk meg til å lure på:

  • Hvorfor senbindingen?
  • Hvorfor bruke en regex i det hele tatt?

@ ckuhn203 adresserte allerede navngivningen i svaret hans, men jeg finner dette:

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

Omgjort til det:

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

… Trenger ikke kommentaren lenger.


Jeg vil bruke VBA til å tilordne verdien av cellene i den tomme kolonnen, basert på verdien til den tilstøtende strengen i den andre kolonnen.

Jeg tror at «s [mis | ab] bruker VBA: Excel i seg selv er veldig flink til å håndtere tildeling av celleverdier basert på andre celler «verdier.


regexAdmin.Pattern = "Admin" 

Jeg tror at «s [mis | ab] bruker regex: hvis mønsteret ditt bare er et vanlig ord, prøver du mest sannsynlig å drepe en mygg med en bazooka. Feil verktøy for t han jobber her.

Svar

Hver gang du får tilgang til Range-objektet, bør det gjøres med en enkelt lese / skrive-operasjon.

Før du går inn i for-sløyfen, bør du lese hele området du ønsker å jobbe med.

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

Nå kan du jobbe med dataene:

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 

Til slutt skriver du dataene tilbake for å utmerke seg:

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

Svar

I B1:

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

Så er det bare å fylle det ned. Dette er ikke mellom store og små bokstaver.

Denne autofyllingen kan gjøres på to måter, enten interaktivt i regnearket eller programmatisk:

Interaktivt : Excel har en autofyllfunksjon. Når B1 er valgt og den formelen er satt inn, er det bare å dobbeltklikke på fyllhåndtaket, som er den lille firkanten i nederste høyre hjørne av cellen når den er valgt. Excel vil intelligent kopiere formelen ned til slutten av det sammenhengende området som har data. Betydning hvis A1-A256 har data uten blanke, vil den automatisk fylle ut til B256. Alternativt, hvis det er blanke, blar du til bunnen og velger B256 (eller hva enden er). Deretter Ctrl + Shift + Pil opp for å velge området som fører til B1, og Ctrl + D for å kopiere det ned (tenk d = ditto)

Ved hjelp av VBA … hvis du må gjøre dette programmatisk: med formelen som inneholder celle som ditt valg:

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

Det er andre alternativer tilgjengelig for autofyll for å gjøre noen kule triks.Kan kopiere en bokstavelig verdi i stedet for en formel, eller også fylle en serie basert på et mønster. Du kan også angi egendefinerte mønstre for at den skal gjenkjenne, for eksempel bransjer du ofte gjentar i ting eller byer du har butikker i osv.

Kommentarer

  • Velkommen til Code Review! Jeg savnet fullstendig at OP

ikke trengte å søke i kolonnen! ++ Beste løsningen her.

Svar

Å kombinere alle de andre svarene sammen, gjorde det skiftende på små og store bokstaver som regex i originalen, fjernet behovet for å spesifisere hvor mange rader og deklarere alle variablene fordi Option Explicit unngår så mange feil i 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 

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *