Problema Query StampaUnione

di il
15 risposte

Problema Query StampaUnione

Buongiorno,

ho notato un comportamento alquanto strano su un file al quale sto lavorando.

OrigineDati.accdb è un piccola database dove tengo alcuni dati che devono poi essere riportati in una StampaUnione di word.

La query della stampaUnione è la seguente:


sqlString = "SELECT * FROM [Tab1] ORDER BY [Nome] ASC"

dopodiché per sviluppare un pdf per ogni singolo record si è andati a cercare il numero dei record sui quali eseguire uno per uno l'esportazione del pdf:

'ci si posiziona sull'ultimo record
ActiveDocument.MailMerge.DataSource.ActiveRecord = wdLastRecord
'si conta quanti record ci sono
hmrecords = ActiveDocument.MailMerge.DataSource.ActiveRecord
'ci si posiziona sul primo record
ActiveDocument.MailMerge.DataSource.ActiveRecord = wdFirstRecord

   For i = 1 To hmrecords
	   [ecc...] ' esportazione
   next i

Ho provato a modificare la query di origine dati inserendo un filtro where:

sqlString = "SELECT * FROM [Tab1] WHERE [Aggiornato] = False ORDER BY [Nome] ASC"

ebbene ora il codice precedente non mi funziona più, o meglio funziona ma solo per il primo record che viene caricato; 
Senza WHERE, il file leggeva tutti i record, diciamo 80, con WHERE, il file a monitor si popola correttamente con solo i record filtrati, per esempio 10, ma hmrecord assume valore 1. e il ciclo for next si esaurisce dopo aver processato il primo record

?? come mai? 

ho provato a risolvere il mio problema utilizzando .RecordCount, ma mi riconta comunque tutti e gli 80 record al posto che i singoli 10 filtrati.

l'obiettivo sarebbe quello di snellire il file per farlo lavorare più velocemente e importare di volta in volta solamente i record interessati, perché attualmente il file sonda tutti i record e salta l'elaborazione del record per il quale [Aggiornato] = True; 

La soluzione sembra li a portata di mano, “basta far girare il ciclo for next per ogni record presente, dopo aver importato solo quelli necessari”…..eppure c'è qualcosa che non quadra.

Dove sto sbagliando? se riporto la query all'originale il problema non si presenta.

Grazie mille

Ciao

