在一个范围内有条件地改变值的最有效的方法是什么?

我只想运行一个(大)范围,并用给定的replace值replace某些值(如果它们高于给定的最大值或低于给定的最小值…也是一个特定的字符)。

我的第一个想法是简单地遍历每个单元格,并在必要时进行检查/replace。 我有一种感觉,这个程序会很慢,我很好奇,如果有更好的方法来完成这个。

任何时候我写代码,在VBA中做类似的事情,我会注意到每个单元格的值都是逐个单元格地变化的,看起来好像有更好的方法。 提前致谢。

编辑:

我还没有写这个实现,因为我知道结果会是什么,如果可能的话,我宁愿做一些不同的事情,但是看起来像这样

For something If(Range.Value == condition) Range.Value = replacement_value Range = Range.Offset(a, b) End For 

在单独的列中创build公式,然后仅copy/paste special values only

 = if(A2 > givenvalue; replace; if(A2< anothergivenvalue; anotherreplace; if (A2 = "particularcharacterortext"; replaceonemore; A2))) 

将公式放入空列中的空单元格中,拖动或复制/粘贴到整个列。 之后,如果新值正常, copy/paste values onlycopy/paste values only到原始位置。

以下VBA代码提供了一个简单的框架,您可以自定义以满足您的需求。 它包含了在你的问题的评论中提到的许多优化,例如closures屏幕更新并将比较从工作表移动到数组。

你会注意到这个macros做了一个相当大的比较和replace。 我运行它的数据集是在A1:Y100000范围内的1到1000之间的250万个随机数。 如果一个数字大于250且小于500,我用0replace它。这需要replace数据集中所有数字的24.9%。

 Sub ReplaceExample() Dim arr() As Variant Dim rng As Range Dim i As Long, _ j As Long Dim floor as Long Dim ceiling as Long Dim replacement_value 'assign the worksheet range to a variable Set rng = Worksheets("Sheet2").Range("A1:Y100000") floor = 250 ceiling = 500 replacement_value = 0 ' copy the values in the worksheet range to the array arr = rng ' turn off time-consuming external operations Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Application.EnableEvents = False 'loop through each element in the array For i = LBound(arr, 1) To UBound(arr, 1) For j = LBound(arr, 2) To UBound(arr, 2) 'do the comparison of the value in an array element 'with the criteria for replacing the value If arr(i, j) > floor And arr(i, j) < ceiling Then arr(i, j) = replacement End If Next j Next i 'copy array back to worksheet range rng = arr 'turn events back on Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Application.EnableEvents = True End Sub 

我对不同的替代方法进行了一些性能testing,用于编码这个简单的比较和replace,我期望的结果与其他人的VBA性能结果一致。 我每次运行10次,计算每次运行所用的时间,并平均计算10次。

vba性能结果

结果显示了使用数组可能产生的巨大影响,特别是当数据集很大时:与逐个testing和更改工作表单元值的代码相比,数组操作 – 将数据集从工作表复制到数组,比较和更改数组值,然后将数组结果写回工作表 – 在这种情况下,平均运行时间从3.6分钟减less到了4分钟,达到98%。

尽pipeclosures外部事件的优化在工作表操作方面造成了明显的差异,运行时间减less了22%,但是当大多数计算工作是基于数组的时候,这些优化几乎没有影响。