Supprimer le code d'un classeur

AGLAS

XLDnaute Nouveau
Bonjour ou Bonsoir le forum,

Je cherche le moyen de supprimer une portion de code dans un classeur qui est généré sur la base d'un modèle ; en fait, pour dire vrai, il s'agit d'un modèle de type MS Project. Une macro VBA de mon classeur Excel exécute MS Project avec le nom du modèle à ouvrir en paramètre, ensuite la macro VBA Sub Project_Open() du modèle Project (équivalente à Sub Workbook_Open() pour Excel) s'exécute à son tour et attribut un nouveau nom au projet avant de l'enregistrer. Le Hic c'est que le code fait parti du voyage et donc lorsque l'on tente d'ouvrir à nouveau le projet ainsi enregistré, la macro tente de s'exécuter également... Il me faudrait une astuce parce que là je sèche, alors j'ai pensé au forum, mon affaire est un peu tordue mais, on sait jamais... Merci donc à toute suggestion.
 

Hellboy

XLDnaute Accro
Bonsoir AGLAS

Je crois que c'est ça le problème, le transfert du nouveau nom.

Je m'explique, tu pourrais faire en sorte, que la macro s'exécute en ajoutant une condition:

IF LeNomDuClasseurOriginal = ThisWorkBook.Name then

execute la macro

End IF

Donc si le nom du classeur n'est pas celui de l'original, la macro ne sera pas lancé.

a+
 

AGLAS

XLDnaute Nouveau
Merci Hellboy, c'est ce qu'il s'appelle avoir de la jugeote. Je m'attendais même pas à une véritable solution c'est dire l'état de mon moral... Et d'ailleurs si je peux me permettre vu que tu à l'air si smart, je voudrais te soumettre ce qui sera sans doute l'un des derniers pb à résoudre avant que mon usine à gaz ne tourne (et fasse peter les plombs de l'immeuble) ; une question d'optimisation plus ardue que je me l'étais imaginé : je gère un ensemble de tâches, chaque tâche est représentée sur une ligne au travers de différentes colonnes (Nom, durée, Ressource...), la dernière colonne étant réservée à la notation des autres tâches (et donc lignes) impactées en cas de modification des valeurs. Pour des raisons que je ne vais pas détailler ici, je peux pas recourrir à des fonctions perso appelées par les cellules impactées. Non, je traite directement à partir du Sub Worksheet_Change de la feuille. Et c'est là que se pose le pb, au niveau de la notation déjà parce que je ne peux pas utiliser le n° des lignes impactées en dur, cela doit rester relatif et la notation du type : =LIGNE($D$100)&';'&LIGNE($D$125)&';'LIGNE($D$148)
n'est pas avantageuse parce que pour traiter derrière, il faut tout dépiauter et je ne suis pas sûr que cela soit la bonne méthode. L'idéal cela aurait été une notation qui fournisse un tableau, comme pour une fonction standard avec plusieurs arguments, ainsi je n'aurais eu à faire qu'une boucle du type :

For i = 0 to Ubound(Listdelignes)

'traitement d'actualisation des lignes impactées

Next i

J'espère que cela t'inspire parce que moi j'patauge un peu. Un grand merci pour ton aide...
 

Hellboy

XLDnaute Accro
Bonsoir AGALAS

La flaterie et ton humour aura eu raison de mon retour. :)

Je ne suis pas sure du tout de saisir ce que tu explique. Car n'ayant pas le fichier devant moi, c'est drôlement difficile.

Mais.........

Je crois que l'utilisation de ta procédure évènementcielle est bonne, c'est peut être que tu n'utilise pas toute sa possibilité. Par Exemple:


Private Sub Worksheet_SelectionChange(ByVal Target As Range)

End Sub


Tu vois l'argument TARGET, cet argument contient plus d'information que tu le soupçonne. Bien sur que target est la cellule qui est modifié et donc pas conséquent pas celle qui se trouve dans la colonnes ou tu veux procéder a des changements si j'ai bien saisis.

2 choses:

1- Target contien le numéro de la ligne ou le changement se produit.
Ex:

Private Sub Worksheet_SelectionChange(ByVal Target As Range)
       
Dim intNoLigne            As Integer
       
        intNoLigne = Target.Row
End Sub

Donc comme tu connais toi le numéro de ta dernière colonne, tu peux donc avoir les 2 informations que tu as de besoin pour ton traitement. Ex:


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
       
Dim intNoLigne            As Integer
       
        intNoLigne = Target.Row
        Cells(intNoLigne, NoColonne).Value = 'J'espère que j'ai compris'
End Sub

2- Maintenant, si tu fais des traitement dans ta dernières colonne, cette procédure va s'activer aussi. Parce que tu effectue un changement !!!
Donc tu pourrais détercter a partir de Target le numéro de la colonne a qui appartien le changement et par condition si cette colonne est la dernières aucun traitement ne sera fait. !


