Come variare una criterio in una query

di il
14 risposte

Come variare una criterio in una query

Buonasera,

ho una query che deve variare un criterio (WHERE) che è un identificativo stringa. Per variare il criterio non ho trovato di meglio che cancellare la precedente query e crearne una nuova con  le istruzioni rispettivamente db.querydefs.delete nomequery e set qd=db.createquerydef(nomequery,stringaquery). In questo modo poi apro il report e posso. stamparlo.

In una variabile z ho inserito l'identificativo stringa che di volta in volta viene modificato;  ma non riesco a modificare il parametro della query in vba.

Potete aiutarmi indicandomi l'istruzione querydefs per aggiornare solo l'identificativo? La query è modificabile ma non riesco a modificarla.

Grazie 

14 Risposte

  • Re: Come variare una criterio in una query

    Puoi impiegare una query parametrica in cui imposti da VBA i parametri senza la necessità, quindi, di cancellare e ricreare la query.
    https://learn.microsoft.com/en-us/office/client-developer/access/desktop-database-reference/parameters-declaration-microsoft-access-sql
    https://www.devhut.net/ms-access-vba-run-parameter-query-in-vba/
    https://www.universalclass.com/articles/computers/parameter-queries-in-microsoft-access-2013.htm
    http://etutorials.org/Microsoft+Products/access/Chapter+1.+Queries/Recipe+1.1+Specify+Query+Criteria+at+Runtime/
    https://www.filoweb.it/quaderno/501-Aprire-una-query-parametrica-da-codice-VBA-
    https://stackoverflow.com/questions/61366483/how-to-pass-parameters-to-query-from-another-query-in-ms-access-without-vba

    NB ma visto che parli di report non facevi prima a fornire la where conditions, direttamente quando lo apri.

  • Re: Come variare una criterio in una query

    01/05/2023 - willy55 ha scritto:


    NB ma visto che parli di report non facevi prima a fornire la where conditions, direttamente quando lo apri.

    Ciao Willy,

    io semplicemente modificavo in OpenReport il RecordSource del Report passando semplicemente la stringa Sql oppure il nome della Query

  • Re: Come variare una criterio in una query

    01/05/2023 - tatixtatix6 ha scritto:


    Buonasera,

    ho una query che deve variare un criterio (WHERE) che è un identificativo stringa. Per variare il criterio non ho trovato di meglio che cancellare la precedente query e crearne una nuova con  le istruzioni rispettivamente db.querydefs.delete nomequery e set qd=db.createquerydef(nomequery,stringaquery). In questo modo poi apro il report e posso. stamparlo.

    In una variabile z ho inserito l'identificativo stringa che di volta in volta viene modificato;  ma non riesco a modificare il parametro della query in vba.

    Potete aiutarmi indicandomi l'istruzione querydefs per aggiornare solo l'identificativo? La query è modificabile ma non riesco a modificarla.

    Grazie 

    Spiega meglio in quanto spesso si sottovaluta la possibilità di usare la proprietà FILTER di Form/Report che viene valorizzata usando il Parametro WHERE CONDITION su Chiamata OpenReport/OpenForm… 

  • Re: Come variare una criterio in una query

    Buonasera

    scrivo la routine:

    <

    Private Sub Comando55_Click()

    Dim Db As DAO.Database
    Dim qd As QueryDef
    Dim z As String
    Dim stringaquery As String
    Dim nomequery As String

    nomequery = "I0000_query_report"
    z = Me.Rda_numero

    Set Db = CurrentDb()

    Db.QueryDefs.Delete nomequery

    stringaquery = "SELECT I0000_Rda.Rda_numero, I0000_Rda.Data_rda, C0000_Societa.Nome_societa, A0000_B_Park.Nome, A0100_Lotti.Nome1, I2000_Ente_richiedente.Suffisso, I2000_Ente_richiedente.Ente, L0000_People.Nominativo, I3000_Spese_a_carico.Pagatore, I0000_Rda.Altro_rda, I0000_Rda.D_q1," & _
    "I0000_Rda.Testo_q1, I0000_Rda.D_q2, I0000_Rda.Testo_q2, I0000_Rda.D_q3, I0000_Rda.Testo_q3, I0000_Rda.D_q4, I0000_Rda.Testo_q4, I0000_Rda.Motivo_rda, B0010_FORNITORE.Nome_fornitore, I0000_Rda.Motivo_fornitore, I0000_Rda.Nr_1, I0000_Rda.Allegato_1, I0000_Rda.Nr_2, " & _
    "I0000_Rda.Allegato_2, I0000_Rda.Data_consegna_lavori, I0000_Rda.Collegamento_RDA FROM I0000_Rda, A0000_B_Park, A0100_Lotti, I2000_Ente_richiedente, L0000_People, I3000_Spese_a_carico, B0010_FORNITORE, C0000_Societa WHERE (((I0000_Rda.Rda_numero)= '" & z & "') AND " & _
    "((C0000_Societa.ID_Societa)=[I0000_Rda].[Societa]) AND ((A0000_B_Park.ID_BPark)=[I0000_Rda].[ID_Bparks]) AND ((A0100_Lotti.ID_Lotti)=[I0000_Rda].[Lotti]) AND ((I2000_Ente_richiedente.ID_ente_richiedente)=[I0000_Rda].[ID_Ente_Richiedente]) AND " & _
    "((L0000_People.ID)=[I0000_Rda].[Richiedente]) AND ((I3000_Spese_a_carico.ID_Spese_a_carico)=[I0000_Rda].[Scelta_fattur]) AND ((B0010_FORNITORE.ID_Fornitore)=[I0000_Rda].[Fornitore_rda]));"

    Set qd = Db.CreateQueryDef(nomequery, stringaquery)

    Me.Requery
    DoCmd.OpenReport "I0000_query_report", acViewReport, "", "", acNormal
       DoCmd.RepaintObject acReport, "I0000_query_report"

    Db.QueryDefs.Delete nomequery

    stringaquery = "SELECT I0000_Rda.Rda_numero, I0000_Rda.Data_rda, C0000_Societa.Nome_societa, A0000_B_Park.Nome, A0100_Lotti.Nome1, I2000_Ente_richiedente.Suffisso, I2000_Ente_richiedente.Ente, L0000_People.Nominativo, I3000_Spese_a_carico.Pagatore, I0000_Rda.Altro_rda, I0000_Rda.D_q1," & _
    "I0000_Rda.Testo_q1, I0000_Rda.D_q2, I0000_Rda.Testo_q2, I0000_Rda.D_q3, I0000_Rda.Testo_q3, I0000_Rda.D_q4, I0000_Rda.Testo_q4, I0000_Rda.Motivo_rda, B0010_FORNITORE.Nome_fornitore, I0000_Rda.Motivo_fornitore, I0000_Rda.Nr_1, I0000_Rda.Allegato_1, I0000_Rda.Nr_2, " & _
    "I0000_Rda.Allegato_2, I0000_Rda.Data_consegna_lavori, I0000_Rda.Collegamento_RDA FROM I0000_Rda, A0000_B_Park, A0100_Lotti, I2000_Ente_richiedente, L0000_People, I3000_Spese_a_carico, B0010_FORNITORE, C0000_Societa WHERE " & _
    "(((C0000_Societa.ID_Societa)=[I0000_Rda].[Societa]) AND ((A0000_B_Park.ID_BPark)=[I0000_Rda].[ID_Bparks]) AND ((A0100_Lotti.ID_Lotti)=[I0000_Rda].[Lotti]) AND ((I2000_Ente_richiedente.ID_ente_richiedente)=[I0000_Rda].[ID_Ente_Richiedente]) AND " & _
    "((L0000_People.ID)=[I0000_Rda].[Richiedente]) AND ((I3000_Spese_a_carico.ID_Spese_a_carico)=[I0000_Rda].[Scelta_fattur]) AND ((B0010_FORNITORE.ID_Fornitore)=[I0000_Rda].[Fornitore_rda]));"

    Set qd = Db.CreateQueryDef(nomequery, stringaquery)

    Me.Requery

    Db.Close
    Set Db = Nothing

    end Sub
    >

    La query è molto banale, è molto lunga perchè concatena molti campi. Prima viene cancellata, con

    Db.QueryDefs.Delete nomequery

    poi viene riscritta con la condizione che viene 

    z = Me.Rda_numero

    e senza ripetere  ….  WHERE (((I0000_Rda.Rda_numero)= '" & z & "') AND " & _……

    in questo modo la query ha un solo record poi apro il report in questo modo:

    DoCmd.OpenReport "I0000_query_report", acViewReport, "", "", acNormal
       DoCmd.RepaintObject acReport, "I0000_query_report"

    poi cancello e ripristino la query come all'inizio senza il fattore Z che la riduce a un record solo.

    Forse si puo' utilizzare un controllo sul report ma francamente non conosco bene i report.

    Grazie dell'aiuto

  • Re: Come variare una criterio in una query

    Fai come credi, ma quello che fai non serve a nulla, anzi…

    CANCELLI una query per rifarla uguale…? Cambi solo la where…?

    Ma secondo te ha senso…?

    Giusto per chiarezza ottieni lo stesso risultato, come ti ho suggerito, con solo 1 riga di codice, al posto di tutto quel pastone.

    Peraltro devi usare l'inserimento del codice usando il tasto nel menu affinché venga formattato.

    Prova a rifletterci

  • Re: Come variare una criterio in una query

    Ciao,

    concordo con @Alex

    Se mi posso permettere … quando si scrive un codice, oltre alla sostanza, si deve progettare in modo snello, rileggibile, etc... Chiunque e non solo l'autore, dovrà essere in grado, anche a distanza di poco tempo, di poterlo capire, leggerlo e modificarlo senza nessuna difficoltà… etc.

    Nella programmazione e scrittura del codice e, non meno importante, nella sua progettazione devono essere tenuti in considerazione alcuni aspetti fondamentali che si rifanno a degli standard. Questi vanno sempre rispettati per i motivi sopra citati.

    La tecnica è molto importante per ottenere flessibilità ed efficacia. 
    Nel tuo caso era semplicissimo impostare:

    1) un oggetto Query  da mettere nelle proprietà Origine Record, solo di comodo per progettare e costruire il report



    2) creare una routine che va in esecuzione su caricamento del  Report



    3) nella routine evento è sufficiente prendere la stringa Sql della query, semplificarla e personalizzarla per le proprie esigenze. 
    in questo esempio dalla Query denominata Qry_Demo che lavora sulla Tabella Anagrafica, si prende la stringa Sql e la si riporta nel codice

    Private Sub Report_Load()
    Me.RecordSource = "SELECT Anagrafica.* " & _
                     "FROM Anagrafica " & _
                     "WHERE Cognome Like '*Rossi*';"
    End Sub
    • Nella SELECT non è necessario elencare tutti i campi… si mette un * che per il 99,99% dei casi può andare bene
    • La WHERE si può personalizzarla a proprio piacimento passando una variabile che conterrà le condizioni volute
    • I passi del codice devono essere commentati per una maggiore comprensibilità

    4) Semplificare, descrivere, parametrizzare e flessibilità
    in questo esempio la stringa Where Condition viene imppstata sulla base del valore Tipo Ricerca impostato su vSearch che può assumere i valori 1,2 o 3 secondo il tipo di ricerca da effettuare e da filtrare sul campo Cagnome… per corrispondenza =, oppure che contenga Like, oppure per diverso <>… in questo caso si vuole filtrare il Cognome Rossi.

    ' SET RECORDSOURCE FOR THE REPORT
    Private Sub Report_Load()
    ' set conditions variable where
    Dim strWhere As String
    ' checks to set the where condition
    Select Case vSearch
       ' search matches exact
       Case 1
           strWhere = "Cognome = 'Rossi'"
       ' search it contains
       Case 2
           strWhere = "Cognome Like '*Rossi*'"
       ' find different values
       Case 3
           strWhere = "Cognome <> 'Rossi'"
    End Select
    ' set recordsource for the report
    Me.RecordSource = "SELECT Anagrafica.* FROM Anagrafica WHERE " & strWhere & ";"
    End Sub

    Altro sistema, se non sbaglio quello suggerito da @Alex, poi lui eventualmente mi correggerà, è quello di utilizzare la proprietà Filter
    Riprendendo il codice sopra riportato si semplifica nel seguente modo sostituendo la condizione WHERE con FILTER

    ' SET RECORDSOURCE FOR THE REPORT
    Private Sub Report_Load()
    ' check and set filter
    Select Case vSearch
       ' search matches exact
       Case 1
           Me.Filter = "Cognome = '" & strMySearch & "'"
       ' search it contains
       Case 2
           Me.Filter = "Cognome Like '*" & strMySearch & "*'"
       ' find different values
       Case 3
           Me.Filter = "Cognome <> '" & strMySearch & "'"
    End Select
    ' set filter
    Me.FilterOn = True
    ' set recordsource for the report
    Me.RecordSource = "SELECT Anagrafica.* FROM Anagrafica;"
    End Sub

    N.B. Vedi come la stringa Sql della Query è ulteriormente semplificata, stesso vale per il resto del codice dove Filter sostituisce la WHERE?
    Questo solo un piccolo esempio dove, come potrai capire, è ulteriormente parametrizzabile nella condizione Filter e il cognome, in questo caso Rossi, può essere passato con una Variabile, per esempio in strMySearch ... etc etc…

    Ma se la Query non deve essere modifica dal codice Vba nelle parti di Select From Join Union etc… allora non si rende necessario ricaricarla nella Proprietà Record Source. Pertanto si semplifica ulteriormente eliminando tale istruzione e si ottiene quanto segue:

    ' SET RECORDSOURCE FOR THE REPORT
    Private Sub Report_Load()
    ' check and set filter
    Select Case vSearch
       ' search matches exact
       Case 1
           Me.Filter = "Cognome = '" & strMySearch & "'"
       ' search it contains
       Case 2
           Me.Filter = "Cognome Like '*" & strMySearch & "*'"
       ' find different values
       Case 3
           Me.Filter = "Cognome <> '" & strMySearch & "'"
    End Select
    ' set filter
    Me.FilterOn = True
    End Sub

    Ovviamente e umilmente questi sono solo dei piccoli consigli …  poi ognuno ha i suoi metodi e tecniche.

  • Re: Come variare una criterio in una query

    No Franco ancora più semplice…!

    La query di base con tutti i RECORDS la si lascia standard compilata nel DB che è più performante, poi si usa la WHERECONFDITION di OpenForm/OpenReport, riporto la WHERE del post originale che non è completa ma così si capisce:

    DoCmd.OpenReport "nomeReport", , , "[I0000_Rda.Rda_numero]= '" & z & "'" ' eventaulmente altra condizione
    ' Attenzione che se il campo Rda_Numero è Numerico non servono gli apicetti

    Ora se la Form o il Report sono basati su quella Query BASE che mostra tutti i Records oppure una quota in quanto già presente la WHERE, passando al parametro OPENREPORT come mostrato, si concatenano i 2 Criteri in AND…

    Come dicevo 1 riga di codice.

  • Re: Come variare una criterio in una query

    03/05/2023 - @Alex ha scritto:


    No Franco ancora più semplice…!

    La query di base con tutti i RECORDS la si lascia standard compilata nel DB che è più performante, poi si usa la WHERECONFDITION di OpenForm/OpenReport, riporto la WHERE del post originale che non è completa ma così si capisce:

    DoCmd.OpenReport "nomeReport", , , "[I0000_Rda.Rda_numero]= '" & z & "'" ' eventaulmente altra condizione
    ' Attenzione che se il campo Rda_Numero è Numerico non servono gli apicetti

    Ora se la Form o il Report sono basati su quella Query BASE che mostra tutti i Records oppure una quota in quanto già presente la WHERE, passando al parametro OPENREPORT come mostrato, si concatenano i 2 Criteri in AND…

    Come dicevo 1 riga di codice.

    Ottimo !!!!   

  • Re: Come variare una criterio in una query

    Ciao a tutti 

    facendo tesoro dei consigli vi dico come ho risolto:

    <

    Private Sub Comando55_Click()

    Dim Db As DAO.Database

    Dim z As String

    z = Me.Rda_numero

    Set Db = CurrentDb()

    DoCmd.OpenReport "I0000_query_report", acViewReport, "", QueryDefs![I0000_query_report].Rda_numero = z, acNormal

       DoCmd.RepaintObject acReport, "I0000_query_report"

    Db.Close

    End Sub

    Molto meglio

    grazie di tutto

  • Re: Come variare una criterio in una query

    Ho visto che Alex ha scritto la soluzione che ho trovato io. In realtà non è mia, me l'ha suggerita Alex quando ha detto che si poteva fare con una sola riga e mi si è accesa la lampadina.

    Non è sembrare accondiscendente ma dare a Cesare quel che è di Cesare. Solo una considerazione, potevi suggerire prima la soluzione completa invece di farmi trovare oggi la soluzione al lavoro (non faccio il programmatore) che indirettamente mi hai suggerito.

    Tutto sommato  non mi sembra “pappa pronta”: era una istruzione. Poi dopo averla scritta hai addirittura suggerito di fare attenzione agli apici. Comunque ti ringrazio perchè il suggerimento mi ha indirizzato: sono andato a rivedere ieri a letto l'ultimo libro di Mike Davis (a letto). Stamane poi, come ripeto, ho provato la soluzione.

    Per quanto riguarda la complessità, la query in realtà è banalissima anche se lunga

    Comunque grazie a tutti. 

  • Re: Come variare una criterio in una query

    Ciao,
    ma il DAO Db e Current Db a che ti servono ?

    la dichiarazione della variabile z perchè la fai ?

  • Re: Come variare una criterio in una query

    Ciao Franco, 

    in realtà sono rimaste dentro. Per quanto riguarda z tendo sempre a definire le variabili. Devi sapere che solo da poco ho capito come scrivere un Report prendendo un solo valore da un oggetto. Anzi è il mio primo REPORT da quando programmo in Access. Sono appassionato di programmazione ma lavoro troppo per dedicarmi ad essa come vorrei. Ogni tanto faccio qualcosa per diletto. 

    Ora ho fatto un data base con i collegamenti a tebelle sul PC. Tra poco mi vorrei cimentare a mettere le tabelle  sul server. Mi vengono i brividi.

  • Re: Come variare una criterio in una query

    Niente di più semplice…  se sei neofita, di tanto in tanto bisogna sbatterci il naso ;))))

    Cmq quella variabile z non se po' vedè ;))
    Il codice che non serve si cancella ;))

    Se devi confrontare due stringhe carattere usare gli Apicini per racchiudere la variabile di confronto
    
    Private Sub Comando55_Click()
    DoCmd.OpenReport "I0000_query_report", acViewReport, , "Rda_numero='" & CStr(Me.Rda_numero) & "'", acNormal
    End Sub
    
    Se devi confrontare due campi numerici non usare gli Apicini 
    
    Sub Comando55_Click()
    DoCmd.OpenReport "I0000_query_report", acViewReport, , "Rda_numero=" & Me.Rda_numero, acNormal
    End Sub

    - se Me.Rda_numero è di tipo numerico lungo e il confronto è di tipo stringa carattere, allora basta usare Cstr per covertire in tipo stringa 
    - nella Where Condition, avendo già aperto l'oggetto Query, è sufficiente fare riferimento semplicemente al campo da condizionare
    - se il confronto avviene tra stringhe carattere userai racchiudere la tua variabile di confronto tra gli Apicini altrimenti se il confronto è numerico niente Apicini
    - nell'argomento Filter mettere il valore “” non serve… se non hai Filtri da impostare, allora non imposti nulla per tale argomento

  • Re: Come variare una criterio in una query

    Dimenticavo una cosa… ma il Repaint perchè lo fai ?

    03/05/2023 - tatixtatix6 ha scritto:


    DoCmd.RepaintObject acReport, "I0000_query_report"

Devi accedere o registrarti per scrivere nel forum
14 risposte