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

时间:2017-04-24 19:50:41

标签: excel excel-vba office-2016 listobject vba

历史上,Excel中的外部数据查询用QueryTables表示 ListObjects出现在某个时刻,但它们尚未与QueryTable兼容且无法包含它们。

在Office 2007中,它们不仅兼容,而且是默认设置。从那时起,创建外部查询意味着创建ListObjectQueryTable已缩减为内部组件。

"单机"没有包装在ListObject中的QueryTables无法再使用该界面创建,但可以使用代码创建,并且在新旧文件格式中都得到完美支持。

然后Excel 2016出现并引入了一个错误,如果是#34;独立" QueryTable将在某些情况下永久损坏工作簿。从bug中保存QueryTables的唯一方法是将它们包装在ListObject中。

所以我有10k +遗留的Excel文档,其中现有的QueryTable需要用ListObject包裹。重要的是,大多数查询表的右侧都有公式filled down automatically

使用Excel界面,将查询包装在列表中很简单(激活查询结果中的单元格,插入 - - 确定)并且像人们期望的那样工作,留下一个完整功能的列表,从查询中获取数据。

将此操作录制为宏会产生:

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

然而,执行这个非常代码而不进行任何修改会导致Frankenstein查询表:它看起来像外部的列表对象,但它不起作用,无法刷新,无法编辑,显示旧式属性对话框,并且列表对象报告它是xlSrcRange而不是由界面创建的列表报告的xlSrcQuery

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

enter image description here

很明显,转换表时界面的功能远远超过宏录制器捕获的功能。

我尝试使用各种参数调用ListObjects.Add,提供Range作为来源,WorkbookConnection作为来源,QueryTable's Connection作为来源 - 这一切都是只要它与现有的QueryTable重叠,就无法工作。

我已经考虑取消链接现有的QueryTable并从头开始重新创建ListObject,但这会导致表格中的公式出现各种问题。

以编程方式将现有QueryTableListObject打包在一起的完整,正确的代码是什么,与界面完全匹配?

它目前在我看来,我将不得不通过直接操作xslx格式中的XML来实现它,我讨厌它。

2 个答案:

答案 0 :(得分:0)

我在尝试将可查询表格CSV转换为表格时遇到了同样的问题。我没有找到将查询表转换为listobject的直接方法,但由于我的信息是静态的,我使用了一个简单的解决方法。

  1. 使用querytable方法
  2. 创建临时工作表以导入数据
  3. 将数据从临时工作表复制到计划工作表
  4. 将复制的数据转换为表格,然后插入公式
  5. 如果您的XML数据不是动态的,并且不需要保留指向外部数据的链接,那么这可能对您有用。否则这不是一个有效的解决方法。

答案 1 :(得分:0)

我无法以编程方式将QueryTable包装在ListObject中,但是我可以为Microsoft的Excel 2016/2019 QueryTable错误提供缓解措施,因为避免其影响似乎是您的真正目标。

  1. Closed-source 3rd-party Excel add-in by Event 1 Software-以我的经验,这通常可以解决问题,但是我只有少数报告仍然受到影响。您需要2.11或更高版本。您可以使用以下公式检查已加载的加载项的版本:= XLQT3Version()

  2. 更改报表设计以减少Microsoft错误的风险(来源:报表设计的广泛工作,包括未安装任何Event 1产品的系统上的工作):

2.1确保QueryTable的标题不属于QueryTable。您仍然可以在表格上方设置一个手动标题。

2.2在QueryTable的第一行上方(在QueryTable和手动标题之间)插入空白行。

2.3在新的空白行中,粘贴QueryTable所需的所有格式和公式。

2.4将新行的heigt设置为“ 3”。这样可以防止将标头完全或部分复制到QueryTable的主体中。相反,该错误将导致所需的格式和公式被复制到QueryTable中,而不是破坏oueryTable的那些部分。重要提示:切勿隐藏行或将行高度设置得过低。这样做会消除其保护作用。

2.5刷新前禁用所有数据过滤器。您可以在刷新完成后重新应用它们。如果需要自动执行此操作,请挂钩QueryTable的刷新之前/之后的事件,或者使用宏将其删除,然后启动刷新,然后将其还原。

2.6在刷新和还原之前,也应删除分组的行和小计。刷新后。分组的列可以。

  1. 手动完成(来源:Event 1 Software的技术支持)

3.1在错误损坏文档后,打开一个未保存的受影响文档。也就是说,文档没有损坏,但是会被MS错误损坏。

3.2不允许文档连接到数据源或刷新。取消所有登录请求。

3.3等待至少4秒钟。

3.4刷新QueryTable(如果需要,请登录)。

3.5再次刷新QueryTable(有时是第三次)。