Un grand merci a toutes et a tous pour ce site remarquable!
J'ai commence VBA il y a trois mois et avec le soutien de XLD, j'ai aujd'hui le sentiment que les possibilites qu'offre Excel sont vraiment sans limites... C'est un veritable regal de vous lire, vous prenez le temps d'aller au fond des choses, et lorsque j'etudie les differentes macros jointes aux posts, je decouvre et j'apprend tjs de nouvelles choses.
Je souhaite creer un fichier de gestion des appels d'offre ou je vais devoir faire appel a plusieurs macros donc une dizaine de modules, je pense. Je souhaite aussi faire un "pupitre de controle" avec differents boutons qui "appellent" ces macros avec mises a jour des valeurs des variables au moment du click sur le bouton.
Je voudrais donc faire qqch de "structure" (dans un esprit modulaire) du genre :
PHP:
Private Sub CommandButton1_Click()
dim X as...
dim Y as...
etc
Run ("macro1", variable1=X, variable2=Y,...)
Run ("macro2", variableA=variable1, variableB=variable2,...)
End sub
Ici, "variable1" et "variable2" serait declares dans "macro1" et "variableA" et variableB" dans "macro2".A noter que mes macros sont du type old fashion, avec des boucles a profusion, mais l'optimisation viendra dans un deuxieme temps.
Mais, y'a rien a faire, apres avoir epluche l'aide VBA sur "Run Method", je n'arrive a rien, je n'ai tjs pas pu appeller une macro. Comment "appelle-t-on correctement une macro" avec la commande RUN? Comment se passe alors la declaration des variables? Est ce que les variables utilisees dans "macro1" vont garder leur valeur si je les utilise encore dans "macro2"? Sinon, comment faire le lien?
Enfin, derniere petite question, dans le super pack "liste de validation" de Celeda, je voudrais savoir si on peut facilement appliquer la liste deroulante dynamique a des cellules et non pas a des user forms? Je voudrais en fait, creer un bouton "start" qui declenche une macro qui fait que toute nouvelle cellule sur laquelle je clique, affiche la liste dynamique et un bouton "stop" qui arrete la macro? Est-ce que cela est realisable? Ou suis-je en train d'essayer de pondre une "usine a gaz"?
Run est plutôt utilisé pour lancer une procédure ou fonction d'un autre classeur. Pour passer des paramètres avec Run, un extrait de l'aide VBA :
Code:
[B][SIZE=2]Exemple[/SIZE][/B]
Cet exemple montre comment appeler la fonction macro My_Func_Sum,
qui est définie dans la feuille macro MyCustom.xlm
(cette dernière doit être ouverte). Dans cet exemple,
la fonction accepte deux arguments numériques, 1 et 5.
mySum = Application.[B]Run[/B]("MYCUSTOM.XLM!My_Func_Sum", 1, 5)
MsgBox "Macro result: " & mySum
J'ai eu le temps ce week end de me pencher sur la question et, en effet, j'etait completetement dans le faux avec cette fameuse commande RUN.
J'ai re-declare toutes mes macros en "PUBLIC SUB MacroName (variable1, variable2)" et puis j'ai appelle mes macros avec la fonction "CALL MacroName (variable1, variable2)" comme tu le suggerais pierrejean : ca marche nickel!!!!
Je vais enfin pouvoir travailler avec plusieurs petits modules de code et surtout passer moins de temps a debugger!!!
Hasco,
Mon projet en est encore au stade embryonnaire donc, des qu'il sera un peu plus mature, je posterai un fichier exemple.
Je reviens avec mon probleme de declaration que je pensais resolu... Comme l'a dit Hasco, je me suis senti pousser des ailes mais la realite me rattrape... Apres recherche je n'ai pas trouve d'explication sur le forum pour mon cas qui, je pense, est plutot commun...
Alors pour faire simple et conci, j'ai joint un petit fichier "exple" pour que vous puissiez voir quel est mon probleme...
Pour resumer:
L'appui sur le bouton appelle deux macros :
- une premiere macro qui detecte deux ranges (le range "CODERANGE" et le range "SUPPLIERSRANGE") dans la worksheets "MASTER"
- une deuxieme macro qui detecte a l'interieur de "CODERANGE" des "sous-ranges" tels que "RAWPART_range", "MANUFAC_range", etc...
A noter que la deuxieme macro utilise elle meme une troisieme macro pour detecter les "sous-ranges". Seuls les paramatres initiaux de la 3eme macro changent pour chaque "sous-range"...
Mais voila, alors que ma premiere macro marche tres bien, mes macros 2 et 3 ne fonctionnent pas du tout, les parametres crees par la deuxieme ne se transferent pas a la troisieme et inversement... Je pense que le probleme se situe tjs au niveau de la declaration des variables car le test de chaque macros seule me semble OK...
Comme te l'a dit Hasco il faut y aller pas a pas et commencer par l'étude de petits exemples montrant l'usage des variables et la transmission des paramètres
Ton exemple fourmille de déclarations de variables pas toujours évidentes a suivre
De plus il est difficile de remonter d'un code que l'on n'a pas conçu vers l'algorithme (les désirs de celui qui a écrit le code)
Si tu pouvais nous expliquer dans la bonne vieille langue de Molière ce que tu souhaites on pourrait t'aider plus efficacement en t'expliquant a chaque étape le raisonnement et l'utilisation des variables (publiques ou non) , des paramètres , etc..
Je suis desole de ce "meli-melo", c'est la qu'on voit le novice, le non-initie, quoi... J'aurais du mettre plus de notes et commentaires... Toutes mes excuses.
Merci de venir a mon secours aussi vite... Je m'explique donc avec les mots de Moliere.
Les trois macros du fichiers joint sont prevues pour pouvoir etre utilisees independemment les unes des autres pour diverses utilisations dans des menus, bla, bla... D'ou l'utilisation de variables pour "parametrer" la macro lors de chaque utilisation (le fichier "Exple" est donc un exemple d'utilisation parmi d'autres).
Macro1 : DETECT_RANGES_MASTER But : 1. Detecter le range variable "CODERANGE" qui se trouve TOUJOURS entre la cellule "$$CODE.STRT$$" et la cellule "$$CODE.END$$".
2. Detecter le range variable "SUPPLIERRANGE" qui se trouve TOUJOURS entre la cellule "$$SUPP.STRT$$" et la cellule "$$SUPP.END$$". Donnees de sortie : deux ranges "CODERANGE" et "SUPPLIERRANGE"
Macro2 : DETECT_RANGESGROUP_MASTER(coderange) But : Detecter les ranges variablesRAWPART_range, MANUFAC_range, FINISH_range, CONTROL_range et STANDARD_range dont le texte des cellules "codes" commencent respectivement par "RW*","MF*","FH*",CT*" et enfin "SC*". Tous ces ranges spnt inclus dans le range "CODERANGE" detecte par la macro1.
Donnees de sorties : les cinq ranges suivants : RAWPART_range
MANUFAC_range
FINISH_range
CONTROL_range
STANDARD_range
Macro3 : DETECT_GROUP_MASTER(coderange As Range, app As String, grouprange As Range) But : Detecter le range "grouprange" dans le range "CODERANGE". Les cellules du range "grouprange" sont les cellules qui commencent toutes par "app".
Donc avec un nouveau parametre "app" (exple app="RW*" ou "MF*", etc...) le range "grouprange" me donnera donc respectivement "RAWPART_range", "MANUFAC_range", etc... Donnees de sortie : 1 seul range "grouprange" que je viens reinjecter dans le range correspodant (dans ma macro2) avec la commande SET par exple:
Ici, je donne a "app" la valeur "FH*" puis je lance ma macro3 dont qui va chercher dans "CODERANGE" (de la macro1) le "grouprange" dont les cellules commencent par"FH". Ensuite je reviens dans la macro2 et j'injecte la valeur de "grouperange" dans "FINISH_range" et je passe au range suivant...
Voila j'espere que c'est plus clair...
Mon probleme ici est que les valeurs de "CODERANGE", "app", "grouprange" ne se transferent pas d'une macro a l'autre. D'ou les declarations de variables alambiquees car je sais pas trop ou je mets les pieds...
Je fais un deuxieme post sinon ca va etre imbuvable a la lecture...
Note 1: La macro1 fonctionne tres bien toute seule...
Note 2: La macro3 en tant que telle fonctionne (testee et re-testee), seul le parametrage des variables ne fonctionne pas...
Note 3: L'appel de la macro3 dans la macro2 est fait pour economiser des lignes de codes et reduire la taille de mon fichier... Qui pese deja 300Ko avec seulement deux menus. J'ai prevu 10 menus...
Le worksheets MASTER est la matrice sur laquelle je travaille pour ranger mes donnees... sur les lignes les articles (un article par ligne) et sur les colonnes les fournisseurs (un fournisseurs par colonne, ranges par groupes). La selection des fournisseurs se fait avec un "X" dans la colonne, puis lorsque j'ai le prix de ce fournisseur pour l'article en question, je remplace ce "X" par le prix, etc...
Ces fameuses detections de ranges pemettent de faire ensuite une selection facilitee, avec menus deroulants, etc et aussi a detecter les zones ou ma macro devra mettre des "X" lors de la validation de la selection des fournisseurs. Je souhaite faire qqch du genre "intersect" [ligne article] & [colonnes du range fournisseur selectionne] puis mettre toutes les valeurs a "X".
Les codes servent quand a eux a creer des "groupes" de fournisseurs...
Peut etre je n'ai pas utilise la bonne structure de travail, j'ai repris ce qui se fait actuellement dans mon entreprise. Cela permet aux adeptes de l'ancien systeme de continuer a travailler en manuel...
Toutefois, si qqun a une suggestion pour ameliorer/optimiser cette "base de donnees", toute critique sera la bienvenue...
Bonjour pierrejean, Bonjour Hasco, Bonjour le forum,
GENIAL !!! Merci beaucoup pour vos modifs, les deux fichiers fonctionnent a merveille! Meme les tests les plus farfelus donnent d'excellents resultats...
Je comprends maintenant ou je faisais mes erreurs dans les declarations de variables. Vous venez vraiment de debloquer mon projet... Merci.
Deux petites questions avant que je m'embarque dans la creation d'une usine a gaz :
- Les variables declarees en "Public" comme vous l'avez fait dans vos fichiers respectifs ne restent "stockees" en memoire que lorsque le code "tourne", n'est-ce pas? Si oui, y'a t-il une facon elegante de stocker la valeur de ces variables entre deux lancements de macros ?
- Est-ce que ces variables peuvent etre utilisees/exportees de la meme facon dans un autre module ou worksheets, tjs pendant que le code "tourne"?
Hasco,
Pour repondre a ta question sur les colonnes, il s'agit en fait exactement du probleme que je vais avoir. L'utilisation "manuelle" de ce fichier se fait en ajoutant de nouvelles colonnes (nouveaux fournisseurs) ou en enlevant/cachant des colonnes (fournisseurs inutiles) au MASTER, donc en modifiant en permanence les colonnes.
Mon idee est de faire une parade a cette modification intempestive des colonnes avec un code unique par "type" de fournisseur. Ainsi, si qqun vient ajouter une colonne fournisseur de type "RW*" a la fin du tableau (mais utilise le codage fournisseur adequat bien sur), ma macro le detectera et incluera cette derniere colonne dans le range "RAWPART_range". D'ou l'idee de travailler avec des "detecteurs de ranges" et des codes...
C'est la solution qui m'a parue la plus fiable pour eviter de passer a cote des erreurs de mise en page et pour que l'utilisation manuelle soit toujours possible... Enfin, si tu vois une meilleure strategie, moins "lourde", je suis ouvert a la critique...
- Les variables declarees en "Public" comme vous l'avez fait dans vos fichiers respectifs ne restent "stockees" en memoire que lorsque le code "tourne", n'est-ce pas?