Private Sub Worksheet_SelectionChange(ByVal Target As Range)
       
Dim intNoLigne            As Integer
       
   
' C'est juste un exemple. Il y a mainte autre façons de connaitre par commande
   
' la dernière colonne ou il y a présence de données dans une feuile
       
Const CLastCol            As Byte = 12
   
' Ceci est la négation d'une question. Si Pas égal à
       
If Not Target.Column = CLastCol Then
                intNoLigne = Target.Row
                Cells(intNoLigne, NoColonne).Value = 'J'espère que j'ai compris'
       
End If
End Sub


a+
 

AGLAS

XLDnaute Nouveau
Non Hellboy, merci mais, je me suis mal fait comprendre, je ne fais aucune modification dans la dernière colonne, je cherche juste à trouver le bon formalisme pour mon traitement pour accèder rapidement aux N° des lignes à traiter. Par exemple :

ligne n° 2 ... durée : 5,00 ... (et en dernière colonne) lignes impactées : 34;25;28
ligne n° 8 ... durée : 12,5 ... lignes impactées : 12;34;36

Et le traitement va lire la dernière colonne et pour chaque n° de ligne qu'il trouve effectue le traitement d'actualisation. Il doit bien avoir un moyen de définir une liste d'adresses (ou de lignes) dans une cellule autrement qu'en les concaténant grossièrement (comme dans mon précédent message). Sinon ça voudrait dire que dans le traitement je déconcatène avec du Instr() pour trouver le caractère de séparation et compagnie. Non faut que j'trouve un truc, c'est vachement important pour moi de sortir de là (alleeeez, si vous plaît m'sieu, je serais sage après).

PS : Hé n'empêche que ça fait 6 mois que je développe à mort avec VBA et je ne savais même pas à quoi servait Target :eek:
 

AGLAS

XLDnaute Nouveau
Salut Hellboy, le forum,

Le pb, c'est que ce n'est pas facile à expliquer et je veux bien essayer de poster le gourbi, mais c'est très gros (il y a des Userform de partout avec des spreadsheet, un paquet de feuilles, menus, boutons et consort) et donc il faudrait que je le réduise au stric minimum et ça risque de me prendre du temps ; je vais essayer.

Bon, mais je me demande si j'espère pas l'impossible ; l'idéal serait d'obtenir les références des cellules soumises au recalcul après modification de la valeur d'une cellule quelconque ; fantasme ou réalité, je ne saurais dire mais Excel doit bien stocker l'info sous une forme ou une autre....
 

Hellboy

XLDnaute Accro
re AGLAS

Je me ré-essaie avec autre chose.

Cela répond peut être plus a ton deuxième message.


Public Sub Test()
Dim strLigneImpactés()                As String
Dim intItem                                    As Integer
Dim bytColonneRef                        As Byte

'    Pour accélérer le processus du traitement, il faut éviter de rafraichir l'écran. Toute une différence
        Application.ScreenUpdating =
False
'    La commande Split(introduite avec Office 2000) met en Array l'information que tu lui donne
'    et sépare les éléments avec le délimiteur que tu choisis
        strLigneImpactés = Split(Cells(1, 1), ';')
       
       
For intItem = 0 To UBound(strLigneImpactés)
       
'    Juste pour un exemple a faire quelque chose
                Cells(strLigneImpactés(intItem), bytColonneRef).Activate
'    Cellule impacté
       
Next intItem
       
        Application.ScreenUpdating =
True
       
End Sub

Donne moi des nouvelles !

a+
 

AGLAS

XLDnaute Nouveau
Bonsoir, Bonjour le forum, Salut Hellboy,

D'abord merci Hellboy, je devais t'informer avant que tu m'adreses ton dernier message, car j'avais finalement trouvé l'astuce (l'instruction plus exactement) qui permet d'identifier les références des cellules impactées par un recalcul (après modification de la valeur d'une cellule quelconque) ; il suffit de boucler dans le Sub Worksheet_Change sur la méthode Dependents comme suit :

Dim c As Range

For Each c In Target.Dependents

'traitement des cellules dont le recalcul dépend de la valeur
'de la cellule modifiée (Target.value)
Next c

J'ai trouvé ça vendredi, j'étais aux anges, mais ça n'a pas duré (purée de purée) ; je dois absolument ordonner les adresses des cellules du Target.Dependents suivant leur indice de ligne avant de les soumettre au traitement ; Cela veut dire que la ligne 30 doit être traitée avant la ligne 70 sinon mon astuce tombe à l'eau. Et... je sais pas comment faire avec For Each, ni même avec une boucle For classique. J'ai fais plusieurs tentatives sans succès et je suis un peu saturé. Tu n'aurais pas une petite idée sur la manière de procéder par hasard Monsieur s'il vous plaît merci beaucoup ? Non parce que j'aimerais bien faire une vraie nuit de sommeil... Comme avant que je ne commence à développer en VBA...

