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 :

Noeuds (Nodes) dans une forme libre (freeForm) [XL-365]


Sujet :

Macros et VBA Excel

  1. #1
    Membre confirmé
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2017
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Août 2017
    Messages : 64
    Par défaut Noeuds (Nodes) dans une forme libre (freeForm)
    Bonjour,
    Une forme libre est composée d'un ensemble de segments reliant des nœuds (nodes).
    Pour une forme libre composée exclusivement de segments droits la forme comporte donc autant de nœuds que de segments + 1 (le nœud d'origine).
    Je n'ai pas de problème (en VBA) pour insérer ou supprimer des segments (avec leur nœud d’extrémité) tant que la courbe ne comporte que des segments droits.
    Mais si la forme comporte un, plusieurs ou exclusivement des segments courbes, sur chacun d'entre-eux Excel ajoute deux points de contrôle qui permettent de déterminer la courbure du segment (méthode des courbes de Bézier d'ordre 3).
    Le problème est que dans les descriptifs Office des méthodes qui permettant d'insérer, de supprimer ou de modifier un segment, le mot "nœud" (node) est utilisé indifféremment pour désigner ceux qui séparent les segments et ces points de contrôle !
    La propriété "Shapes.Vertices" qui permet de récupérer dans un tableau les coordonnées de tous les nœuds d'une forme libre n'indique pas de quel type de nœud il s'agit...
    Quelqu’un peut-il m'aider dans ce problème ?

  2. #2
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 414
    Billets dans le blog
    3
    Par défaut
    Bonjour,

    il semble que chaque Node a une propriété SegmentType qui aura la valeur msoSegmentLine ou msoSegmentCurve selon le cas

  3. #3
    Membre Expert
    Avatar de tototiti2008
    Homme Profil pro
    Formateur/développeur
    Inscrit en
    Octobre 2008
    Messages
    1 414
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Formateur/développeur

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 414
    Billets dans le blog
    3
    Par défaut
    Re,

    ma première réponse est plus pour répondre à la question : est-ce que ce sont des segments droits ou des courbes de bezier
    pour différencier les points de coins et les points de tangentes, je pense qu'il faut plutôt surveiller la propriété Node.Editingtype
    https://learn.microsoft.com/fr-fr/of...de.editingtype
    L'aide dit que ça prend différentes valeurs, mais dans les faits quand je regarde la propriété j'ai l'impression que EditingType renvoie une erreur quand c'est un point de tangente (à vérifier)

    Edit : c'est une erreur si on n'a pas édité les tangentes et désolidarisées, sinon ça change de valeur
    en effet ça a l'air pas clair
    peut-être une meilleure propriété ailleurs pour vérifier ça (pas encore trouvé pour ma part)

  4. #4
    Membre confirmé
    Homme Profil pro
    Retraité
    Inscrit en
    Août 2017
    Messages
    64
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 79
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Août 2017
    Messages : 64
    Par défaut Solution trouvée...
    Merci de la réponse.

    Connaître le type de segment associé à un nœud c'est possible.
    Mais le problème c'est que dans le cas d'un segment courbe la réponse sera toujours 1 (segment courbé) que l'on désigne le nœud d’extrémité (sommet) ou l'un des 2 nœuds précédents (points de contrôle de la courbe).
    Donc si plusieurs segments courbes se suivent, il est impossible de savoir quels nœuds sont des sommets.
    Et seuls l'index des sommets peuvent être utilisés pour insérer ou supprimer un segment ou modifier le position de son extrémité. !

    Pour info, les nœuds qui sont des sommets sont les seuls points de connexion (ConnectionSite) sur lesquels ont peut attacher des connecteurs.
    On peut bien connaître le nombre total de ces points (ConnectionSiteCount) mais cela n'est pas utile pour modifier un nœud ou un segment intermédiaire.

    La solution qui me semble la plus simple serait de n'utiliser que des segments courbés.
    Lorsqu'on en insère un nouveau, on peut facilement aligner ses points de contrôle avec ses sommets, il a alors la même apparence que des segments droits.
    Mais dans ce cas, l'index des sommets de le courbe sera toujours égal un multiple de 3 décrémenté de 1 (le nœud de départ).

    Je vais partir sur cette piste...

    Merci quand même pour la réponse !

    Merci de m'avoir mis sur la piste d'une autre solution très simple.
    La fonction suivante permet de savoir si un nœud est un sommet ou non :

    Function NoeudFL(Sp As Shape, n As Integer) As Boolean
    'Retourne "True" si le noeud n de la forme libre Sp est un sommet
    Dim i As Integer, j As Integer
    If Sp.Type <> msoFreeform Then Exit Function
    If Sp.Nodes.Item(n).SegmentType = msoSegmentLine Then
    NoeudFL = True
    Else
    For i = 1 To n - 1
    j = j + Sp.Nodes.Item(i).SegmentType
    'j n'est incrémenté que si le noeud(i) fait partie d'un segment courbe (Segment type = 1)
    Next i
    NoeudFL = j Mod 3 = 0
    End If
    End Function

  5. #5
    Invité de passage
    Homme Profil pro
         ​​​  
    Inscrit en
    Décembre 2025
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Autre

    Informations professionnelles :
    Activité :      ​​​  

    Informations forums :
    Inscription : Décembre 2025
    Messages : 22
    Par défaut
    En interne Excel utlise des bézier que ce soit pour les segments droits ou lisses c'est les positions des points du controls qui déterminent le type le lissage

    Pour connaître le type du point il faut calculer sa position pour les segments droit on lit un seul poins pour les beziers on avance par 3 poins, toutefois il faut distinguer entre les positions des points de controls pour les béziers (crtl1,crtl2, Sommet)et les splines (LCrtl, sommet, RCrtl):

    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
    19
    20
    21
    22
    23
    24
    25
    26
    Sub Macro2()
     Dim sh As Object, nd As Object
     On Error Resume Next
       ActiveSheet.Shapes("FreeFormOO").Delete
     On Error GoTo 0
     
      With ActiveSheet.Shapes.BuildFreeform(msoEditingCorner, 80, 20)
          .AddNodes msoSegmentLine, msoEditingCorner, 200, 20
          .AddNodes msoSegmentCurve, msoEditingCorner, 225, 30, 228, 60, 230, 76
          .AddNodes msoSegmentCurve, msoEditingCorner, 228, 95, 214, 126, 196, 136
          .AddNodes msoSegmentLine, msoEditingCorner, 120, 136
         Set sh = .ConvertToShape
          sh.Name = "FreeFormOO"
      End With
     
      Dim Pts, nBr As Long, I As Long, J As Long
      I = 1
      While I <= sh.Nodes.Count
          nBr = IIf(sh.Nodes(I).SegmentType = msoSegmentCurve, 3, 1)
          For J = 1 To nBr
             Pts = sh.Nodes(I).Points
             Debug.Print IIf(J = nBr, "Sommet", "Ctrl" & J), Pts(1, 1), Pts(1, 2)
             I = I + 1
          Next
       Wend
    End Sub
    Affiche:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Sommet         80            20 
    Sommet         200           20 
    Ctrl1          225           30 
    Ctrl2          228           60 
    Sommet         230           76 
    Ctrl1          228           95 
    Ctrl2          214           126 
    Sommet         196           136 
    Sommet         120           136

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

Discussions similaires

  1. mesure d'une forme libre dans Visio
    Par FilouT dans le forum Visio
    Réponses: 0
    Dernier message: 29/05/2023, 16h44
  2. [XL-2013] Selection d'objet dans une forme libre
    Par remi_62 dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 31/05/2019, 15h23
  3. [XL-2007] Récuperer le nom d'une image inserée dans une forme libre
    Par Miike dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 19/11/2017, 22h25
  4. Texte dans une forme libre
    Par Eric94360 dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 06/12/2015, 14h53
  5. Insérer du texte dans une forme libre
    Par francoislc dans le forum Excel
    Réponses: 7
    Dernier message: 27/02/2015, 10h29

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