将一列中的值乘以100,根据另一列的值,引用一个表

我有一个表中有字段(列)帐号,名称和平衡。 对于任何以“100”开头的账号,相应的余额必须乘以100。

表格名称是“数据”,表格名称是“数据”

我目前使用下面的代码:

Sub Balance() Worksheets("DATA").Activate Dim c As Range For Each c In Range("A2:A" & Cells(Rows.Count, "A").End(xlUp).Row) If c.Value Like "100*" Then c.Offset(0, 2).Value = c.Offset(0, 2).Value * 100 Next c End Sub 

这是有效的,但是它贯穿每一行都需要很长时间才能运行。 我也想要一个不同的代码,这将允许我引用列名而不是使用偏移量,所以如果添加列,我的同事不必更新代码。

我是新来的macros,所以帮助将不胜感激。

循环播放一系列的单元格本来就很慢。 把数据移动到一个Variant数组会更快,然后将结果移回到工作表

尝试这个

 Sub Balance() Dim ws As Worksheet Dim rng As Range Dim dat1 As Variant, dat2 As Variant Dim i As Long Set ws = Worksheets("DATA") With ws Set rng = Range(.Cells(2, 1), .Cells(.Rows.Count, 1).End(xlUp)) End With dat1 = rng.Value dat2 = rng.Offset(, 2).Value For i = 1 To UBound(dat1, 1) If dat1(i, 1) Like "100*" Then dat2(i, 1) = dat2(i, 1) * 100 End If Next rng.Offset(, 2) = dat2 End Sub 

版本来利用Table

 Sub Balance() Dim ws As Worksheet Dim rng1 As Range, rng2 As Range Dim lo As ListObject Dim dat1 As Variant, dat2 As Variant Dim i As Long Set ws = Worksheets("DATA") Set lo = ws.ListObjects("Data") Set rng1 = lo.ListColumns("Account Number").DataBodyRange Set rng2 = lo.ListColumns("Balance").DataBodyRange dat1 = rng1.Value dat2 = rng2.Value For i = 1 To UBound(dat1, 1) If dat1(i, 1) Like "100*" Then dat2(i, 1) = dat2(i, 1) * 100 End If Next rng2 = dat2 End Sub 

而不是循环单元格或数组,使用Range.Find和Range.FindNext来标识匹配的单元格。

 Sub Balance() Worksheets("Sheet1").Activate Dim c As Range Dim AccountCol As Long Dim BalanceCol As Long Dim LastAccountRow As Range Dim FirstFoundCell As Range AccountCol = WorksheetFunction.Match("Account", Rows("1:1"), 0) BalanceCol = WorksheetFunction.Match("Balance", Rows("1:1"), 0) With Range(Cells(1, AccountCol), Cells(Cells(Rows.Count, 1).End(xlUp).Row, AccountCol)) Set c = .Find("100", .Cells(1, AccountCol), xlValues, xlPart) If Not c Is Nothing Then Set FirstFoundCell = c If Left(c.Value2, 3) = "100" Then Cells(c.Row, BalanceCol) = Cells(c.Row, BalanceCol) * 100 End If Set c = .FindNext(c) Do Until c.Address = FirstFoundCell.Address If Left(c.Value2, 3) = "100" Then Cells(c.Row, BalanceCol) = Cells(c.Row, BalanceCol) * 100 End If Set c = .FindNext(c) If Left(c.Value2, 3) = "100" Then Cells(c.Row, BalanceCol) = Cells(c.Row, BalanceCol) * 100 End If Loop End If End With End Sub 

这将在Account列中find第一个包含“100”的单元格,validationfind的值是否以100开头,然后将Balance乘以100.然后尝试查找包含“100”的下一个单元格,直到find的单元格与FirstFoundCell匹配。

要引用一个表,只需将Match函数replace为表列的结构化引用即可:

  AccountCol = [Table1[Account]].Column BalanceCol = [Table1[Balance]].Column 

你不需要为这个范围或数组而循环。

此代码是IF(LEFT(A2,3)="100", A2*100,A2)的VBA单拍范围IF(LEFT(A2,3)="100", A2*100,A2)

 Sub Short() Dim rng1 As Range With Sheets("data") Set rng1 = .Range(.[a2], .Cells(Rows.Count, "A").End(xlUp)) rng1.Value2 = Evaluate("=IF(LEFT(" & rng1.Address & ",3)=""100""," & rng1.Address & "*100," & rng1.Address & ")") End With End Sub 

这可能会更快一些(没有testing,但非常类似于@ brettdj的答案):

 [Data[Balance]] = [IF(LEFT(Data[Account Number],3)="100", Data[Balance]*100, Data[Balance])]