XL 2010 For each controls impossible-résolu

Docdav

XLDnaute Junior
Bonjour,
j'ai un formulaire de saisie, avec plusieurs checkbox, nommée Box32,Box33, etc, le nombre étant la colonne dans lequel le résultat va se mettre. Rien de sorcier, une boucle d'écriture.

Mais...certaines checkbox doivent être modifiées en Frame avec 2-3 choix. J'ai la routine pour celles-ci.

Le problème est que la boucle des chekbox est rompue puisque certaines n'existent pas.
Soit faire plusieurs boucles sur les box existantes (pas propre)
Soit faire une boucle qui cherche les chekbox et fais le boulot.

Un exemple de ce que j'ai trouvé et qui ne marche pas : ça doit préremplir toutes les box normalement.

Dim obj As Control
For Each obj In Me.Controls
If TypeOf obj.Object Is msforms.CheckBox Then obj.Object.Value = True
Next obj

Avez-vous une idée.
Je mets mon fichier, pas du tout optimisé (va falloir que je fasse des modules), qui bug si il n'y a pas qq chose en ligne 6.

Il fonctionnait très bien avant de passer à ces choix multiples avec uniquement des box.
J'essaie d'avoir un fichier comptable mac (il faut juste que je déclare les listes dans ce fichier et ça fonctionne)

Merci de votre lecture et de votre aide.
David.
 

Pièces jointes

  • Formulaire-PC-modif.xlsm
    2.3 MB · Affichages: 115

Docdav

XLDnaute Junior
Bonjour,
bonne nouvelle, ce code pour remplir excel avec les cases cochées fonctionne :
Code:
For Each cbx In Me.Controls
        If Left(cbx.Name, 3) = "Box" Then F.Cells(lignevide, 1 * Right(cbx.Name, 2)) = cbx.Value * -1
  Next

Donc le nettoyage fonctionne, l'écriture fonctionne, reste la lecture de la feuille préremplir les cases quand on choisit une fiche déjà remplie, je suis en train de chercher.

Je devrais aussi faire la même chose, lire, enregistrer ou nettoyer pour les frames
J'ai essayé ceci pour le nettoyage,étape la plus simple mais ça bloque pour l'instant.

Code:
  '-----nettoyage cases multiples------
Dim frm As Control
For Each frm In Me.Controls
        For Each c In Me.frm.Controls
        c.Value = False
        Next c
Next frm

Merci des infos déjà données, je continue d'explorer
 

Docdav

XLDnaute Junior
Re, j'ai essayé ces 2 méthodes pour remplir les box en fonction de la feuille excel, mais niet...
Code:
'   -----boucle remplissage CheckBox-----
Dim cbx As Control
    For Each cbx In Me.Controls
        If F.Cells(lignevide, Right(cbx.Name, 2)) = 1 Then cbx.Value = True
   Next

