mailmerge wordexcel



  • mailmerge word/excel di roberto21 data: 16/06/2017 14:42:37

    Tempo fa ho scritto una sub per stampare una lettera word con dati di una tabella excel (primo pezzo di codice), e tutto funzionava. Dovendo realizzare una cosa simile, ho pensato bene di copiare il codice pari pari, cambiando solo i nomi dei files (secondo pezzo di codice). Per qualche motivo, non funziona pi nulla. Tutto si blocca sulla istruzione OpenDataSource: sul mio pc, word va in crash, e quindi excel va in errore di runtime (automation), "remote procedure call failed". Provando su altri pc, word non va in crash, ma si ferma chiedendo il nome della tabella relativa a uno strano workbook il cui nome pathname.xls (p.es. il nome appare come c:users obertodocuments.xls, mentre dovrebbe essere c:users obertodocuments icevute.xlsm). Ammesso che qualcosa non quadri sul mo pc, anche se ho reinstallato office senza risultato, pare strano tutto il comportamento. E' cambiato qualcosa nel meccanismo di passaggio dei parametri o nelle chiamate?
    Notare che facendo il mailmerge a mano con gli stessi files, tutto funziona perfettamente.
     
    Sub PrintLettera2(numerotessera As String)
    'Mail merge e stampa su stampante di default
    
    'On Error GoTo ErrorHandler
    
    ' open template in Word
    Dim filepath As String
    Dim WordApp As Word.Application
    Dim WordDoc As Word.Document
    Set WordApp = New Word.Application
    filepath = ThisWorkbook.Path
    Debug.Print filepath, numeroricevuta
    With WordApp
        .Visible = True
        Set WordDoc = .Documents.Open(filepath & "Lettera Nuovi Soci.docx")
    End With
    'MailMerge selected records from table to Word document
    With WordApp
        .ActiveDocument.MailMerge.OpenDataSource Name:=filepath & "" & ThisWorkbook.Name, _
            ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
            AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
            WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
            Format:=wdOpenFormatAuto, _
            SQLStatement:="SELECT * FROM `rangesoci` WHERE [Numero Tessera] =" & numerotessera, SQLStatement1:="", _
            SubType:=wdMergeSubTypeAccess
        With .ActiveDocument.MailMerge
            .Destination = wdSendToPrinter
            .SuppressBlankLines = True
                          
            With .DataSource
                .FirstRecord = wdDefaultFirstRecord
                .LastRecord = wdDefaultLastRecord
            End With
            .Execute Pause:=False
        End With
               
    End With
    
    WordDoc.Close SaveChanges:=False
    WordApp.Quit
    End Sub
    
    *************
    
    Sub PrintRicevuta(numeroricevuta As String)
    'Mail merge e stampa su stampante di default
    
    'On Error GoTo ErrorHandler
    
    ' open template in Word
    Dim filepath As String
    Dim WordApp As Word.Application
    Dim WordDoc As Word.Document
    Set WordApp = New Word.Application
    filepath = ThisWorkbook.Path
    Debug.Print filepath, numeroricevuta
    With WordApp
        .Visible = True
        Set WordDoc = .Documents.Open(filepath & "stamparicevuta.docx")
    End With
    'MailMerge selected records from table to Word document
    With WordApp
        .ActiveDocument.MailMerge.OpenDataSource Name:=filepath & "" & ThisWorkbook.Name, _
            ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
            AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
            WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
            Format:=wdOpenFormatAuto, _
            SQLStatement:="SELECT * FROM `rangericevute` WHERE [Numero] =" & numeroricevuta, SQLStatement1:="", _
            SubType:=wdMergeSubTypeAccess
        With .ActiveDocument.MailMerge
            .Destination = wdSendToPrinter
            .SuppressBlankLines = True
                          
            With .DataSource
                .FirstRecord = wdDefaultFirstRecord
                .LastRecord = wdDefaultLastRecord
            End With
            .Execute Pause:=False
        End With
               
    End With
    
    WordDoc.Close SaveChanges:=False
    WordApp.Quit
    End Sub


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

    Eccoti qua
    Il problema che dobbiamo ricostruirci tutto lo scenario (modello Word, base dati, percorsi) per fare test affidabili, e ci vuole un po' di tempo.
    L'unica cosa certa che non "E' cambiato qualcosa nel meccanismo di passaggio dei parametri o nelle chiamate? ".
    Per sicurezza comunque dicci su quali versioni di Word e Excel stai lavorando (magari cambiato davvero qualche oggetto interno particolare al mailmerge).

    edit: vedo adesso che hai specificato "Office 2010"


  • di roberto21 data: 16/06/2017 18:59:06

    Ben ritrovato. Guarda, questo codice per stampare le ricevute talmente banale (e corto) che posso anche spedirvelo tutto. Il punto che fatto sulla falsariga del precedente, ben pi complicato, che continua a funzionare perfettamente. Non riesco a capire che cosa ci sia di diverso, continuo a provare e vi faccio sapere.


  • di Vecchio Frac data: 16/06/2017 19:49:24

    Non il codice in s il punto, ma probabilmente la base dati (o il riferimento a qualche collegamento mancante)


  • di roberto21 data: 16/06/2017 22:55:08

    Ho scoperto (un po' per caso) che se la stringa sql fatta cos
    "SELECT * FROM `Ricevute$`"
    Word non va in crash e la procedura va fino in fondo. Ovviamente, questo non mi va bene, perch non mi servono TUTTI i record, ma solo uno, quello che individuo con il WHERE. Inoltre, Ricevute il nome del worksheet contenente la tabella delle ricevute (nome: Table1), ma se metto Table1 o Table1$ al posto di Ricevute, word torna a crashare. Inserendo WHERE, word va in crash comunque. Non capisco se il problema stia proprio qui, ma ho provato (non esagero) decine di combinazioni, e word va in crash sempre, tranne che con quella stringa...


  • di Vecchio Frac data: 17/06/2017 12:00:52

    Io so che il dollaro $ si mette alla fine dei qualificatori dei fogli quando si lavora con ADO per connettersi a tabelle appunto su Excel. Il range specifico si inserisce dopo il $ ad esempio: SELECT * FROM [Foglio1$A1:A100] (probabilmente funziona anche con un range definito: "SELECT * FROM [Foglio1$myTable]").
    Particolarmente bizzarro che Word crasha comunque e non dovrebbe in ogni caso.
    Riesci a fornirmi una base dati d'esempio e il modello della lettera?
    L'alternativa abbandonare la stampa unione e far fare tutto a Excel (il modello documento avr dei segnaposto che verranno sostituiti al momento della creazione della lettera con un find/replace).


  • di roberto21 data: 17/06/2017 12:58:32

    Ti ho spedito sia il docx che il xlsm. E' tutto l.
    Vorrei precisare una cosa che non del tutto chiara. Semfaccio il mail merge da word a mano, indico come sorgente dati excel il foglio ricevute.xlsm. Word mi apre il dialogo confirm data source, indicando come open data source "OLE DB Database files". Dando Invio, Woprd mi chiede di Seledt Table, ma nell'elenco ci sono solo i nomi dei worksheet (FoglioIniziale, Ricevute, Sheet3) e non Table1 come mi aspetterei. Scelgo Ricevute, e proseguo (la tabella individuata comunque, anche se il nome non compare).
    Se invece di OLE dB scelgo EXCEL files via ODBC, word crasha; scegliendo Excel files via DDE, vien fuori "named or cell range": Entire spreadsheet: anche in questo caso, proseguendo, la tabella viene individuata, ma datasource l'intero workbook.Ho provato ad inserite nell'opensourcedata il parametro Connection relativo all'OLE, ma word crasha ugualmente.


  • di roberto21 data: 17/06/2017 18:57:28

    Ciao. Con questa enne+unesima prova, il marchingegno funziona. Non mi chiedere perch, vorrei saperlo anch'io, anche tenendo conto che l'altro programma funziona senza fare tante storie e senza tante complicazioni. Il gioco delle parti fra il SELECT (FROM nome dello worksheet) e CONNECTION (nome del range) non mi chiaro e non mi convince. Dubito di essere all'uscita del tunnel, comunque cos funziona.
     
    Sub PrintRicevuta(numeroricevuta As String)
    'Mail merge e stampa su stampante di default
    
    'On Error GoTo ErrorHandler
    
    ' open template in Word
    Dim filepath, SQLStmt, WorkbookName As String
    Dim WordApp As Word.Application
    Dim WordDoc As Word.Document
    Set WordApp = New Word.Application
    filepath = ThisWorkbook.Path
    WorkbookName = ThisWorkbook.FullName
    Debug.Print filepath, numeroricevuta
    With WordApp
        .Visible = True
        Set WordDoc = .Documents.Open(filepath & "stamparicevuta.docx")
    End With
    SQLStmt = "SELECT * FROM `Ricevute$` WHERE [Numero] = " & numeroricevuta
    'MailMerge selected records from table to Word document
    With WordDoc
        With .MailMerge
            .MainDocumentType = wdFormLetters
            .OpenDataSource Name:=WorkbookName, _
            ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
            AddToRecentFiles:=False, PasswordDocument:="", PasswordTemplate:="", _
            WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
            Format:=wdOpenFormatAuto, Connection:="rangericevute", _
            SQLStatement:=SQLStmt, SQLStatement1:="", _
            SubType:=wdMergeSubTypeAccess
       
            .SuppressBlankLines = True
                          
            With .DataSource
                .FirstRecord = wdDefaultFirstRecord
                .LastRecord = wdDefaultLastRecord
            End With
            .Destination = wdSendToPrinter
            .Execute Pause:=False
        End With
               
    End With
    
    WordDoc.Close SaveChanges:=False
    WordApp.Quit
    End Sub
    


  • di Vecchio Frac data: 18/06/2017 18:41:55

    Io l'ho fatta pi semplice e ho provato con la soluzione che avevi scartato (ma che hai ripreso nel secondo esempio) e cio
    SQLStmt = "SELECT * FROM [ricevute$] WHERE [Numero] =" & numeroricevuta

    e funzionava perfettamente (l'unica cosa strana che ho fatto aver cancellato l'origine dati dal foglio word).
    Per le mie prove poi ho impostato l'uscita a nuovo documento invece che a stampante, ma penso che sia ininfluente.
    Vedo che hai messo
    .OpenDataSource Name:=WorkbookName
    ma puoi anche lasciare il path cpmpleto con:
    .OpenDataSource Name:=ThisWorkbook.FullName
    .
    Ti prego poi di dimenticarti la sub auto_open che non si usa pi da qualche migliaio di anni (usa l'evento Workbook_Open() al suo posto) ^_^
    Comunque, benvenuto nel misterioso mondo dei programmi che da una parte funzionano senza problemi e dall'altra, stesso scenario, danno mille incomprensibili problemi :)


  • di roberto21 data: 19/06/2017 15:06:16

    OK, grazie mille. Pare che usando [Ricevute$] nel FROM non occorra la clause Connection:=rangericevute che avevo messo io. Rimane il mistero del perch il "vecchio" codice non funzioni (quello includeva solo FROM `rangesoci`), ma per il momento un problema minore, basta che funzioni.
    Grazie, e "keep on the good work", come dicono gli anglofili.


  • di Vecchio Frac data: 19/06/2017 15:49:46



    (s, sembra strano anche a me, posso solo ipotizzare versioni di Word diverse, ma pazienza)