IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Comment passer le range Target à une fonction ? (c'est la valeur et pas l'objet qui est passé !?) [XL-2010]


Sujet :

Macros et VBA Excel

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2006
    Messages : 5
    Points : 9
    Points
    9
    Par défaut Comment passer le range Target à une fonction ? (c'est la valeur et pas l'objet qui est passé !?)
    Bonjour,

    Je pensais connaître VBA, mais pas assez, visiblement :-)

    Dans la procédure
    Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range)
    j'appelle une fonction de validation de la valeur de Target en fonction de sa position.

    L'argument de cette fonction est le range Target

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ...
    ...
        If Not ValidationPremiereLigne(Target) Then
            Exit Sub
        End If

    Ma fonction ValidationPremiereLigne se trouve dans un module "normal" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function ValidationPremiereLigne(MaCellule As Range) As Boolean
    ...
    ...
    Je m'attends à ce que ce soit un objet range (Target) qui soit passé à la fonction. Or c'est la valeur de Target qui est passée, et pas l'objet.
    Il y a donc quelque chose qui m'échappe.

    J'ai cherché sur le web, sur le forum : cela a l'air très simple pour tout le monde...sauf pour moi.

    Merci a la bonne âme qui pourra m'aider.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Bonjour,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Function ValidationPremiereLigne(ByRef MaCellule As Range) As Boolean 'Contrairement à ByVal par défaut !
    End Function

  3. #3
    Membre extrêmement actif
    Homme Profil pro
    aucune
    Inscrit en
    Avril 2016
    Messages
    7 563
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 82
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : aucune

    Informations forums :
    Inscription : Avril 2016
    Messages : 7 563
    Points : 12 422
    Points
    12 422
    Par défaut
    Bonjour Robert
    Attention -->> sous VBA, c'est l'argument ByRef, qui est en vigueur par défaut.
    Je n'accepte pas de demande d' "amitié" individuelle. Tout développeur est pour moi un ami.
    Je n'ouvre AUCUN classeur tiers (avec ou sans macro ******). Ne m'en proposez donc pas .

    ****** : Non, non ... un classeur .xlsx ne "peut" par exemple et entre autres pas contenir un activex (de surcroît invisible) , "bien sûr" ...

    Il est illusoire de penser que l'on saurait exprimer valablement et précisément en un langage (rigide) de développement ce que l'on peine à exprimer dans le langage naturel, bien plus souple.

  4. #4
    Membre expert
    Profil pro
    Inscrit en
    Février 2007
    Messages
    2 267
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2007
    Messages : 2 267
    Points : 3 663
    Points
    3 663
    Par défaut
    Bonjour,

    si tu mets un espion tu vois autre chose que Range/Range dans son type ?
    Ca parait étonnant. Que lis-tu comme type ?
    eric

  5. #5
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 379
    Points : 12 075
    Points
    12 075
    Billets dans le blog
    8
    Par défaut re
    re
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Function ValidationPremiereLigne(MaCellule As Range) As Boolean
     ...
     ...
    en fait ton target est bien transmis en tant que range

    maintenant tout depend du code que tu a dans cette fonction et de la facon dont tu utilise le target(Macellule)

    je pense que ca doit venir de la
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  6. #6
    Membre chevronné
    Avatar de NVCfrm
    Homme Profil pro
    Administrateur Système/Réseaux - Developpeur - Consultant
    Inscrit en
    Décembre 2012
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Administrateur Système/Réseaux - Developpeur - Consultant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 1 036
    Points : 1 917
    Points
    1 917
    Billets dans le blog
    5
    Par défaut
    Bonjour à tous.
    Citation Envoyé par jphcrutzen Voir le message
    Bonjour,
    ...
    Je m'attends à ce que ce soit un objet range (Target) qui soit passé à la fonction. Or c'est la valeur de Target qui est passée, et pas l'objet.
    Il y a donc quelque chose qui m'échappe.
    Il y a quelque chose qui nous échappe dans ce que tu veux exprimer comme problème.
    Ce qui aurait épargné une perte de temps à tous, c'était de montrer le code de manipulation de ta variable maCellule dans la fonction. Et nous indiquer là ou ça coince.

    Un petit rappel des fondamentaux s'impose :
    - La variable passée par réference consiste à affecter à l'argument de la fonction la reference de ladite variable. Un peu semblabe aux pointeurs dans les langages de bas niveau. La fonction ayant cette variable definie par reference, manipule directement la variable d'origine via sa reference.

    - Le passage par valeur va "cloner" la variable dans une autre. Toute les manipulations sont effectuées sur une copie de variable qui dispose de sa propre référence.

    On revient à cette notion de reference qui veut que pour affecter une valeur, VBA a besoin d'une reference.
    Toutes les variables pointent sur une reference et une seule. Une reference peut avoir pour valeur une donnée intrinsèque, voir une autre réference.
    Une reference peut être désignée par plusieurs variables.
    La reference serait la zone mémoire réservée pour un type de donnée.
    Et VBA se contente en interne de changer la reference d'une variable par la reference de celle qui lui a été affectée. Pour illustrer :
    Soit A = 1, B = 0, C = A.
    B dispose d'une réference dont la valeur est 0.
    C de la meme reference que A valant 1.
    Ceci pour dire que nous avons 2 references definies pour 3 variables, et que l'affectation C = A n'affecte pas la valeur 1 à ce dernier, mais fait pointer C sur la reference de A. La lecture de sa valeur renverra 1.
    Si nous avons une fonction attendant un argument du même type que A, que nous voudrions lui transmettre la valeur de A, mais nous ne voulons pas que cette valeur soit changée au retour de la fonction appelée, il suffit de forcer par le mot clé ByVal le passage d'argument, pour retrouver la valeur 1, meme si la fonction appelée y a effectué des changements.

    Ce mécanisme adopté par VBA peut avoir l'air troublant, mais compréhensible quand on sait qu'une variable objet par exemple peut avoir un grand nombre de sous variables de données plus ou moins importantes.

    Tu auras remarqué , il se trouve que la variable Target elle même est définie ByVal dans la procédure évènementielle Private Sub Workbook_SheetChange(ByVal Sh As Object, ByVal Target As Range). Une protection de VBA pour qu'elle ne soit pas déferencée dans la routine invisible qui a déclenché cet appel par un code du genre Set Target = UnAutreRange . Quand la routine invisible reprendra la main, elle trouvera que Target reference en son sein le même Range.

    Tu pouuras donc changer la (les) valeur(s) de Target ou même la redefinir (c'est une variable comme toute autre) dans ta sous routine. Mais dans la suite quand Workbook_SheetChange rendra l'âme, pardon la main; la réference de Target à l'origine reste le même.

    Ton problème se situe t-il quelque part là bas ... dans une boucle évènementielle ???

    Je penses que ces quelques lignes t'auront permis de comprendre.
    Ousmane


    Quand on tombe dans l'eau, la pluie ne fait plus peur.

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Août 2006
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Août 2006
    Messages : 5
    Points : 9
    Points
    9
    Par défaut
    Bonjour et merci à tous les contributeurs.

    J'ai simplifié au maximum mon code, et ça fonctionne maintenant comme attendu.

    Le problème provenait de ce que, dans ma fonction ValidationPremiereLigne(MaCellule as Range), je faisais un appel à une seconde fonction EstPremiereLigneCommande(MaCellule)
    C'est là que je perdais le fil.

    Merci Ousmane pour les explications précises. Je vais les garder sous le coude.
    Merci aux autres pour les pistes de recherche, et notamment à Patrick.

  8. #8
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 57
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 122
    Points : 55 947
    Points
    55 947
    Billets dans le blog
    131
    Par défaut
    Citation Envoyé par NVCfrm Voir le message
    [...]
    Et VBA se contente en interne de changer la reference d'une variable par la reference de celle qui lui a été affectée. Pour illustrer :
    Soit A = 1, B = 0, C = A.
    B dispose d'une réference dont la valeur est 0.
    C de la meme reference que A valant 1.
    Ceci pour dire que nous avons 2 references definies pour 3 variables, et que l'affectation C = A n'affecte pas la valeur 1 à ce dernier, mais fait pointer C sur la reference de A. La lecture de sa valeur renverra 1.[...]


    Dans le cas que tu cites, C ne pointe pas vers A et il y a bien trois références et non deux comme tu l'affirmes et C n'a pas la même référence que A. On affecte à une nouvelle variable C la valeur de A, mais après, chacune vit sa vie... Si ce que tu disais était exact, le code suivant afficherait 4, alors qu'il affiche 1... En affectation directe et pour les variables simples, c'est toujours la valeur qui est passée, pas la référence.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sub Test()
      Dim A, B, C
     
      A = 1
      B = 2
      C = A
      A = 4
      MsgBox C
    End Sub
    Ce que tu dis est vrai si A et C étaient des objets, car dans ce cas, Set C = A transmet à C la référence à A, de sorte que si tu modifies C, tu modifies A puisque c'est le même objet.

    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  9. #9
    Membre chevronné
    Avatar de NVCfrm
    Homme Profil pro
    Administrateur Système/Réseaux - Developpeur - Consultant
    Inscrit en
    Décembre 2012
    Messages
    1 036
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité : Administrateur Système/Réseaux - Developpeur - Consultant
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Décembre 2012
    Messages : 1 036
    Points : 1 917
    Points
    1 917
    Billets dans le blog
    5
    Par défaut
    Citation Envoyé par Pierre Fauconnier Voir le message
    Ce que tu dis est vrai si A et C étaient des objets, car dans ce cas, Set C = A transmet à C la référence à A, de sorte que si tu modifies C, tu modifies A puisque c'est le même objet.

    Merci d'avoir précisé ce détail qui est ce auquel je me réfère dans cette discussion qui est attachée de fait à un objet.

    Quand on lit la discussion au début, on a un demandeur qui a un problème dans le passage en argument ByVal d'un objet Range.

    Ma réponse est restée mentalement accrochée à la notion des variables objet.
    L'explication démonstrative ne voulant pas être lourd en écriture, vu que je ne pensais pas qu'on pouvait croire en lisant, penser que je parles d'autre chose.
    Je comprends la remarque, qui relève cette insuffisance si on venait juste lire la partie incriminée.
    Pour ceux qui me connaissent un peu mieux et qui maîtrisent le sujet, il n'y a pas matière à équivoque.
    Ousmane


    Quand on tombe dans l'eau, la pluie ne fait plus peur.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. VBA - Passer un range d'une feuille spécifique à une fonction
    Par mydomdom dans le forum Macros et VBA Excel
    Réponses: 11
    Dernier message: 28/03/2017, 15h50
  2. Réponses: 6
    Dernier message: 04/04/2011, 21h22
  3. Comment passer un argument dans une fonction
    Par DeezerD dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 22/01/2008, 18h13
  4. [c#] passer un textbox dans une fonction
    Par damn dans le forum ASP.NET
    Réponses: 5
    Dernier message: 08/09/2005, 16h54
  5. Passer en paramètre d'une fonction (...)
    Par Captain_JS dans le forum C++
    Réponses: 5
    Dernier message: 03/11/2004, 07h18

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo