9

我已将问题简化为以下测试用例:

  1. 创建一个新的工作簿;

  2. 输入一个常数值,例如123进入Sheet1!A1

  3. 定义一个名称,例如foo,指代公式=CHOOSE(!$A$1, Sheet1!$A$1)

  4. 将常数值1输入Sheet2!A1

  5. 将公式输入=foo到其他单元格中Sheet2,例如:观察结果,正如预期的那样,结果是在上面的步骤 2Sheet2!B1中输入的值;Sheet1!A1

  6. 创建然后运行包含以下代码的 VBA 过程:

    Sheets("Sheet1").Outline.ShowLevels 1
    

您会注意到步骤 5 中的单元格现在包含#VALUE!错误。

此外,简单的工作表重新计算(无论是使用F9键还是Application.Calculate方法)都不能解决问题:必须从 VBA执行完全Application.CalculateFull重新计算(使用方法),或者从交互式 UI完全重建CTRL(使用+ ALT+ SHIFT+F9组合键)。

通过反复试验,我确定了这种情况的出现:

  • CHOOSE()index 参数必须涉及相对工作表单元格引用(不是常量或绝对工作表引用);

  • 被索引的CHOOSE()值参数必须涉及对另一张表的引用;

  • 显示的大纲级别的更改必须来自 VBA程序(而不是来自交互式 UI 或 VBA 即时窗口中的大纲控件);和

  • 方法调用(其ShowLevels参数无关紧要)必须应用于在任何值(尽管不是索引)参数中引用的工作表CHOOSE()

这是怎么回事?

我非常希望在CHOOSE()不触发此错误的情况下将我在值参数中引用的工作表折叠到其最高大纲级别,因为从 UX 的角度来看,完全重新计算我的实际工作簿(仍然只有几秒钟)是不可取的。

解决方法的建议(同时仍然使用包含CHOOSE()函数的定义名称以及相对表索引参数)将是最受欢迎的!

我的平台:Windows 7 Home Premium(SP1,64 位)上的 Excel 2010(14.0.6123.5001,32 位)。

4

2 回答 2

1

The problem is with your named formula: =CHOOSE(!$A$1, Sheet1!$A$1), specifically the !A1

The leading ! is invalid (without a preceeding sheet name, eg Sheet1!$A$1 is valid). Just specify a sheet and your problem goes away.

I suspect this may not satisfy you, depending on why you used !A1 in the first place. If it's that you want =foo to use an index value from A1 on the sheet the formula =foo is placed on use INDIRECT("A1") instead of !A1


BTW I think your may have found a bug, or at least undefned behaviour, in that the formula =CHOOSE(!$A$1, Sheet1!$A$1) is invalid and should always return a #Value error.

于 2012-11-02T08:40:36.057 回答
0

如果包含此 UDF,它是否给出正确的行为?

Public Function fooUDF(inCell As Range)
    fooUDF = ThisWorkbook.Worksheets(inCell.Value).Range("A1").Value
End Function

使用 UDF 而不是定义的名称/公式可能会对性能产生影响。它采用 in 参数也可能存在问题,而您的原始方法没有。这可以通过运行一个宏来为每个工作表引入一个工作表定义的公式来规避,如下所示:(不包括循环遍历所有必要工作表的部分)

Public Sub InsertName()
    ThisWorkbook.Worksheets("Sheet2").Names.Add Name:="fooformula", _
        RefersToR1C1:="=fooudf(Sheet2!R1C1)"
End Sub
于 2012-11-02T09:25:03.810 回答