Excel 在VBA中向每行添加1而不使用for循环

Excel 在VBA中向每行添加1而不使用for循环,excel,vba,Excel,Vba,正在寻找向列中的每一行添加特定数字的简单方法。类似于range(“b1:b9”)=range(“a1:a9”)+1 由此: 为此: 启动宏记录器 在空单元格中键入1 复制那个单元格 选择要向其中添加该值的单元格 打开“粘贴特殊”对话框 选择“添加”并确定 停止宏记录器。按原样使用该代码或将其转换为其他代码 Range("C1").Value = 1 Range("C1").Select Application.CutCopyMode = False

正在寻找向列中的每一行添加特定数字的简单方法。类似于
range(“b1:b9”)=range(“a1:a9”)+1

由此:

为此:


启动宏记录器

  • 在空单元格中键入1
  • 复制那个单元格
  • 选择要向其中添加该值的单元格
  • 打开“粘贴特殊”对话框
  • 选择“添加”并确定
停止宏记录器。按原样使用该代码或将其转换为其他代码

Range("C1").Value = 1
Range("C1").Select
Application.CutCopyMode = False
Selection.Copy
Range("A1:A5").Select
Selection.PasteSpecial Paste:=xlPasteAll, Operation:=xlAdd, SkipBlanks:= False, Transpose:=False
寻找“高效时间”的解决方案和避免循环不是一回事

如果你在这个范围内循环,那么是的,它会很慢。将范围数据复制到一个变量数组,循环该数组,然后将结果复制回范围是很快的

这是一个演示

子演示()
变暗rng As范围
Dim dat作为变量
我想我会坚持多久
将t1设置为单色
t1=Timer()'仅用于报告运行时
'通过您选择的任何方式获取对您的范围的引用。
'这里我指定1000000行作为演示
设置rng=范围(“A1:A1000000”)
dat=rng.Value2
对于i=1至UBound(dat,1)
dat(i,1)=dat(i,1)+1
下一个
rng.Value2=dat
Debug.Print“Added 1 to”&UBound(dat,1)和“rows in”&Timer()-t1;“秒”
端接头
在我的硬件上,这大约需要1.3秒

仅供参考,粘贴特殊添加技术更快

增加范围值
  • 在以下示例中,
    Add
    解决方案需要2.4s,而
    Array
    解决方案需要8.7s(在我的机器上)来处理5列
  • 数组
    解决方案中,选择从未更改,它只是将结果写入范围
  • Add
    解决方案模拟了这种行为,将所有选择设置为最初的状态。因此出现了复杂情况
选项显式
'添加解决方案
子增量RangeValuesTest()
增加范围值表1.范围(“A:E”),1'2.4s
端接头
子增量范围值(_
比瓦尔rg As射程_
ByVal加数(双精度)
Application.ScreenUpdating=False
Dim isNotAW为布尔值:isNotAW=Not rg.Worksheet.Parent为ActiveWorkbook
将iwb设置为工作簿
如果isNotAW,则设置iwb=ActiveWorkbook:rg.Worksheet.Parent.Activate
将iSNOAS标注为布尔值:iSNOAS=非rg。工作表为ActiveSheet
将iws设置为工作表
如果不是,则设置iws=ActiveSheet:rg.sheet.Activate
尺寸cSel作为变量:设置cSel=选择
将aCell设置为范围:设置aCell=ActiveCell
将sCell设置为范围:设置sCell=rg.Cells(rg.Rows.Count、rg.Columns.Count)
将S值调整为双精度:S值=sCell.Value+加数
sCell.Value=加数
斯凯尔,收到
rg.PasteSpecial xlPasteAll,XLPasteSpecialLoperationAdd'95%
Application.CutCopyMode=False
sCell.Value=s值
阿塞尔,激活
cSel.选择
如果不是,则iws.激活
如果不允许,则iwb.激活
Application.ScreenUpdating=True
端接头
'阵列解决方案
子增量范围值RAYTEST()
增加范围值射线片1.范围(“A:E”),1'8.7s
端接头
子增量范围值数组(_
比瓦尔rg As射程_
ByVal加数(双精度)
与rg
长度为的Dim rCount:rCount=.Rows.Count
长度为的Dim cCount:cCount=.Columns.Count
作为变量的Dim数据
如果rCount>1或cCount>1,则
数据=.Value
其他的
ReDim数据(1对1,1对1):数据=.Value
如果结束
变暗r为长,c为长
对于r=1,则为rCount
对于c=1的情况,应计算
数据(r,c)=数据(r,c)+加数
下一个c
下一个r
.值=数据'80%
以
端接头

您可以使用Evaluate,它看起来相当快

Sub Add1()

    With Range("A1:A10000")
        .Value = Evaluate(.Address & "+1")
    End With

End Sub
#一,。禁用自动计算

Application.Calculation = xlCalculationManual
#二,。禁用屏幕更新

Application.ScreenUpdating = False
#三,。只要您的行条目不超过~56000,但您的数据集是大量的,那么读入数组、在数组中执行操作、然后一次性输出该数组的速度就会更快

array1 = Range(cells(3,2), cells(12,2)).value

for i = 1 to ubound(array1, 1)
    array1(i, 1) = array(i, 1) + 1
next i

range(cells(3,10), cells(12,10)) = array1
请注意,数组1将是2D,在上面的示例中,您将寻址(1,1)到(10,1)

然后在粘贴回后,重新启用自动计算器,然后重新启动屏幕更新

Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True

请注意性能,使用内置函数,例如
Selection.PasteSpecial
对于小数据集来说是快速的,如果您查看了10万行,那么请重新考虑for-Loop的性能。您的意思是for-Loop对于大数据集来说是快速的吗?这就是我有这个问题的真正原因。寻找最节省时间的解决方案。我觉得,如果我能做一些事情,例如“代码>范围(“B1:B9”)=范围(“A1:A9”)+ 1 < /CUL>,它将是最快的。请看这里的答案,了解我真正的意思是由上面的注释:使用Excel内置C++是用更小的数据集最快的方式。对于较大的数据集,使用字典的速度更快。建议完全限定范围引用并加入(
&
)范围的
.Parent.Name
属性加上
前面的“!”分隔符。Address
或use Address(外部:=真的。谢谢你的精彩回答。我运行了它,速度确实很快。我对VBA数组不太熟悉。你能解释一下这个代码
dat=rng.Value2
在做什么吗?我不明白为什么我们可以得到范围
rng.Value2
的值返回
rng
对象的
Value2
属性,这是一个2D数组,大小与范围相同,包含范围中单元格的值。它更快的原因是访问工作表的每个操作都有时间开销。引用
rng.Values2
是一个操作,循环范围是多个操作。是否使用range.value创建
dat
的数据类型/值2与
Dim阵列相同(1到