[VBA Excel] Fonction rebelle (maj de cellule)

Fonction rebelle (maj de cellule) [VBA Excel] - VB/VBA/VBS - Programmation

Marsh Posté le 06-05-2005 à 20:37:44    

Bonjour à tous,  
 
Je débute avec VBA mais c'est plutôt laborieux : Voilà quelques jours maintenant que je cherche le moyen de modifier le contenu d'une cellule via une fonction personnalisée (que j'ai nommé IFEXIST) exécutée à partir d'autre cellule (is that possible or not ?).  
 
C'est la dernière ligne de la fonction qui semble poser problème (sans elle, cela fonctionne plutôt bien, mais avec elle la fonction renvoie #VALEUR). Je n'emploie visiblement pas les bons arguments pour convaincre cette fonction de faire ce que j'attends d'elle, peut-être même que je poursuis là un voeu pieux ; pour une raison que j'ignore, il n'est peut être pas possible de modifier une autre cellule que celle qui exécute la fonction ou bien je n'ai pas la bonne syntaxe pour le faire... Qu'en pensez-vous ? :pt1cable:      
 
Function IFEXIST(ParamArray Prédécesseur() As Variant)  
 
 
    Dim colSelection, colDatefin, colDatedeb, i As Integer  
    Dim debFlag As Boolean  
    Dim datedeb, datefinPrec As Date  
 
 
    colDatedeb = 5  
    colDatefin = 6  
    colSelection = 10  
    datedeb = Cells(ActiveCell.Row - 1, colDatedeb)  
    'MsgBox datedeb, vbQuestion + vbOKOnly  
 
    debFlag = True  
 
   For i = 0 To UBound(Prédécesseur())  
         LigSelection = Prédécesseur(i) + 1  
         If Cells(LigSelection, colSelection) = "Vrai" Then  
 
              datefinPrec = Cells(LigSelection, colDatefin).Value  
              If datefinPrec > datedeb Then  
                datedeb = datefinPrec  
              End If  
 
              If debFlag Then  
                IFEXIST= IFEXIST & Prédécesseur(i)  
                debFlag = False  
              Else  
                IFEXIST= IFEXIST & ";" & Prédécesseur(i)  
              End If  
           End If  
    Next i  
                '-----------------------------ci-après la ligne posant problème ----
                ActiveCell(ActiveCell.Row, colDatedeb).Value = datedeb  
End Function  
   

Reply

Marsh Posté le 06-05-2005 à 20:37:44   

Reply

Marsh Posté le 06-05-2005 à 21:18:36    

Essaye ça:
 

Selection.cells(1, colDatedeb) = datedeb

 


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 21:23:14    

Attention dans tes Dim.
 

Citation :

Dim datedeb, datefinPrec As Date


Seul datefinPrec est défini comme Date
datedeb est un variant.
 
Il faut répéter le as pour chaque variable.
 
Ca n'a rien de dramatique à l'usage mais si tu déclares tes variables, autant qu'elles le soient proprement.


Message édité par AlainTech le 06-05-2005 à 21:23:33

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 21:25:04    

Merci pour ta réponse Alain, mais le pb c'est qu'il ne s'agit pas d'une cellule positionnée en ligne 1 ; autrement dit je ne suis pas censé savoir de quelle ligne il s'agit, cette fonction peut être exécutée par différentes cellule.

Reply

Marsh Posté le 06-05-2005 à 21:29:15    

Je l'avais bien compris...
 
As-tu essayé?
 
Essaye d'abord et viens me dire quoi après.
 
La propriété cells se réfère à Selection et je lui dis: Va sur la même ligne (row 1) que la sélection dans la colonne colDatedeb.


Message édité par AlainTech le 06-05-2005 à 21:29:36

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 21:29:28    

Merci encore Alain... Nos messages respectifs se sont croisés. Pour ce qui est de la déclaration des variables dim, je vais en tenir compte, mais le pb reste entier.

Reply

Marsh Posté le 06-05-2005 à 21:30:21    

Rebelote, je vais essayé de suite.

Reply

Marsh Posté le 06-05-2005 à 21:33:17    

Non, effectivement le pb demeure. Le résultat est toujours #VALEUR

Reply

Marsh Posté le 06-05-2005 à 21:42:55    

Mets un msgbox(datedeb) juste avant ta ligne à problème.


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 21:48:59    

Je l'ai déjà fait et le contenu est celui attendu, c'est à dire la date la plus en aval des lignes flaguées à VRAI.  

Reply

Marsh Posté le 06-05-2005 à 21:48:59   

Reply

Marsh Posté le 06-05-2005 à 21:54:54    

Juste un truc.
 
Tu me dis que la fonction renvoie un #VALEUR...
Veux-tu dire que c'est ce qui se met dans la cellule ou bien c'est la valeur renvoyée par ta fonction à une fonction appelante?


Message édité par AlainTech le 06-05-2005 à 21:55:14

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 22:02:15    

=IFEXIST(72,80,90) saisi dans ma cellule par exemple affiche dans cette même cellule après exécution : #VALEUR

Reply

Marsh Posté le 06-05-2005 à 22:10:10    

Oula, je comprends mieux ce que tu fais.
Dans ta fonction, tu renvoies une valeur qui doit se mettre dans ta cellule et, en plus, tu modifies le contenu de cette même cellule.
Donc tu vires le contenu qui devrait rester =IFEXIST(72,80,90).
 
Je pense que le problème vient de là.
 
Ne peux-tu lancer une Sub (et pas une Function) par un événement plutôt que de taper ton appel à la fonction dans la cellule?


Message édité par AlainTech le 06-05-2005 à 22:11:12

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 22:12:22    

Je dois me casser, maintenant.
Je t'écris un MP.


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 06-05-2005 à 22:21:15    

La fonction renvoie une valeur qui se trouve être une concaténation de n° de ligne (que je gère moi) séparés par des points virgules, la présence dans chaque n° de ligne étant conditionnée par un test sur une cellule de la ligne désignée (Flagée VRAI ou FAUX), in fine le résultat du calcul (cette liste) est affichée comme il se doit dans la cellule comme le ferait n'importe qu'elle autre fonction d'excel. Mais pour le reste, il me faut modifier dans la foulée une autre cellule qui découle en partie de ce traitement en tout cas, qui en est tributaire, de toutes les lignes inspectées l'une doit fournir une date, la date plus en aval de toutes ligne, pour ça je n'ai pas de problème à la déterminer, mais ensuite, il s'agit de coller cette date dans une cellule qui elle se trouve sur la même ligne que la cellule qui "exécute" la fonction en question et c'est là que le gourbi se prend les pieds dans le tapis.

Reply

Marsh Posté le 07-05-2005 à 10:45:12    

J'étais à peine parti que je me rendais compte de ma connerie...
Ce n'est, bien sur, pas la même cellule que tu modifies.
Me suis un peu planté.
 
As-tu essayé de faire ta modification de cellule avant d'assigner une valeur à ta fonction?


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 09-05-2005 à 11:56:00    

Merci Alain mais, j'ai décidé de contourner le pb autrement, par contre, j'ai un autre petit soucis avec un filtre automatique qui me laisse un peu perplexe ; j'ai enregistré une macro pour récupérer le code relatif à l'application d'un filtre automatique qui fonctionne très bien manuellement, mais lorsque j'exécute le code généré, j'ai la désagréable suprise de constater qu'en dehors des titres de colonnes (la ligne 1), aucune ligne n'est retenue, et ce, alors le critère de filtre (visible sur clic sur la flèche située sur la colonne) est bien le bon (VRAI dans le cas présent). Tu n'aurais pas une idée sur le sujet des fois ? Ci-après le bout de code :
 
    Selection.AutoFilter Field:=10, Criteria1:="VRAI"  '<- la ligne posant pb
    Rows("1:540" ).Select
    Selection.Copy
    Workbooks.Add
    ActiveSheet.Paste
 

Reply

Marsh Posté le 09-05-2005 à 14:43:05    

C'est tout con et typiquement Microsoft.
 
Il faut remplacer "VRAI" par True (sans guillemets).


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 09-05-2005 à 19:39:52    

C'est terrible quand même de se prendre les pieds dans le tapis pour si peu. Merci à toi Alain, tu ne sais pas à quel point c'est providentiel... sauf qu'entre temps je me suis trouvé confronté à 1 nouveau casse-tête sur lequel je m'arrache les cheveux depuis 3 bonnes heures   :fou: . J'ai en partie recyclé ma fonction de concaténation, sauf que je l'ai adapté grossièrement pour qu'elle me renvoit cette fois-ci des références de cellules, ce qu'elle fait à peu très (...); REF() donc renvoit une suite d'adresse de type B25;B28;B29;B30... mais lorsque je tente d'exploiter le résultat avec une fonction standard alors là ça capote net. En gros ça donne quelque chose du genre :
 
SOMME(REF(B24;B25;B26;B27;B28;B29;B30;B31;B32))*10/100    -> renvoie #VALEUR!
 
sachant que REF(B24;B25;B26;B27;B28;B29;B30;B31;B32) renvoit pourtant une suite de réf. concaténée avec ";"
 
Je pige pas   :bounce:.  
 
D'autre part je me demandais s'il existe un moyen simple de convertir une référence de type B20 en 2,20 ? De manière à lire la valeur d'une cellule au moyen de la commande Cells(ligne, colonne) et donc sans la sélectionner (j'ai peut être pas tout compris mais bon). Enfin voilà, je ne voudrais pas te gonfler avec mes questions mais je suis comme qui dirait un peu dans mouise ; je me suis engagé à produire une sorte d'interface Excel/Project et je galère comme pas possible :kaola:. Un grand merci par avance donc pour toute info sur ces sujets. Oliv.
 
 

