none
Afficher dans un sous-formulaire (Access) la liste de résultat d'une requête paramétrée dont les paramètres sont issus de deux cases à cocher

    Question

  • Bonjour tout le monde, J'ai une question en VBA pour ACCESS 2010 concernant un sous-formulaire, une requête paramétrée, et deux cases à cocher pour les paramètres de la requête. l'objectif étant d'afficher dans le sous-formulaire le résultat de la requête après le changement d'état de l'une ou l'autre des cases à cocher.

    J'ai converti en VBA la macro qui donne le résultat suivant mais celle-ci ouvre un onglet pour me présenter les résultats. J'aimerai savoir comment faire pour que ce résultat s'affiche dans un sous formulaire de la même fiche que les cases à cocher.

    DoCmd.SetParameter "Voulez-vous les mouvements ", Forms!NEWFILTRES!FiltreMouvements
    DoCmd.SetParameter "Voulez-vous les justifications", Forms!NEWFILTRES!FiltreJustifications
    'DoCmd.OpenQuery ne permet pas de choisir la destination
        DoCmd.OpenQuery "RequêteFiltresMouvementsJustifications", acViewNormal, acEdit
          
    Merci,

    Cent souci à résoudre. Moins un, est un souci de moins mais un autre prend sa place. Tout en gardant le sou rire.

    • Moved by ArgyronetMVP, Moderator Tuesday, May 29, 2012 1:07 PM 0045303e-3afb-4615-87a0-b0cc65374b50 (Origine :Développement VBA)
    Saturday, May 26, 2012 9:15 AM

Answers

  • Oui, je sais mais F1 ou un moteur de recherche peut être aussi votre allié...

    Bon, je me fends d'un exemple de fonction :

    Public Function CreerRequete(ByVal NomRequete As String, ByVal SQL As String, Optional ByRef RetourneEnregistrements As Boolean) As Boolean
    Dim oQDF                                                    As DAO.QueryDef
    Dim oRS                                                     As DAO.Recordset
    
        On Error GoTo CreerRequete_Error
        On Error Resume Next
        Set oQDF = CurrentDb.CreateQueryDef(NomRequete, SQL)
        If Err <> 0 Then
            Set oQDF = CurrentDb.QueryDefs(NomRequete)
            oQDF.SQL = SQL
        End If
    
        On Error GoTo CreerRequete_Error
        Set oRS = CurrentDb.OpenRecordset("SELECT * FROM [" & NomRequete & "]", 2)
        With oRS
            With oRS
                RetourneEnregistrements = Not .EOF
                .Close
            End With
        End With
        CreerRequete = True
        On Error GoTo 0
    CreerRequete_Exit:
        Set oQDF = Nothing
        Exit Function
    CreerRequete_Error:
        CreerRequete = False
        Resume CreerRequete_Exit
    End Function

    que vous pouvez utiliser comme suit

    CreerRequete "Ma requêtes","SELECT * FROM Clients WHERE Ville = 'London';", blnEnregistrements


    Argy

    Monday, June 04, 2012 7:45 AM
    Moderator

