IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Access Discussion :

Code VBA à implanter sous Access 2010 [AC-2010]


Sujet :

Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur Mécanique
    Inscrit en
    Juillet 2015
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 31
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Mécanique
    Secteur : Transports

    Informations forums :
    Inscription : Juillet 2015
    Messages : 12
    Par défaut Code VBA à implanter sous Access 2010
    Bonjour à tous,

    Je crée en ce moment même une base de données, et j'ai besoin d'une requête récursive un peu lourde qui doit passer par un code VBA sous ACCESS 2010.

    J'ai trouvé ce merveilleux code, dans une conversation de ce forum

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Public Sub compter(idpiece As String, idPieceACompter As String, ByRef QtteTotal As Integer, Optional nb As Integer = 1)
      '
      Dim qdf As DAO.QueryDef
      Dim rcs As DAO.Recordset
      '
       QtteTotal = QtteTotal + _
            nb * Nz(DLookup("[Quantite]", "COMPOSITION", "[ComposantId]='" & idpiece & "' AND [ComposeId]='" & idPieceACompter & "'"), 0)
     
      ' ici j'utilise une requête enregistrée et paramétrée, nommée "RSelect" dont voici le SQL:
      ' PARAMETERS [Référence pièce ?] Text ( 12 );
      ' SELECT COMPOSITION.ComposeId, COMPOSITION.Quantite
      ' FROM COMPOSITION
      ' WHERE COMPOSITION.ComposantId = [Référence pièce ?] ;
      '
      Set qdf = CurrentDb.QueryDefs("RSelect")
          qdf.Parameters("[Référence pièce ?]") = idpiece
     
      Set rcs = qdf.OpenRecordset
     
      If Not rcs.EOF Then
        rcs.MoveFirst
            Do While Not rcs.EOF
                If rcs.Fields(0) <> idPieceACompter Then
                  Call compter(rcs.Fields(0), idPieceACompter, QtteTotal, rcs.Fields(1)) ' <==appel récursif
                End If
            rcs.MoveNext
            Loop
      End If
     
      Set qdf = Nothing
      Set rcs = Nothing
     
    End Sub
    qui est apellée par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Sub appel()
    Dim qt As Integer
    '
    qt = 0
        Call compter("aile", "rivet", qt)         ' réponse: 183
        ' Call compter("aileron", "rivet", qt)    ' réponse: 13
        ' Call compter("train", "rivet", qt)      ' réponse: 20
        ' Call compter("aile", "charniere", qt)   ' réponse: 5
     
    MsgBox (qt)
    '
    End Sub
    Donc mon problème est de savoir très précisément comment implanter cette macro VBA sous Acess 2010, car ça m'a l'air un peu figé. Des captures d'écrans seraient les bienvenues

    Merci à tous d'avance !!!

  2. #2
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 218
    Billets dans le blog
    16
    Par défaut Ailes, rivets, récursivité, Access vba, macros et tout ça...
    Bonsoir develalex,


    J’ai retrouvé du code VBA que j’avais développé il y a environ un an pour m’entraîner. Ce code pourrait être rendu moins verbeux, mais j’ai déjà supprimé plein d’instructions servant à des choses qui ne nous concernent pas ici.

    Pour récupérer ce code (ou tout autre !) :

    Dans la barre de menus, cliquer sur l’onglet « Database Tools » (désolé pour les termes, je n’ai que la version 2013 et angloricaine d’ACCESS... ) :







    Cliquer sur l’icône « Visual Basic » : on entre dans l’univers VBA (bien sombre ) :






    Pour arriver à amorcer la pompe, on clique sur l’icône qui va bien (« Insert Module ») :





    Fiat lux ! On a droit maintenant de créer des instructions :






    Coller le code VBA (que je fournis un peu plus loin).





    Avant d’exécuter le code, créer les tables COMPOSANT (équivalente de la table COMPOSITION de mon message précédent) et PILE (table temporaire, dans laquelle on empile les comptages) :

    COMPOSANT
    {EnsembleId varchar, EnsembleParent varchar, Quantite integer}
    KEY {EnsembleId, EnsembleParent} ;

    PILE
    {PileId autonumber, Niveau integer, EnsembleId varchar, EnsembleParent varchar, Quantite integer}
    KEY {Niveau EnsembleId, EnsembleParent} ;

    Les fonctions et procédures présentes dans le code VBA :

    Une fonction (AilesRivetsRecursonsAmorce()) permet d’amorcer la pompe ; elle passe la main à une procédure récursive (AilesRivetsRecursonsJoyeusement) qui compte les composants (exemple, les rivets) du composé (exemple, l’aile).


    Code VBA :

    
    Option Compare Database
    Option Explicit
    
    '-------------------------------------------------------------------------
    '   Amorce du comptage
    '-------------------------------------------------------------------------
    
    Function AilesRivetsRecursonsAmorce()
    
    Dim MaBase As DAO.Database
    Dim Amorce As Integer, LeComposé As String, LeComposant As String, TotalOut As Integer
    
    Set MaBase = CurrentDb
    
    Amorce = 1
    LeComposé = "aile"
    LeComposant = "rivet"
    
    ' Initialisation de la pile utilisée pour les récursions
    MaBase.Execute "DELETE FROM PILE ;"
    
    'C'est parti pour compter les rivets !
    Call AilesRivetsRecursonsJoyeusement(Amorce, LeComposé, LeComposant, TotalOut)
     
     AilesRivetsRecursonsAmorce = TotalOut
     
    ' Au résultat
     MsgBox " Composé : " & LeComposé & Chr(13) & Chr(13) _
            & "Nombre total d'éléments du type " & LeComposant & " : " & TotalOut
    
    
    MaBase.Execute "DELETE FROM PILE ;"
    
    Set MaBase = Nothing
     
    End Function
    
    '-------------------------------------------------------------------------
    '   Routine récursive
    '-------------------------------------------------------------------------
    
    Sub AilesRivetsRecursonsJoyeusement(ByRef Amorce As Integer, ByVal LeComposé As String, ByVal Composant As String, ByRef TotalOut As Integer)
    
    Dim MaBase As DAO.Database, Sqlresult As DAO.Recordset
    Dim Kount As Integer, Requete As String, theNiveau As Integer
    
    Set MaBase = CurrentDb
    
    Requete = "SELECT COUNT(*) AS Kount FROM PILE ;"
    Set Sqlresult = MaBase.OpenRecordset(Requete, dbOpenDynaset)
    Kount = Sqlresult.Fields("Kount")
    
    If Kount = 0 Then
        theNiveau = 1
    Else
        Requete = "SELECT DISTINCT MAX(Niveau) AS MaxNiveau FROM PILE ;"
        Set Sqlresult = MaBase.OpenRecordset(Requete, dbOpenDynaset)
        theNiveau = Sqlresult.Fields("MaxNiveau").Value + 1
    End If
    
    If Amorce = 1 Then
        
        Requete = "INSERT INTO PILE (EnsembleId, EnsembleParent, Quantite, Niveau) VALUES ('" & LeComposé & "', 0, 0, 1) ;"
        MaBase.Execute Requete
            
        Requete = "INSERT INTO PILE (EnsembleId, Ensembleparent, Quantite, Niveau)" _
                       & " SELECT EnsembleId, Ensembleparent, Quantite, " & 2 _
                       & " FROM   COMPOSANT" _
                       & " WHERE  Ensembleparent = '" & LeComposé & "' ;"
            
        MaBase.Execute Requete
            
        '' Allez petit ! on récurse !
        Call AilesRivetsRecursonsJoyeusement(0, LeComposé, Composant, TotalOut)
    Else
        Requete = "SELECT COUNT(*) AS Kount " _
                    & "FROM (SELECT x.EnsembleId " _
                          & "FROM   COMPOSANT AS x INNER JOIN PILE AS y ON x.Ensembleparent = y.EnsembleId " _
                          & "WHERE  Niveau = " & theNiveau - 1 & ") as truc ; "
                     
        Set Sqlresult = MaBase.OpenRecordset(Requete, dbOpenDynaset)
        Kount = Sqlresult.Fields("Kount")
    
        If Kount > 0 Then
    
             
            Requete = "INSERT INTO PILE (EnsembleId, Quantite, Niveau, Ensembleparent) " _
                        & " SELECT x.EnsembleId, SUM(x.Quantite * y.Quantite), " & theNiveau & ", x.Ensembleparent " _
                        & " FROM   COMPOSANT AS x INNER JOIN PILE AS y ON x.Ensembleparent = y.EnsembleId " _
                        & " WHERE  Niveau = " & theNiveau - 1 _
                        & " GROUP BY x.EnsembleId, x.Ensembleparent, " & theNiveau & " ;"
    
    
    MaBase.Execute Requete Call AilesRivetsRecursonsJoyeusement(0, LeComposé, Composant, TotalOut)
    
            Requete = "SELECT SUM(Quantite) AS TotalOut FROM PILE WHERE EnsembleId = '" & Composant & "' ;"
       
    
    Set Sqlresult = MaBase.OpenRecordset(Requete, dbOpenDynaset) If Not IsNull(Sqlresult.Fields("totalOut")) Then TotalOut = Sqlresult.Fields("totalOut") Else TotalOut = 0 End If Sqlresult.Close End If End If End Sub
    Pour contrôler les boucles infinies, il serait bon de tester la profondeur atteinte !


    Pour tester et exécuter le code VBA directement :






    Pour exécuter les instructions pas à pas, utiliser la touche de fonction F8 :







    Pour exécuter à partir d’une macro, on commence par créer celle-ci (logique ^^) :

    Barre de menu : onglet « CREATE », icône « Macro » :






    Cézigue nous demande d’ajouter une action (je rappelle que j’utilise ACCESS 2013, mais en principe ça marche aussi pour ACCESS 2010) :





    Dans sa liste déroulante on choisit « RunCode » (ExécuterCode) :






    On fournit le nom de la fonction qui prendra la main :






    On ferme la fenêtre et on donne un nom à la macro :





    Elle est là !






    On l’exécute en double cliquant sur son nom :

    =>









    J’espère qu’il n’y aura pas de problème avec ACCESS 2010...

  3. #3
    Rédacteur/Modérateur

    Avatar de ClaudeLELOUP
    Homme Profil pro
    Chercheur de loisirs (ayant trouvé tous les jours !)
    Inscrit en
    Novembre 2006
    Messages
    20 596
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 80
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de loisirs (ayant trouvé tous les jours !)
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 596
    Par défaut
    Nom d'une pipe, c'est la grande forme !

  4. #4
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 218
    Billets dans le blog
    16
    Par défaut Ad augusta per angusta
    Salut Claude,


    Heu... Accouchement un peu pénible d’un code quand même verbeux, dans le contexte bridant des macros ACCESS (et la chaleur n’aide pas...)

    La requête proposée par Chamberlin il y a 20 ans dans Database Programming & Design (mai 1996) est quand même plus légère er rafraîchissante :





    Ou la mouture qu’il a proposée en 1994 avec ses collègues d’IBM dans Extending relational database technology for new applications (IBM Systems Journal , Vol 33, No 2, 1994) :





    Mais les choses étant ce qu’elles sont...

  5. #5
    Rédacteur/Modérateur

    Avatar de ClaudeLELOUP
    Homme Profil pro
    Chercheur de loisirs (ayant trouvé tous les jours !)
    Inscrit en
    Novembre 2006
    Messages
    20 596
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 80
    Localisation : Belgique

    Informations professionnelles :
    Activité : Chercheur de loisirs (ayant trouvé tous les jours !)
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2006
    Messages : 20 596
    Par défaut
    d’un code quand même verbeux
    ... ce qui le rend compréhensible !

  6. #6
    Expert éminent
    Avatar de fsmrel
    Homme Profil pro
    Spécialiste en bases de données
    Inscrit en
    Septembre 2006
    Messages
    8 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Spécialiste en bases de données
    Secteur : Conseil

    Informations forums :
    Inscription : Septembre 2006
    Messages : 8 218
    Billets dans le blog
    16
    Par défaut
    Une précision :

    Fonction AilesRivetsRecursonsAmorce :

    Plutôt que de les avoir en dur dans le code, on peut préférer choisir les valeurs du composant et du composé à l’aide de la fonction InputBox :

      
    Function AilesRivetsRecursonsAmorce()
    
    Dim MaBase As DAO.Database
    Dim Amorce As Integer, LeComposé As String, LeComposant As String, TotalOut As Integer
    
    Set MaBase = CurrentDb
    
    Amorce = 1
    
    LeComposé = InputBox("Composé : ")
    LeComposant = InputBox("Composant : ")
    
    ' Initialisation de la pile utilisée pour les récursions
    MaBase.Execute "DELETE FROM PILE ;"
    
    'C'est parti pour compter les rivets !
    Call AilesRivetsRecursonsJoyeusement(Amorce, LeComposé, LeComposant, TotalOut)
     
     AilesRivetsRecursonsAmorce = TotalOut
     
    ' Au résultat
     MsgBox " Composé : " & LeComposé & Chr(13) & Chr(13) _
            & "Nombre total d'éléments du type " & LeComposant & " : " & TotalOut
    
    
    MaBase.Execute "DELETE FROM PILE ;"
    
    Set MaBase = Nothing
     
    End Function
    
    

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Code barre gratuit sous access 97
    Par massol joel dans le forum Contribuez
    Réponses: 7
    Dernier message: 05/07/2017, 16h18
  2. Génération pdf sous access 2010 vba
    Par facilordi dans le forum VB 6 et antérieur
    Réponses: 0
    Dernier message: 24/03/2015, 11h54
  3. [AC-2010] Récupérer une Séquence Oracle en VBA sous Access 2010
    Par stef75 dans le forum VBA Access
    Réponses: 3
    Dernier message: 13/02/2013, 10h56
  4. [Formulaire] code VBA et runtime Access
    Par Frenchguy dans le forum Runtime
    Réponses: 11
    Dernier message: 23/11/2006, 17h09
  5. code VBA versus assistant Access
    Par zephyr59 dans le forum Access
    Réponses: 6
    Dernier message: 10/04/2006, 15h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo