Giorni fa avevo la necessità creare un automatismo su Lotus Notes che, partendo da un elenco di documenti selezionati all’interno di una vista me li esportasse in PDF.
Facile direte voi, basta entrare nel documento e lanciare la stampa su una PDF printer.
Ma se io volessi che la stampa fosse del tutto automatizzata per l’insieme dei documenti selezionati, e che per esempio, il nome del file fosse composto dal valore di alcuni campi del documento stesso?
Soluzione
Prima di tutto devo installare PDFCreator, un software libero per piattaforma Windows che consente di generare file in formato PDF da qualsiasi documento. La caratteristica che mi interessa è che PDFCreator è dotato di un’interfaccia COM, attraverso la quale posso manipolare via codice i settaggi di stampa, per esempio gli posso dire di salvare in maniera automatica, andandogli a specificare il nome del file.
In secondo luogo creo una procedura che, per ogni documento selezionato all’interno della vista, esegua le seguenti operazioni:
1) crea il nome del file PDF in base alle mie necessità
2) se il file esiste già lo cancella
3) crea istanza PDFCreator
4) setta proprietà istanza
5) apre il doc, lo stampa e lo chiude
6) prima di passare il doc successivo aspetta che il PDF sia stato creato (Function isFileCreated)
Codice
Sub Click(Source As Button) On Error Goto Errore Dim w As New NotesUIWorkspace Dim session As New NotesSession Dim db As NotesDatabase Dim doc As NotesDocument Dim uidoc As NotesUIDocument Dim collection As NotesDocumentCollection ' PDF Dim PDFCreator As Variant Dim pdfDir As String Dim pdfFile As String Dim pdfPath As String Dim aryFileChar(8) As String aryFileChar(0)="/" aryFileChar(1)="" aryFileChar(2)=":" aryFileChar(3)="?" aryFileChar(4)="*" aryFileChar(5)="""" aryFileChar(6)="|" aryFileChar(7)="<" aryFileChar(8)=">" pdfDir="C:pdf" If Dir(pdfDir,16)="" Then Messagebox "Directory di salvataggio pdf non trovata, creare la seguente cartella: " & pdfDir,16,"Attenzione!" Exit Sub End If 'creo istanza PDFCreator Set PDFCreator = CreateObject("PDFCreator.clsPDFCreator") If Not PDFCreator.cStart("",True) Then Msgbox "La stampante PDF non è stata avviata!",16,"Export" Exit Sub End If Set db = session.CurrentDatabase Set collection = db.UnprocessedDocuments Set doc = collection.GetFirstDocument() 'ciclo sui doc selezionati While Not(doc Is Nothing) 'come esempio do messo un nome file creato da 2 campi del documento, l'importante è che creino un nome univoco pdfFile = Replace(doc.Nome(0),aryFileChar,"_") & "-" & Replace(doc.Cognome(0),aryFileChar,"_") & ".pdf" pdfPath = pdfDir & pdfFile 'se il file esiste già lo cancello If Not Dir(pdfPath) = "" Then Kill pdfPath 'setto le proprità dell'oggetto che mi interessano With PDFCreator .cOption("UseAutosave") = 1 .cOption("UseAutosaveDirectory") = 1 .cOption("AutosaveDirectory") = pdfDir .cOption("AutosaveFilename") = pdfFile .cOption("AutosaveFormat") = 0 .cClearCache End With 'apro il doc, lo stampo (sulla stampante PDFCreator) e lo richiudo Set uiDoc = w.EditDocument(False,Doc,True,"",True,True) Call uidoc.Print( "1",,,,"PDFCreator") Call uiDoc.Close(True) Set uiDoc = Nothing 'utilizzo la funzione isFileCreated per aspettare che sia stato creato il file prima di passare al doc successivo If Not isFileCreated(pdfPath) Then Msgbox "File non creato" Set doc = collection.GetNextDocument(doc) Wend Fine: On Error Resume Next PDFCreator.cClose Set PDFCreator = Nothing Exit Sub Errore: msgErrore="Si è verificato un errore imprevedibile." msgErrore= msgErrore & Chr(13) & "RIF. " & Error & " (alla linea " & Erl & ") della procedura: Crea PDF (Click)" Messagebox msgErrore,16,"Errore!" Resume Fine End Sub
Funzione isFileCreated:
Function isFileCreated ( filePath As String ) As Boolean On Error Goto Errore Dim contatore As Integer Dim fileSize As Long isFileCreated = False Do While Dir$(filePath$, 0) = "" If contatore > 30 Then Exit Function Sleep 1 contatore = contatore + 1 Loop fileSize = Filelen(filePath$) contatore = 0 Do While (Filelen(filePath$) = 0 Or Filelen(filePath$) > fileSize) fileSize = Filelen(filePath$) If contatore > 30 Then Exit Function Sleep 1 contatore = contatore + 1 Loop isFileCreated = True Exit Function Errore: msgErrore="Si è verificato un errore imprevedibile." msgErrore= msgErrore & Chr(13) & "RIF. " & Error & " (alla linea " & Erl & ") della procedura: isFileCreated" Messagebox msgErrore,16,"Errore!" Exit Function Resume End Function
Essendo il ciclo + veloce dell’effettiva creazione dei PDF ho dovuto aggiungere questa funzione, che in pratica farà passare il programma al documento successivo solo dopo che il PDF del documento in elaborazione è stato effettivamente creato.