我有一个包含字段(列)帐号,名称和余额的表。 对于任何以“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,所以如果添加了列,我的同事就不必更新代码。
我是宏的新手,所以非常感谢帮助。
答案 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])]