Reply

Marsh Posté le 10-05-2005 à 09:18:19    

Euh, pourquoi utilises-tu REF()?
Dans le cas ci-dessus, SOMME(B24:B32) suffit...


Message édité par AlainTech le 10-05-2005 à 09:21:15

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 10-05-2005 à 12:01:42    

Non, en fait l'exemple n'est pas parlant, mais bon, laisse tomber, j'ai trouvé le moyen de faire ce que je voulais, mais dis-moi (sans vouloir abuser de ton temps) sais-tu comment je peux intercepter une modification sur une plage de cellules ? Non parce que j'ai créé un certain nombre de fonctions qui dépendent de la valeur de cellules connexes et les éventuelles modifications de celles-ci ne sont pas suivies d'une actualisation des cellules contenant les fonctions s'y rapportant.

Reply

Marsh Posté le 10-05-2005 à 13:24:25    

Pour intercepter les changements:
Dans le code de la FEUILLE tu mets

Private Sub Worksheet_Change(ByVal Target As Excel.Range)


Message édité par AlainTech le 10-05-2005 à 13:25:10

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 10-05-2005 à 18:25:24    

Merci mais ça ne change rien ; en fait, j'ai 2 feuilles dans mon classeur, sur la 1ère, il y a des cases à cocher de type formulaire associées à des cellules qui répercutent leur état VRAI ou FAUX si cochées ou non. Dans la 2nde feuille, il y a d'autres cellules qui pointent sur ces cellules (de la 1ère feuille) et en fait les fonctions perso devraient pouvoir être recalculées à chaque modification de la valeur d'une de ces cellules. Et en plaçant le code que tu m'as filé dans l'espace Worksheet, ou general, que ce soit lorsque je clique sur une case à cocher de la 1ère feuille ou encore lorsque je modifie la valeur VRAI <-> FAUX dans la 2nde, rien ne se passe...

