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

时间:2017-02-28 20:47:40

标签: excel excel-vba 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.Offset(0, 2).Value = c.Offset(0, 2).Value * 100
Next c

End Sub

这样可行,但是它需要很长时间才能运行,因为它经过了每一行。我还想要一个不同的代码,允许我引用列名而不是使用offset,所以如果添加了列,我的同事就不必更新代码。

我是宏的新手,所以非常感谢帮助。

4 个答案:

答案 0 :(得分:4)

在一系列细胞上循环本身就很慢。将数据移动到变体数组,处理该数据然后将结果移回工作表会更快

试试这个

(0.f,1.f,df_dy)

利用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

答案 1 :(得分:1)

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

//import libraries
import java.util.Scanner;

public class Milestone1 {

public static void main(String[] args) {
    //define variables
    Scanner scnr = new Scanner(System.in);
    int patternDes = 0;
    boolean world[][] = new boolean[Config.WORLD_ROWS][Config.WORLD_COLUMNS];


    //print statements 
    System.out.println("Welcome to Conway's Game Of Life");
    System.out.println("--------------------------------");
    System.out.println("1)Glider 2)Beacon 3)Beehive 4)R-pentomino");
    System.out.println("5)Random 6)Custom or 7)Exit");
    System.out.print("Choose a pattern:");

    //Have the scanner choose a pattern
    patternDes = scnr.nextInt();

    //check constraints
    while(!(patternDes <= 7 &&  patternDes >= 1))
    {
        System.out.println("Enter a number between 1 and 7: ");
        if(!scnr.hasNextInt()){
            scnr.nextLine();
            continue;
        }
        else{
            patternDes = scnr.nextInt();
            if((patternDes <= 7 && patternDes >= 1)){
                break;
            }
            else{
                continue;
            }
        }
    }
    //write another while loop now

}

}

这会在“帐户”列中找到包含“100”的第一个单元格,验证找到的值是否以100开头并将“Balance”乘以100.然后尝试查找包含“100”的下一个单元格,直到找到的单元格与FirstFoundCell匹配为止

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

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

答案 2 :(得分:0)

你根本不需要循环 - 范围或数组。

此代码是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

答案 3 :(得分:0)

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

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