【问题标题】:Evaluate a relative reference from VBA relative to a known cell评估来自 VBA 相对于已知单元格的相对引用
【发布时间】:2015-06-19 03:17:26
【问题描述】:

我正在使用here - !A1 描述的技巧来获取单元格范围,包括当前单元格(通常用于 Rows() 函数)。这非常适合日常使用,并且消除了我在以前必须使用相邻的一组行时移动范围时遇到的许多错误。

不幸的是,我的公式需要通过 VBA 进行评估。将__THISCELL__ 作为我的!A1 单元格,并将包含公式的单元格作为$Z$100,以下计算结果为错误:

Application.Evaluate(rngCell.formula)

以下计算结果为$A$1:$Z$50

rngCell.Worksheet.Evaluate(rngCell.formula)

显然,一种方法是在评估之前将__THISCELL__ 替换为rngCell.Address(External:=True),但关键在于:我希望能够在使用THIS_CELL、@987654332 的工作簿中执行我的公式解析器@ 或 __THISCELL 安全,我还希望能够安全地在名称为 __NOT__THIS_CELL__ 的工作簿中执行我的代码。

为此,我只需要一种机制来评估相对于特定单元格地址的相对引用 - 因为人们确实在 VBA 中使用 R1C1 引用,所以我想它一定存在。不过,我不知道。有人可以帮忙吗?

注意:我喜欢尽可能避免摆弄ActiveCellSelection 等,因为这些闻起来就像SendKeys 的 excel 等价物——当你访问它们时谁知道用户在做什么。不过,即便如此,我也不确定我会得到正确的答案,因为对于 Worksheet.Evaluate 方法,我没有定位在 $A$1 单元格中!

【问题讨论】:

  • AFAIK Evaluate 始终解析相对于 A1 的相对命名范围,因此您将无法计算其他单元格的正确值。为什么需要手动解析公式?
  • 我们经常使用CUBEVALUE,我需要能够从 MDX 传递的任意公式中提取 n,以生成我们传入的成分 CUBEMEMBERSCUBESETs 以执行询问。 CUBEMEMBERS 并不太邪恶 - 有一个 .mdx 属性按索引显示成员(尽管例如,如果你通过 FILTER() 到达那里,那么它会丢失),但 CUBESETs 没有工作.mdx 属性,所以需要找到传递给函数的参数。由于可以通过任意数量的INDEXVLOOKUP 或命名范围过程找到它,因此基本上意味着公式解析!
  • 能否提供更详细的示例,说明您所做的工作以及预期结果。还要解释THIS_CELLTHISCELL__THISCELL__NOT__THIS_CELL__之间的区别。假设rngCell 指的是与开头提到的问题中描述的THIS_CELL 等效的名称是正确的吗?
  • 嗯,这个想法是用户可以定义任何具有!A1(或!RC)内容的名称。这些名称只是他们可以使用的一些名称。他们可以很容易地将其定义为 ScotlandDragonsFooBar,而且我不希望我的代码在上面中断!

标签: vba excel


【解决方案1】:

如果我理解您的问题,我相信您正在寻找Range().Offset 方法。

Range().Offset(rOffset, cOffset) 指的是一个低于rOffset 和在给定范围右侧的cOffset 的范围(允许向上和向左的负值)。此外,.Offset 可以访问和设置范围的所有属性,就像使用 .Range 一样。

【讨论】:

  • 恐怕不会 - 这会让我从一个范围通过 X 和 Y 到另一个范围的指定距离。我想做的是获取一些构成公式的文本并对其进行评估,就好像它已输入到已知单元格中一样。要查看问题,请将光标放在A1 中并创建一个新的命名范围。在引用框中,输入=$B1。现在在单元格A1:A5 中输入您的姓名,然后在B 列中添加一些内容。请注意,即使公式相同,它们总是引用右侧的单元格?现在,我知道我正在使用来自A5 的公式,但 Excel 没有!问题是如何告诉它!
  • @tobriand this 并不总是指右边,它总是指列B
  • @EEM - 可能我使用的是Worksheet.Evaluate 而不是Application.Evaluate。我会检查我的代码并告诉你。
【解决方案2】:

我暂时采用的方法隐含在问题中:当检测到命名范围时,存储当前选择和工作表,选择我们用作评估上下文的那个,然后使用 Evaluate.这似乎可以工作,前提是要评估的单元格在活动表内。

我不喜欢到处乱跳选择 - 感觉很脏 - 但没有更优雅的解决方案,它确实有效。

【讨论】:

  • 按照您在其他答案下方的评论中描述的那样配置工作表,Evaluate 始终返回 B1 值,无论哪个工作表或单元格当前处于活动状态(至少在 2010 年)。对于活动工作表,rngCell.Worksheet.Evaluate(rngCell.formula) 应该给出与Application.Evaluate(... 相同的结果。
  • 嗯...嗯,它肯定对我有用,所以我会再次检查我所做的一切。我可能使用Worksheet.Evaluate 而不是Application.Evaluate,这有时可以更好地处理与当前工作表相关的相对范围。
  • Application.Evaluate 等同于 Activesheet.Evaluate
  • 不,不完全是。它们绝对相似,但是如果您创建一个带有断点的 UDF 并将其传递给 Application.Evaluate,它会被调用两次,而 Worksheet.Evaluate 只会被调用一次。关于这个问题有一篇很好的帖子,重点关注fastexcel.wordpress.com/2011/11/02/… 上声明的效率。我敢肯定他们对待名字的方式也有所不同,但不记得细节了。
猜你喜欢
  • 2018-09-18
  • 1970-01-01
  • 1970-01-01
  • 2022-10-20
  • 2014-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-08
相关资源
最近更新 更多