Query in MS Access

di il
8 risposte

Query in MS Access

Buongiorno a tutti,

qui ci sono dei  Maestri, ecco perchè spero di essere fortunato e di ricevere attenzione :)

Ms Access 2007, Windows 10

Devo correlare fra loro due tabelle con campi similari, riferite a una terza tabella con il campo chiave, per ottenere una vista complessiva che tenga conto di eventuali valori Null dove i dati non sono correlati. Chissà se si può fare.

Il contesto: un piccolo gestionale dove ricevo e registro dei documenti, poi li smisto agli utenti (assegnando la pratica) e li invio via mail. Le informazioni registrate sono nominativo e data di assegnazione/smistamento, nominativo e data di trasmissione mail. Le tabelle coinvolte sono tre:

  • tabella dei documenti (qui interessa l'id del documento sottoposto alle operazioni di assegnazione/smistamento e trasmissione)
  • tabella dello smistamento (contiene id del documento cui è correlata, data e nome dell'assegnatario)
  • tabella della mailbox (contiene id del documento cui è correlata, data e nome del destinatario mail)

Vorrei una vista che, dato uno specifico id documento, per ogni nominativo mi mostri in una colonna la data di smistamento e in un'altra colonna la data di trasmissione mail. Sempre se esistono.

tabella documenti

id_docoggettothumbnail
1000

tabella smistamento

id_docnominativodata
1000topolino10/07/2024
1000pluto15/07/2024

tabella mailbox

id_docnominativodata
1000topolino10/07/2024
1000papeirno10/07/2024

Vorrei il risultato seguente:

Per id doc = 1000:

nominativodata smistamentodata trasmissione mail
topolino10/07/202410/07/2024
paperino 10/07/2024
pluto15/07/2024 

Io non ci sono riuscito. Il massimo che sono riuscito a fare è una query che fonde in una colonna smistamento e mailbox, distinguendo nel dato se trattasi di (S)mistamento o (M)ailbox:

select nominativo, 'S: ' & data as movimento
  from tbsmistamento
  where dataproteusid = 1000
union all
select destinatario, 'M: ' & data as movimento
  from tbmailbox
  where dataproteusid = 1000
nominativomovimento
TopolinoS: 15/07/2024
PlutoS: 15/07/2024
TopolinoM: 10/07/2024
PaperinoM: 15/07/2024
Q1

Altri tentativi orribili e infruttuosi, che coinvolgono alcuni Join, mi vergogno a pubblicarli. Comunque non ottengo il risultato voluto. Risultato che poi mi serve per scorrere il recordset risultante e sistemare i dati in modo coerente dentro una Listview che… ma questo so farlo :)

In conclusione, se avete avuto la pazienza di arrivare fin qui, grazie in anticipo a chi può o vuole darmi un'indicazione (sempre se si può fare).

8 Risposte

  • Re: Query in MS Access

    Io non ho capito molto la struttura che usi…

    La tabella Documenti è la Master(Lato 1 con PK=Id_Doc immagino) e le 2 Tabelle (Smistamento e Mailbox) sono lato M, con Chiave Esterna Id_Doc..?

    Questi dettagli magari devi darli…

    In ogni caso con la UNION no ottieni nulla di certo, devi fare una Query con un JOIN tra i Campi [Nominativo] tra le 2 Tabelle lato M, ed un JOIN con la Tabella Documenti su ID_DOC… non sapendo cosa è Pk e cosa non lo è, se hai Indici o meno… butto li una query solo a titolo di esempio:

    SELECT mailbox.ID_DOC, mailbox.Nominativo, mailbox.Data AS DataMail, tbsmistamento.Data AS datasmistamento
    FROM documenti INNER JOIN (tbsmistamento INNER JOIN mailbox ON tbsmistamento.Nominativo = mailbox.Nominativo) ON 
    (documenti.ID_DOC = mailbox.ID_DOC) AND (documenti.ID_DOC = tbsmistamento.ID_DOC);
  • Re: Query in MS Access

    30/07/2024 - @Alex ha scritto:


    Io non ho capito molto la struttura che usi…

    Grazie Alex. Confidavo in un tuo interessamento :)

    Mi dispiace di essere stato lacunoso, ero convinto di aver fornito un quadro complessivo comprensibile.

    La tabella Documenti è master con chiave primaria su id_doc (intero lungo). Questo id_doc fa ovviamente da chiave per le due tabelle separate (smistamento e mailbox), su due campi interi lunghi. Il resto dei campi interessati è di tipo Text(255).

    Poichè molti sono gli utenti cui possono essere smistati o inviati i documenti, la relazione è uno a molti, per entrambe le tabelle. Ho indicizzato solo la tabella dei documenti (su id_doc) e non le altre due tabelle (secondo me non serve: sono finalizzate solo a recuperare i record correlati).

    L'esempio che proponi è buono ma ottengo come risultato solo il nominativo che è contemporaneamente presente sia in tabella smistamento che in tabella mailbox. Non fatico a credere perchè, dal momento che l'And pone questo vincolo. Purtroppo correggendo con Or ottengo che l'espressione Join non è supportata.

    Comunque non è che con una query UNION non ottengo nulla “di certo”, un risultato accrocchiato lo ottengo, ma poi deve essere interpretato riga per riga. A questo punto posso rassegnarmi a fare due query semplici, una per tabella, e scorrere i due recordset che ne derivano, ma volevo provare a fare tutto in una volta. 

  • Re: Query in MS Access

    30/07/2024 - vecchio frac ha scritto:


    Grazie Alex. Confidavo in un tuo interessamento :)

    Mi dispiace di essere stato lacunoso, ero convinto di aver fornito un quadro complessivo comprensibile.

    La tabella Documenti è master con chiave primaria su id_doc (intero lungo). Questo id_doc fa ovviamente da chiave per le due tabelle separate (smistamento e mailbox), su due campi interi lunghi. Il resto dei campi interessati è di tipo Text(255).

    …..

    Purtroppo gli utenti presenti nel forum spesso hanno basi e concetti tecnici non così solidi e scontati… meglio non lasciare queste cose all'interpretazione.

    Ho capito, quello che vuoi nello specifico lo puoi ottenere solo con una TempTable ed una routine VBA che cicla estrae i records e riempie la temptable, sono poche righe di codice… ma se hai l'esigenza è la soluzione.

    P.S. in questo caso ad esempio conviene indicizzare i campi Nominativo e Destinatario, in quanto le query dovranno filtrare non solo per FK ma anche per Nominativo e/o Destinatario quando andrai a cercare la corrispondenza nell'altra tabella e l'uso degli indici è fondamentale in questi casi.

  • Re: Query in MS Access

    30/07/2024 - @Alex ha scritto:


    lo puoi ottenere solo con una TempTable ed una routine VBA

    30/07/2024 - @Alex ha scritto:


    Purtroppo gli utenti presenti nel forum spesso hanno basi e concetti tecnici non così solidi e scontati… meglio non lasciare queste cose all'interpretazione.

    +1

    Immagino che tu abbia capito. Accogliendo il suggerimento ho fatto così, con qualche lieve modifica per adattare tutto al contesto. 

    Sub test()
    Dim s As String
        
        With CurrentDb
            s = "CREATE TABLE tmp (nominativo VARCHAR(255), sm_data DATETIME, mb_data DATETIME); "
            .Execute s, dbFailOnError
            s = "INSERT INTO tmp SELECT nominativo, data as sm_data FROM tbSmistamento WHERE id_doc=1000;"
            .Execute s, dbFailOnError
            s = "INSERT INTO tmp SELECT destinatario as nominativo, data as mb_data FROM tbMailbox WHERE id_doc=1000;"
            .Execute s, dbFailOnError
        End With
            
    End Sub

    Il risultato è questo:

    nominativosm_datamb_data
    Topolino10/07/2024
     
    Pluto15/07/2024
     
    Topolino
     
    10/07/2024
    Paperino
     
    10/07/2024
    tmp

    che risponde abbastanza bene alla richiesta (un successivo scorrimento di questa tabella mi permette di recuperare i valori giusti dei campi giusti e di inserirli nei Subitems corretti della Listview di destinazione). 

    Non è esattamente come avevo immaginato di ottenere ma presumo che non si può sempre ottenere tutto.

    Grazie della tua pazienza.

  • Re: Query in MS Access

    Non usrerei il CREATE TABLE, basta creare la Tabella a mano e poi usarla.

    Non usrerei poi le altre 2 Actions Queries, ma il VBA con 2 Cicli.

    Primo ciclo sulla Tabella nominativo, in cui vai ad inserire nella TempTable Id_Doc/Nominativo e sm_data, quì sei sicuro che nella TempTable non ci siano già records quindi nessun controllo.

    Secondo ciclo sulla Tabella tbMailbox, ma prima vai a cercare, con FindFirst nella TempTable se Nomuinativo esiste già, se esiste vai in edit sul campo mb_data, altrimenti se NoMatch è False inserisci il Record che non era presente…

    In questo modo ottieni esattamente il risultato che hai chiesto.

  • Re: Query in MS Access

    Sembrerebbe una master/detail dove la detail è divisa in due tabelle legate 1 a 1

    Il campo in comune è iddoc.

    Select * from A

    Inner join B on A.iddoc=B.iddoc

    Where iddoc=[parametro]

    A:  Select* from documenti

    B: Select * from smistamento 

         inner join mailbox on         

          ismistamemto.ddoc=mailbox.iddoc

  • Re: Query in MS Access

    30/07/2024 - @Alex ha scritto:


    Non userei il CREATE TABLE, basta creare la Tabella a mano e poi usarla.

    L'esempio era solo per… esempio, pero' il resto del tuo ragionamento mi piace molto anche se a questo punto potrei cavarmela riempiendo Array o Dizionari senza smanettare su tabelle e recordset. Il punto sulla query era per imparare qualcosa di strano =)

    30/07/2024 - sihsandrea ha scritto:


    Sembrerebbe una master/detail dove la detail è divisa in due tabelle legate 1 a 1

    Le due tabelle di dettaglio non son legate fra loro. Hanno solo un campo in comune con la tabella principale che contiene l'id del documento di cui si vuol conoscere la storia (smistamento per assegnazione e trasmissione mail).

    Grazie per l'interessamento.

  • Re: Query in MS Access

    30/07/2024 - vecchio frac ha scritto:


    30/07/2024 - @Alex ha scritto:


    Non userei il CREATE TABLE, basta creare la Tabella a mano e poi usarla.

    L'esempio era solo per… esempio, pero' il resto del tuo ragionamento mi piace molto anche se a questo punto potrei cavarmela riempiendo Array o Dizionari senza smanettare su tabelle e recordset. Il punto sulla query era per imparare qualcosa di strano =)

    Innanzitutto Access non gestisce nativamente i Dictionary ed eviterei di referenziare una libreria per questo… magari usa una Collection che consente l'uso di Key di ricerca anche se rende la collection più lenta, ma probabilmente meglio dell'array in questo caso…

    Tuttavia questa soluzione che potrebbe avere un senso, io uso spesso array e collection ma con le classi che non espongono graficamente dati, poi ti inibisce una qualsivoglia possibilità di rappresentazione visuale, servirebbe una FlexGrid da popolare con la collection… ed onestamente buonsenso vuole che sia meglio la temptable nell'economia globale.

    In ogni caso ora a mio avviso hai centrato la strada è giusto sperimentare e valutare la soluzione più efficiente e funzionale.

Devi accedere o registrarti per scrivere nel forum
8 risposte