Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
This script prints a report into a PDF file using PDFCreator 3.4 (it may be compatible with PDFCreator 2.0+, but I have not tested it).
It includes error control, and configurable timeouts in case PDFCreator is open when the function is called (or it takes longer than expected).
Also forgive the spanish comments I will finish translating it as I can.
' =========================================================================== '
' PDFCreator3_Print_Report '
' =========================================================================== '
' This function prints a report into a PDF file using PDFCreator. The '
' function will return `True` if the process succeds, and `False` elswere. It '
' contains timeout configuration in order to avoid QlikView from blocking. '
' '
' This implementation is based in PDFCreator 3.4. '
' --------------------------------------------------------------------------- '
' More information: '
' + http://docs.pdfforge.org/pdfcreator/3.4/en/pdfcreator/com-interface/ '
' --------------------------------------------------------------------------- '
' Arguments: '
' + sPDFName (String): File name (without extension). '
' + sPDFPath (String): File route (for example C:\Users\User\Desktop). No end '
' slash is needed. '
' + ReportID (String): Report ID to print. '
' --------------------------------------------------------------------------- '
' Return value: '
' + Boolean: `True` it succedss, `False` else. '
' =========================================================================== '
Private Function PDFCreator3_Print_Report(sPDFName, sPDFPath, ReportID)
Dim objQueue 'As Object [PDFCreator.JobQueue]
Dim objPrintJob 'As Object [PDFCreator.PrintJob]
Dim i 'As Long
Dim result 'As Boolean
Const CFG_AUTHOR = "Oficina de Gestión del Servicio (ofigesser@ree.es) - Bip"
Const CFG_DPI = "300"
' Constantes del límite de tiempo '
' --------------------------------------------------------------------------- '
' Estas constantes marcan el tiempo máximo en segundos a esperar por las '
' operaciones. De esta manera podemos evitar dejar a QlikView bloqueado con '
' la macro esperando indefinidamente a algo que no va a suceder. '
' '
' Hay 2 constantes, una para las operaciones de la cola de impresión (esperar '
' a que se vacíe, esperar a que aparezca el trabajo...) que implica un tiempo '
' relativamente corto, mientras que el otro implica el tiempo de espera para '
' finalizar la impresión. '
' '
' Adicionalmente hay otra constante que mide el tiempo que QlikView estará '
' dormido cuando esté esperando en bucle por una petición (para aquellos '
' casos en los que el bucle se haga desde la macro). '
Const TIMEOUT_QUEUE = 10 's
Const TIMEOUT_PRINT = 300 's (5 min)
Const SLEEP_INTERVAL = 20 'ms
' Valor de retorno por defecto '
' --------------------------------------------------------------------------- '
' Se define un valor de retorno por defecto de False, esto es, fallo y que, a '
' no ser que se llegue al final de la función, no se cambiará por True. '
PDFCreator3_Print_Report = False
' Control de errores '
On Error Resume Next
' Creación del objeto de la cola de impresión '
' --------------------------------------------------------------------------- '
' Generalmente, cuando esto falla es porque no está instalado el PDFCreator '
' (2.0 o superior) en el ordenador. En caso de fallar avisará y evitará que '
' se siga con el código o que haya una salida abrupta del código. '
' '
' Este bloque se encarga de generar e inicializar la cola de impresión. '
' '
' De vez en cuando falla si se llama a la función 2 veces seguidas, por lo '
' que antes de inicializar la cola, tratará de liberarla (por si hubiera '
' alguna cola pendiente). '
'msgbox "0 - Initialize"
Set objQueue = CreateObject("PDFCreator.JobQueue")
If Err.Number <> 0 Then
MsgBox "No es posible llamar a PDFCreator." & vbCrLf & "Revisa la instalación de PDFCreator.", vbCritical
Exit Function
End If
objQueue.ReleaseCom
Err.Clear
objQueue.Initialize
If Err.Number <> 0 Then
MsgBox "Ha fallado la inicialización de la cola de impresión." & vbCrLf & "Si tienes la ventana de PDFCreator abierta, debe estar cerrada antes de comenzar el proceso.", vbExclamation
objQueue.ReleaseCom
Set objQueue = Nothing
Err.Clear
Exit Function
End If
' Vaciado de la cola de impresión '
' --------------------------------------------------------------------------- '
' Esperamos a que se vacíe la cola de impresión de la impresora. Esto evita '
' bloqueos o saltos de pasos que podrían desestabilizar el código. '
' '
' Este bloque contiene el primer *timeout* corto (el de colas). '
'msgbox "1 - Vaciado de cola"
i = 0
Do Until objQueue.Count = 0
ActiveDocument.GetApplication.Sleep SLEEP_INTERVAL
i = i + 1
If i > (TIMEOUT_QUEUE * 1000 / SLEEP_INTERVAL) And objQueue.Count <> 0 Then
msgbox "3.1"
If MsgBox("Aparentemente la impresora de PDF está ocupada y no se está liberando." & vbCrLf & "Revisa por si hubiera algún cuadro de diálogo bloqueándolo." & vbCrLf & "¿Quieres seguir esperando?", vbYesNo + vbQuestion) <> vbYes Then
MsgBox "No se pudo imprimir el documento", vbExclamation
objQueue.ReleaseCom
Set objQueue = Nothing
Err.Clear
Exit Function
End If
i = 0
End If
Loop
' Impresión del informe de QlikView '
' --------------------------------------------------------------------------- '
' Se solicita a Qlikview que imprima el informe empleando para ello '
' PDFCreator (que se nombra por el nombre de la impresora). '
'msgbox "2 - PrintReport"
ActiveDocument.PrintReport ReportID, "PDFCreator", false
If Err.Number <> 0 Then
MsgBox "Ocurrió un error a la hora de imprimir desde QlikView el informe.", vbExclamation
objQueue.ReleaseCom
Set objQueue = Nothing
Err.Clear
Exit Function
End If
' Inclusión del documento en la cola '
' --------------------------------------------------------------------------- '
' Se espera hasta que el documento ha sido incuido en la cola de impresión '
' del PDFCreator. '
' '
' Este bloque contine un *timeout* corto (el de colas), integrado en la '
' propia API de PDFCreator. '
'msgbox "3 - WaitForJob"
result = False
Do Until result
result = objQueue.WaitForJob(TIMEOUT_QUEUE)
if Not result Then
If MsgBox("Aparentemente la impresora no está aceptando el informe en su cola de impresión." & vbCrLf & "Revisa por si hubiera algún cuadro de diálogo bloqueándolo." & vbCrLf & "¿Quieres seguir intentándolo?", vbYesNo + vbQuestion) <> vbYes Then
MsgBox "No se pudo imprimir el documento", vbExclamation
objQueue.ReleaseCom
Set objQueue = Nothing
Err.Clear
Exit Function
End If
End If
Loop
' Carga del informe a imprimir '
' --------------------------------------------------------------------------- '
' Este código captura el informe a imprimir, y lo almacena en la variable '
' objPrintJob. '
'msgbox "4 - GetPrintJob"
Set objPrintJob = objQueue.NextJob
If Err.Number <> 0 Then
MsgBox "Ocurrió un error al capturar el informe de la cola de impresión.", vbExclamation
objQueue.ReleaseCom
Set objQueue = Nothing
Err.Clear
Exit Function
End If
' Configuración del informe a imprimir '
' --------------------------------------------------------------------------- '
' Este código se encarga de configurar el informe, nombre, directorio, '
' autor... '
'msgbox "5 - SetProfileSetting"
With objPrintJob
.SetProfileSetting "AuthorTemplate", CFG_AUTHOR
.SetProfileSetting "FileNameTemplate", sPDFName
.SetProfileSetting "OpenViewer", "false"
.SetProfileSetting "OpenWithPdfArchitect", "false"
.SetProfileSetting "OutputFormat", "Pdf"
.SetProfileSetting "ShowAllNotifications", "false"
.SetProfileSetting "ShowOnlyErrorNotifications", "false"
.SetProfileSetting "ShowProgress", "false"
.SetProfileSetting "ShowQuickActions", "false"
.SetProfileSetting "TitleTemplate", sPDFName
.SetProfileSetting "TargetDirectory", sPDFPath
'.SetProfileSetting "JpegSettings.Dpi", CFG_DPI
'.SetProfileSetting "PngSettings.Dpi", CFG_DPI
'.SetProfileSetting "TiffSettings.Dpi", CFG_DPI
'.SetProfileSetting "PdfSettings.PageOrientation", "Landscape"
'.SetProfileSetting "PdfSettings.CompressColorAndGray.Enabled", "true"
'.SetProfileSetting "PdfSettings.CompressColorAndGray.Compression", "JpegMinimum"
'.SetProfileSetting "PdfSettings.CompressColorAndGray.Resampling", "true"
'.SetProfileSetting "PdfSettings.CompressColorAndGray.Dpi", CFG_DPI
'.SetProfileSetting "PdfSettings.CompressMonochrome.Enabled", "true"
'.SetProfileSetting "PdfSettings.CompressMonochrome.Resampling", "true"
'.SetProfileSetting "PdfSettings.CompressMonochrome.Dpi", CFG_DPI
.PrintJobInfo.PrintJobAuthor = CFG_AUTHOR
.PrintJobInfo.PrintJobName = sPDFName
End With
If Err.Number <> 0 Then
msgbox Err.Number & ": " & Err.Description
MsgBox "Ocurrió un error al iniciar la conversión del informe a PDF.", vbExclamation
objQueue.ReleaseCom
Set objPrintJob = Nothing
Set objQueue = Nothing
Err.Clear
Exit Function
End If
' Inicio de la impresión '
' --------------------------------------------------------------------------- '
' Este bloque se encarga de iniciar la conversión y de establecer el fichero '
' donde se guardará el fichero. '
'msgbox "6 - ConvertTo"
objPrintJob.ConvertToAsync (sPDFPath & "\" & sPDFName & ".pdf")
If Err.Number <> 0 Then
msgbox Err.Description
MsgBox "Ocurrió un error al configurar la impresión.", vbExclamation
objQueue.ReleaseCom
Set objPrintJob = Nothing
Set objQueue = Nothing
Err.Clear
Exit Function
End If
' Impresión del documento '
' --------------------------------------------------------------------------- '
' Se espera hasta que PDFCreator haya terminado de imprimir el documento. '
' '
' Este bloque contine un *timeout* largo. Si se supera el *watchdog* largo, '
' se da la opción de volver a esperar la mitad del *timeout* original. '
'msgbox "7 - IsFinished"
i = 0
Do Until objPrintJob.IsFinished
ActiveDocument.GetApplication.Sleep SLEEP_INTERVAL
i = i + 1
If i > (TIMEOUT_PRINT * 1000 / SLEEP_INTERVAL) And Not objPrintJob.IsFinished Then
If MsgBox("Al parecer está tardando más de la cuenta en imprimirse el PDF." & vbCrLf & "¿Quieres seguir esperando?", vbYesno + vbQuestion) <> vbYes Then
MsgBox "No se pudo imprimir el documento", vbExclamation
objQueue.ReleaseCom
Set objPritnJob = Nothing
Set objQueue = Nothing
Err.Clear
Exit Function
End If
i = i \ 2
End If
Loop
' Revisión del éxito de la operación '
' --------------------------------------------------------------------------- '
' Se verifica que la operación se ha terminado con éxito. '
'msgbox "8 - IsSuccessful"
If objPrintJob.IsSuccessful Then
MsgBox objPrintJob.GetOutputFiles.GetFilename(0)
PDFCreator3_Print_Report = True
Else
PDFCreator3_Print_Report = False
MsgBox "No se pudo imprimir el documento.", vbExclamation
End If
' Cierre '
' --------------------------------------------------------------------------- '
' Se cierran los objetos y libera la memoria. '
objQueue.ReleaseCom
Set objPrintJob = Nothing
Set objQueue = Nothing
Err.Clear
On Error GoTo 0
End Function