【问题标题】:Excel VBA Function update only on changeExcel VBA 函数仅在更改时更新
【发布时间】:2012-11-12 22:47:32
【问题描述】:

我有一个作为 VBA 模块实现的函数,它以一个单元格作为参数并查询 Web 服务以返回结果。由于数据来源较远,此函数可能需要几秒钟才能返回。

问题在于,某些操作(例如删除任何列)似乎会导致每个公式都重新计算,即使不需要更改也是如此。当我的工作表有数百行时,这可能需要几分钟,在此期间 Excel 没有响应。

我想找到一些方法来检测不需要更改并跳过此步骤。我尝试过的一些事情:

  • 确定要更改的单元格的当前值,我可以从中确定是否需要更新。但是 ActiveCell.Value 是空白的,并且尝试将单元格本身作为第二个参数传递会遇到循环引用警告。
  • 创建了第二列来保存旧输入值,然后将其传递给函数并与新值进行比较。但是,函数无法在成功时更新此旧值,并且尝试仅使用公式进行更新总是会遇到循环引用警告。此外,函数似乎不能返回“无变化”,所以我需要存储和使用旧结果。

有什么方法可以防止某些操作更新工作表上的每个公式?

其他要求:

  • 可能有一种方法可以禁用所有公式自动计算,但我绝对希望在输入参数单元格后立即更新每一行。我也不想强迫用户按下按钮来更新功能。
  • 我尝试在 Visual Studio 中制作自定义电子表格,但发现部署对于我的用户群来说太难维护了。解决方案必须完全包含在启用宏的工作簿中。
  • 使用工作表的 Excel 版本将是 2007 和 2010。

【问题讨论】:

  • 对于一个固定的输入值,返回值是随时间变化的,还是会固定?如果它会改变,在什么样的时间范围内?
  • 您可以使用 worksheet_change 事件来捕获输入范围中的更改,并直接填充输出单元格,而无需使用工作表公式。
  • 所以您是说模块中的函数不能直接更新单元格,但是该特定工作表上的覆盖 worksheet_change 事件可以?我理解对了吗?
  • 是的。通常,从工作表调用的函数不能直接更改工作表 - 它只能返回一个值。尽管有解决此限制的方法,但我认为最好避免使用它们。您的特定工作簿的最佳解决方案是什么将取决于其他因素(例如,远程调用是否应该在重新打开工作簿时全部更新?,完整的远程数据集是否足够小,您可以在本地缓存整个集合?),但是基于事件的更新可能是一个不错的方法。
  • 不,它们不应该在打开表单时更新,是的,结果足够小,可以在本地缓存,我已经在这样做了。听起来这会奏效,非常感谢!

标签: vba excel excel-formula excel-2010


【解决方案1】:

我愿意

  1. 通过将文件/选项/公式/工作簿计算设置为“手动”并关闭“保存时重新计算”来系统地阻止重新计算

  2. 创建一个Private Sub Worksheet_Change(ByVal Target As Range) 并确定在什么条件下应该进行重新计算(Target.Worksheet.Calculate) - 例如确定目标的坐标(使用Target.ColumnTarget.Row),然后调用从 Worksheet_Change 触发器内部查询。

  3. 最终,我会将重新计算指令放在它自己的 Sub 中,并在工作表中制作一个按钮,以便用户可以 - 根据他/她的意愿 - 手动触发重新计算(以防 F9 键不是为用户所知)

  4. 还可以考虑使用由 Worksheet_Change 触发器 If Target.Row = X And Target.Column = Y(= 参数)设置的全局布尔变量 need_Query,并让查询函数检查(并重置)该布尔值,然后进入仅查询If need_Query Then,否则不执行任何操作退出。确保在工作表加载时也将 need_Query 设置为 FALSE。

  5. 最后,您可以将查询函数转换为Sub,并在 Worksheet_Change 触发器中制定一些更复杂的条件来触发它(例如,如果某个列发生更改等)。

    李>

【讨论】:

  • 其中大部分似乎是从其他地方复制粘贴的,因为它要么不适用,要么违背我的要求。但是,第 2 点与蒂姆·威廉姆斯的评论相同,因为您的回复是唯一作为答案完成的回复,所以我将其标记为正确。
  • 可能从我自己的代码库中复制和粘贴...我在适当的情况下使用上述所有内容...我真的不需要窃取别人的答案...我更感兴趣在建设性讨论中而不是在钩子和加号中...想要表明将查询从函数移动到子中,您可以完全控制何时触发它...如果有更多要求或想要更详细的解释,让我们讨论
  • 我不是在指责你抄袭。我只是说蒂姆的答案是针对我的具体问题量身定制的,而你的答案是一堆有时适用于我的提示。具体来说,Tim 回答了为什么 Worksheet_Change 在模块函数不起作用时起作用。不过,您的信息很有帮助,我已将其标记为我的问题的答案。
猜你喜欢
  • 1970-01-01
  • 2015-05-04
  • 2019-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多