Database 在access vba中输出多个报告会导致错误3014,打开的表太多

Database 在access vba中输出多个报告会导致错误3014,打开的表太多,database,vba,reporting-services,runtime-error,ms-access-2010,Database,Vba,Reporting Services,Runtime Error,Ms Access 2010,我正在使用VBA和MS Access 2010从公司数据库中编写报告。我有近3000名员工,我需要为每位员工编写10份不同的报告,然后将这10份报告合并为每位员工的一份pdf。这些文件然后保存在按工作地点排序的目录中 我写的代码非常好,并且完成了预期的工作,除非在写出1024个报告后,我收到一个错误。错误号3014,无法再打开表 根据我在互联网上能找到的,这与Jet表引用有关,并且很难排除故障。我已经遵循了我能找到的建议,我相信我在使用后已经正确地关闭了所有东西。我想这个问题可能是在合并pdf文

我正在使用VBA和MS Access 2010从公司数据库中编写报告。我有近3000名员工,我需要为每位员工编写10份不同的报告,然后将这10份报告合并为每位员工的一份pdf。这些文件然后保存在按工作地点排序的目录中

我写的代码非常好,并且完成了预期的工作,除非在写出1024个报告后,我收到一个错误。错误号3014,无法再打开表

根据我在互联网上能找到的,这与Jet表引用有关,并且很难排除故障。我已经遵循了我能找到的建议,我相信我在使用后已经正确地关闭了所有东西。我想这个问题可能是在合并pdf文件例程中出现的,但即使您对此进行了注释,它仍然会在1024个报告中失败

我希望这段代码能够处理大约30000份报告而不会失败。任何想法或想法都将不胜感激

Public Function combined_report(EmployeeSelectionQuery As String)

Dim DefaultPdfDir As String     ' contains path to where pdf files will be written on local computer
Dim rst As Recordset            ' recordset object for set of selected plots from query:Employees_COMBINED
Dim n_employees As Integer      ' Number of employees selected by query:Employees_COMBINED
Dim current_employee_number As Variant     ' current employee number, used when writing combined reports
Dim current_duty_station As Variant     ' current duty station, used when writing combined reports
Dim strWhere As String          ' String containing the where clause for the combined openreport WhereCondition
Dim arrayReport(0 To 9) As Variant      ' Array containing all the reports to be processed in combined
Dim strReport As Variant        ' String containing prefix to reports
Dim tempOutputPdfFile As String ' Individual report before they are combined
Dim combinedOutputPdfFile As String     ' Combined report composed of individual reports REQUIRES that adobe acrobat - full version be installed.
Dim intCounter As Integer       ' A iteration counter used to update the status bar
Dim combOutputPdfFile As String ' Combined Output Pdf File Path

On Error GoTo error_handler

Set rst = CurrentDb.OpenRecordset(EmployeeSelectionQuery)

'Force Access to accurately update .RecordCount property
rst.MoveLast
rst.MoveFirst
n_employees = rst.RecordCount

If n_employees = 0 Then
  Call MsgBox("No employees selected by query: " & EmployeeSelectionQuery, vbCritical + vbOKOnly + vbDefaultButton1, "No Employees Selected")
  combined_report = False
