Mail merge da excel



  • Mail merge da excel
    di roberto21 data: 25/03/2013 10:08:25

    Sono alle prese con il problema di attivare da excel un semplice mail merge, per stampare una copia di una form letter già predisposta con i campi giusti, chiamando la macro con un preciso valore del record da stampare.
    Premetto di aver già implementato la cosa senza usare il mail merge, usando invece una copia della form letter con i segnalibri (bookmarks) al posto dei campi, e sostituendo i segnalibri uno alla volta con il valore dei campi. Ma, per mia curiosità e anche perchè la tecnica del mail merge appare più adatta e più elegante. Ho trovato del codice da adattare, e ci ho provato, finendo dritto in difficoltà impreviste. Notare che il mail merge da word con lo stesso file excel di dati usato in queste prove non dà alcun problema.

    Il codice è riportato sotto. Descrivo i problemi, cercando di essere chiaro.
    Il file word (FormLetter) viene aperto senza problemi. A questo punto viene eseguita l'istruzione di OpenDataSource che dovrebbe agganciare il file excel al file word. Questo file si chiama Book1Test.xlsx, nel suo sheet1 è definito il range ElencoCompleto. Il file book1test si trova nella stessa directory della formletter (e del file excel contenente questa macro: ecco il motivo di str=this.workbook.path). Quando l'istruzione viene eseguita, la macro si ferma e aspetta. Che cosa? nella finestra della formletter di word è apparso un dialogo che si aspetta un nome di tabella: Select Table. Nel riquadro grande non c'è niente, nel menu a tendina dei workbook sono elencati i workbook presenti nella cartella Documenti, che è quella parent di quella contenente i files della prova. In ogni caso, non posso fare nient'altro che Cancel, e interrompere il tutto. E' chiaro che ci deve essere un errore nella opendatasource, ma mi sfugge.
    Aggiungo una cosa che a me pare strana. Fra le tante prove, ho provato a creare una copia di book1test.xlsx in modalità excel2003, come book2test.xls. Eseguendo con questo file, il dialogo Select Table di word compare sempre, ma stavolta nel riquadro è presente il nome del range ElencoCompleto, e nel menu a tendina dei workbook sono presenti i workbook della cartella corretta, incluso Book1test e Book2test. Stavolta posso dare ok, la macro prosegue ma...stampa TUTTI i record, non solo quello che pensavo di avere selezionato.

    Mi piacerebbe capire che cosa sta succedendo e dove sbaglio. I siti da dove ho rimediato il codice che ho modificato non menzionano problemi del genere...Grazie a tutti in anticipo per le spiegazioni
    Roberto
     
    Sub PrintLetter2(numerorecord As Integer)
    
    On Error GoTo ErrorHandler
    
    ' open template in Word
    Dim str As String
    Dim WordApp As Word.Application
    Dim WordDoc As Word.Document
    
    Set WordApp = CreateObject("Word.Application")
    str = ThisWorkbook.Path
    Debug.Print str, numerotessera
    
    With WordApp
        .Visible = True
        Set WordDoc = .Documents.Open(str & "formletter.docx")
    End With
    'MailMerge selected records from table to Word document
    
        WordDoc.MailMerge.OpenDataSource Name:=str & "Book1test.xlsx", _
        ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=False, AddToRecentFiles:=False, _
        PasswordDocument:="", PasswordTemplate:="", WritePasswordDocument:="", _
        WritePasswordTemplate:="", Revert:=False, Format:=wdOpenFormatAuto, _
        Connection:=str & "Book1test.xlsx", _
        SQLStatement:="SELECT * FROM [ElencoCompleto] WHERE [Numero record] = numerorecord", _
        SQLStatement1:=""
        
    'send merged document into new Word document
    
        WordDoc.MailMerge.Destination = wdSendToPrinter
        WordDoc.MailMerge.Execute
    
    'close without saving
    
        WordDoc.Close SaveChanges:=False
    
    
    ErrorHandlerExit:
    Exit Sub
    ErrorHandler:
    If Err = 429 Then
    'word is not running; open word with CreateObject
    Set appWord = CreateObject(Class:="Word.Application")
    End If
    
    End Sub



  • di Vecchio Frac data: 25/03/2013 10:51:37

    Ciao Roberto, sapevo che prima o poi arrivavi con questo quesito :)
    Io ti farei un po' di osservazioni:
    - non chiamare una variabile locale con il nome di una funzione predefinita (in particolare, "str": serve ad altri scopi)
    - se in Excel hai referenziato la libreria di Word non serve CreateObject, puoi fare direttamente
    Set WordApp = New Word. Application
    (questo per evitare confusioni tra early e late binding)
    - se viceversa non vuoi referenziare in Excel la libreria di Word (cosa legittima), evita di riferirti alle costanti intrinseche di Word e utilizza i corrispondenti valori numerici:
    WordDoc.MailMerge.Destination = wdSendToPrinter
    deve diventare
    WordDoc.MailMerge.Destination = 1
    (in caso di *non* referenziazione della libreria di Word)

    Credo comunque che hai scritto male il parametro SQLStatement nell'OpenDataSource, dove specifichi il numero di record da stampare:
    SQLStatement:="SELECT * FROM [ElencoCompleto] WHERE [Numero record] = " & numerorecord
    (altrimenti scritto dentro le virgolette diventa parte della stringa e non viene assegnato il corrispondente valore, ma sono sicuro che lo sai e che questo è solo un errore di distrazione ^_^)






  • di roberto21 data: 26/03/2013 10:53:27

    E' certamente un errore di distrazione, ma mim era sfuggito completamente, in quanto ero alle prese con problemi seri di "word has stopped working" come spiego più avanti. Sistemandom la chiamata SQL il problema sembra sparito: diciamo che era non immediato collegare causa ed effetto... (cerco di consolarmi invano per la mia stupidità).
    Invece trovo strano quanto sege. Il file Book1test contiene solo nello sheet1 una tabella, che per motivi di facilità di gestione è stata definitaprima come range (ElencoCompleto) e poi come tabella (tabella1) per sfruttare la pèroprietà della tabella di allargarsi automaticamente quando aggiungi records: sulla tabella è in fatti basata una seri di tabelle pivot che in questo modo riesco ad aggiornare senza ridefinire il range di base.
    Orbene, nei vari siti dove hopescato il codice si tende a fare riferimento sempre allo workshhet, come ad es. SQL select * from sheet1$ where... o anche connection := sheet1$. Quando ho usato questo sistema mi son beccato "microsoft word has stopped working", seguito da tentativi di recovery e finalment da "an error prevented word fom working correctly, windows will quit the application and notify you of possiblke solutions" o qualcosa di simile. Questo accade anche se il riferimento è a tabella1, non accade (come nell'esempio) se il riferimento è al range name. La stessa cosa accade anche senza la macro, ossia direttamente vda word, tentando di agganciare dal file principale word (formletter) il file excel nelle varie modalità.
    Riuscire a gestire il mailmerge è giàò una vittoria, questò è un problem secondario, ma per curiosità mi piacerebbe sapere se ci sono regole per agganciare il file excel...

    Grazie dei consigli e della pazienza, sei gentilissimo
    Roberto



  • di Vecchio Frac data: 26/03/2013 11:44:58

    Sarò sincero, questa mi mancava e mi sembra una cosa molto ganza:
    cit. " per sfruttare la proprietà della tabella di allargarsi automaticamente quando aggiungi records"
    Ma poi ho visto che lavori su Excel 2010 e tutto si spiega (io sono fermo a Excel 2003 ^_^)

    Sul segno di dollaro alla fine del foglio/tabella di lavoro, è vero che quando mi connetto a Excel via ADO si deve specificare il segno di dollaro (mai saputo perchè). Sulle cause che ogni tanto (spesso) portano i prodotti Office (soprattutto Access) a inchiodarsi senza scampo con il funereo "ha smesso di funzionare", queste sono talmente tante e varie che è impossibile darti una ragione completa.
    Per dirti, una volta ho cancellato file di estensione exd in una certa infima sotto sotto sotto cartella di Dati Applicazioni e magicamente lo stesso file Access problematico partiva regolarmente. Salvo poi ricrearsi quei file e inchiodarsi di nuovo l'applicativo ^_^

    Regole per agganciare il file Excel... un bel recordset ADO e via a riempire i segnalibri di Word :) (estremizzo)