Экспортировать несколько листов в PDF одновременно без использования ActiveSheet или Select
Она была пробурена в голову, чтобы избежать ошибок и обеспечить хороший опыт пользователя, то лучше избегать использования .Select
, .Activate
, ActiveSheet
, ActiveCell
и т.д.
Имея это в виду, есть ли способ использовать метод .ExportAsFixedFormat
для подмножества Sheets
в рабочей .ExportAsFixedFormat
без использования одного из перечисленных выше? Пока что я смог придумать только один способ:
- использовать
For Each
; однако это приводит к отдельным PDF файлам, что не годится. -
использовать код, подобный тому, что генерируется записи макросов, который использует .Select
и ActiveSheet
:
Sheets(Array("Sheet1", "Chart1", "Sheet2", "Chart2")).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"exported file.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, openafterpublish:= True
Возможно, невозможно не использовать ActiveSheet
, но я могу, по крайней мере, обойти использование .Select
как-нибудь?
Я попробовал это:
Sheets(Array("Sheet1", "Chart1", "Sheet2","Chart2")).ExportAsFixedFormatType:= _
xlTypePDF, Filename:= "exported file.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, openafterpublish:= _
True
Это производит:
ошибка 438: объект не поддерживает это свойство или метод
Ответы
Ответ 1
Ненавижу, чтобы вычеркнуть старый вопрос, но мне бы не хотелось, чтобы кто-то наткнулся на этот вопрос, прибегая к программной гимнастике в других ответах. Метод ExportAsFixedFormat
экспортирует только видимые рабочие листы и диаграммы. Это намного чище, безопаснее и проще:
Sub Sample()
ToggleVisible False
ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, FileName:= _
"exported file.pdf", Quality:=xlQualityStandard, _
IncludeDocProperties:=True, IgnorePrintAreas:=False, _
OpenAfterPublish:=True
ToggleVisible True
End Sub
Private Sub ToggleVisible(state As Boolean)
Dim ws As Object
For Each ws In ThisWorkbook.Sheets
Select Case ws.Name
Case "Sheet1", "Chart1", "Sheet2", "Chart2"
Case Else
ws.Visible = state
End Select
Next ws
End Sub
Ответ 2
Это было пробурено в мою голову (через много....
Я знаю, что вы MEAN;)
Вот один из способов, который не использует .Select/.Activate/ActiveSheet
Логика:
- Удалить ненужные листы
- Экспортировать всю книгу.
- Закройте книгу без сохранения, чтобы вернуть свои удаленные листы.
Код
Sub Sample()
Dim ws As Object
On Error GoTo Whoa '<~~ Required as we will work with events
'~~> Required so that deleted sheets/charts don't give you Ref# errors
Application.Calculation = xlCalculationManual
For Each ws In ThisWorkbook.Sheets
Select Case ws.Name
Case "Sheet1", "Chart1", "Sheet2", "Chart2"
Case Else
Application.DisplayAlerts = False
ws.Delete
Application.DisplayAlerts = True
End Select
Next ws
'~~> Use ThisWorkbook instead of ActiveSheet
ThisWorkbook.ExportAsFixedFormat Type:=xlTypePDF, Filename:= _
"exported file.pdf", Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, openafterpublish:=True
LetsContinue:
Application.Calculation = xlCalculationAutomatic
Application.DisplayAlerts = True
'~~> VERY IMPORTANT! This ensures that you get your deleted sheets back.
ThisWorkbook.Close SaveChanges:=False
Exit Sub
Whoa:
MsgBox Err.Description
Resume LetsContinue
End Sub
Ответ 3
EDIT: с радостью сообщаем, что принятый в настоящее время ответ сделал эту идею совершенно ненужной.
Спасибо Siddharth Rout за предоставленную мне идею для этого!
EDIT: как написано ниже, этот модуль работает, но не полностью; проблема заключается в том, что диаграммы не сохраняют свои данные после того, как листы, на которые они ссылаются, были удалены (это несмотря на включение команды pApp.Calculation = xlCalculationManual
). Я не смог понять, как это исправить. Будет обновляться, когда я это сделаю.
Ниже приведен модуль класса (реализующий методологию этот ответ) для решения этой проблемы. Надеюсь, что это будет полезно для кого-то, или люди могут предлагать отзывы об этом, если они не работают для них.
WorkingWorkbook.cls
'**********WorkingWorkbook Class*********'
'Written By: Rick Teachey '
'Creates a "working copy" of the desired '
'workbook to be used for any number of '
'disparate tasks. The working copy is '
'destroyed once the class object goes out'
'of scope. The original workbook is not '
'affected in any way whatsoever (well, I '
'hope, anyway!) '
''''''''''''''''''''''''''''''''''''''''''
Option Explicit
Private pApp As Excel.Application
Private pWorkBook As Workbook
Private pFullName As String
Property Get Book() As Workbook
Set Book = pWorkBook
End Property
Public Sub Init(CurrentWorkbook As Workbook)
Application.DisplayAlerts = False
Dim NewName As String
NewName = CurrentWorkbook.FullName
'Append _1 onto the file name for the new (temporary) file
Do
NewName = Mid(NewName, 1, InStr(Len(NewName) - 4, NewName, ".") - 1) _
& Replace(NewName, ".", "_1.", Len(NewName) - 4, 1)
'Check if the file already exists; if so, append _1 again
Loop While (Len(Dir(NewName)) <> 0)
'Save the working copy file
CurrentWorkbook.SaveCopyAs NewName
'Open the working copy file in the background
pApp.Workbooks.Open NewName
'Set class members
Set pWorkBook = pApp.Workbooks(Dir(NewName))
pFullName = pWorkBook.FullName
Application.DisplayAlerts = True
End Sub
Private Sub Class_Initialize()
'Do all the work in the background
Set pApp = New Excel.Application
'This is the default anyway so probably unnecessary
pApp.Visible = False
'Could probably do without this? Well just in case...
pApp.DisplayAlerts = False
'Workaround to prevent the manual calculation line from causing an error
pApp.Workbooks.Add
'Prevent anything in the working copy from being recalculated when opened
pApp.Calculation = xlCalculationManual
'Also probably unncessary, but just in case
pApp.CalculateBeforeSave = False
'Two more unnecessary steps, but it makes me feel good
Set pWorkBook = Nothing
pFullName = ""
End Sub
Private Sub Class_Terminate()
'Close the working copy (if it is still open)
If Not pWorkBook Is Nothing Then
On Error Resume Next
pWorkBook.Close savechanges:=False
On Error GoTo 0
Set pWorkBook = Nothing
End If
'Destroy the working copy on the disk (if it is there)
If Len(Dir(pFullName)) <> 0 Then
Kill pFullName
End If
'Quit the background Excel process and tidy up (if needed)
If Not pApp Is Nothing Then
pApp.Quit
Set pApp = Nothing
End If
End Sub
Процедура тестирования
Sub test()
Dim wwb As WorkingWorkbook
Set wwb = New WorkingWorkbook
Call wwb.Init(ActiveWorkbook)
Dim wb As Workbook
Set wb = wwb.Book
Debug.Print wb.FullName
End Sub
Ответ 4
Опция без создания нового WB:
Option Explicit
Sub fnSheetArrayPrintToPDF()
Dim strFolderPath As String
Dim strSheetNamesList As String
Dim varArray() As Variant
Dim bytSheet As Byte
Dim strPDFFileName As String
Dim strCharSep As String
strCharSep = ","
strPDFFileName = "SheetsPrinted"
strSheetNamesList = ActiveSheet.Range("A1")
If Trim(strSheetNamesList) = "" Then
MsgBox "Sheet list is empty. Check it. > ActiveSheet.Range(''A1'')"
GoTo lblExit
End If
For bytSheet = 0 To UBound(Split(strSheetNamesList, strCharSep, , vbTextCompare))
ReDim Preserve varArray(bytSheet)
varArray(bytSheet) = Trim(Split(strSheetNamesList, strCharSep, , vbTextCompare)(bytSheet))
Next
strFolderPath = Environ("USERPROFILE") & "\Desktop\pdf\"
On Error Resume Next
MkDir strFolderPath
On Error GoTo 0
If Dir(strFolderPath, vbDirectory) = "" Then
MsgBox "Err attempting to create the folder: '" & strFolderPath & "'."
GoTo lblExit
End If
Sheets(varArray).Select
ActiveSheet.ExportAsFixedFormat Type:=xlTypePDF, Filename:=strFolderPath & strPDFFileName, _
OpenAfterPublish:=False, IgnorePrintAreas:=False
MsgBox "Print success." & vbNewLine & " Folder: " & strFolderPath, vbExclamation, "Printing to PDF"
lblExit:
Exit Sub
End Sub