如何以编程方式将QueryTable包装在ListObject中?

历史上Excel中的外部数据查询用QueryTable表示。
ListObjects出现在某个时间点,但它们还不兼容QueryTable并且不能包含它们。

在Office 2007中,它们不仅兼容,而且是默认的。 从那时起,创build一个外部查询意味着创build一个ListObject ,而QueryTable被简化为它的内部组件。

没有包含在ListObject中的“独立”QueryTable不能再使用该接口创build,但可以使用代码创build,并且在新旧文件格式中都得到完全支持。

然后Excel 2016来了,并介绍了一个错误,如果一个“独立的”QueryTable,将永久损坏工作簿在某些情况下。 从Bug中保存QueryTables的唯一方法是将它们包装在一个ListObject中。


所以我有10k +遗留的Excel文档,现有的QueryTable需要用ListObject来包装。 重要的是,大多数查询表都有自动填充的右边的公式。

使用Excel接口,将查询包装到列表中是很简单的(在查询结果中激活一个单元格, InsertTableOk ),并像预期的那样工作,留下一个完整的列表,从查询中获取数据。

将此操作logging为macros将产生:

 ActiveSheet.ListObjects.Add(xlSrcRange, Range("$B$5:$D$9"), , xlYes).Name = _ "Table_Query_from_MS_Access" 

但是,如果执行这个代码而不做任何修改,将会产生一个Frankenstein查询表:它看起来像外部的列表对象,但不起作用,无法刷新,无法编辑,显示旧式属性对话框和列表对象报告它是xlSrcRange ,而不是由接口创build的列表报告的xlSrcQuery

就像电子一样,它干扰自己(列表对象部分与查询表部分重叠,并且因为这个原因拒绝刷新,即使它们应该是同一个 – 回想起查询表右边有公式,他们现在也必须成为名单的一部分):

在这里输入图像说明

非常显然,转换表格时的界面比macros录制器捕获的要多得多。

我曾尝试调用ListObjects.Add与各种参数,提供一个作为源的Range作为来源的WorkbookConnection Connection作为源的QueryTableConnection – 只要它重叠现有的QueryTable都不工作。

我已经研究了取消链接现有的QueryTable并重新创buildListObject的地方,但是这会在表格周围的公式中引起各种问题。

什么是完整,正确的代码以编程方式包装与ListObject的现有QueryTable ,完全匹配的接口呢?

它目前看起来像我将不得不通过直接操纵我讨厌的xslx格式的XML来做到这一点。