К сожалению, в коде нет способа сделать это полностью аккуратно, но все же это можно сделать после введения параметра WindowMode метода DoCmd.OpenReport. Это позволяет открыть отчет в режиме предварительного просмотра и скрыть его. Затем можно установить свойства объекта «Принтер» отчета (например, выходной принтер и ориентацию), а затем использовать DoCmd.PrintOut для печати диапазона страниц.
Стоит отметить:
Вы не можете сделать это в событии OnOpen отчета, потому что изменение всего, что влияет на макет, не даст вам правильных результатов. Например, если в событии OnOpen вы изменили ориентацию с книжной на альбомную, у вас не будет точного подсчета количества страниц в отчете, поскольку отчет не был отформатирован во время запуска события OnOpen. , Для всего, кроме страниц, все в порядке.
Я бы реализовал это с помощью публичной функции и диалоговой формы. Функция будет выглядеть примерно так:
Public Function PrintReport(strReport As String) As Boolean
' open report in PREVIEW mode but HIDDEN
DoCmd.OpenReport strReport, acViewPreview, , , acHidden
' open the dialog form to let the user choose printing options
DoCmd.OpenForm "dlgPrinter", , , , , acDialog, strReport
With Forms!dlgPrinter
If .Tag <> "Cancel" Then
Set Reports(strReport).Printer = Application.Printers((!cmbPrinter))
Reports(strReport).Printer.Orientation = !optLayout
Application.Echo False
DoCmd.SelectObject acReport, strReport
DoCmd.PrintOut acPages, !txtPageFrom, !txtPageTo
PrintReport = True
End If
End With
DoCmd.Close acForm, "dlgPrinter"
DoCmd.Close acReport, strReport
Application.Echo True
End Function
Форма диалога будет выглядеть примерно так:
альтернативный текст http://dfenton.com/DFA/examples/PrinterProperties.png
Как вы можете видеть выше, я открываю это диалоговое окно с параметром OpenArg, который является именем отчета. В событии OnLoad диалогового окна я инициализирую элементы управления в форме:
Dim varPrinter As Printer
Dim strRowsource As String
Dim strReport As String
If Len(Me.OpenArgs) > 0 Then
strReport = Me.OpenArgs
Me.Tag = strReport
For Each varPrinter In Application.Printers
strRowsource = strRowsource & "; " & varPrinter.DeviceName
Next varPrinter
Me!cmbPrinter.RowSource = Mid(strRowsource, 3)
' first check to see that the report is still open
If (1 = SysCmd(acSysCmdGetObjectState, acReport, strReport)) Then
With Reports(strReport).Printer
Me!cmbPrinter = .DeviceName
Me!optLayout = .Orientation
End With
Me!txtPageTo = Reports(strReport).Pages
End If
End If
Я использую свойство формы .Tag для имени отчета, а затем делаю все на его основе, включая внесение изменений в свойства отчета на лету, что возможно потому, что отчет открыт в режиме предварительного просмотра, но не виден.
Например, у меня есть это событие AfterUpdate позади группы опций Layout:
With Reports(Me.Tag)
.Printer.Orientation = Me!optLayout
Me!txtPageTo = .Pages
End With
Причина, по которой я меняю номера диапазонов страниц, заключается в том, что изменение ориентации, скорее всего, изменит количество страниц. В отличие от события OnOpen, изменения свойств формата отчета, открытого невидимым в режиме предварительного просмотра, происходят немедленно.
Я использую свои стандартные методы для диалоговых форм, то есть кнопки «Отмена» и «Продолжить» устанавливают для свойства формы .Visible значение False, что позволяет вызывающему коду продолжать работу. Для кнопки «Отмена» я установил для свойства .Tag формы значение «Отмена» и проверяю свойство .Tag, когда код продолжается в контексте вызова (см. Выше).
Итак, это не так здорово, как если бы можно было установить диапазон страниц непосредственно для объекта Printer, но он выполняет свою работу.
Одна вещь, которую необходимо изменить в рабочем коде, - убедиться, что в функции PrintReport был обработчик ошибок, чтобы в случае сбоя можно было снова включить Application.Echo (в противном случае пользователь может застрять в пустой экран и не может работать). Альтернативой было бы просто позволить отчету появляться на экране при вызове метода DoCmd.SelectObject. Но если я скрываю предварительный просмотр отчета от пользователя, я бы хотел пройти весь путь до конца.
Для получения дополнительной информации об этом вам следует исследовать объект .Printer в обозревателе объектов (F2 в VBE), а Статья базы знаний MS 290293 полезна для объяснения взаимодействия между Application.Printers. коллекция и объект Application.Printer и объекты, связанные с конкретным отчетом. Я также нашел небольшой учебник на сайте Office , который прояснил некоторые вещи.