Gestion des shapes (affichage, grouper...)

Lalalathuile Messages postés 8 Statut Membre -  
yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   -
Bonjour tout le monde,

Je suis nouveau en VBA et je ne sais pas gérer l'affichage des shapes selon des résultats

En résumé :
J'ai un plan (image de fond) ou j'ai ajouté des nœuds (insertion => forme => Ellipse). J'ai ensuite ajouté des connecteurs en les nœuds (insertion => forme =>connecteur).
A côté du plan, j'ai une matrice composé de n lignes et n colonnes (n = nombre de nœuds) qui peut varier selon les demande de la journée.

Exemple :

x 1 2 3 4 Dans l'exemple on a x(1, 2) = 1, j'aimerais que lorsqu'une valeur est égal
1 0 1 0 1 à 1 un connecteur s'affiche entre les 2 nœuds (entre le nœud 1 et 2 pour
2 1 0 0 1 l'exemple mais si il est égale à 0 il disparaisse.
3 0 0 0 0 Je sais qu'on peut utiliser la fonction :
4 1 1 0 0 ActiveSheet.Shapes("Connecteur droit 15").Visible = True (ou False)
Pour activer un connecteur.

Par contre dans certains cas le trajet entre deux nœuds est composé de plusieurs connecteurs (exple : il y a un virage).

1) J'aimerai dans premier temps grouper les connecteur qui vont ensemble (VBA ou non) et ensuite leur donner un nom :
Exemple : les connecteurs 15, 16 et 17 forme le trajet du noeud 1 au 2, j'aimerai les grouper puis ensuite nommer la forme : "12" (12 => trajet de 1 à 2)

2) J'aimerai pouvoir afficher les nouvelle forme selon leur nouveau nom avec une boucle :
For i = 1 to 4
For j = to 4
If cells(i,j) = 1 then

ActiveSheet.Shapes(i&j).Visible = True (si i = 1 et j = 2, activer le connecteur 12)

Else

ActiveSheet.Shapes(i&j).Visible = False

Next
Next

Je ne sais pas si c'est possible et je ne connais pas la syntaxe exacte ? Est-il possible d'intégrer i et j dans les parenthèses ?

3) Ne pas afficher les noeuds qui ne sont utilisé, dans l'exemple le noeud 3 n'est pas utilisé, il faudrait le faire disparaître du plan, peut-ont donné de ce qu'il a écris dedans à une shape ? Faudrait faire la somme pour chaque ligne ou chaque colonne de la matrice et si elle égal à 0, ne pas afficher le noeud correspondant mais cette partie reste encore vague

Merci d'avance pour vos réponses, je ne sais pas si j'ai été clair...

Lalalathuile

