假设我创建了一个Sub(不是函数),其生命中的任务是获取活动单元格(即选择)并将相邻单元格设置为某个值.这很好用.
当您尝试将该Sub转换为函数并尝试从电子表格中评估它时(即将其公式设置为"= MyFunction()")Excel会嘲笑您试图影响非活动的值单元格,只需强制函数返回#VALUE而不触及相邻单元格.
是否有可能关闭这种保护行为?如果没有,有什么好办法绕过它?如果可能的话,我正在寻找有能力的开发人员在1-2周内完成的事情.
此致,艾伦.
注意:我使用2002,所以我倾向于使用适用于该版本的解决方案.话虽如此,如果未来的版本使这个变得更容易,我也想知道它.
这是不可能的,这是有道理的,因为:
调用工作表函数时,包含该函数的单元格不一定是活动单元格.所以你无法可靠地找到相邻的细胞.
当Excel重新计算工作表时,它需要维护单元格之间的依赖关系.因此,它不能允许工作表函数任意修改其他单元格.
你能做的最好的就是:
处理SheetChange事件.如果包含您的功能的单元格正在更改,请修改相邻单元格.
将工作表函数放在相邻单元格中以返回所需的值.
更新
关于评论:"我希望此功能能够处理'空白'电子表格,因此我不能真正依赖可能尚不存在的电子表格的SelectionChange事件,但需要调用此函数":
你能把你的功能放在XLA插件中吗?然后您的XLA加载项可以处理在该Excel实例中打开的所有工作簿的Application SheetChange(*)事件?
关于评论:"仍然,如果你将Excel保存在CalculationMode = xlManual并填写正好值,你应该很好"
即使CalculationMode是xlManual,Excel也需要在单元格之间维护引用的依赖关系树,以便它可以按正确的顺序计算.如果其中一个函数可以更新任意单元格,这将搞乱订单.这可能是Excel强加此限制的原因.
(*)我最初在上面写了SelectionChange,现在更正了 - 当然正确的事件是SheetChange用于工作簿或应用程序对象,或者更改为Worksheet对象.
更新2 关于AlanR的帖子的一些评论描述了如何使用计时器"有点"使其工作:
目前尚不清楚定时器功能("Woohoo")将如何知道要更新的单元.您没有信息指示哪个单元格包含触发计时器的公式.
如果公式存在于多个单元格中(在相同或不同的工作簿中),则在重新计算期间将多次调用UDF,从而覆盖timerId.因此,您将无法可靠地销毁计时器,并且会泄漏Windows资源.