Reply

Marsh Posté le 11-05-2005 à 05:26:59    

Le code que je te donne n'est que "l'enveloppe".
Tu dois y mettre le code que tu veux.
 
Dans ton cas, je pense plutôt à l'option de recalcul automatique qui ne serait pas cochée.
 
Si elle est bien cochée, je sais qu'il est possible de forcer un recalcul.
Pas le temps de chercher maintenant.
Si tu trouves, le code est à mettre dans la fonction événementielle que je t'ai donnée.

Reply

Marsh Posté le 12-05-2005 à 02:25:37    

Ok Alain, je vais mettre en application, merci encore. Une petite question subsidiaire tout de même : tu ne saurais pas comment je pourrais copier via VBA un userform attaché à mon classeur courant dans un autre classeur ?

Reply

Marsh Posté le 12-05-2005 à 08:45:47    

Oups, copier un formulaire par VBA.
Je veux bien chercher si ça en vaut la peine mais... Dans quel but???


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 12-05-2005 à 11:05:56    

Oui ça vaut la peine (enfin je pense) ; en fait j'ai un classeur paramétrable qui propose une liste d'options (cases à cocher sur un la 1ère feuille), celles-ci se rapportent à un arbre de tâches (sur la 2nde feuille) ; en clair l'utilisateur sélectionne ou non des macros tâches et à la validation, l'arbre s'y rapportant est créé dans nouveau classeur à partir de l'arbre générique ; chaque nouveau classeur ainsi constitué correspond un nouveau projet qui va vivre sa vie indépendamment du classeur dont il est issu ; cela veut dire qu'il est ensuite susceptible d'être modifié, quant à la charge impartie à chaque tâche notamment, sachant que la charge de certaines tâches détermine celle d'autres tâches (prorata), c'est pourquoi j'ai besoin d'importer certaines formules qui doivent rester actives dans le classeur généré (et gérer les références en fonction !...), le gourbi inclût une fonctionnalité d'aide au chiffrage (la userform en question), elle doit figurer dans le document généré. Je me rends bien compte que cela peut paraître nébuleux, mais je ne vois pas comment procéder autrement, je ne peux pas enregistrer mon classeur initial sous un autre nom parce que les lignes exclues de la sélection demeurent (même masquées) et cela compromettrait ensuite l'importation du gourbi dans Ms Project (heu oui, il y a aussi Project, mais j'en fait mon affaire). Voilà je crois que cela peut te donner une idée assez précise du problème posé. Qu'en penses-tu ?


Message édité par oaglas le 12-05-2005 à 11:11:39
Reply

Marsh Posté le 12-05-2005 à 11:09:20    

Et créer un classeur "template", préformaté mais sans données... Ca ne peut pas convenir?


---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 12-05-2005 à 11:14:31    

Heu un classeur template sans données ? Et mes lignes où est-ce que je vais les chercher à ce moment là ? Sachant que les formules sont attachées aux lignes... Comment tu vois le truc exactement ?

Reply

Marsh Posté le 12-05-2005 à 14:16:47    

Comme je ne connais pas le contenu de ton classeur, je peux difficilement répondre.
Je sais seulement que moi, quand j'ai un classeur qui doit se répéter, je le sauve (read only) avec les données (formules) qui sont toujours les mêmes et je crée les classeurs "données utilisables" à partir de là (via "Enregistrer sous..." ).
 
En relisant ton exposé ci-dessus, j'imagine que ton utilisateur pourrais faire tous ses choix puis (éventuellement en cliquant sur un bouton) "enregistrer sous..." le classeur avec les choix qu'il a faits.
 
Suis pas certain d'avoir bien compris ton but donc ma proposition ne correspond, peut-être, pas à ce que tu cherches.


Message édité par AlainTech le 12-05-2005 à 14:18:01

---------------
Si on vous donne une info qui marche, DITES-LE!!!! ------ Si vous trouvez seul, AUSSI, votre solution peut servir à d'autres! ------ Je dois la majorité de mes connaissances à mes erreurs!
Reply

Marsh Posté le 13-05-2005 à 10:49:12    

Le Template fonctionne, je l'appelle depuis ma macro, puis insère les lignes qui vont bien et termine par un enregistrer sous, mais cela oblige à gérer 2 classeurs pour en générer un autre, car je ne peux en l'état enregistrer le 1er classeur ; je ne vais pas rentrer dans les menus détails mais disons qu'en l'état le classeur d'origine ne peut pas être exporté vers Ms Project. Si toutefois tu avais une idée sur la manière dont je peux via VBA copier ce userform dans un autre classeur en même temps que le reste, je suis preneur. En tout cas merci pour tout.
 

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed