Jeg har et Excel-regneark, der består af to kolonner, hvoraf den ene er fyldt med strenge, og den anden er tom. Jeg vil gerne bruge VBA til at tildele værdien af cellerne i den tomme kolonne baseret på værdien af den tilstødende streng i den anden kolonne.

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 bruges denne sløjfe til en stor mængde data, tager det alt for lang tid at arbejde, og det meste af tiden går det simpelthen ned i Excel.

Er der nogen der kender en bedre måde at gøre dette på?

Svar

Det korte svar er:

Brug ikke , brug en formel. Især en kombination af IF og SØG .

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

Men dette er kodegennemgang, så lad os gøre det alligevel.

  • Regex er langsom. Det ser ud til, at du kun bruger det til sagsfølsomhed. I betragtning af det kan du direkte sammenligne celleværdier ved at bruge StrComp med indstillingen vbTextCompare. ( nyttig artikel om StrComp )

  • i og j bruges typisk til loop-tællere, men row og col giver mere mening i dette tilfælde.

Her kan dette se ud:

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 ville tro, at en simpel strengesammenligning ville være meget hurtigere end 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 kode ‘ t adresserer ikke sagfølsom sammenligning, men du ‘ er korrekt. Regex er overkill, og strengesammenligning foretrækkes i dette tilfælde. (Velkommen til Code Review forresten!)

Svar

Må jeg foreslå en 50% reduktion i runtime /indsats?

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 

Har ingen bemærket, at OP taler om “at kontrollere EN kolonne, skrive til NÆSTE tilstødende”, virkelig? Hvorfor sløjfekolonner da? Det andet pass ville kun kontrollere enten en tom celle eller en med “Udnyttelse” i den.

Svar

Wow. Bare at læse igennem de første par linjer fik mig til at undre mig:

  • Hvorfor den sene binding?
  • Hvorfor bruge en regex overhovedet?

@ ckuhn203 adresserede allerede navngivningen i sit svar, men jeg finder dette:

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

Omvendt til det:

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

… Behøver ikke kommentaren længere.


Jeg vil gerne bruge VBA til at tildele værdien af cellerne i den tomme kolonne baseret på værdien af den tilstødende streng i den anden kolonne.

Jeg synes, at “s [mis | ab] bruger VBA: Excel selv er meget god til at håndtere tildeling af celleværdier baseret på andre celler “værdier.


regexAdmin.Pattern = "Admin" 

Jeg tror, at “s [mis | ab] bruger regex: hvis dit mønster kun er et almindeligt ord, prøver du sandsynligvis at dræbe en myg med en bazooka. Forkert værktøj til t han job her.

Svar

Når du har adgang til Range-objektet, skal det gøres med en enkelt læse / skrive-operation.

Inden du går ind i for-sløjfen, skal du læse hele det interval, du vil arbejde med.

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

Nu kan du arbejde 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 

Endelig skriv dataene tilbage for at excelere:

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

Svar

I B1:

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

Derefter skal du bare udfylde det. Dette er ikke mellem store og små bogstaver.

Denne autofyldning kan udføres på to måder, enten interaktivt i regnearket eller programmatisk:

Interaktivt : Excel har en autofyldningsfunktion. Når B1 er valgt, og den formel er sat i, skal du bare dobbeltklikke på udfyldningshåndtaget, som er den lille firkant i nederste højre hjørne af cellen, når den er valgt. Excel kopierer formlen intelligent til slutningen af det sammenhængende område, der har data. Det betyder, at hvis A1-A256 ikke har data uden mellemrum, udfyldes den automatisk til B256. Alternativt, hvis der er blanke, skal du rulle til bunden og vælge B256 (eller hvad enden er). Derefter Ctrl + Skift + pil op for at vælge det område, der fører til B1, og Ctrl + D for at kopiere det ned (tænk d = dito)

Brug af VBA … hvis du skal gøre dette programmatisk: med formlen, der indeholder celle som dit valg:

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

Der er andre muligheder for autofyld for at lave et par seje tricks.Kan kopiere en bogstavelig værdi i stedet for en formel eller også udfylde en serie baseret på et mønster. Du kan også indstille brugerdefinerede mønstre, som den kan genkende, såsom forretningsområder, du ofte gentager i ting eller byer, hvor du har detailplaceringer, osv.

Kommentarer

  • Velkommen til Code Review! Jeg savnede fuldstændigt, at OP ikke ‘ ikke behøvede at søge i kolonnen! ++ Bedste løsning her.

Svar

Ved at kombinere alle de andre svar sammen, blev det ufølsomt som det regex i originalen, fjernede behovet for at angive, hvor mange rækker og deklarere alle variabler, fordi Option Explicit undgår så mange fejl 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 

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *