Mám excelový list skládající se ze dvou sloupců, z nichž jeden je vyplněn řetězci a druhý prázdný. Chtěl bych použít VBA k přiřazení hodnoty buněk v prázdném sloupci na základě hodnoty sousedního řetězce v druhém sloupci.

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 

The problém je v tom, že při použití této smyčky pro velké množství dat to trvá příliš dlouho, než to funguje, a většinou to prostě zhroutí Excel.

Ví někdo lepší způsob, jak to udělat?

Odpověď

Krátká odpověď je:

Nepoužívejte , použijte vzorec. Zejména kombinace IF a HLEDAT .

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

Toto je ale kontrola kódu, tak to stejně udělejme.

  • Regulární výraz je pomalý. Zdá se, že to používáte pouze pro necitlivost na případy. Vzhledem k tomu můžete přímo porovnat hodnoty buněk pomocí StrComp s možností vbTextCompare. ( užitečný článek o StrComp )

  • i a j se obvykle používají pro počítadla smyček, ale row a col dávejte v tomto případě větší smysl.

Takto by to mohlo vypadat:

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 

Odpověď

Myslím si, že jednoduché porovnání řetězců bude mnohem rychlejší než 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 

Komentáře

  • Tento kód ‚ neřeší necitlivé srovnání malých a velkých písmen, ale ‚ opravujete. Regulární výraz je přehnaný a v tomto případě se dává přednost porovnání řetězců. (Mimochodem Vítejte v Code Review!)

Odpověď

Mohu navrhnout 50% snížení doby běhu /úsilí?

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 

Nikdo si nevšiml, že OP hovoří o tom, že „zkontrolujete JEDEN sloupec, zapíšete na DALŠÍ sousední“, opravdu? Proč tedy smyčkové sloupce? Druhý průchod by zkontroloval pouze prázdnou buňku nebo buňku s „Exploitation“.

Odpověď

Páni. Už jen přečtení prvních pár řádků mě napadlo:

  • Proč pozdní vazba?
  • Proč vůbec používat regex?

@ ckuhn203 se již ve své odpovědi zabýval pojmenováním, ale shledávám toto:

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

Proměnilo se v to:

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

… Už komentář nepotřebuji.


Chtěl bych pomocí VBA přiřadit hodnotu buněk v prázdném sloupci na základě hodnoty sousedního řetězce v druhém sloupci.

Myslím si, že použití [VBA | ab] pomocí VBA: Excel je sám o sobě velmi dobrý při řešení přiřazování hodnot buněk na základě jiných hodnoty buněk.


regexAdmin.Pattern = "Admin" 

Myslím, že „používání [regexu]: pokud je váš vzor pouhým slovem, pravděpodobně se snažíte zabít komára pomocí bazuky. Špatný nástroj pro t Zde pracuje.

Odpovědět

Kdykoli přistupujete k objektu Range, mělo by to být provedeno jednou operací čtení / zápisu.

Před vstupem do smyčky for byste si měli přečíst celý rozsah, se kterým chcete pracovat.

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

Nyní můžete pracovat s údaji:

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 

Nakonec data zapište zpět do aplikace Excel:

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

Odpovědět

V B1:

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

Poté jej stačí vyplnit. Toto nerozlišuje velká a malá písmena.

Tuto automatickou výplň lze provést dvěma způsoby, a to buď interaktivně v listu, nebo programově:

Interaktivně : Excel má funkci automatického vyplňování. Když je vybrána B1 a je vložen tento vzorec, stačí dvakrát kliknout na úchyt výplně, což je malý čtvereček v pravém dolním rohu buňky, když je vybrána. Excel inteligentně zkopíruje vzorec na konec souvislého rozsahu, který má To znamená, že pokud má A1-A256 data bez mezer, automaticky se vyplní na B256. Alternativně, pokud existují mezery, přejděte dolů a vyberte B256 (nebo jakýkoli konec). Pak Ctrl + Shift + šipka nahoru vyberte rozsah vedoucí k B1 a Ctrl + D jej zkopírujte dolů (myslím d = ditto)

Používání VBA … pokud to musíte udělat programově: s výběrem vzorce obsahujícího buňku:

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

Pro automatické vyplňování jsou k dispozici další možnosti, jak provést několik skvělých triků.Může kopírovat doslovnou hodnotu namísto vzorce nebo také vyplnit řadu na základě vzoru. Můžete také nastavit vlastní vzory, které rozpozná, například oblasti podnikání, které běžně opakujete ve věcech nebo městech, ve kterých máte prodejny atd.

Komentáře

  • Vítejte ve službě Code Review! Úplně mi chybělo, že OP nepotřeboval ‚ prohledávat sloupec! ++ Nejlepší řešení zde.

Odpověď

Kombinace všech ostatních odpovědí dohromady způsobila, že je malá a velká písmena jako regex v originálu, odstranil potřebu specifikovat kolik řádků a deklarovat všechny proměnné, protože Option Explicit se vyhne tolika chybám ve 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 

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *