我已将问题减少到以下测试用例:
创建新工作簿;
输入一个常数值,例如123
Sheet1!A1
;
定义名称,例如foo
,指的是公式=CHOOSE(!$A$1, Sheet1!$A$1)
;
将常量值1
输入Sheet2!A1
;
将公式=foo
输入Sheet2
上的其他单元格,例如Sheet2!B1
:观察到,正如预期的那样,结果是在上面的第2步中输入Sheet1!A1
的值;
创建然后运行包含以下代码的VBA过程:
Sheets("Sheet1").Outline.ShowLevels 1
您会注意到步骤5中的单元格现在包含#VALUE!
错误。
此外,简单的工作表重新计算(无论是使用 F9 键还是Application.Calculate
方法)都无法解决问题:必须执行完整从交互式UI重新计算VBA(使用Application.CalculateFull
方法)或完全重建(使用 CTRL + ALT + SHIFT + F9 组合键。)
通过反复试验,我确定了出现这种情况:
CHOOSE()
索引参数必须包含相对表单元格引用(不是常量或绝对表引用);
正在编制索引的CHOOSE()
值参数必须包含对另一个工作表的引用;
显示的大纲级别的更改必须来自VBA 过程(不是来自交互式UI或VBA立即窗口中的大纲控件);以及
ShowLevels
方法调用(其参数不相关)必须应用于CHOOSE()
的任何值(但不是索引)参数中引用的工作表。
发生了什么事?
我非常希望将我在CHOOSE()
的值参数中引用的工作表折叠到其最高大纲级别而不会触发此错误,作为对我实际工作簿的完全重新计算(仍然只有几秒钟)从UX的角度来看,这是不可取的。
对于解决方法的建议(虽然仍然使用包含CHOOSE()
函数的定义名称以及相对表索引参数)将是非常受欢迎的!
我的平台:Windows 7 Home Premium(SP1,64位)上的Excel 2010(14.0.6123.5001,32位)。
答案 0 :(得分:1)
问题在于您的命名公式:=CHOOSE(!$A$1, Sheet1!$A$1)
,特别是!A1
前导!
无效(没有前面的工作表名称,例如Sheet1!$A$1
有效)。只需指定一张表,您的问题就会消失。
我怀疑这可能不会让您满意,具体取决于为什么您首先使用!A1
。如果您希望=foo
使用工作表上A1
的索引值,则将公式=foo
放在上,而不是使用INDIRECT("A1")
{ {1}}
BTW我认为您可能发现了一个错误,或者至少是未定义的行为,因为公式!A1
无效且总是返回=CHOOSE(!$A$1, Sheet1!$A$1)
错误。< / p>
答案 1 :(得分: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