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

VBA Access Discussion :

Fermer les object Tab en VBA


Sujet :

VBA Access

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 126
    Par défaut Fermer les object Tab en VBA
    Bonjour,

    Je voudrais fermer les Object Tab qui représentent les tables, queries, forms, etc. ouverts, dans l'accueil Access.
    Il s'agit des tab qui s'ajoutent en-dessous du menu (ribbon), à mesure que l'on ouvre des tables, des queries et des forms.
    Attention: il s'agit des Object Tab, pas de Control Tab que l'on peut mettre dans un Form !

    Pas de problème pour le faire en donnant le type et le nom de l'objet, ex:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        DoCmd.Close acQuery, "queryxyz"
        DoCmd.Close acTable, "tablexyz"
    Ca fait le job.

    Mais ce que je voudrais faire, c'est fermer en série, sans devoir donner le nom des objets. J'imagine un For Each ... Next

    Mais sur quels types d'objets et sur quelles collections ?

    Merci d'avance.

  2. #2
    Expert éminent
    Avatar de tee_grandbois
    Homme Profil pro
    retraité
    Inscrit en
    Novembre 2004
    Messages
    8 962
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Novembre 2004
    Messages : 8 962
    Par défaut
    bonjour,
    J'imagine un For Each ... Next
    oui, c'est la bonne méthode en parcourant les objets de l'application, exemple pour les tables:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Sub AllTables() 
     Dim obj As AccessObject, dbs As Object 
     Set dbs = Application.CurrentData 
     ' Search for open AccessObject objects in AllTables collection. 
     For Each obj In dbs.AllTables 
         If obj.IsLoaded = True Then 
             ' Print name of obj. 
             Debug.Print obj.Name 
         End If 
     Next obj 
    End Sub
    mais ce type de code est un cas extrême et, de toute façon, en fermant la base tout objet ouvert sera fermé.
    Car dans une base bien conçue, les ouvertures et fermetures des objets en cascade à partir d'un menu sont maitrisées: des boutons ouvrent et ferment les formulaires qui peuvent ouvrir un état ou un autre formulaire mais ne doit pas laisser (sauf un état en aperçu avant impression si on choisit de ne pas m'imprimer) un objet ouvert sans qu'une action d'un bouton ne puisse fermer cet objet précédemment ouvert jusqu'à revenir au menu du début.
    Enfin, les objets requêtes ou tables ne devraient s'afficher que dans un formulaire.

    C'est pour cela que les formulaires doivent avoir le plus souvent possible la propriété modale à oui

  3. #3
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 126
    Par défaut
    Merci.

    Mais problème avec

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     Dim obj As AccessObject
     Dim dbs As Object
     
     Set dbs = Application.CurrentData
     ' Search for open AccessObject objects in AllTables collection.
     For Each obj In dbs.AllTables
         If obj.IsLoaded = True Then
             DoCmd.Close obj, acTable
         End If
     Next obj
    Mais j'ai un runtime error 438 sur la ligne DoCmd.Close obj, acTable:
    l'objet ne supporte pas la méthode (DoCmd).
    Alors comment faire pour fermer le tab quand c'est une table, quand c'est un query, et quand c'est un form.

    L'idée de fermer en série, c'est de "faire le ménage" dans ce qui est ouvert.

  4. #4
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 682
    Par défaut
    Les parametres sont inversés
    il faut voir aussi si tu dois utiliser un .Name avec ton obj
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Migrer les applications VBA Access et VBA Excel vers la Power Platform
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Coffrets disponibles de mes ouvrages : https://www.editions-eni.fr/jean-philippe-andre
    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

  5. #5
    Membre très actif
    Profil pro
    Inscrit en
    Février 2007
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Février 2007
    Messages : 126
    Par défaut
    Merci Jean-Philippe.

    Ca fonctionne très bien.
    Alors je vais compliquer un peu les choses: je voudrais fermer aussi des tab qui ont été créées par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    'MyQuerySQL est un string qui contient le SQL du query dont je veux afficher le résultat
     
    Dim NomQueryDef As String
        With CurrentDb
            .QueryDefs.Delete NomQueryDef
            .CreateQueryDef NomQueryDef, MyQuerySQL
        End With
     
    'on affiche la requête et on la supprime dans la foulée
        DoCmd.OpenQuery NomQueryDef
        CurrentDb.QueryDefs.Delete NomQueryDef
    Il faut donc fermer un tab qui contient le résultat d'un query ... qui a déjà été supprimé.

    c'est pour ça que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    For Each tmp In CurrentDb.QueryDefs
        If SysCmd(acSysCmdGetObjectState, acQuery, tmp.Name) = acObjStateOpen Then
            DoCmd.Close acQuery, tmp.Name
        End If
    Next
    ne ferme pas ce tab.

    Comment faire ?

  6. #6
    Expert éminent
    Avatar de tee_grandbois
    Homme Profil pro
    retraité
    Inscrit en
    Novembre 2004
    Messages
    8 962
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Novembre 2004
    Messages : 8 962
    Par défaut
    pour les requêtes, c'est sensiblement le même code que pour les tables mais avec AllQueries (voir à la fin du lien l'exemple d'utilisation)
    idem pour les formulaires: Allforms, les états: AllReports ...

  7. #7
    Expert éminent
    Avatar de tee_grandbois
    Homme Profil pro
    retraité
    Inscrit en
    Novembre 2004
    Messages
    8 962
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : retraité

    Informations forums :
    Inscription : Novembre 2004
    Messages : 8 962
    Par défaut
    Alors je vais compliquer un peu les choses: je voudrais fermer aussi des tab qui ont été créées par:
    je crois reconnaitre du code que j'ai donné pour un autre post ...
    Dans ce cas le Object.Isloaded ne fonctionnera pas puisque l'objet est détruit ...
    il serait préférable de modifier le code précédent et ne pas supprimer l'objet après affichage, on ajoute la gestion d'erreur au cas où l'objet existe déjà (à dire vrai, cela devrait être systématique dans du code VBA):
    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
    'MyQuerySQL est un string qui contient le SQL du query dont je veux afficher le résultat
     On Error GoTo GestErr
     
    Dim NomQueryDef As String
        With CurrentDb
            .QueryDefs.Delete NomQueryDef
            .CreateQueryDef NomQueryDef, MyQuerySQL
        End With
     
    'on affiche la requête 
        DoCmd.OpenQuery NomQueryDef
    'on rafraichit la fenêtre base de données pour faire apparaitre l'objet créé
        RefreshDatabaseWindow
     
    GestErr:
    If err <> 0 Then
        Select Case err
        Case 3265    ' élément non trouvé dans la collection car requête non trouvée
            Resume Next
        Case Else
            MsgBox err.Number & "-" & err.DESCRIPTION
            Exit Sub
        End Select
    End If
    le code de fermeture des objets ouverts devrait fonctionner maintenant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Dim obj As AccessObject, dbs As Object
    Set dbs = Application.CurrentData
     
     For Each obj In dbs.AllQueries
         If obj.IsLoaded Then DoCmd.Close acQuery, obj.Name, acSaveNo
     Next obj

  8. #8
    Rédacteur/Modérateur

    Avatar de Jean-Philippe André
    Homme Profil pro
    Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Inscrit en
    Juillet 2007
    Messages
    14 682
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : Canada

    Informations professionnelles :
    Activité : Architecte Power Platform, ex-Développeur VBA/C#/VB.Net
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2007
    Messages : 14 682
    Par défaut
    Salut

    effectivement, une boucle For Each avec un test sur l'ouverture

    par exemple pour les tables ca donnerait un code comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub piou()
    Dim tmp
    For Each tmp In CurrentDb.TableDefs
    If SysCmd(acSysCmdGetObjectState, acTable, tmp.Name) = acObjStateOpen Then
        DoCmd.Close acTable, tmp.Name
    End If
    Next
    End Sub
    à toi de l'adapter pour ton cas et les objets que tu voudras parcourir.
    Cycle de vie d'un bon programme :
    1/ ça fonctionne 2/ ça s'optimise 3/ ça se refactorise

    Pas de question technique par MP, je ne réponds pas

    Mes ouvrages :
    Migrer les applications VBA Access et VBA Excel vers la Power Platform
    Apprendre à programmer avec Access 2016, Access 2019 et 2021

    Apprendre à programmer avec VBA Excel
    Prise en main de Dynamics 365 Business Central

    Coffrets disponibles de mes ouvrages : https://www.editions-eni.fr/jean-philippe-andre
    Pensez à consulter la FAQ Excel et la FAQ Access

    Derniers tutos
    Excel et les paramètres régionaux
    Les fichiers Excel binaires : xlsb,

    Autres tutos

Discussions similaires

  1. [XL-2007] Fermer les conditions IF VBA
    Par Eskalibur dans le forum Macros et VBA Excel
    Réponses: 9
    Dernier message: 13/03/2018, 13h54
  2. [VBA-E] Empécher l'ouverture ou fermer les classeur de macros personnalisé
    Par LitteulKevin dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 07/03/2007, 20h37
  3. [VBA-E]fermer les fichier exel en cour lors d'une ouverture
    Par fournier dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 22/02/2006, 09h54
  4. fermer les pop up si le parent est fermé
    Par grinder59 dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 13/12/2005, 05h26
  5. [MFC] Fermer les Popup, mais pas l'appli
    Par Grey dans le forum MFC
    Réponses: 4
    Dernier message: 16/11/2005, 20h30

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