2012-11-12 80 views
4

我有一个函数,我已经实现了一个VBA模块,它将一个单元格作为参数并查询Web服务以返回结果。由于数据来源是远程的,因此该功能可能需要几秒钟才能返回。Excel VBA函数更新仅在更改

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

我想找到一些方法来检测,不需要改变,并跳过这一步。我尝试过的一些东西:

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

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

其他要求:

  • 有可能禁用所有公式自动计算的方式,但我肯定要各行尽快进入参数小区更新。我也不想强制用户按下按钮来更新功能。
  • 我尝试在Visual Studio中执行自定义电子表格,但发现部署太难以维护我的用户群。解决方案必须完全包含在启用宏的工作簿中。
  • Excel版本用床单将是2007年和2010年
+0

对于一个固定的输入值,返回值是否会随着时间的推移而变化,还是会被修复?如果它会改变,在什么样的时间范围内? –

+2

您可以使用worksheet_change事件来捕获输入范围中的更改,并直接填充输出单元格,而无需使用工作表公式。 –

+0

所以你说模块中的函数不能直接更新单元格,但是该特定工作表上的重写工作表change事件可以?我理解对吗? –

回答

2

我会

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

  2. “上的保存重新计算”创建Private Sub Worksheet_Change(ByVal Target As Range)和确定,在何种条件下重新计算应该发生(Target.Worksheet.Calculate) - 例如确定目标的坐标(使用Target.ColumnTarget.Row),并从Worksheet_Change触发器内调用查询。

  3. 最终我会把重新计算指令放在它自己的Sub中,并在表单中设置一个按钮,这样用户可以根据他/她的愿望手动触发重新计算(以防万一F9键未知给用户)

  4. 还可想到使用全局布尔变量need_Query这是由Worksheet_Change触发If Target.Row = X And Target.Column = Y(=参数设置),并有查询功能检查(和复位)是布尔,和走在只能查询If need_Query Then,否则退出不执行操作。确保need_Query在工作表加载时也设置为FALSE。

  5. 最后,你可以在查询功能转换成Sub制定的Worksheet_Change触发一些更复杂的条件来启动它(例如,如果某列的变化等)。

+0

其中大部分内容似乎都是从其他地方复制粘贴的,因为它不适用或违反我所述的要求。然而,第2点与Tim Williams的评论相同,因为你的回答是唯一的答案,所以我会将其标记为正确的。 –

+0

复制和粘贴可能来自我自己的代码库......我使用上面的所有适当的......我真的不需要偷别人的答案......我更喜欢建设性的讨论比在钩子和加号......想要显示将查询函数转换为子函数时,您可以完全控制何时启动该函数......如果有更多要求或者您想要更详细的解释,让我们来讨论 – MikeD

+0

我并没有指责你剽窃。我只是说蒂姆的回答是针对我的具体问题量身定做的,而你的一些技巧有时适用于我。具体来说,Tim回答了为什么Worksheet_Change在模块函数不工作的情况下工作。尽管如此,你的信息是有帮助的,我已经标记为我的问题的答案。 –