Message édité par: AGLAS, à: 02/10/2005 01:43
 

myDearFriend!

XLDnaute Barbatruc
Bonsoir Aglas, Hellboy,

Je n'ai pas de solution à te proposer Aglas, mais je me permets juste de t'informer qu'il serait un peu plus correct de préciser que ton idée lumineuse de vendredi s'appelle Jean-Marie Lien supprimé *... et que poser la suite de ta question dans 2 fils en même temps n'est pas vraiment respectueux des usages dans ce forum...

* Pour info, Jean-Marie te donnait le tuyau le jeudi et le vendredi Hellboy planchait encore sur ce problème car il n'en avait pas connaissance...

Bonne fin de soirée.
 

AGLAS

XLDnaute Nouveau
Bonsoir, Bonjour le forum, myDearFriend, Hellboy,

Pour ton information myDearFriend, Jean-Marie n'est pas à l'origine de ce que tu as qualifié d'idée lumineuse. C'est d'ailleurs pourquoi je ne l'ai pas remercié immédiatement car je ne m'attendais pas précisémment à sa réponse. Tu observeras d'ailleurs dans le message laissé sur le forum et auquel Jean-Marie a répondu que je parlais déjà de 'notion de dépendance' ; c'est ainsi que je me suis mis tout seul sur la voix... Il ne faut pas croire que je m'en remets corps et âme à la bienveillance du forum ; en réalité je compte principalement sur moi-même. Je suis un vieil étudiant et dispose d'une longue expérience de quiproquos en tous genres ; après coup cela ne m'étonne pas que tu aies sauté à pieds joints dans ce qui te semblait une évidence. Mais parfois les apparences sont trompeuses. Et si j'ai dérogé aux bons usages du forum, j'espère que le forum ne m'en voudra pas trop car je reste reconnaissant à ceux qui m'ont prêté main forte, toi y compris. Sans doute qu'une fois mon mémoire accouché, je mettrais moi aussi mes quelques connaissances à contribution. Mais pour l'instant, j'observe que je n'ai pas encore couché une seule ligne de ce foutu mémoire et qu'il me reste à peine 2 mois avant la date limite ; c'est sans doute ce qui explique mon empressement et le fait que je me sois permis de diffuser plus largement.

Quant à Hellboy, ma déception est à la mesure de l'estime que je te portais ; car enfin tu avais toute ma sympathie et mon respect. Aujourd'hui, je découvre ce message goguenard, en forme de queue de poisson, une blague de mauvais goût ; quelle mesquinerie, franchement. Si j'avais été plus jeune et moins blasé je me serais sans doute appliqué à aboyer généreusement en guise de réponse. Mais... il est déjà 04H30 et je vais plutôt utiliser l'énergie qui me reste à tordre le coup de mon prog, alors Salut et bon vent.

PS : il est 09H00, mon pb est réglé. Au fait Hellboy, si d'aventure la mémoire te revenait... envoie-moi un télégramme, ça presse plus, d'acodac ? Merci quand même. ;)

Message édité par: AGLAS, à: 02/10/2005 09:20
 

LaurentTBT

XLDnaute Nouveau
Bonjour à tous,

Les gars, faut pas travailler si tard, les nerfs finissent par lâcher!

Aglas, si tu trouves le temps, puisque tu sembles avoir solutionné ton pb, pourrais-tu nous le faire partager?

Sinon, j'écris ce matin en réaction à ce que tu as écris plus haut:

Sinon ça voudrait dire que dans le traitement je déconcatène avec du Instr() pour trouver le caractère de séparation et compagnie

En fait, il existe une fonction VBA qui fait cela toute seule: SPLIT
qui sépare une chaine selon un séparateur choisi, et envoi chaque élément dans un tableau.

Si par exemple la dernière colonne est la 10ème, cela pourrait donner:

Code:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)

Dim T() As String
Dim i As Byte
T = Split(Cells(Target.Row, 10), ';')
' ici, je prend la cellule correspondant à la 10ème colonne
' sur la ligne de la cellule qui vient d'être modifiée
' avec SPLIT, le tableau T comprend chaque élément de la chaine
' de caractères de cette cellule, séparés par le ;

For i = 0 To UBound(T)
    MsgBox (T(i)) 'par exemple
'Reste à faire le traitement que tu souhaites
' pour chaque ligne impactée dont T(i) te donnes la référence
Next i

End Sub

Je ne sais pas si cela répond à la question exactement,
mais cela permet de parler de cette fonction SPLIT super utile.

Bonne journée.

Laurent.
 

Discussions similaires

Statistiques des forums

Discussions
312 228
Messages
2 086 421
Membres
103 205
dernier inscrit
zch