'''------------autre essai remplissage checkbox--------
Dim b As Byte
For b = 40 To 100
If F.Cells(ligneEnreg, b) = 1 Then Controls("Box" & b).Value = True 'Else Controls("Box" & b) = False
Next b
 

Modeste

XLDnaute Barbatruc
Re,

Comme demandé hier "raccroche" ça à un emplacement dans ton code (au moins une procédure!). Pense aussi au fait que tu as fait évoluer le code et que nous ne disposons que de la première version.

Si "LigneVide" correspond à ce que je soupçonne, ça ne saurait pas donner grand chose comme résultat!?

D'autre part, si tu parcours tous les contrôles de ton UserForm, rien ne te permet de savoir qu'il s'agira d'une CheckBox (plutôt que d'une ComboBox, TextBox, Frame, etc.). Il me semble que je bouclerais sur les n° des colonnes concernées (si j'ai bien compris, tu pourras ensuite, en fonction de ce n°, identifier la CheckBox concernée avec quelque chose comme:
Me.Controls("Box" & format(n°_de_colonne,"00"))= Cells(n°_de_ligne, n°_de_colonne) ... valable uniquement pour les CheckBoxes et à condition que n°_de_ligne et n°_de_colonne correspondent à quelque chose d'utilisable!
 

Docdav

XLDnaute Junior
Re, en effet erreur du à du copier-coller de bout de code sur le 1er essai avec lignevide. j'ai mis ligneEnreg mais j'ai une erreur 1004. je regarde cette erreur et la proposition. il faudrait que je passe par des modules, ce serait plus simple à relire ?

j'avais mis sur le 1er essai un test pour savoir si checkbox, mais ça ne marchait pas. je vais réessayer
 

Docdav

XLDnaute Junior
Re,

Me.Controls("Box" & format(n°_de_colonne,"00"))= Cells(n°_de_ligne, n°_de_colonne)

Re,
c'est un peu ce je faisais avant, et , si en effet les box sont ainsi box32 doit lire ou ecrire sa valeur dans la case (ligne=ligne vide pour enregister, ligneenreg en lecture,;(colonne=32); elles ne sont pas continues, la case 35 peut etre un frame avec 3 choix (qu'il va falloir que je parametre aussi, on a pas fini...)

donc, toujours en lecture des cases de feuilles excel pour préremplir les box...
j'avais tenté un if...and mais ça coince erreur 1004

Code:
Dim cbx As Control
    For Each cbx In Me.Controls
        If (TypeOf cbx Is MSForms.CheckBox) And (F.Cells(ligneEnreg, Right(cbx.Name, 2)) = 1) Then
        cbx.Value = True
        End If
    Next cbx

F=feuille où sont les données à lire


autre question
pour mettre à zero tous les frames de la feuille j'ai testé ceci sans effet (mais ne met pas d'erreur non plus...):

Code:
  '-----nettoyage cases multiples------
Dim frm As Control
For Each frm In Me.Controls
        For Each c In Me.Sexe.Controls
        c.Value = False
        Next c
Next frm
 

Pièces jointes

  • Formulaire-PC-V2-modif.xlsm
    2.3 MB · Affichages: 51

Docdav

XLDnaute Junior
Re, et bonsoir par la même...
n'avanceant pas, j'ai repris mon formulaire initial, avec uniquement des checkbox, numérotées et dans l'ordre.
je l'ai transformé en créant des modules.
J'ai compris qu'il fallait remplacer Me par le nom de la feuille, le rajouter devant les controls aussi ?
J'ai remis le "set... qui donne un nom raccourci à ma feuille"
(en fait j"aurais du faire pareil plutot que faire des rechercher/remplacer pour le Me)
J'ai compris comment appeler les modules.

je mets le fichier.
le module vider les champs fonctionne, les enregistrements aussi.
je vais mettre la recherche predictive de Jacques Bois Gontier.

Puis je repasserais à ces frame et les boucles qui merdoient.

Merci beaucoup à tous, je progresse par étape, à défaut d'avoir trouver une solution je suis allé apprendre autre chose.
 

Pièces jointes

  • Formulaire-PC-Modules.xlsm
    2.2 MB · Affichages: 55

Modeste

XLDnaute Barbatruc
Bonsoir,

Tu es difficile à suivre! La méthode essais-erreurs ne peut fonctionner que si tu essaies de comprendre pourquoi certaines choses ne fonctionnent pas. Faire marche-arrière après avoir avancé dans une direction sans avoir "balisé" correctement t'expose à t'apercevoir un jour que tu es occupé à re-parcourir un sentier ... que tu as déjà emprunté et qui, au terme d'un long détour, t'avait ramené au point de départ.
Tu risques également de construire une véritable "usine à gaz", si tu adaptes une partie, simplement parce que ça semble mieux fonctionner (ce sera peut-être le cas à un moment et dans un contexte particulier ... et ne fonctionnera plus un peu plus tard)
Avance sur un sujet, un objectif ou une procédure à la fois, sinon tu donnes l'impression de "tirer dans tous les sens".
 

Docdav

XLDnaute Junior
Bonsoir,
j'ai essayé, n'y arrivant pas, et voyant mon code dégueulasse, ayant besoin d'un fichier qui fonctionne, j'ai décidé de repartir de ce qui marchait, mais de l'embellir, le rendre plus simple et efficace. d'où le passage en module (1ère fois que j'en fais)
Je pourrais revenir vers vous avec un fichier plus simple et compréhensible.
Et plus facilement amélioré ou modifié, car là pour un changement il fallait le recopier x fois...

Maintenant je passe à la saisie prédictive, ensuite je passerais aux frappes, qui impliquent de modifier les boucles sur les box...d'où vient tout le problème.
 

Modeste

XLDnaute Barbatruc
Bonjour Docdav, le forum,

Quand tu en auras terminé, donc, avec la saisie prédictive et que tu repasseras par ici, voici une façon "d'alléger ton code":
pour chaque contrôle dans ton formulaire, modifie le nom en ajoutant un préfixe en 3 lettres, représentant le type de contrôle (j'ai testé avec cmb pour ComboBox, tbx pour TextBox, opt pour OptionButton et j'ai gardé Box pour CheckBox, puisqu'ils étaient nommés ainsi). Ta ComboBox ChoixFiche devient donc cmbChoixFiche, la TextBox Date_Inter devient tbxDate_Inter, le OptionButton9 devient opt9 et Box06 ... ne change pas.
Quand tu auras tout renommé, teste le code suivant (qui remplace tes +- 40 lignes actuelles)

VB:
Private Sub B_vide_Click()
'Application.EnableEvents = False
For Each ctrl In Me.Controls
    Select Case Ucase(Left(ctrl.Name, 3))
        Case "TBX", "CMB"
            ctrl.Value = ""
        Case "BOX", "OPT"
            ctrl.Value = False
    End Select
Next ctrl
'Application.EnableEvents = True
Les 2 lignes mises en commentaire permettent de désactiver la gestion des événement sinon, chaque fois que tu vides un champ date ou heure tes procédures de contrôle de formatage vont s'exécuter. Ne supprime les apostrophes qu'après avoir vérifier que le reste fonctionne.

Si tu dois exécuter la même portion de code (après avoir copié le contenu des tes différents contrôles dans la feuille, en fin de Sub B_validation_Click(), par exemple) tu peux renommer la procédure ci-dessus Sub Vider_Champs() et l'appeler depuis différents emplacements dans ton code (ce qui évitera la répétition de parties de code identiques)
 

Docdav

XLDnaute Junior
Bonjour,
j'ai passé tout ce que je pouvais en module (notamment vider les champs, qui est appelé sur plusieurs boutons).

Quelle synthèse ce code, magnifique (et en plus compréhensible, sans faire appel à d'obscure méthode compliquée...).
Je n'ai pas encore compris le coup des évènements, je vais tester et lire sur le sujet.

Je galère encore un peu pour la saisie prédictive, mais j'y travaille.
Je vais retourner sur le sujet avec le nouveau fichier avec les modules, plus simple à lire.
Je reviendrais ici plus tard pour réussir à faire des boucles de lecture-écriture de cellules, avec les optionbutton car compliqué pour moi, je n'y arrive pas. mais je progresse.

C'est déjà plus clair avec les modules.

Merci.
 

Docdav

XLDnaute Junior
Bonjour Modeste, je suis en train de renommer mes variables de cases à remplir, et je vois pointer une solution avec la routine donnée au dessus, pour la lecture ou l'écriture, si je renomme ma textbox Date_Inter en tbxDate_Inter02 (j'aimerais garder l'info de la case remplie, mais si ça devient trop long je passe a tbx02 ?).
Je peux utiliser qq chose comme "case" et avec ".name" selectionner les types (avec left comme ci-dessus) et enregistrer dans la bonne cellule excel avec "right" qui selectionnera le nombre ?
J'ai bon ?
 

Docdav

XLDnaute Junior
Bonsoir Modeste,
merci de me lire, et de m'apprendre.
j'ai renommé tout mes controles.
j'ai inséré le code dans le module "nettoyer les champs" (à la place de toutes mes lignes) , j'ai appelé la routine clean, je l'appelle par "call clean" (ce qui fonctionnait avec mes lignes précédentes)
j'ai ajouté dim ctrl, je l'ai mis aussi dans l'userform au cas où.
ça bloque sur la ligne "for each..." avec un code 438.

j'ai laissé les lignes applications en commentaires, mais en enlevant le commentaire ça bloque aussi.
comme c'est en module j'ai changé le Me par le nom de la feuille.

Code:
Sub clean()
Dim ctrl As Control

'Application.EnableEvents = False
For Each ctrl In Feuille_Saisie.Controls
    Select Case UCase(Left(ctrl.Name, 3))
        Case "TBX", "CMB"
            ctrl.Value = ""
        Case "BOX", "OPT"
            ctrl.Value = False
    End Select
Next ctrl
'Application.EnableEvents = True
End Sub

avez-vous une idée ?
 

Pièces jointes

  • Formulaire-PC-V3-Modules-ok sauf relecture-pred-pour modif.xlsm
    2.2 MB · Affichages: 51

Statistiques des forums

Discussions
312 232
Messages
2 086 461
Membres
103 220
dernier inscrit
samira2024