首页 > 解决方案 > 在此示例中如何避免 VBA 中的选择/活动语句?

问题描述

需要将所有工作表导出到一个 PDF 文件中,所以我找到了这段代码,它可以工作(导出一个 PDF,每个工作表都有一个页面)。但我不想使用 select / active 语句,我更喜欢使用存储对象的变量。

问题:如何避免在此代码中选择/ ActiveSheet?

ThisWorkbook.Sheets(Array("Sheet1", "Sheet2")).Select

ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
    "C:\tempo.pdf", Quality:= xlQualityStandard, IncludeDocProperties:=True, _
     IgnorePrintAreas:=False, OpenAfterPublish:=True

标签: excelvba

解决方案


TL;DR:在这种情况下,您无法避免Select,因为您需要 的后期装订行为ActiveSheet.ExportAsFixedFormat,这显然考虑到了选定的纸张——早期装订Worksheet.ExportAsFixedFormat不这样做。


ExportAsFixedFormat是 的成员Excel.Worksheet

ActiveSheet不是Excel.Worksheet虽然,但它是Object(所以任何反对的成员都必然是迟到的)。这是一个重要的细节。

当你这样做时:

ThisWorkbook.Sheets(Array("Sheet1", "Sheet2")).Select

.Select成员调用不是针对对象进行的Worksheet:给定一个工作表名称数组,Sheets(or Worksheets) 属性返回一个Excel.Sheets集合对象,就是.Select被调用的对象。这也是一个重要的细节。

您可能知道,您在 Excel 对象模型中处理的对象是 COM 对象。在 COM 中,除非另有说明,否则接口是可扩展的:您可以这样编写:

Debug.Print Application.Sum(2, 2)

并得到一个输出——即使Sum它不是Application类的编译时成员:成员调用在运行时被解析(这就是“后期绑定”),并且因为 COM 对象是通过特定成员选择来扩展WorksheetFunction的,Application.Sum在运行时工作得非常好,尽管你没有得到任何编译时验证:你基本上是蒙着眼睛编码,成员名称中的任何拼写错误都会在运行时引发错误 438(但即使编译得很好指定) ,Option Explicit并且参数中的任何错误(错误类型、错误顺序、错误数量的参数)将在运行时引发错误 1004。

这就是为什么您通常要避免隐式后期绑定,因此要针对ActiveSheetand进行编码Selection:因为这些Object对象(对于成员调用反对 相同Variant)没有定义编译时接口,使用它们是蒙着眼睛编写代码,这很容易出错。

但早期绑定代码并不总是 100% 等同于后期绑定代码。

这是一种这样的情况:ExportAsFixedFormat成员在早期绑定时在运行时以一种方式表现,而在后期绑定时表现不同。通过后期绑定调用,您可以导出单个 PDF 文档,其中集合中的每个工作表都有一个页面,而针对仅导出Sheets工作表的早期绑定调用,并且由于没有,您无法进行后期绑定调用直接针对避免调用和后续的后期绑定成员调用。Worksheet.ExportAsFixedFormatSheets.ExportAsFixedFormatSheets(Array(...)).SelectActiveSheet

还有许多其他成员,尤其是WorksheetFunction成员,在后期绑定和早期绑定时表现不同。


推荐阅读