Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Excel 与重复引用同一范围相比,何时使用更好?_Excel_Vba - Fatal编程技术网

Excel 与重复引用同一范围相比,何时使用更好?

Excel 与重复引用同一范围相比,何时使用更好?,excel,vba,Excel,Vba,我有一个自动创建表单的代码,所以它最多会引用一些单元格两到三次来设置字段名,并且可能会根据需要更改字体大小或颜色。在设置值并更改字体的情况下,我可以每次引用该范围,生成2行代码,或者使用With引用一次,但总共4行代码。直觉上,我认为2行少于4行,但我是一个noob,我不确定使用它是否有一些效率,如果整个脚本都使用它的话,这些效率会增加多少。比如说: Range("A1").value = "Hi" Range("A1").font.size = 12 Vs 哪个更快 在这种情况下,您不会得到

我有一个自动创建表单的代码,所以它最多会引用一些单元格两到三次来设置字段名,并且可能会根据需要更改字体大小或颜色。在设置值并更改字体的情况下,我可以每次引用该范围,生成2行代码,或者使用With引用一次,但总共4行代码。直觉上,我认为2行少于4行,但我是一个noob,我不确定使用它是否有一些效率,如果整个脚本都使用它的话,这些效率会增加多少。比如说:

Range("A1").value = "Hi"
Range("A1").font.size = 12
Vs

哪个更快

在这种情况下,您不会得到明显的速度差异⇒ 为自己优化。 今天的主要优化是那些维护代码的人的时间和精力

因此,如果增益将比代码快2%或占用的内存少5%,那么您就不是在优化处理。如果增益对于速度或内存来说是微不足道的,那么只需优化代码以获得最简单的可读性

这也意味着,内部具有不同强调的同一代码结构可以以一种方式优化一次,以另一种方式优化第二次。当然,对RangeA1的调用应该始终只进行一次,并将结果存储到变量中


在您的情况下,使用RangeA1。。。以…结束。它提供了更清晰的上下文,并且避免了开发人员阅读相同的文本。省略相同文本的重复,也不容易出错。

我按照建议在循环中对示例代码进行了100000次测试,使用的速度大约快了2%。With的时间为36.07秒,Range示例的时间为36.81秒


考虑到所有的注释,With似乎在各个方面都更好,因为它既更快又更容易阅读,即使该范围仅被引用了两次。

我使用此例程进行了测试:

Sub UseWith()
Dim oCell As Range
Dim sName As String
Dim lColorIndex As Long
Dim bItalic As Boolean
Dim sSize As Single
Dim bStrikethrough As Boolean

TimerStart "1"
For Each oCell In Sheet2.UsedRange
    sName = oCell.Font.Name
    lColorIndex = oCell.Font.ColorIndex
    bItalic = oCell.Font.Italic
    sSize = oCell.Font.Size
    bStrikethrough = oCell.Font.Strikethrough
Next

TimerReport

TimerStart "2"

For Each oCell In Sheet2.UsedRange
    With oCell.Font
        sName = .Name
        lColorIndex = .ColorIndex
        bItalic = .Italic
        sSize = .Size
        bStrikethrough = .Strikethrough
    End With
Next
TimerReport
End Sub
结果:

1 0.2040441766

20.1509655957


所以1比2慢大约35%。

为什么不把它放在一个循环10万次的循环中进行测试呢?这与性能无关。这其实是纯粹的懒惰。当任何表达式在代码中被复制时,解决方案是将其提取到局部变量中——在本例中,它是一个对象这一事实使其具有合法性,但使用Set target=ActiveSheet.RangeA1并在目标之外工作,您将获得完全相同的好处。With块仅用于隐藏本地对象引用-在任何情况下,任何一种方法都比为需要反对的每个语句取消引用同一对象要好。对于选择主要基于观点作为接近理由的接近选民来说,你根本不正确。这里有一个明显更好的选择。@K.Dᴀᴠɪs C污染了我:虽然结果证明了一个明显的结论,即选项1对范围索引器的调用较少,但仅通过一次迭代无法获得任何合理的基准,特别是当您在测试的两段代码之间重复使用变量时。这个结论是轶事。多次运行得出不同的结论,两次测试的结果相反。轶事?我不同意。我按照原来的顺序和相反的顺序把这个程序运行了十几次。结果是相当可复制的,两次的标准偏差分别为0.002(平均时间为0.2 vs 0.15)。在这种特定情况下,无论速度差异如何,相同代码结构、内部强调程度不同的语句可以一次优化,另一次优化是不正确的。反复调用RangeA1所使用的方法,而RangeA1在确定无法更改时所使用的方法始终是一种优化,无论您如何实现该目标。@Comintern–哦,是的,我故意留下了这个空白,以保持答案简短。对于第一种情况,必须将函数结果存储在变量中。但是,VBA仍然存在,所以它并不重要。你看,OP在这里解决了代码加速2%的问题,但是如果他们真的想要更快,他们会搜索不同的方法。正如我发现的,VB.NET的计算速度快了200-400%。从这个角度来看,节省几%的努力看起来……VBA仅仅是一个脚本玩具的态度对使用它的程序员来说是难以置信的贬低。使用集成到环境中的编程语言在Excel中解决问题并不意味着您不应该关心2%的性能提升。当然,这并不意味着你应该获得许可去做一些愚蠢的事情,比如重复调用一个返回相同内容的函数。如果更少的VBA开发人员表现得像脚本小子,而更多的人表现得像程序员,那么web上就不会有如此多的垃圾VBA代码了…@Comintern–当然,为自己编写脚本是一回事,而将其作为示例代码发布则是另一回事。后者承担更多的责任,应该在出版前重新考虑。但通常情况下,人们不这样做
t在乎——这是你们写的关于行为脚本小子和程序员的常见后续行动。那个么,若你们的答案是谁在乎,那个么这是一个怎样的答案呢?
Sub UseWith()
Dim oCell As Range
Dim sName As String
Dim lColorIndex As Long
Dim bItalic As Boolean
Dim sSize As Single
Dim bStrikethrough As Boolean

TimerStart "1"
For Each oCell In Sheet2.UsedRange
    sName = oCell.Font.Name
    lColorIndex = oCell.Font.ColorIndex
    bItalic = oCell.Font.Italic
    sSize = oCell.Font.Size
    bStrikethrough = oCell.Font.Strikethrough
Next

TimerReport

TimerStart "2"

For Each oCell In Sheet2.UsedRange
    With oCell.Font
        sName = .Name
        lColorIndex = .ColorIndex
        bItalic = .Italic
        sSize = .Size
        bStrikethrough = .Strikethrough
    End With
Next
TimerReport
End Sub