Excel 基于另一列的值(引用表),将列中的值乘以100

Excel 基于另一列的值(引用表),将列中的值乘以100,excel,vba,Excel,Vba,我有一个表,其中包含字段(列)帐号、名称和余额。 对于任何以“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

我有一个表,其中包含字段(列)帐号、名称和余额。 对于任何以“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
这是可行的,但它需要很长时间才能运行,因为它贯穿每一行。我还需要一个不同的代码,允许我引用列名而不是使用偏移量,这样,如果添加了列,我的同事就不必更新代码


我不熟悉宏,因此非常感谢您的帮助。

在一系列单元格上循环本质上是缓慢的。将数据移动到一个变量数组,处理该数组,然后将结果移回工作表,速度更快

试试这个

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
利用
表的版本

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列中找到包含“100”的第一个单元格,验证找到的值是否以100开头并将余额乘以100。然后,它尝试查找下一个包含“100”的单元格,直到找到的单元格与FirstFoundCell匹配

要引用表,只需将匹配函数替换为对表列的结构化引用:

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

对于这个范围或数组,根本不需要循环

此代码是一个VBA单炮射程等效程序
IF(左(A2,3)=“100”,A2*100,A2)

代码


这可能会快一点(未经测试,但与@brettdj的答案非常相似):


这太完美了!速度快得可笑。可以用表引用替换引用吗?这正是我需要的。谢谢您的帮助。@CKIM因为您是新来的,当您得到满足您需要的答案时,出于好奇,您应该通过点击勾选来“接受”它(完全取决于您是否接受哪个答案,如果有的话)(因为我认为克里斯·尼尔森的答案可能是最好的解决方案)但是你的电子表格中有很多公式是关于余额的吗?计算是否设置为自动?如果是这样,每次更改一个平衡值时,可能会重新计算许多其他单元格。因此,您可以通过在代码开始时通过编程将计算设置为手动,然后在代码结束时将其设置回自动,从而大大提高速度。
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
[Data[Balance]] = [IF(LEFT(Data[Account Number],3)="100", Data[Balance]*100, Data[Balance])]