Ms access MS Access使用VBA打印报表

Ms access MS Access使用VBA打印报表,ms-access,vba,reporting,Ms Access,Vba,Reporting,我有一份非常密集的VBA报告。当我预览它时,一切都很好,但当我在预览后打印它时,一切都变得古怪。我花了很多时间来缩小可能性,并以一定程度的信心得出结论,这是MS Access中的一个bug 到目前为止,我打印报告的方法是使用docmd.openreport“report”打开报告。然后我使用docmd.printout命令,以便设置页面范围、排序规则等 有没有一种方法可以直接打印一份报告,而不必先预览就可以设置页面浏览、校对等选项 谢谢, 杰夫很久以前,我遇到了一个非常棘手的案子。我必须做一些字

我有一份非常密集的VBA报告。当我预览它时,一切都很好,但当我在预览后打印它时,一切都变得古怪。我花了很多时间来缩小可能性,并以一定程度的信心得出结论,这是MS Access中的一个bug

到目前为止,我打印报告的方法是使用
docmd.openreport“report”
打开报告。然后我使用
docmd.printout
命令,以便设置页面范围、排序规则等

有没有一种方法可以直接打印一份报告,而不必先预览就可以设置页面浏览、校对等选项

谢谢,
杰夫

很久以前,我遇到了一个非常棘手的案子。我必须做一些字段创建,移动和格式化,这只能用一种方法完成。我采取了一种大胆的方法,这成为了唯一的方法:我在设计模式下打开了隐藏的报告,让vba完成它的工作,完成后,报告被更改为正常可见,以便显示和打印。

很久以前,我遇到了一个非常困难的情况。我必须做一些字段创建,移动和格式化,这只能用一种方法完成。我采取了一种大胆的方法,这成为了唯一的方法:我在设计模式下打开了隐藏的报告,让vba完成它的工作,完成后,报告被更改为正常可见,以便显示和打印。

一个解决方案是在报告设计中设置打印机选项,保存这些更改并打印它。缺点是,这会将报表绑定到特定的打印机,除非您进入设计并更改它

DoCmd.OpenReport "ReportName", acViewDesign, Null, Null, acHidden

Dim oRpt As Report
Set oRpt = Reports(0)
oRpt.UseDefaultPrinter = False
oRpt.Printer = Application.Printers("printer name")

With oRpt.Printer
    .PaperBin = acPRBNAuto
    .PaperSize = acPRPSLetter
    .Copies = 1
    .PrintQuality = acPRPQMedium
End With

DoCmd.Close acReport, "ReportName", acSaveYes
DoCmd.OpenReport "ReportName", acViewNormal

Set oRpt = Nothing

一种解决方案是在报告设计中设置打印机选项,保存这些更改并打印。缺点是,这会将报表绑定到特定的打印机,除非您进入设计并更改它

DoCmd.OpenReport "ReportName", acViewDesign, Null, Null, acHidden

Dim oRpt As Report
Set oRpt = Reports(0)
oRpt.UseDefaultPrinter = False
oRpt.Printer = Application.Printers("printer name")

With oRpt.Printer
    .PaperBin = acPRBNAuto
    .PaperSize = acPRPSLetter
    .Copies = 1
    .PrintQuality = acPRPQMedium
End With

DoCmd.Close acReport, "ReportName", acSaveYes
DoCmd.OpenReport "ReportName", acViewNormal

Set oRpt = Nothing

不幸的是,没有办法在代码中完整地完成这项工作,但自从引入DoCmd.OpenReport方法的WindowMode参数以来,仍然可以完成这项工作。这样就可以在打印预览模式下打开报告并将其隐藏。然后可以设置报表打印机对象的属性(例如输出打印机和方向),然后使用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
我使用表单的.Tag属性作为报表名称,然后根据该属性执行所有操作,包括动态更改报表属性,这是可能的,因为报表在预览模式下打开,但不可见

例如,我在布局选项组后面有一个AfterUpdate事件:

  With Reports(Me.Tag)
    .Printer.Orientation = Me!optLayout
    Me!txtPageTo = .Pages
  End With
我更改页面范围编号的原因是,更改方向很可能会更改页面数量。与OnOpen事件不同,在打印预览模式下以不可见方式打开的报表的格式属性会立即发生更改

我使用对话框窗体的标准方法,即使用“取消”和“继续”按钮将窗体的.Visible属性设置为False,从而允许调用代码继续。对于Cancel按钮,我将表单的.Tag属性设置为“Cancel”,并在代码在调用上下文中继续时检查.Tag属性(参见上文)

因此,这并不像直接在打印机对象上设置页面范围那样好,但是它完成了工作

生产代码中需要更改的一件事是确保PrintReport函数中有一个错误处理程序,以便在出现错误时可以重新打开Application.Echo(否则,用户可能会被一个空白屏幕卡住,无法工作)。另一种方法是,在调用DoCmd.SelectObject方法时,让报告显示在屏幕上。但是如果我对用户隐藏报表预览,我会一直这样做


有关此方面的详细信息,您应该研究对象浏览器中的.Printer对象(VBE中的F2),这有助于解释Application.Printers集合和Application.Printer对象以及与特定报表关联的对象之间的交互。我还发现这澄清了一些事情。

不幸的是,没有办法在代码中完全做到整洁,但自从引入DoCmd.OpenReport方法的WindowMode参数以来,仍然可以做到这一点。这样就可以在打印预览模式下打开报告并将其隐藏。然后可以设置报表打印机对象的属性(例如输出打印机和方向),然后使用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
我使用表单的.Tag属性作为报表名称,然后根据该属性执行所有操作,包括动态更改报表属性,这是可能的,因为报表在预览模式下打开,但不可见

比如说