小编SIO*_*SIO的帖子

减去VBA中的范围(Excel)

我想做什么

我正在尝试编写一个函数来减去Excel范围.它应该采用两个输入参数:范围A和范围B.它应该返回一个范围对象,该范围对象由作为范围A的一部分的单元组成,并且不是范围B的一部分(如在set减法中)

我试过的

我在Web上看到一些使用临时工作表来执行此操作的示例(快速,但可能会引入一些受保护工作簿等问题)以及其他一些示例逐个单元格通过第一个范围检查与第二个交叉点的交叉点一个(非常慢).

经过一番思考后,我想出了这个代码{1},它运行得更快,但仍然很慢.从表示整个工作表的范围中减去需要1到5分钟,具体取决于第二个范围的复杂程度.

当我查看代码试图找到使其更快的方法时,我看到了应用分而治之的范式的可能性,我做了{2}.但这使我的代码变慢了.我不是一个CS家伙,所以我可能做错了,或者这个算法根本不是应该使用分而治之的,我不知道.

我也尝试使用大多数递归来重写它,但这需要永远完成或(更经常地)抛出了堆栈空间错误.我没有保存代码.

我能够做的唯一(略微)成功的改进是添加一个翻转开关{3}并首先通过行,然后(在下一次调用中)通过列而不是通过同一个调用中的两个,但效果没有我想象的那么好.现在我看到即使我们没有在第一次调用中遍历所有行,在第二次调用中我们仍然循环通过与第一次调用相同的行数,只有这些行有点短:)

感谢您在改进或重写此功能方面的任何帮助,谢谢!

解决方案基于Dick Kusleika接受的答案

Dick Kusleika,非常感谢您提供答案!我想我会通过一些修改来使用它:

  • 摆脱了全局变量(mrBuild)
  • 修复了"一些重叠"的情况,以排除"无重叠"的情况
  • 添加了更复杂的条件,以选择是从上到下还是从左到右分割范围

通过这些修改,代码在大多数常见情况下运行得非常快.正如有人指出的那样,棋盘式的巨大范围仍然会很慢,我同意这是不可避免的.

我认为这段代码仍有改进的余地,如果我修改它,我会更新这篇文章.

改进可能性:

  • 选择如何分割范围(按列或按行)的启发式方法

{0}解决方案代码

Public Function SubtractRanges(rFirst As Range, rSecond As Range) As Range
'
' Returns a range of cells that are part of rFirst, but not part of rSecond
' (as in set subtraction)
'
' This function handles big input …
Run Code Online (Sandbox Code Playgroud)

excel vba range excel-vba

10
推荐指数
1
解决办法
2万
查看次数

标签 统计

excel ×1

excel-vba ×1

range ×1

vba ×1