Home
Home

---Soumis par Terry Kreft---

Fermer tous les formulaires avec la syntaxe  "For Each".

(Q) J'essaie de fermer tous les formulaires en bouclant sur la collection Forms et en utilisant  "For Each frm". Mais cela ne semble pas fonctionner correctement. Qu'est-ce qui ne va pas et comment fermer tous les formulaires?

(A) Un For... Each... Next traverse la collection  Forms dans la même séquence que ces formulaires furent ouverts (séquence de l'index), d'où ce code

   dim frm as form   
   for each frm in forms      
     debug.print frm.name   
   next

produira le même effet que

   dim intX as integer
   for intX = 0 to Forms.Count-1      
     debug.print Forms(intX).name   
   next

Le problème c'est qu'en "enlevant" des éléments de la collection, en fermant le premier formulaire, les éléments situés par après, dans la collection, glissent de position. Ainsi, enlevant l'item 0, l'item 1 glisse en position 0, l'item 2 glisse en position 1, etc. Mais lors de la prochaine étape, dans la boucle, on cherchera à effacer l'item maintenant en position 1, et, on le remarque, l'item qui a glissé en position 0 ne sera pas affecté par la fermeture.

Si on brise la boucle ci-dessus, en étapes effectuées et qu'on change le print pour un docmd.close, supposant trois formulaires, 0, 1 et 2, le code effectue effectivement ce qui suit

   dim intX as integer
  'Première fois dans la boucle
  intX=0
  docmd.close acform, forms(intx).name
  
  'Le premier formulaire est fermé, donc enlevé de la collection des
  'formulaires ouverts. À ce point, le second formulaire passe en position 
  'zéro et le dernier et troisième formulaire passe 
  'en position un.
  intX=1 

  '(dernière fois qu'on exécute la boucle, par rapport à forms.count - 1 
  'terminant la boucle) 
  docmd.close acform, forms(intx).name

  'Ceci influence le second formulaire actuellement dans la collection
  'ce qui était initialement notre troisième
  'formulaire et la "boucle" se termine, laissant notre
  'second formulaire ouvert

Donc, la réponse est de soit continuellement enlever le premier item de la collection jusqu'à ce qu'il n'y ait plus d'item, ou encore, de partir par la fin, vers le début de la collection. Donc, soit

   do while forms.count>0      
    docmd.close acform,forms(0).name   
   loop

soit

   dim intx as integer   
   dim intCount as integer   
   intCount = Forms.count-1
   for intX= intCount to 0 step -1     
    docmd.close acform,forms(intX).name
   next

Vous pouvez aisément laisser ouvert un formulaire, dans le second cas, pas dans le premier,  en ajoutant une condition du genre

   for intX= intCount to 0 step -1
        if forms(intX).Name <> "MyFormToKeepOpen" then
            docmd.close acform,forms(intX).name        
        end if    
   next