Else

  DoCmd.Hourglass True

  'Set HomeDir and create output folder
  DefaultPdfDir = "C:\temp"
  MakeDir DefaultPdfDir


  arrayReport(0) = "REPORT_1"
  arrayReport(1) = "REPORT_2"
  arrayReport(2) = "REPORT_3"
  arrayReport(3) = "REPORT_4"
  arrayReport(4) = "REPORT_5"
  arrayReport(5) = "REPORT_6"
  arrayReport(6) = "REPORT_7"
  arrayReport(7) = "REPORT_8"
  arrayReport(8) = "REPORT_9"
  arrayReport(9) = "REPORT_10"


  'Set counter to zero
  intCounter = 0

  Do While (Not (rst.EOF))

        'Get employee number and duty station to name the files and sort by directory
        current_employee_number = rst!EN
        current_duty_station = rst!DUTY_STATION

        'Make the output directory if it doesn't exist and specify the output file path
        MakeDir "C:\Final\" & current_duty_station
        combOutputPdfFile = "C:Final\" & current_duty_station & "\" & current_employee_number & ".pdf"


        'Increment counter by one for each employee processed
        intCounter = intCounter + 1

        'Where statement used by DoCmd.OpenReport to run the report for one employee only
        strWhere = "[EN] = " & current_employee_number & " OR [en] = " & current_employee_number

        'Process each report
        For Each strReport In arrayReport

            'Specify the file path and name for the report
            tempOutputPdfFile = DefaultPdfDir & "\" & current_employee_number & "_" & strReport & ".pdf"

            'Update Status Bar
            Status ("Processing " & intCounter & " of " & n_employees & ": " & tempOutputPdfFile)

            'Open the report and write it to a pdf file
            DoCmd.OpenReport strReport, acViewPreview, "", strWhere, acHidden
            DoCmd.OutputTo acOutputReport, strReport, acFormatPDF, tempOutputPdfFile, False
            DoCmd.Close acReport, strReport, acSaveNo

            'Merge the files
            MergePdfFiles combOutputPdfFile, tempOutputPdfFile, combOutputPdfFile


        Next strReport

        'Delete the last temp file before moving on to the next employee
        DeleteFile tempOutputPdfFile

    rst.MoveNext

  Loop

  'Close everything up
  Status ("")
  rst.Close
  Set rst = Nothing
  DoCmd.Hourglass False
  combined_report = True

End If

Exit Function
error_handler:
    MsgBox "Error: " & Err.Number & vbNewLine & _
           "Description: " & Err.Description, vbCritical, "combined_report function error"
    DoCmd.Hourglass False
    combined_report = False
    Status ("")

End Function
尝试注释掉“DoCmd.OutputTo”语句,看看它是否有错误。我猜这个命令除了在前面的DoCmd.OpenReport行中打开的报告之外,还打开了一个报告


(我本想将此添加为注释,但因此不允许添加)

我使用DoCmd.OpenReport,因为它内置了WHERE子句功能。在阅读了JayroGreybeard的评论后,我意识到同时使用OpenReport和OutputTo方法似乎是多余的。因此,我重写了代码,删除了OpenReport调用,并在调用OutputTo之前修改了每个报告的QueryDef

出于某种原因,这解决了这个问题


谢谢你的帮助

我对3014错误也有同样的问题。我将报告输出为PDF格式,同时在屏幕上为用户显示报告(同时使用Docmd.OpenReport和Docmd.OutputTo,这对单个报告很有效。但是,当我批量运行报告并导出/显示报告时。(该工具自动生成采购订单)3014错误将在大约100份报告中出现


当我关闭DoCmd.OpenReport以批量运行PDF格式的报告时,3014错误消失了。我已重新测试,无法在1000秒内毫无问题地运行报告批处理。

Hmmm。哪一行引发了错误?我读了一些关于这个有趣问题的文章。我想知道分页类型的解决方案是否有效。就像只处理x一样一次记录的数量。我想知道如果你跳出函数,Jet表引用是否会被清理…我确实尝试过通过向函数添加停止和启动参数来对此进行分页。使用宏,我将运行1000个报告,跳出函数,然后对下千个报告进行宏调用。我仍然得到了同样的问题。Erl属性指向状态之间的空行(“处理……”和“注释”打开报表并将其写入PDF文件)。此外,这不是错误的原因,但在“循环”语句之后,我将使用“RST.Calm”。“语句。我添加了rst.Close行,感谢您捕捉到它!我还注释掉了DoCmd.OutputTo语句,即使在这两个更改之后,代码在1024个报告后仍然退出。