在VBA中创build一个1:N的数组
这是一个超级简单的问题,我还没有能够从以前的答案拼凑出我想要的解决scheme。
我有一张纸上有N张图片,只是想分组。 通常我会使用:
Sheets("Mail").Shapes.Range(Array(1,2,3,4,5)).Group
但显然这是行不通的,如果我想从1到N.我目前正在尝试:
For i = 0 To Y / 33 ReDim Preserve test(i) test(i) = i Next i Sheets("Mail").Shapes.Range(Array(test())).Group
但我不知道如何使用我的testing对象来复制我在非常规情况下使用的格式。 任何帮助感激!
这是一个函数,从M到N返回数字数组:
Public Function ReturnArrayAtoB(ByVal M As Long, ByVal N As Long) As Variant Dim lngCounter As Long Dim arrReturn As Variant ReDim arrReturn(N - M) For lngCounter = 0 To N - M arrReturn(lngCounter) = M + lngCounter Next lngCounter ReturnArrayAtoB = arrReturn End Function
这就是你如何称呼它:
arrA = ReturnArrayAtoB(1, 5) arrB = ReturnArrayAtoB(10, 12)
第一个返回Array(1,2,3,4,5)
,第二个返回Array(10,11,12)
为了完整性,使用Evaluate
函数创build连续数组有更简洁的方法:
Public Function ReturnArrayWithEvaluate(ByVal M As Long, ByVal N As Long) As Variant Dim vArr1 As Variant vArr1 = Application.Transpose(Evaluate("ROW(" & M & ":" & N & ")")) ReturnArrayWithEvaluate = vArr1 End Function
Vityata在评论中指出,这种方法有一些缺点:
- 如果
N > ActiveSheet.Rows.Count
失败 - 它具有有限的可移植性,因为
ROWS
在其他VBA版本中不存在,例如Access VBA
- 性能方面,这是不值得的
我在此报告一些testing,其中我将N
的值从10,000
变为1,000,0000
并运行两种方法(对于M=1
)。
基准设置
使用的function:
Private Declare Function GetTickCount Lib "kernel32.dll" () As Long Public Function ReturnArrayWithEvaluate(ByVal M As Long, ByVal N As Long) As Variant Dim vArr1 As Variant vArr1 = Application.Transpose(ActiveSheet.Evaluate("ROW(" & M & ":" & N & ")")) ReturnArrayWithEvaluate = vArr1 End Function Public Function ReturnArrayAtoB(ByVal M As Long, ByVal N As Long) As Variant Dim lngCounter As Long Dim arrReturn As Variant ReDim arrReturn(N - M) For lngCounter = 0 To N - M arrReturn(lngCounter) = M + lngCounter Next lngCounter ReturnArrayAtoB = arrReturn End Function Sub test() Dim M As Long, N As Long Dim lTicks As Long Dim lCnt As Long, lStep As Long, lCnt2 As Long Dim vArrReturn As Variant Dim vArrResults As Variant M = 1 N = 10000 lStep = 9900 / 2 lCnt2 = 1 ReDim vArrResults(1 To 99 * N / lStep + 1) For lCnt = N To N * 100 Step lStep lTicks = GetTickCount vArrReturn = ReturnArrayAtoB(M, lCnt) vArrResults(lCnt2) = GetTickCount - lTicks lCnt2 = lCnt2 + 1 Next lCnt Range("B2").Resize(lCnt2 - 1, 1).Value2 = Application.Transpose(vArrResults) lCnt2 = 1 For lCnt = N To N * 100 Step lStep lTicks = GetTickCount vArrReturn = ReturnArrayWithEvaluate(M, lCnt) vArrResults(lCnt2) = GetTickCount - lTicks lCnt2 = lCnt2 + 1 Next lCnt Range("C2").Resize(lCnt2 - 1, 1).Value2 = Application.Transpose(vArrResults) End Sub
结果
横轴表示N
,纵轴表示每种方法使用的时间。
对于大型数组,评估比循环更快。
Evaluate
比循环更快的断言实际上是不正确的!
平均而言,这两种方法大致同时消耗:
-- Average Looping is 57 ticks -- Average Evaluate is 62 ticks -- Median ticks are 62 for both methods
总的来说,我认为坚持循环可能是一个更好的select。