Salvataggio file di word in pdf



  • Salvataggio file di word in pdf
    di David (utente non iscritto) data: 04/08/2017 11:14:14

    Salve a tutti e grazie anticipatamente per le risposte che potessero giungermi.
    Ho una lettera in formato doc dove ho dei segnalibri assegnati per importare dati da Excel, cosa che avviene senza problemi.
    Ho usato una macro in word per salvare il file in formato pdf, una volta aggiunte modifiche o immagini da parte dell'utilizzatore, utilizzando un ciclo IF per salvare il file con il nome ricavato dal testo associato al segnalibro chiamato NOME. Se il testo esiste mi dovrebbe salvare il file come ad es. "testoassociatonomesegnalibro.pdf", altrimenti con il nome del foglio di word già aperto come ad es."vecchionome.pdf".
    Il problema riguarda l'oggetto Range.Words(), utillizzato con ActiveDocument, del quale non capisco bene la sintassi, e che funziona solo associando il valore 1 all'opzione Words(), altrimenti non va.
    Così facendo però mi salva il file pdf solo con una parola (ad es. associato al segnalibro NOME ho "Casa di Cura" e quest'istruzione mi cattura solo "Casa" tralasciando il resto).
    Allego il codice e spero che qualcuno possa darmi qualche dritta in merito.
    Saluti

    David

     
    Sub Salva_file_PDF()
    '
    ' Salva_file_PDF Macro
    '
    'Dim p As String
    Dim vn As String
    Dim n As String
    
    p = ActiveDocument.Path
    vn = "vecchionomefileaperto"
      
    n = ActiveDocument.Bookmarks("NOME").Range.Words(1).Text
    
    If n = "" Then
        ChangeFileOpenDirectory p & ""
            ActiveDocument.ExportAsFixedFormat OutputFileName:=p & "" & vn & ".pdf", _
            ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
            wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, to:=1, _
            Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
            CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
            BitmapMissingFonts:=True, UseISO19005_1:=False
            Else
            ActiveDocument.ExportAsFixedFormat OutputFileName:=p & "" & n & ".pdf", _
            ExportFormat:=wdExportFormatPDF, OpenAfterExport:=False, OptimizeFor:= _
            wdExportOptimizeForPrint, Range:=wdExportAllDocument, From:=1, to:=1, _
            Item:=wdExportDocumentContent, IncludeDocProps:=True, KeepIRM:=True, _
            CreateBookmarks:=wdExportCreateNoBookmarks, DocStructureTags:=True, _
            BitmapMissingFonts:=True, UseISO19005_1:=False
            
            
    End If
    
    
    
    End Sub
    



  • di patel data: 04/08/2017 11:35:58

    prova semplicemente con
     
    n = ActiveDocument.Bookmarks("NOME").Range






  • di Vecchio Frac data: 04/08/2017 11:38:19

    Prima osservazione.
    Il codice è per Word, quindi devi avere chiaro il modello ad oggetti su cui stai lavorando, che è diverso da quello di Excel, dove i Range sono un'altra cosa.

    Seconda osservazione.
    L'oggetto Bookmark punta a una posizione all'interno del documento quindi può essere associato a un testo (solitamente è così) o a un'immagine. Il testo in Word è costituito da caratteri, frasi, paragrafi, parole. Il Range indica una porzione di ciascun insieme considerato.
    L'istruzione "ActiveDocument.Bookmarks("NOME").Range.Words(1).Text" si riferisce all'insieme dei segnalibri del documento attivo, in particolare al segnalibro NOME, in corrispondenza del quale ci sarà del testo, del quale preleva soltanto la prima parola (ecco perchè in "Casa di Cura" ti restituisce solo "Casa"). Devi omettere la parte di Words(1) e conservare Range.Text, che si riferisce all'intero segnalibro definito.





  • di David (utente non iscritto) data: 04/08/2017 11:51:22

    Ciao a patel e a Vecchio Frac.

    Avevo già provato con le vostre indicazioni ma nel debug ho visto che la variabile n non conteneva nulla e quindi nel ciclo IF passava direttamente ad ELSE.
    Non vorrei che ci fosse qualcosa che mi sono perso perché il testo associato ai segnalibri presenti nel file provengono da celle di Excel.
    Proprio per questo motivo avevo trovato questa possibilità di utilizzare Words(1) ma a quanto ne capisco restituisce (correttamente) solo la prima parola del testo associato al segnalibro. Per questo mi chiedevo se esistesse un parametro tipo "*" oppure "All" da inserire in Words() ma non funzionano.
     
    n = ActiveDocument.Bookmarks("NOME").Range.Text sia 
    n = ActiveDocument.Bookmarks("NOME").Range
    
    DEBUG
    
    Variabili Locali
    Espressione       Valore          Tipo
          i                     ""           String



  • di Vecchio Frac data: 04/08/2017 11:57:47

    Infatti Range.Text fa quello che intendi tu con Range.Words(*).Text (che non esiste).
    Mi viene il sospetto che i segnalibri vengano sovrascritti e quindi perduti nel passaggio da Excel a Word.
    Sarebbe interessante vedere la parte di codice che trasferisce i contenuti da Excel a Word.
    Si potrebbe anche seguire un'altra strada e cioè inserire nel file master di Word delle parole chiave da ricercare/sostituire in fase di import da Excel.

    Tipo:
    Egregio Sig. @NOME
    @Indirizzo
    @Città

    Le allego la fattura @Numero.

    E poi in fase di lettura della base dati sostituisci con Replace le diverse occorrenze delle parole precedute da @ con il valore corretto.
    Io faccio così con successo in alcuni modelli distribuiti ai miei colleghi.





  • di patel data: 04/08/2017 12:35:05

    io ho testato la tua macro su un mio file di word e funziona benissimo (dopo la correzione)





  • di David (utente non iscritto) data: 04/08/2017 13:55:36

    Rieccomi qui. Ho provato ad aprire il file di word senza importare nulla da Excel (una macro da Excel mi apre la lettera preimpostata in Word e mi inserisce i dati associati ai segnalibri di word), a richiamare il segnalibro NOME e ad inserire una parola ("Ciao").
    Ebbene, solo con l'opzione ActiveDocument.Bookmarks("NOME").Range.Words(1) (.Text o meno)
    mi trova la parola "Ciao", altrimenti nada.
    Ciò significa che comunque il segnalibro c'è e funziona. Non capisco perché non mi rimandi nulla col solo .Range.
    Adesso comunque vedo di applicarmi al discorso alternativo di Vecchio Frac.
    Ciao patel, ciao Vecchio Frac e grazie ancora.



  • di David (utente non iscritto) data: 07/08/2017 15:46:38

    Ciao a tutti,

    sia patel che Vecchio Frac hanno cercato di aiutarmi ma ho sempre lo stesso problema: utilizzando l'istruzione n = ActiveDocument.Bookmarks("NOME").Range la sub() mi restituisce sempre n="" e quindi mi salva il file in formato pdf col nome del file di Word aperto e non col nome associato al segnalibro. Il segnalibro è in funzione perché utilizzando l'istruzione n = ActiveDocument.Bookmarks("NOME").Range.Words(1).Text la sub() mi cattura la prima parola associata al segnalibro NOME. Potrei pensare che il segnalibro sia associato solo alla prima parola ma non capirei lo stesso perché con il solo .Range non me la catturi ugualmente. Boh!!!.
    Chiedo se fattibile.
    Saluti
    Davide



  • di David (utente non iscritto) data: 08/08/2017 12:36:53

    Ciao a tutti,

    nel codice della sub ho aggiunto la funzione len() per capire quanti caratteri mi restituiva l'istruzione
    n = ActiveDocument.Bookmarks("NOME").Words(1).Text
    ed ho visto che la risposta era 5 caratteri. Quindi della stringa "Casa di Cura Pico de Paperis" mi cattura la parola "Casa" e lo spazio successivo, cioè "Casa ". Infatti il file salvato diviene "casa .pdf".
    Non so se questa informazione possa aiutare.
    Ho provato ad utilizzare len() anche sulla istruzione che dovrebbe essere corretta come
    n = ActiveDocument.Bookmarks("NOME").Range
    ma mi restituisce il valore zero. Proprio come se non vedesse il testo associato al segnalibro. O ho bisogno di riassociare tutta la stringa al segnalibro oppure il fatto che ci siano degli spazi vuoti tra le parole mette in crisi il discorso.






  • di Vecchio Frac data: 08/08/2017 14:05:42

    C'è qualcosa che non funziona nel file di Word originale, dovresti allegarlo per vederlo.
    Infatti ho creato, un documento nuovo, un lungo segnalibro di cinque parole, l'ho selezionato e gli ho assegnato un nome, poi in Immediata con ActiveDocument.Bookmarks("nome").Range ho ottenuto l'intero testo del segnalibro, spazi compresi.
    Ne deduco che il tuo segnalibro è impostato effettivamente come "Casa " e non come "Casa di Cura Pico de Paperis".
    Come vengono impostati i segnalibri: da codice o manualmente?





  • di David (utente non iscritto) data: 08/08/2017 14:31:13

    Salve Vecchio Frac,

    Ho allegato sia il file di Excel che quello di Word. Ho anche copiato la macro di Excel che mi permette di aprire in Word una lettera con del testo presente e di copiare i dati di alcune celle associandole ai segnalibri precedentemente inseriti (manualmente). La macro è molto sporca perché sto cercando varie vie d'uscita e quindi non è definitiva.

    Grazie e saluti

    David

     
    Sub Pulsante537_Click()
    
    'Dim ReplSel As Boolean
    Dim path As String
    Dim Stringa1 As String
    Dim Stringa2 As String
    Dim Stringa3 As String
    Dim Stringa4 As String
    
    path = ActiveWorkbook.path
    
    
    
    'On Error Resume Next 'gestione errori step by step
    'cerca istanza di Word già aperta
    'Set Wrd = GetObject(, "Word.Application")
    'Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
    
      
    '  PercorsoStandard = "C:"    'inserisci il percorso che desideri aprire di default
    
    'With fDialog
    '    .AllowMultiSelect = False
    '    .Title = "Cerca il file carta_intestata_SI_compilata.doc"
    '    .InitialFileName = PercorsoStandard
    
    '    If .Show = -1 Then
    '        For Each selezione In .SelectedItems
    '            FileDaAprire = selezione
    '            ActiveWorkbook.FollowHyperlink Address:=FileDaAprire
    '        Next
    '    Else
    '        MsgBox "Caricamento annullato!", vbInformation  'quanto premi ‘cancella’ la macro si stoppa
    '        Exit Sub
    '    End If
    'End With
    
    'If Err.Number = 429 Then
    'se c'è stato un errore è perchè Word non era già aperto:
    'aprilo adesso
    'Set Wrd = CreateObject("Word.Application")
    'End If
    'On Error GoTo 0 'ripristina la segnalazione degli errori
    
    Wrd.Visible = True
    Wrd.Activate
    
    'ReplSel = Wrd.Options.ReplaceSelection
    'Wrd.Options.ReplaceSelection = True
    
    Set Doc = Wrd.Documents.Open(path & "" & "carta_intestata_SI_compilata.doc")
    
    
    
    Stringa1 = Range("B3")
    Stringa2 = Range("F3")
    Stringa3 = Range("I10")
    Stringa4 = Range("B10")
    
    If Stringa1 & Stringa2 & Stringa3 & Stringa4 <> "" Then
    
    Doc.Bookmarks("NOME").Select     'nome del segnalibro
     Wrd.Selection.TypeText Range("B3").Value
    
    Doc.Bookmarks("Indirizzo").Select     'nome del segnalibro
     Wrd.Selection.TypeText Range("F3").Value
    
    Doc.Bookmarks("Contatto").Select     'nome del segnalibro
     Wrd.Selection.TypeText Range("I10").Value
    
    Doc.Bookmarks("RACC_EMAIL").Select     'nome del segnalibro
     Wrd.Selection.TypeText Range("B10").Value
    
    Else
    
    Exit Sub
    'Wrd.Close
    End If
    
    'Dim Wrd As Object
    ' Dim path As String
    ' Dim x As Integer
     
    ' path = ActiveWorkbook.path
     
    ' Set Wrd = GetObject(path & "" & "carta_intestata_SI_compilata.doc")
     
    ' Wrd.Application.Visible = True
    ' Wrd.Activate
     '
      
    ' Wrd.Bookmarks("NOME").Select
    ' Wrd.Bookmarks("NOME").Range = Range("B3").Value
     '
    ' x = Len(Range("B3").Value)
    ' Wrd.Bookmarks.Selection.MoveRight Unit:=wdCharacter, Count:=x, Extend:=wdExtend
    ' Wrd.Bookmarks.Add Range:=Wrd.Application.Selection.Range, Name:="NOME"
    
    
    
    
    'End Sub



  • di Vecchio Frac data: 08/08/2017 15:03:09

    Bene, prima di esmainar eil edit by VF: esaminare il codice Excel va sistemato il fatto che i segnalibri non funzionano come dovrebbero perchè in effetti nel file di Word sono solo dei puntatori a una locazione di zero caratteri.
    In finestra Immediata ho fatto questo semplice test che puoi replicare anche tu:
    for each b in activedocument.Bookmarks: ?b.name, b.Start, b.end: next
    e ho ottenuto l'elenco dei quattro bookmarks memorizzati dove si vede che il carattere di inizio e di fine coincidono: per esempio il segnalibro NOME inizia e termina al carattere numero 9 del testo (subito dopo Spett.le + tab, dove il tab è il nono carattere).
    Non mi hai detto come sono stati impostati questi segnalibri: se manualmente o se da codice.
    In ogni caso ogni segnalibro *non* ricomprende il testo cui vorresti che si riferisse. *Probabilmente* è in fase di riassegnazione del testo, che ogni volta fai manualmente, che si perde il riferimento al segnalibro (come ipotizzavo ieri).
    Comunque torno al consiglio che avevo già dato e cioè lasciar perdere i segnalibri di Word e impostare dei tuoi segnaposto che poi vai a sostituire con il testo recuperato dalla tabella Excel. vedrai che così diventa più semplice (non mi impelagherei nemmeno in una stampa unione, peraltro sarebbe più agevole dei segnalibri che comunque sono oggetti sempre misteriosi).





  • di Vecchio Frac data: 08/08/2017 15:11:28

    Nota en-passant: ho visto anche la relativa complessità del file di Excel e ti consiglio di riscrivere tutto il gestionale in Access, reportistica compresa (leggi composizione e generazione delle lettere ed invio delle mail), soprattutto se poi il file è condiviso e ci lavorano più persone.





  • di Vecchio Frac data: 08/08/2017 15:33:30

    Altra annotazione.
    Ho appena provato il pulsante "Carta Intestata" eccetera del foglio Excel: avvia Word e compila perfettamente i segnalibri impostati inserendovi correttamente i dati prelevati dalle celle Excel.
    Quindi può essere che quando tu fai la pulizia del file di Word per prepararlo alla nuova compilazione, sovrascrivi i segnalibri. Potresti quindi creare un modello di lettera (.dotx) e utilizzare questo per generare il nuovo documento (basato su modello), senza doverti poi preoccupare di ripulire il file usato come modello.

    Nel file Excel ho visto che utilizzi lo stesso codice con minime variazioni per spedire una mail: ti basta scriverlo una sola volta e richiamarlo passando in argomento i dati del destinatario). Memo codice, più facilità a manutenerlo e più leggibilità. Ci son tante altre cose da fare per sistemare il codice Excel, ma andiamo per gradi :)





  • di DAvid (utente non iscritto) data: 08/08/2017 15:34:32

    Salve ancora Vecchio Frac,

    I segnalibri erano stati inseriti manualmente.
    Ho assegnato i segnaposti nel file di word in questo modo: a (segnaposto1) con copia incolla ho inserito (@NOME). E così per gli altri. Nel menù riferimenti/citazioni infatti mi compare un menù a tendina con segnati segnaposto1, segnaposto2 ecc.
    Ti chiedo un aiuto in merito alla modifica della sub di copiatura celle. Che codice devo inserire e come mi devo comportare? Ho intuito che in pratica associ non più il segnalibro ma il segnaposto ed utilizzi la funzione replace per "sovrascrivere" il termine speciale col contenuto della cella. Ma come fare?
    Scusa il disturbo e grazie 1000.

    David

    P.S. Hai ragione a parlare di Access, ma in azienda ho avuto un po' di problemi a causa del file di Excel non partorito da me ma ereditato e non modificabile per problemi di estetica! Giuro!!!! Inoltre nell'ultimo mese mi hanno chiesto almeno 5/6 modifiche di vario genere che mi hanno incasinato. Quando si programma occorrerebbe avere uno schema a flussi o almeno una traccia che tenga conto di cosa si vuol fare ed i risultati che si vogliono ottenere. Ma qui mi sembra di essere in balia del vento. In più io non sono un programmatore ma ho programmato all'università l'ultima volta quasi 20 anni fa'. Con linguaggio macchina, l'assembler, TurboPascal, c, c++ ma oggi mi sento un ignorante. Ho appena scaricato un manuale di VBA che mi permetta di evitare almeno gli errori più grossolani quali assegnazioni di variabili, oggetti ed istruzioni.
    Sorry per lo sfogo e grazie ancora tante. Sia a te che a tutti quelli che "donano" il loro tempo per rispondere a chi come me si trova impelagato in queste faccende.

    David



  • di Vecchio Frac data: 08/08/2017 16:06:19

    Nel merito:
    la strada è quella che intuisci. Lascia perdere segnalibri e citazioni. Prepara un modello lettera .dotx dove nei punti "caldi" scrivi qualcosa che dovrà essere sostituito da altro testo: io dicevo @NOME ma nel file che faccio usare alla segreteria per esempio c'è [DATORE DI LAVORO] tra quadre, quindi libertà assoluta, basta che la convenzione ti sia chiara. Lo script Excel apre il modello Word, fa un Replace dei segnaposto che cerca e trova con .Find, quindi propone all'utente il file compilato, lo salva e lo invia allegato a una mail (o lo trasforma in PDF, non ricordo cosa ne devi fare).
    Appena riesco allego il codice da provare.

    Sullo sfogo:
    capisco bene e so che ci sono dinamiche aziendali di cui non possiamo fare a meno. Peccato perchè per un lavoro grosso come questo Access sarebbe la strada giusta. fermo restando che quando si ereditano lavori altrui poi bisogna spendere settimane a entrare nella logica dei predecessori e senza uno schema del progetto è dura :) Per gestire VBA e procedere passo passo sei nel posto giusto. Del resto non sei del tutto nuovo nell'ambiente e hai la tua bella esperienza (hai citato linguaggi ben più complessi di VBA).





  • di Vecchio Frac data: 08/08/2017 16:31:58

    Allego il tuo codice modificato (ho lasciato tutta la parte commentata relativa alla scelta del file da finestra di dialogo, magari è una funzionalità che devi implementare in seguito).
    Ti allego anche una piccola immagina di come devi sostituire nel file doc la parte dell'intestazione, così si capisce meglio come funziona il codice ("immagine.png").
    Nota che ogni segnaposto può essere in grassetto, sottolineato, grande, rosso eccetera e mantiene la formattazione dopo la sostituzione :)
     
    Option Explicit
    
    Sub Pulsante537_Click()
    Dim wdApp As Object, wdDoc As Object
    Dim ReplSel As Boolean
    Dim myPath As String
    
        myPath = ActiveWorkbook.path
        
        On Error Resume Next 'gestione errori step by step
        
        'cerca istanza di Word già aperta
        Set wdApp = GetObject(, "Word.Application")
        
        'Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
        
          
        '  PercorsoStandard = "C:"    'inserisci il percorso che desideri aprire di default
        
        'With fDialog
        '    .AllowMultiSelect = False
        '    .Title = "Cerca il file carta_intestata_SI_compilata.doc"
        '    .InitialFileName = PercorsoStandard
        
        '    If .Show = -1 Then
        '        For Each selezione In .SelectedItems
        '            FileDaAprire = selezione
        '            ActiveWorkbook.FollowHyperlink Address:=FileDaAprire
        '        Next
        '    Else
        '        MsgBox "Caricamento annullato!", vbInformation  'quanto premi ‘cancella’ la macro si stoppa
        '        Exit Sub
        '    End If
        'End With
        
        If Err.Number = 429 Then
            'se c'è stato un errore è perchè Word non era già aperto:
            'aprilo adesso
            Set wdApp = CreateObject("Word.Application")
        End If
        On Error GoTo 0 'ripristina la segnalazione degli errori
        
        ReplSel = wdApp.Options.ReplaceSelection
        wdApp.Options.ReplaceSelection = True
        
        Set wdDoc = wdApp.Documents.Open(myPath & "" & "carta_intestata_SI_compilata.doc")
        '(es:"C:personalefile.doc")
        
        wdApp.Visible = True
        
        With wdDoc.Content.Find
            .Execute FindText:="@NOME", ReplaceWith:=Range("B3"), Replace:=2    '2=wdReplaceAll
            .Execute FindText:="@INDIRIZZO", ReplaceWith:=Range("F3"), Replace:=2
            .Execute FindText:="@CONTATTO", ReplaceWith:=Range("I10"), Replace:=2
            .Execute FindText:="@RACC_EMAIL", ReplaceWith:=Range("B10"), Replace:=2
        End With
        
        wdApp.Options.ReplaceSelection = ReplSel
        
        'genera file pdf
        'exportformat: 17 = PDF
        'metti openafterexport := false per non aprire il pdf dopo la creazione
        wdDoc.ExportAsFixedFormat myPath & "OFFERTA " & Range("B3"), ExportFormat:=17, OpenAfterExport:=True
        
        MsgBox "Operazione completata", vbInformation
        wdDoc.Close False
        wdApp.Quit
        
        Set wdDoc = Nothing
        Set wdApp = Nothing
            
    End Sub
    
    
    






  • di David (utente non iscritto) data: 08/08/2017 20:14:54

    Grazie 1000 ancora Vecchio Frac,

    Il codice funziona alla grande ed evita i problemi dei segnalibri. Soluzione molto lineare e limpida. Ho soltanto messo gli apici alla chiusura di word perché i commerciali possono aggiungere altre righe di testo in manuale prima di salvare la lettera carta intestata.
    Ma adesso provo a ricoincolgere excel per dare il nome file dalla cella direttamente per ottenere il file pdf. E per rispondere alla tua domanda seguente la risposta è sì. Non so se sia megli utilizzare una casella di controllo cui far vista re i tipi di offerta inserire nella lettera di word o se farlo direttamente con una spunta sul figlio di excel. Devo prima associare alla spunta la selezione della cella o della tabella accanto e poi copiare la selezione su word. Grazie ancora e se hai qualche consiglio sei sempre bene accetto .
    David