在VBA中创建1:N的数组
这是一个超级简单的问题,我还没能从前面的答案中拼凑出一个解决方案 我有N张图片在一张纸上,只是想把它们分组。通常我会使用:在VBA中创建1:N的数组,vba,excel,Vba,Excel,这是一个超级简单的问题,我还没能从前面的答案中拼凑出一个解决方案 我有N张图片在一张纸上,只是想把它们分组。通常我会使用: Sheets(“Mail”).Shapes.Range(数组(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())).G
Sheets(“Mail”).Shapes.Range(数组(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
但是我不知道如何使用我的测试对象来复制我在非一般情况下使用的格式。感谢您的帮助 这是一个函数,将数值数组从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)
第一个返回数组(1,2,3,4,5)
第二个函数返回
数组(10,11,12)
为了完整起见,有一种更简洁的方法可以使用Evaluate
函数创建连续数组:
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
- 它的可移植性有限,因为
在其他VBA版本中不存在,例如行
访问VBA
- 就性能而言,这是不值得的
N
的值从10000
更改为10000000
,并运行这两种方法(对于M=1
)
基准设置
使用的功能:
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
,纵轴显示每个方法使用的时间
对于大型阵列,求值比循环快
断言求值
比循环快实际上是不正确的
平均而言,这两种方法消耗的时间大致相同:
-- Average Looping is 57 ticks
-- Average Evaluate is 62 ticks
-- Median ticks are 62 for both methods
总的来说,我认为坚持循环可能是一个更好的选择。这是否接受整数变量作为参数?我想以
ReturnArrayAtoB(1,Y)
的形式使用它,其中Y是代码前面定义的整数。目前它提供了一个类型不匹配。@alex1stef2-将我代码中的long改为integer wherewhere,它应该可以工作。我没有尝试过YowE3K的版本,但简单地将long改为integer就行了!谢谢你的帮助@alex1stef2-带有ByVal
的版本同时接受整数和Long now您的语句不是简单的Sheets(“Mail”).Shapes.Range(test).Group
,因为test
已经是一个数组了吗?(您需要将test(i)=i
更改为test(i)=i+1
)好消息。我使用过这种方法,这种方法确实比循环提供了更好的性能。。因此+1It有两个缺点-缺点1-它只在Excel中工作(无访问权限等),缺点2-第二次使用大N/M比率的测试是错误的,但您没有注意到-如果您使用Excel中的行,1000万应该会给出错误。看一看你收到的数组-应该是错误2015。@Zac-阅读我的评论并再次检查你的代码,使用它是危险的。最后但并非最不重要的一点是-循环2^16次的最佳使用比使用Evaluate快得多。@Vityta感谢提示-我用额外的实验和注释修改了文章。代码应该是可复制的,所以如果你能仔细检查结果,那就太好了!