All replies

  • Bonjour,

    Pour ma part, vous ne prenez pas la bonne direction dans le sens où il faut, dans la mesure du possible, éviter de passer des valeurs de contrôles de formulaire dans les requêtes sous cette forme. Il est préférable de manipuler la requête avec un objet QueryDef. Là, soit vous créez la requête n'existe pas (CreateQueryDef) soit vous modifiez sa propriété SQL si elle existe déjà.

    L'objet Recordset lecteur du résultat de la requête peut renvoyer alors les données dans le formulaire.


    Argy

    Tuesday, May 29, 2012 1:13 PM
    Moderator
  • Merci de me présenter l'erreur, mais j'aurai bien apprécié la correction. Du genre syntaxe. Je vais étudier le QueryDef. Merci pour votre participation.

    Cent souci à résoudre. Moins un, est un souci de moins mais un autre prend sa place. Tout en gardant le sou rire.

    Saturday, June 02, 2012 8:59 AM
  • Oui, je sais mais F1 ou un moteur de recherche peut être aussi votre allié...

    Bon, je me fends d'un exemple de fonction :

    Public Function CreerRequete(ByVal NomRequete As String, ByVal SQL As String, Optional ByRef RetourneEnregistrements As Boolean) As Boolean
    Dim oQDF                                                    As DAO.QueryDef
    Dim oRS                                                     As DAO.Recordset
    
        On Error GoTo CreerRequete_Error
        On Error Resume Next
        Set oQDF = CurrentDb.CreateQueryDef(NomRequete, SQL)
        If Err <> 0 Then
            Set oQDF = CurrentDb.QueryDefs(NomRequete)
            oQDF.SQL = SQL
        End If
    
        On Error GoTo CreerRequete_Error
        Set oRS = CurrentDb.OpenRecordset("SELECT * FROM [" & NomRequete & "]", 2)
        With oRS
            With oRS
                RetourneEnregistrements = Not .EOF
                .Close
            End With
        End With
        CreerRequete = True
        On Error GoTo 0
    CreerRequete_Exit:
        Set oQDF = Nothing
        Exit Function
    CreerRequete_Error:
        CreerRequete = False
        Resume CreerRequete_Exit
    End Function

    que vous pouvez utiliser comme suit

    CreerRequete "Ma requêtes","SELECT * FROM Clients WHERE Ville = 'London';", blnEnregistrements


    Argy

    Monday, June 04, 2012 7:45 AM
    Moderator
  • Bonjour Argyronet,

    J'espère que vous ne me tiendrai pas trop rigueur de ce qui va suivre.

    L'option F1 est trop, trop, peu descriptive, démunie de l'essentiel (que faire avec, quel résultat, comment l'exploiter) en d'autres termes, il y a beaucoup, beaucoup plus de réponses depuis un moteur de recherche. MAis pour mon cas et celui d'autres personnes ce sujet et très mal expliqué.

    J'ai pesé comme j'ai pu pour bien faire comprendre le besoin. Simple de par l'avis d'un utilisateur ayant ce besoin (qui sous Transact-SQL ou visual studio ne pose aucun problème) trouve que l'aspect access permet de modéliser de très agréable états sans effort.

    J'ai révisé en évitant les fautes de votre modèle . Mais comment l'associer entre la réactivité des cases à cocher et la mise à jour du sous-formulaire.

    Je vous présente un modèle de programmation qui demande moins de ligne mais dont je n'arrive pas à mettre à jour le formulaire.

    J'espère vivement que vous apprécirez les critiques, car ceux sont elles! Qui nous rendent meilleurs.

    Donc voilà mon modèle (qui fonctionne mais sans réaction du sous-formulaire Me.Fille12)

    ' case à cocher deux états (false ou true)

    Private Sub FiltreMouvements_Click() 'convertion en integer pour soulager la sub FiltreResult If FiltreResult(FiltreMouvements.Value * -10 + FiltreJustifications.Value * -1) = False Then _ FiltreMouvements.Value = Not FiltreMouvements.Value End Sub ' case à cocher deux états (false ou true)

    Private Sub FiltreJustifications_Click() 'convertion en integer pour soulager la sub FiltreResult If FiltreResult(FiltreMouvements.Value * -10 + FiltreJustifications.Value * -1) = False Then _ FiltreJustifications.Value = Not FiltreJustifications End Sub

    ' fonction réactive selon case à cocher retournant un éventuel abandon

    Private Function FiltreResult(check As Integer) As Boolean On Error GoTo fin: 'ReqSource pour référence à la requête souhaitée 'ReqDestination pour référence à la requête rattachée au sous-formulaire Dim ReqSource, ReqDestination As DAO.QueryDef Select Case check Case 0: Set ReqSource = CurrentDb.QueryDefs("ReqMouvNon_JustiNon") Case 1: Set ReqSource = CurrentDb.QueryDefs("ReqMouvNon_JustiOui") Case 10: Set ReqSource = CurrentDb.QueryDefs("ReqMouvOui_JustiNon") Case 11: Set ReqSource = CurrentDb.QueryDefs("ReqMouvOui_JustiOui") Case Else: GoTo fin End Select Set ReqDestination = CurrentDb.QueryDefs("ReqResult") ReqDestination.SQL = ReqSource.SQL Me.Fille12.Requery

    'Même avec Me.Refresh c'est néant (le parent rafréchit les enfants)

    FiltreResult = True fin: Set ReqSource = Nothing Set ReqDestination = Nothing End Function

    Dans le Select Case les requêtes peuvent être appellées individuellements selon les cas d'autres formulaires

    Le nom des requêtes est siginficatif pour la clause WHERE de la même table ( dont le détail est sans importance).

    Comment rafraichir Me.Fille12 après avoir corriger ReqResult ?

    D'autres part, accidentellement j'ai trouvé la remarque << 'Me.Fille12.Form.InputParameters >>

    qui m'interpelle sur ma question de départ. Je fouille pour bien comprendre.

    J'espère pouvoir compter sur votre soutient, à bientôt j'espère.


    Cent souci à résoudre. Moins un, est un souci de moins mais un autre prend sa place. Tout en gardant le sou rire.


    Rappel : termes commençant par Req voulant dire Requête intégrante à la bdd.



    • Edited by CentSoucis Thursday, June 07, 2012 10:34 PM
    Thursday, June 07, 2012 9:40 PM
  • Bonjour,

    J'adhère aux critiques, aucun soucis. D'ailleurs ce n'en sont pas.

    Bref, ce que je vous ai sugéré est dynamique et ne nécessite qu'une seule requête. Imaginez 30 secondes que vous ayez 50 cas différents...  avec votre méthode, vous aurez 50 requêtes !!! Et moi, une.

    Par ailleurs,, je vous préconise vivement un peu de lecture sur la convention de nommage des objets; tout objet doit être préfixé pour une meilleure lisibilité d'une part et doit être correctement déclaré. Req ne désigne donc pas un objet requête par définition de convention.
    De plus, comme beaucoup d'autres, lorsque vous écrivez :

    Dim ReqSource, ReqDestination As DAO.QueryDef

    vous croyez que vos 2 variables sont de type QueryDef eh bien non ; la première est Variant, la seconde est un QueryDef.
    Il faut écrire :

    Dim oReqSource As DAO.QueryDef
    Dim oReqDestination As DAO.QueryDef
    

    Donc sur le principe, c'est du coté de la méthode Requery coté Parent et de l'événement Current coté Enfant que vous devez agir et ce quelque soit votre choix.

    Dans le formulaire parent :

    Private Sub cmdRafraichir_Click()
     
        If FiltreResult(Nz(Me!FiltreJustifications, False)) Then
            Me.Fille12.Requery
        Else
            MsgBox "Aucune entrée trouvée pour ces critères !", 64
        End If
    End Sub
    
    Private Function FiltreResultat(ByVal Coche As Integer) As Boolean
    Dim SQLRequete                                  As String
    Dim SQLWhere                                    As String
    
        On Error GoTo L_ErrFiltreResult
        SQLRequete = "SELECT *, [Liste des champs souhaités] FROM LaTable "
        Select Case Check
            Case 0: SQLWhere = "WHERE [Mouv]= 'Non' AND [Justi] = 'Non';"
            Case 1: SQLWhere = "WHERE [Mouv]= 'Non' AND [Justi] = 'Oui';"
            Case 10: SQLWhere = "WHERE [Mouv]= 'Oui' AND [Justi] = 'Non';"
            Case 11: SQLWhere = "WHERE [Mouv]= 'Oui' AND [Justi] = 'Oui';"
            'On force l'impossibilité...
            Case Else: SQLWhere = "WHERE 1 = 0;"
        End Select
        CreerRequete "reqMouvementJusti", SQLRequete & SQLWhere, EnrTrouves
        FiltreResultat = EnrTrouves
        On Error GoTo 0
    L_ExFiltreResult:
        Exit Function
    
    L_ErrFiltreResult:
        FiltreResultat = False
        Resume L_ExFiltreResult
    
    End Function
    

    et dans le formulaire enfant :

    Private Sub Form_Current()
        Me.RecordSource = "reqMouvementJusti"
    End Sub

    Profitez de l'occasion pour nommer correctement votre sous-formualire : Fille12 est aussi parlant de Modifiable147 ou Texte192 !!!

    Avez-vous suivi ?

    P.S. J'ai intentionnellement supposé des noms de champs, de table et de contrôles, il vous appartiendra d'adapter


    Argy

    Friday, June 08, 2012 8:00 AM
    Moderator
  • Bonjour Argy,

    J'ai pris note de la leçon et je tenai à vous répondre avant l'étude des conventions de nommage que je vais respecter. Pour ce qui est des variables entre suivit de virgule, je ne savai pas. MAis il me semble qu'en Visual basic elles sont toutes du même type (je vérifierai çà ultérieurement).

    Je comprends bien votre méthode mais si chacune des requêtes sont employées distinctement, il faudrait reproduire le code (SELECT ...) dans toutes les situations (risque d'erreur important).

    Remplacer ces quatres méthodes par une seule ayant des paramètres c'est l'idéal. MAis là où ça coince c'est la mise à jour du sous-formulaire en fonction des deux cases à cocher.

    J'ai repéré (accidentellement)   sousFormulaire.Form.InputParameters que j'ai besoin de vérifier son utilisation qui pourrer bien faire l'affaire. Je l'espère.

    Je vous souhaite un très bon dimanche Monsieur Argy et je reviens nourrir cette discussion dès que j'ai des arguments et de profiter du nommage conventionné des objects .

    A bientôt Michel.

    A au fait, c'est cool votre état d'esprit.


    Cent souci à résoudre. Moins un, est un souci de moins mais un autre prend sa place. Tout en gardant le sou rire.

    Saturday, June 09, 2012 9:35 AM