15 Risposte

  • Re: Problema Query StampaUnione

    Prova a porre WHERE [Aggiornato]=0 anziché WHERE [Aggiornato]=False.

  • Re: Problema Query StampaUnione

    Ma dove è l'apertura del recordset?

  • Re: Problema Query StampaUnione

    Ciao Antony73, purtroppo il problema non si risolve con il metodo suggerito;

    Ciao Stifone, ho riflettuto sulla tua domanda, suggerisci che in pratica non essendoci l'apertura di un recordset, word va in confusione e usa solo un record dell'origine dati? non ho mai inserito l'apertura del recordset nella stampa unione perché di per sè i record li importa già tutti e nell'anteprima i risultati li vedo (a monitor) effettivamente tutti.

    Grazie mille

    Ciao

  • Re: Problema Query StampaUnione

    E se è cosi a che ti serve impostare sqlString se poi non la usi?

  • Re: Problema Query StampaUnione

    Albino91:

    con WHERE, il file a monitor si popola correttamente con solo i record filtrati

    Non sono certo del suggerimento che sto per darti. Albino91, dici che a un certo punto sul monitor vedi i tuoi record filtrati. A questo punto potresti sfruttare il RecordsetClone da inserire con Set in una variabile rs di tipo Recordset. Dopo di che…For i=1…Next non va bene. Ti consiglio il ciclo:

    Do Until rs.EOF
    …serie di istruzioni…
    rs.MoveNext
    Loop

    Albino91:

    per esempio 10, ma hmrecord assume valore 1. e il ciclo for next si esaurisce dopo aver processato il primo record

    ?? come mai? 

    Come ho suggerito su, usa una variabile rs di tipo Recordset. Usa Do…Loop ricordandoti di usare l'istruzione rs.MoveNext appena prima di Loop.

  • Re: Problema Query StampaUnione

    Scusate sono stato assente per un po'.

    Antony73, la stringa sql viene utilizzata per assicurarsi che la sorgente dati e i filtri e l'ordinamento siano quelli predefiniti, e se non lo sono, che vengano ripristinati quelli voluti. Questo processo avviene come di seguito:

    SorgenteDati = MainDirectory & "Database.accdb"
    sqlString = "SELECT * FROM [Tab1] WHERE [Aggiornato] = False ORDER BY [Nome] ASC"
    
    If ActiveDocument.MailMerge.DataSource.Name <> SorgenteDati Then
       Call DefinireSorgenteDati(SorgenteDati, sqlStr)
    Else
    'RicontrollaSorgenteSQL:
       'Si controlla che i Filtri e l'Ordinamento siano stati impostati correttamete nonostante il nome della SorgenteDati sia corretto
       If ActiveDocument.MailMerge.DataSource.QueryString <> sqlStr Then
           Call DefinireSorgenteDati(SorgenteDati, sqlStr)
       Else
           'SorgenteDati + Filtri + Ordinamento già impostati correttamente
           'MsgBox ActiveDocument.MailMerge.DataSource.Name
           'Debug.Print ActiveDocument.MailMerge.DataSource.QueryString
       End If
    End If
    
    Sub DefinireSorgenteDati(SorgenteDati As String, sqlStr As String)
    ActiveDocument.MailMerge.OpenDataSource Name:=SorgenteDati, _
           ConfirmConversions:=False, ReadOnly:=False, LinkToSource:=True, _
           AddToRecentFiles:=False, PasswordDocument:="Inventata", PasswordTemplate:="Pure", _
           WritePasswordDocument:="", WritePasswordTemplate:="", Revert:=False, _
           Format:=wdOpenFormatAuto, Connection:= _
           "Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=" & SorgenteDati & _
           ";Mode=Read;Extended Properties="""";Jet OLEDB:System database="""";Jet OLEDB:Registry Path="""";Jet OLEDB:Engine Type=6;Jet OLEDB:Database Loc" _
           , SQLStatement:=sqlStr, SQLStatement1:="", SubType:=wdMergeSubTypeAccess
    End Sub

    OsvaldoLaviosa, grazie per il suggerimento. Da quello che capisco questo metodo mi permetterebbe di lavorare direttamente dalla form di access che apre il file di StampaUnione e definirne la query di origine dati usando la query definita dal campo origine dati della form.

    Non ho capito bene come settare il recordset ma leggo qualcos'altro faccio qualche prova e ti do riscontro.

    Intanto grazie mille

  • Re: Problema Query StampaUnione

    Indeciso se attendere o intervenire ulteriormente. Se un utente più esperto ha capito/colto cosa vuole fare Albino91…per favore si faccia avanti.
    Dal mio punto di vista…non ci ho capito nulla. Albino91 hai scritto vari codici VBA, in molti casi non c'è l'evento di partenza. Non riscontro nomi propri di maschera, controlli e conseguente procedura di stampa unione (che io conosco con tutt'altre modalità). Dici che qualcosa funziona…ma io…boh!
    Riprovo pazientemente un passo alla volta e rispondimi chiaramente alle seguenti domande (anche quelle che ti appaiono stupide/banali):
    1) Di cosa parla il database?

    2) Fornisci nomi propri di tabelle, tutti i loro campi, le relazioni

    3) 

    sqlString = "SELECT * FROM [Tab1] ORDER BY [Nome] ASC"

    [Tab1] è un nome troppo generico di tabella. Puoi contestualizzarlo dandogli un nome più “comprensibile”?

    4) Se usi una query, puoi provare a crearla davvero e dargli un nome proprio?

    5) 

    ActiveDocument.MailMerge.DataSource.ActiveRecord 

    Io non conosco questa istruzione. Puoi spiegarmela?

    6) Per capire come funziona la Stampa Unione, leggi qui
    combinare word e access (pierolucarelli.it)

    7) Per capire come funzionano i RECORDSET leggi qui (articolo scritto dall'utente “dragone bianco” nel forum MasterDrive)
    https://1drv.ms/w/s!ArJd2J5n5j_r2xlJvcmH__oz6oJ2?e=qieMMV

  • Re: Problema Query StampaUnione

    Premessa: i codici scritti fino ad ora sono scritti su word, nella macro “Aggiornamento”;

    Attualmente, da una maschera di access, alla pressione di un pulsante, si apre il file word di StampaUnione e si esegue la macro “Aggiornamento”, preciso che da vba di access si esegue la macro “Aggiornamento” scritta sul file word; fino ad ora è sempre stata così la struttura in quanto questo mi permetteva di esportare i pdf anche se il database non era completo e perché non sapevo bene come destreggiarmi nel a fare comunicare i due programmi, infatti spesso e volentieri aprendo il file word di stampa unione da access, il file si apriva due volte oppure mi si incasinava la query o mi dava altri errori che pian piano ho risolto. quindi ho sempre tenuto le cose separate. mi piacerebbe mantenerle separate, ovvero 

    - realizzare un file di StampaUnione di Word in cui nella macro “Aggiornamento” venga eseguito il codice che permette di esportare tutti i singoli pdf. Questo punto attualmente è operativo, "funziona", ha smesso di funzionare quando sono andato a fare le modifiche specificate nel primo post di questa discussione.

    - realizzare una form di access in cui tramite click si possa quindi eseguire la macro “Aggiornamento” del file Word, 

    - realizzare una form di access in cui tramite click su un pulsante si apra il file word e ne si esegua la macro “Aggiornamento” 

    oppure

    - realizzare una form di access in cui tramite click su un pulsante si compili già il file word tramite vba di access e non tramite il vba di word.

    Provo ora a descrivere spero con la massima precisione ciò che hai richiesto:

    1) è un database che serve da base dati per una stampa unione successiva, effettuata con word, per poter creare dei pdf, esportarli singolarmente in un percorso predefinito.

    2) non vorrei essere indiscreto ma preferirei girarti il link al fine di mantenere la discussione aperta, in quanto sono argomenti che ho trattato in un'altra discussione di cui ti giro il link
    https://www.iprogrammatori.it/forum-programmazione/access/realizzazione-query-t51433-30.html#p8701935
    in cui per l'appunto si crea la query nel database che contenga le informazioni necessarie.

    3) la query creata in precedenza al punto 2, di cui riporto l'sql

    "SELECT tabProdotti.CodiceProdotto, tabProdotti.DescrizioneProdotto, TabSingoloPezzoPkg.singoloPzPkg_descrizione, TabMateriale.materiale_descrizione, TabCodice.codice_descrizione, TabConferimento.conferimento_descrizione
    FROM TabCodice INNER JOIN (TabConferimento INNER JOIN (TabMateriale INNER JOIN (TabSingoloPezzoPkg INNER JOIN (tabProdotti INNER JOIN (Packaging_Cumulativa INNER JOIN tabProdPkg ON Packaging_Cumulativa.pk_id = tabProdPkg.idPackaging) ON tabProdotti.idProdotto = tabProdPkg.idProdotto) ON TabSingoloPezzoPkg.id_singoloPzPkg = Packaging_Cumulativa.pk_id_singoloPzPkg) ON TabMateriale.id_materiale = Packaging_Cumulativa.pk_id_materiale) ON TabConferimento.id_conferimento = Packaging_Cumulativa.pk_id_conferimento) ON TabCodice.id_codice = Packaging_Cumulativa.pk_id_codice;"

    4) la query ha effettivamente un nome; è stata creata in due versioni diverse, “querySelCumulativa” (query di selezione), “queryTabCumulativa ” (query di creazione tabella) per eventuali futuri sviluppi.

    5) spero tu non ti offenda, non l'ho capito bene nemmeno io questa parte di codice; ho provato a leggermi le guide ma il concetto di come l'ho utilizzato non mi è molto chiaro in ogni caso. È una istruzione legata al Word, spesso e volentieri, in molti esempi online la si trova in combo con LastRecord e FirstRecord. nel mio codice di word purtroppo non ho mai ben capito come facesse a funzionare, concettaulmente, poi vedevo i numeri che cambiavano, funzionava, era il primissimo codice che mi funzionava ed ero già oltre le mie limitatissime aspettative; ti riporto come viene utilizzato il codice nel mio progetto word:

    
    For i = 1 To hmrecords + 1
              With ActiveDocument.MailMerge
            .Destination = wdSendToNewDocument
            .SuppressBlankLines = True
                With .DataSource
                  .FirstRecord = i
                  .LastRecord = i
                  .ActiveRecord = i
    
    'istruzioni per esportare il singolo pdf con nome estratto da uno dei campi unione
    
    Next i

    6) grazie mille, questo link mi è già stato molto utile in passato per creare altri progetti

    7) grazie mille, questo link ha reso molto più chiari certi argomenti.

    Grazie mille

    Ciao

  • Re: Problema Query StampaUnione

    Il tuo thread abbraccia molti argomenti/problematiche che andrebbero affrontati uno per uno. 
    Innanzitutto hai detto che gestisci la maggior parte del codice di Word…almeno io non sono in grado di aiutarti da questo punto di vista. Preferisco partire e gestire tutto da Access. Prova a leggere questo esempio che io ho creato in un mio database
    Stampa unione
    https://1drv.ms/w/s!ArJd2J5n5j_r5WDHt7y07_l6Mtq3?e=aMIzP7
    cerca di prendere solo quello che serve a te.

    Riguardo il link alla discussione che hai indicato…ricordo di aver rinunciato a partecipare. Ho trovato la struttura troppo caotica…non ci ho capito molto…mi sono fermato.

  • Re: Problema Query StampaUnione

    Grazie mille,

    sto facendo alcune prove ma mi trovo in difficoltà in quanto sembrerebbe che word non riesca a riconoscere 

    Dim db as DAO.Database 
    Dim rs as DAO.Recordset

    errore: tipo definito dall'utente. tipo non definito

    Nonostante la libreria Microsoft ActiveX Data Objects sia abilitata.

    ???

  • Re: Problema Query StampaUnione

    Sei certo sia la Libreria che stai usando in Access…?

    Premetto che non ho letto tutto, ma in Access stai usando DAO magari e non ADO…?

    i 2 Oggetti non sono compatibili ovviamente.

  • Re: Problema Query StampaUnione

    Urca che svista, hai ragione.

    quindi ora ho impostato 

    Dim conn As ADODB.Connection
    Dim adoRS As ADODB.Recordset
    Set conn = New ADODB.Connection
    Set adoRS = New ADODB.Recordset
    Con = "Provider=Microsoft.ACE.OLEDB.12.0;"
    Con1 = Con & "Data Source=" & MainDirectory & "Database.accdb"
    
    adoRS.Open strSQL, Con1
    

    Per iterare il codice attraverso il recordset, solo se il numero dei record è > di 0, ho provato a trovare il numero di record importati tramite

    TotRecord = adoRS.RecordCount

    ma TotRecord prende valore di -1 nonostante hmrecords identifichi correttamente 4 record:

    ActiveDocument.MailMerge.DataSource.ActiveRecord = wdLastRecord
    hmrecords = ActiveDocument.MailMerge.DataSource.ActiveRecord
    ActiveDocument.MailMerge.DataSource.ActiveRecord = wdFirstRecord
    UltimoRecord = ActiveDocument.MailMerge.DataSource.RecordCount
    hmrecords = wdFirstRecord * (-1) '

    quindi il ciclo 

    Do Until adoRS.EOF 
    'codice per la esportazione del singolo record in pdf
    adoRS.MoveNext

    non comincia nemmeno

    ho provato a usare 

    adoRS.MoveFirst 
    adoRS.MoveLast 

    ma mi viene restituito errore di compilazione prevista function o variabile; non sto capendo il perché.

    Grazie mille

    Ciao

  • Re: Problema Query StampaUnione

    23/03/2023 - Albino91 ha scritto:


    mi trovo in difficoltà in quanto sembrerebbe che word non riesca a riconoscere 

    Dim db as DAO.Database 
    Dim rs as DAO.Recordset

    errore: tipo definito dall'utente. tipo non definito

    DAO è una libreria di Access. 
    DAO.Database stai dichiarando una variabile di tipo Database
    DAO.Recordset stai dichiarando una variabile di tipo Recordset.

    Sono tutti concetti strettamente legati a Access. Word non c'entra.

    Il documento di dragone bianco che ti ho suggerito parla dei DAO.Recordset. Usa quelli. Io ADO non l'ho mai usato e non so nemmeno cosa sia.
    I recordset si usano per prendere in considerazione un recordset (ossia un insieme di record…quindi siamo dentro Access). Ogni record deve dare in pasto valori dei singoli campi al tuo documento Word che deve accogliere i propri Bookmark. Il ciclo Do Until rs.EOF…Loop ti serve per ciclare tutti i record, ricordando di mettere sempre un rs.MoveNext appena prima di Loop.

    ActiveDocument.MailMerge.DataSource.ActiveRecord = wdLastRecord
    hmrecords = ActiveDocument.MailMerge.DataSource.ActiveRecord
    ActiveDocument.MailMerge.DataSource.ActiveRecord = wdFirstRecord
    UltimoRecord = ActiveDocument.MailMerge.DataSource.RecordCount
    hmrecords = wdFirstRecord * (-1) '

    Butta via questo set di istruzioni.

  • Re: Problema Query StampaUnione

    La proprietà RecordCount non si aggiorna se non aggiorni il Bookmark … devi fare un MoveLast e subito un MoveFirst vedrai che poi leggi la proprietà valorizzata correttamente.

Devi accedere o registrarti per scrivere nel forum
15 risposte