这些新颖的方法(也许是最好的方法?)在VBA中引用dynamic单元格?

我们通常使用expression式: Cells(i, 1)Cells(i, "A")Range("A" & i)来引用VBA中的一个dynamic单元格,但是我发现下面的怪异代码也可以工作:

 Sub Test1() For i = 1 To 10000 Range("A1")(i) = i Next End Sub 

我也发现使用方括号[]来引用单元格的快捷方式符号(是的,我知道expressionEVALUATE命令的简写方法)也可以用在这里,如下面的代码

 Sub Test2() For i = 1 To 10000 [A1].Resize(1000, 1)(i) = i Next End Sub 

要么

 Sub Test3() For i = 1 To 10000 [A1].Offset(i - 1) = i Next End Sub 

与stream行的观点相反,方括号只能用快捷方式表示固定范围。 我testing了所有这些,他们返回相同的输出。

老实说,我从来没有想过这三个expression式是存在的,所以我想他们可能是新的。 这是真的吗?


我不仅find了他们,还testing了他们看哪一个是最好的。 我最好的意思是在他们的performance使用时间testing。 我testing了这些陈述:

  1. Cells(i, 1) = Rnd
  2. Range("A" & i) = Rnd
  3. Cells(i, "A") = Rnd
  4. Range("A1")(i) = Rnd
  5. [A1].Resize(1000, 1)(i) = Rnd
  6. [A1].Offset(i - 1) = Rnd

到下面的代码

 Sub Test() Dim i As Long Randomize For i = 1 To 1000 'I also tested them with 10,000 loops 'Put the expression here Next End Sub 

我获得了在我的机器上完成的时间如下

 1,000 loops 1 2 3 4 5 6 0.290110725 0.298291317 0.305540433 0.289084126 0.325044276 0.318445433 0.270974218 0.287950980 0.276009685 0.277133638 0.318741694 0.312968414 0.277361318 0.274790389 0.273291810 0.275994401 0.311879789 0.312000675 0.279113453 0.275501647 0.275247422 0.281113426 0.311558662 0.315628943 0.270359637 0.276440868 0.279950951 0.276444561 0.320118775 0.311556754 0.270066136 0.281525061 0.273649022 0.276767648 0.311083246 0.311015128 0.274146235 0.277156933 0.274465750 0.287375210 0.311426416 0.319849274 0.269184843 0.277200430 0.276525859 0.276931561 0.322461782 0.310902381 0.271190611 0.283046575 0.280286123 0.275876294 0.312358236 0.313066500 0.271210909 0.277953463 0.274105173 0.276916590 0.312845710 0.321566549 Average time 0.274371809 0.280985766 0.278907223 0.279363746 0.315751859 0.314700005 

 10,000 loops 1 2 3 4 5 6 1.897854697 1.975970014 2.026380540 1.963044684 2.667340257 2.404596752 1.893136200 1.958722430 1.997488630 1.957524600 2.412742475 2.364692000 1.915567238 1.991447404 2.026974359 1.972207855 2.396174991 2.408500400 1.885336683 1.964379644 2.001175971 1.950138292 2.362537378 2.369196417 1.889658641 1.959677449 1.998453783 1.984470995 2.372677528 2.366525087 1.885327819 1.963668734 1.997487505 2.038683070 2.367691027 2.380044796 1.878379741 1.958654295 2.002764956 2.008183347 2.368766984 2.362091273 1.894069516 1.960857991 1.994435035 2.031241378 2.377953481 2.367554909 1.894528017 1.972240515 2.003587552 1.961539277 2.364523191 2.373092790 1.883387443 1.965169572 1.999893716 1.948455660 2.363346303 2.368680396 Average time 1.891724600 1.967078805 2.004864205 1.981548916 2.405375362 2.376497482 

基于这两个结果,尽pipe对于比较expression式的结果是不确定的: Range("A" & i)Cells(i, "A")Range("A1")(i) [A1].Resize(1000, 1)(i)[A1].Offset(i - 1) ,结果表明最快的性能是Cells(i, 1) 。 这是真的吗? 为什么这样? 我的猜测是在运行时VBA总是使用Cells(i, 1) ,所以当编译代码时,其他expression式中的所有引用都必须转换为expression式1,因为我坚信VBA必须记住它的编译版本和我们用来编写代码的任何expression式。 但这只是我的猜测。

下面的离奇代码

不是真的。 代码并不奇怪。
事情是, Rangevariables是表单的“视口”,而不是固定的混凝土墙。 你完全可以超越你的Range的初始定义Range

该线

 Range("A1")(i) = i 

相当于

 Range("A1").Cells(i).Value = i 

即使Range("A1")只包含一个单元格,这也是完全可行的 – 您只是跨越该单元格。

我从来没有想过这三个expression式是存在的,所以我想他们可能是新的。 这是真的吗?

不,这不对。 他们很老。 我手头最旧的办公室是2003年,它在那里工作,我非常有信心它曾经在Office 95工作。

你从来没有听说过他们的原因可能是因为没有人使用他们,这可能是一件好事。 虽然从对象模型的angular度来看它们是有效的,但它们比更直接的方式更令人困惑。

原来最快的performance是Cells(i, 1) 。 这是真的吗? 为什么这样?

我从来没有testing过(我不会),但逻辑上, Cells(i, 1)应该是最快的,因为它不涉及stringparsing和/或评估。 可以说,所有其他的选项最终都会调用Cells(i, 1)