6 réponses

  1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    bonsoir, peux-tu partager ton fichier?
    0
  2. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    cette partie-ci devrait être facile:
    ActiveSheet.Shapes(i&j).Visible = True (si i = 1 et j = 2, activer le connecteur 12)
    tu peux faire
    ActiveSheet.Shapes(cstr(10*i+j).Visible = True 
    0
    1. Lalalathuile Messages postés 8 Statut Membre
       
      Merci beaucoup, ça fonctionne bien,
      Je n'arrive juste pas à regrouper mes shapes et leur donner le nom que je souhaite ? Grouper deux connecteurs et leur données un nom (12 par exemple) pour pouvoir le mettre dans une boucle ? Je sais pas si on peut faire ça manuellement ou on est obligé de passer par VBA.
      Faut que je fasse un fichier exemple si je veux le partager car c'est un fichier confidentielle. Il faut utiliser quoi pour partager un fichier ?

      Merci d'avance

      Lalalathuile
      0
    2. Lalalathuile Messages postés 8 Statut Membre > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
       
      Merci pour le lien,
      ci-joint le fichier :

      https://www.cjoint.com/c/GFbhmRT4DLb

      Merci d'avance,

      Lalalathuile
      0
    3. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > Lalalathuile Messages postés 8 Statut Membre
       
      si je vois bien, tu as un connecteur (le 57) qui participe à deux trajets.
      comment vas-tu faire?
      je pense à deux options:
      - créer un connecteur supplémentaire, pour que chaque connecteur ne fasse partie que d'un trajet
      - laisser tomber l'idée de shape, et travailler sur les connecteurs, en ayant une table qui fait le lien entre les trajets et les connecteurs
      sinon, en utilisant ton fichier, j'ai pu facilement créer un groupe avec des connecteurs
      je pense à autre chose: ta convention pour nommer les shapes (12 entre 1 et 2), tu dois obtenir 12 aussi entre 2 et 1?
      0
    4. Lalalathuile Messages postés 8 Statut Membre
       
      -Oui, il y a bien des connecteurs utilisé pour faire le même trajet et créer des doubles est un peu fastidieux lorsqu'on a un grand ensemble de noeud, le nombre de trajet augmente en 2^n.
      Je pensais faire :
      1) Si le trajet entre deux noeud est effectué activé le ou les connecteur (ou changer de couleur), de ce fait si un connecteur est utilisé deux fois, il n'y a pas de problème.

      et ne pas s'occuper des trajets qui ne sont pas effectués.

      2) Faire disparaître tout les connecteur qui ne sont pas rouge (je ne sais pas si c'est rouge)

      -Travailler sur les connecteur c'est à dire ? Créer une liaison entre le noeud et l'arc ?

      -Oui, 12 doit être obtenu dans les deux cas, il n'y a pas sens de trajet.

      Merci d'avance,

      Lalalathuile
      0
  3. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    juste pour t'inspirer, ceci désactive toutes les formes:
    Option Explicit
    Sub testlalala()
    Dim uneshape As Shape
    Dim monsheet As Worksheet
    Set monsheet = ActiveSheet
    For Each uneshape In monsheet.Shapes
        Debug.Print uneshape.Name
    Next uneshape
    For Each uneshape In monsheet.Shapes
        uneshape.Visible = False
        Next uneshape
    End Sub
    

    cela te montre aussi comment du code vba peut faire le tour de tous les shapes, découvrir leur noms, et agir sur chacun.
    0
    1. Lalalathuile Messages postés 8 Statut Membre
       
      Merci yg_be, j'ai résussie à masquer les shapes souhaité mais je ne n'arrive pas à afficher ceux voulue.

      Pour la question 1 j'ai fait :

      Sub MasquerObj()
      Dim i As Integer
      Dim n As Integer
      Dim Nbarc As Integer

      Nbarc = 18
      n = 10

      With Sheets("Affichage")
      For Each sh In .Shapes
      For i = 0 To Nbarc

      If sh.Name = "A" & i Then
      sh.Visible = True
      End If

      If sh.Name = "N" & i Then
      sh.Visible = True
      End If

      Next i
      Next sh
      End With
      End Sub

      Mais j'arrive pas à faire la deuxième partie

      Sub Affichage()

      Dim Tabl()
      ReDim Tabl(Nbarc, 5)

      Dim i As Integer
      Dim j As Integer
      Dim n As Integer 'Nombre de noeud
      Dim Nbarc 'Nombre de connecteur


      For i = 1 to Nb arc
      For j = 1 to 5

      Tabl(i,j).Value = Cells(i, j).Value 'Remplissage des la table des connecteurs

      Next j
      Next i


      For i = 1 to n 'Visite de la matrice des trajets
      For j = 1 to n

      If Cells(i,j).Value = 1 Then

      ActiveSheet.Shape(cstr(A&cstr(i))) =True 'Activer les Ai présente dans tabl mais je
      ne sais pas comment faire

      Next j
      Next i

      en Sub

      Je ne vois pas et trouve pas comment récupérer les connecteurs présent dans ma table

      Merci d'avance :), j'ai déjà appris quelque truc mais j'en suis encore loin ...

      Lalalathuile
      0
      1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588 > Lalalathuile Messages postés 8 Statut Membre
         
        ajoute option explicit au début de ton code, pour détecter les variables non déclarées.
        je trouve ceci bizarre:
        For i = 1 to Nb arc 
        For j = 1 to 5 
        
        Tabl(i,j).Value = Cells(i, j).Value 'Remplissage des la table des connecteurs 

        si tab est une table, tu ne peux pas faire .value, fais simplement Tabl(i,j) = Cells(i, j).Value
        cells(i,j) est certainement faux, tu veux sans doute faire cells(i+3,11=j) ou bien cells(i+15, j+11), je suppose, en effet, que tu veux parcourir tes tables "xij" et "connecteurs".
        0
      2. Lalalathuile Messages postés 8 Statut Membre > yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention  
         
        Merci yg_be,

        J'ai rectifié mes erreurs

        Pour le moment j'ai :

        Sub Affichage()

        Dim i As Integer
        Dim j As Integer
        Dim n As Integer 'Nombre de noeud
        Dim traj As Integer 'Nombre de connecteur

        n = 10
        traj = 45

        Dim Tabl()
        ReDim Tabl(traj, 5)
        Dim x()
        ReDim x(n, n)

        For i = 1 To traj
        For j = 1 To 5

        Tabl(i, j) = Cells(i + 15, j + 11).Value 'Remplissage des la table des connecteurs

        Next j
        Next i

        For i = 1 To n
        For j = 1 To n

        x(i, j) = Cells(i + 3, j + 11).Value

        Next j
        Next i

        End Sub

        Je bloque un peu pour afficher les connecteurs en fonction de Tabl(i,j) et x(i,j)...
        As-tu des idées à m'apporter pour avancer ma macro ?

        Merci d'avance,

        Lalalathuile
        0
  4. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    je vois que tu as une matrice, xij, qui représente probablement si deux nœuds doivent être reliés ou pas.
    et une autre matrice, connecteurs, qui définit des trajets, qui sont en fait des ensembles de connecteurs.
    je suppose que les noms des connecteurs détermine la paire de nœuds que le trajet relie.
    ai-je bien compris?
    si oui, tu y étais presque:
    For i = 1 to n 'Visite de la matrice des trajets 
    For j = 1 to n 
    
    If x(i,j) = 1 Then 
        if i<j then
             ntrajet=10*(i-1)+(j-1)
        else
             ntrajet=10*(j-1)+(i-1
        end if
        ' pas encore fait:
        ' il faut calculer ou chercher lignetrajet, la ligne dans Tab où se trouve le trajet ntrajet
        ' ensuite:
        for k = 2 to 8
             nconnecteur=Tab(lignetrajet,k)
             if nconnecteur >=0
                   ActiveSheet.Shape(cstr(nconnecteur)) =True 
             end if
        next k
    end if
    
    Next j 
    Next i 

    attention à mettre une valeur négative dans tab quand tu fais ceci :
    Tabl(i, j) = Cells(i + 15, j + 11).Value 'Remplissage des la table des connecteurs
    , si la valeur n'est pas numérique
    0
    1. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   1 588
       
      il y a moyen de faire plus simple et plus rapide: parcourir la table des trajets plutôt que la matrice des nœuds..
      je ferai une proposition plus tard.
      0
  5. Vous n’avez pas trouvé la réponse que vous recherchez ?

    Posez votre question
  6. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    je propose de remplacer ceci
    For i = 1 To traj 
    For j = 1 To 5 
    
    Tabl(i, j) = Cells(i + 15, j + 11).Value 'Remplissage des la table des connecteurs 
    
    Next j 
    Next i 

    par
    For i = 1 To traj 
    For j =1 To 7 
    if isnum(Cells(i + 15, j + 11).Value) then
        nconn=Cells(i + 15, j + 11).Value
    else
        nconn=-1
    end if
    Tabl( Cells(i + 15,  11), j) = nconn 'Remplissage des la table des connecteurs 
    
    Next j 
    Next i 

    ce qui permet d'utiliser ntrajet au lieu de lignetrajet.
    il faut aussi changer le redim de Tabl: ReDim Tabl(99, 7)
    as-tu mis option explicit, pour être forcé de déclarer toutes tes variables?
    0
  7. yg_be Messages postés 23437 Date d'inscription   Statut Contributeur Dernière intervention   Ambassadeur 1 588
     
    ceci suppose que tu supprimes les zéros des noms des connecteurs 01 à 09.
    option explicit
    Sub Affichage() 
    
    Dim i As Integer 
    Dim j As Integer 
    dim k as integer
    Dim n As Integer 'Nombre de noeud 
    Dim traj As Integer 'Nombre de connecteur 
    dim nconnecteur as integer, ntrajet as integer
    
    n = 10 
    traj = n*(n-1)/2 
    
    Dim  Tabl()  as integer
    ReDim  Tabl(n*(n-1), 7)  as integer
    Dim x()  as integer
    ReDim x(n, n)
    
    For i = 1 To traj 
    For j =1 To 7 
    
    if isnum(Cells(i + 15, j + 11).Value) then
        nconnecteur=Cells(i + 15, j + 11).Value
    else
        nconnecteur=-1
    end if
    Tabl( Cells(i + 15,  11), j) = nconnecteur 'Remplissage de la table des connecteurs 
    
    Next j 
    Next i 
    
    
    For i = 1 To n 
    For j = 1 To n 
    
    x(i, j) = Cells(i + 3, j + 11).Value 
    
    Next j 
    Next i 
    
    For i = 1 to n 'Visite de la matrice des trajets 
    For j = 1 to n 
    
    If x(i,j) = 1 Then 
        if i<j then
             ntrajet=10*(i-1)+(j-1)
        else
             ntrajet=10*(j-1)+(i-1)
        end if
    
        for k = 1 to 7
             nconnecteur=Tabl(ntrajet,k)
             if nconnecteur >=0
                   ActiveSheet.Shape(cstr(nconnecteur)) =True 
             end if
        next k
    end if
    
    Next j 
    Next i 
    
    
    End Sub 
    0