Bonjour à tous,
Après m'être arraché les cheveux sur un problème toute la matinée, et n'ayant bien sûr rien trouvé sur le net, je me décide à solliciter votre aide.
Tout d'abord une rapide mise en contexte : je développe actuellement une macro VBA assez conséquente dont le but est de générer le planning des matchs d'un tournoi sportif. L'utilisateur (pas moi) n'ayant pas de connaissances particulières en Excel, l'idée est de lui faire rentrer les équipes participant au tournoi, puis de lui faire cliquer sur un bouton et qu'il ait ensuite juste à imprimer le planning. Tout ce qu'il y a entre les deux est géré par la macro.
Niveau structurel, je fonctionne en deux étapes. Premièrement à partir de la liste des équipes, chacune affectée de sa catégorie d'âge (11 en tout), je crée les poules et les matchs correspondants, en fonction du nombre d'équipes de la catégorie (un bête select case). Chaque catégorie fait l'objet d'une feuille dans mon classeur.
Une fois que tous les matchs sont créés, je boucle sur l'ensemble des feuilles pour aller copier-coller chaque match dans une nouvelle feuille "planning". Oui, c'est assez Long, mais ce n'est pas très important.
Un des points délicats du programme est qu'une équipe ne peut pas jouer sur 2 créneaux horaires consécutifs ; pour éviter ca, j'ai créé deux variables "Count", que j'associe à chacune des deux équipes. Comme je boucle sur l'ensemble des matchs, les variables prennent une valeur différente à chaque pas d'itération, mais l'équipe reste associée à la dernière valeur prise par "sa" variable Count, et ce jusqu'à son prochain match. En pratique, la valeur de Count est la ligne sur laquelle je colle le match, et donc un horaire. Donc avant de coller je compare toujours Count Avec la ligne ciblée, et je regarde si c'est >1 en valeur absolue. De cette manière une équipe ne joue jamais deux fois de Suite.
Cette technique est fonctionnelle mais un peu lente : à chaque match, je dois aller récupérer la valeur de Count par une commande de type cell.value, et pour cela chercher dans la liste des équipes de la catégorie le nom de l'équipe qui joue le match... fois 2, puisqu'il y a deux équipes par match. Voilà comment je procède:
i concerne la ligne du match, j concerne la ligne de la liste des équipes. Donc à chaque match, je boucle sur la ligne des équipes et je regarde si je trouve le nom de l'équipe A (resp. B). Si oui, je prends sa valeur de Count, qui se trouve dans la cellule adjacente.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13 'Calcul des Count For j = 4 To NE + 4 'Equipe A If Cells(j, 1).Value = Cells(i + 3, 4).Value Then 'CountA = Cells(j, 2).Value End If Equipe B If Cells(j, 1).Value = Cells(i + 3, 8).Value Then 'CountB = Cells(j, 2).Value End If Next
C'est LONG.
Pour accélérer ca, je voudrais avoir recours à un dictionnaire de données. J'en ai déjà manipulé, et je sais que ca fonctionne très bien pour ce genre de problèmes.
Mon idée est simple, avoir une structure du type:
- key: équipe
- item: Count
Rien de plus simple... SAUF QUE: il y a risque de doublon. En effet il suffit qu'un club inscrive 1 équipe dans 2 catégories et on se retrouve avec deux fois la même clé (le nom de la catégorie ne doit pas apparaître dans le nom de l'équipe).
C'est pourquoi j'ai pensé créer plusieurs dictionnaires de données: un par catégorie. Ce n'est pas gênant, les catégories sont toujours au nombre de 11 et leur nom ne change pas. J'ai donc écrit un truc comme ca:
etc pour les autres. (wJA, wJB... sont les noms des catégories d'âge en Allemagne)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 Dim Dico_wJA, Dico_wJB, Dico_wJC, Dico_wJD, Dico_mJA, Dico_mJB, Dico_mJC, Dico_mJD, Dico_mJE, Dico_Minimix Set Dico_wJA = CreateObject("Scripting.Dictionary") Set Dico_wJB = CreateObject("Scripting.Dictionary")
Mon Intention est ensuite de mettre à jour les variables Count avec une commande de ce type:
Le problème... c'est que tout ca s'inscrit dans une boucle sur les feuilles de mon classeur (donc sur les catégories, vous suivez ?), et que je ne peux donc pas écrire explicitement le nom du dictionnaire en question (ex: Dico_wJA) puisque la commande doit être valable pour tous les dictionnaires.
Code : Sélectionner tout - Visualiser dans une fenêtre à part CountA = Dico.Item(Nomdel'équipe)
J'ai donc essayé de créer une fonction, un peu bourrine, qui créerait un dico "neutre" et qui lui donnerait la valeur du dico qui va bien suivant la feuille où on se trouve. Comme ca :
Et c'est là que ca marche plus.
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 Function GetDico() Dim Dico Set Dico = CreateObject("Scripting.Dictionary") Select Case ActiveSheet.Name Case "wJA" Dico = Dico_wJA Case "wJB" Dico = Dico_wJB [...] End Select GetDico = Dico End Function
Quand je Lance le programme il passe bien dans la fonction GetDico, repère bien le bon cas, mais là mon Dico_wJA est annoncé "vide" ("Leer") alors que je l'ai bien rempli auparavant (J'ai vérifié en pas à pas). Du coup j'obtiens une erreur 424: objet requis.
J'ai l'impression que c'est une histoire de déclaration d'objet, de manipulation de types... Je ne dois pas tout à fait maîtriser ces outils.
Merci déjà de m'avoir lu et j'espère que vous pourrez m'aider.
J'ai sans doute oublié des points importants, mais je reste bien sûr à disposition pour vous éclairer dessus.
MJ
Partager