[VB.NET] Mon projet UserForm de VBA à VB.NET [Résolu/Fermé]

Signaler
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015
-
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015
-
Bonjour,

Je bosse sur un projet perso pour me faire un formulaire qui comportera plusieurs boutons pouvant appeler soit une macro, soit ouvrir des fichiers de tout type (fonction ShellExecute).

En challenge perso j'ai voulu me faire des boutons persos (j'étais sous VBA à la base, mais lisez jusqu'au bout. Je vous vois déjà fermer la page).

Bref, j'ai donc écrit mon code en procédurale et mon UserForm marche (je passe par Excel mais au fond il ne me sert à rien). Voici le fichier en question : https://www.cjoint.com/c/EHlrEqQddPl

J'ai ensuite pris l'initiative de changer de monture et de langage. J'oublie donc Excel et le VBA pour aller tâter VS Community et le VB.NET. L'objectif : passer mon code VBA en VB.NET. J'ai lu quelques articles et une page Microsoft qui expose les grosses différences entre le basic et le .NET.
J'ai donc tenté de faire fonctionner mon code en VB.NET mais bien sûr il y a quelques blocages. Voici le projet dans l'état actuel des choses : http://www.cjoint.com/c/EHlrDCmf5zl. Le MouseMove ne fonctionne absolument pas (en gros).

Tout d'abord je ne sais pas s'il est bon de passer en programmation objet. Visiblement c'est la mode et parce que VB .NET le permet il semblerait que tout le monde conseille vivement d'écrire en objet même pour le plus bête code. Votre avis sur la question ? x) Je vous avouerai que j'ai grandement envie de rester en programmation procédurale pour le moment.

Je voudrais également savoir si c'est bien bon d'avoir mis en ByRef les arguments type Integer/Double de mes procédures ou si certains sont inutiles. ^^

Ensuite, si vous avez vu mon projet en VB.NET, je voudrais savoir comment gérer et appeler les évènements de mes Images et Labels que j'initialise dans mon module de classe (public withevents noraj, public withevents noraj_texte). J'ai l'impression de faire quelques choses de mal avec le Handle (qui n'étais pas là sous VBA). Je comprends bien que c'est pour dire avec quel Item cet évènement va se déclencher, mais normalement on utilise la propriété Name de l'Item en question (comme Image1.Click, où j'ai mis noraj.Click par exemple).

Merci de m'éclairer si quelqu'un veut bien passer un peu de son temps à regarder mon projet. Et désolé pour le pavé. ><


Edit :
Une modification qui peut peut-être résoudre le problème : au lieu d'utiliser un seul item Image et de charger 2 images .gif différentes suivant le mousemove, je dois peut-être charger 2 items Image et jouer sur leur propriété .Visible. Je voulais le faire sur mon projet en VBA mais je ne m'y suis pas attardé. Peut-être que je dois passer par ça en VB.NET.

Pour les curieux, je change la BackColor de mes items Image en même temps que le .gif afin de charger et de rafraichir l'item en question, sinon rien ne se passe (problème de priorité de rafraichissement semblerait-il).

2 réponses

Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
555
Bonjour,

un peu de lecture
https://codes-sources.commentcamarche.net/faq/11151-pourquoi-mon-code-vb6-vba-ne-marche-pas-en-vb-net

'il est bon de passer en programmation objet. Visiblement c'est la mode
alors c'est une mode qui dure, la programmation objet date des années 60!
https://fr.wikipedia.org/wiki/Programmation_orientée_objet
C'est une "philosophie" différente de la programmation procédural ou événementielle.

Mais ça marche très bien quand on s'y est mis.


Enfin merci de ne pas envoyer un projet entier.

On traitera point par point, poste le code ici avec la coloration syntaxique.

Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Merci pour la réponse. Cet article fait parti de ceux déjà lus. ^^ J'ai trouvé ça aussi qui était pas mal : https://docs.microsoft.com/en-us/previous-versions/office/developer/office-2003/aa192490(v=office.11)?redirectedfrom=MSDN

Pour le truc de la mode je pense que c'était de trop. :D Je voulais insinuer par là que certaines personnes sont à la limite de te cracher dessus si on écrit en procédurale avec du VB.NET, et que si tu n'écris pas en objet et bien t'as rien compris. J'espère que c'est un peu faux, c'est tout. :p

Pour le projet entier ok je retiens mais je ne vois pas où est le problème. ^^

Bref, voici la moitié de mon module de classe qui gère les évènements de mes boutons persos (1 label + 1 image). L'autre moitié gère l'évènement Click mais on va se contenter du MouseMove pour l'instant :
Option Strict On
Option Explicit On

Public Class Classe1

    Public WithEvents noraj As System.Windows.Forms.PictureBox
    Public WithEvents noraj_texte As System.Windows.Forms.Label

    Private Sub noraj_MouseMove(sender As Object, e As MouseEventArgs) Handles noraj.MouseMove

        Call Outils.reset()

        Call Outils.test_couleur_bouton2(noraj)

    End Sub


    Private Sub noraj_texte_MouseMove(sender As Object, e As MouseEventArgs) Handles noraj_texte.MouseMove

        Dim Ctrl2 As System.Windows.Forms.PictureBox

        Call Outils.reset()

        For Each Ctrl2 In Outils.Controls.OfType(Of PictureBox)
            If noraj_texte.Tag Is Ctrl2.Tag Then
                Call Outils.test_couleur_bouton2(Ctrl2)
            End If
        Next Ctrl2

    End Sub
[...]


Ma procédure reset :
    Sub reset()

        Dim Obj As System.Windows.Forms.PictureBox

        For Each Obj In Me.Controls.OfType(Of PictureBox)

            If Obj.Name Like "Image100*" Then
                Call Me.test_couleur_bouton1(Obj)
            End If
        Next Obj

    End Sub


Le truc c'est que quand je fais un mouseover d'une de mes images de bouton rien ne se passe, l'image ne change pas. Peut-être que c'est trop gourmand ou peut-être qu'il y a une fonction à faire comme un Reprint mais là c'est mon manque de vocabulaire et de connaissance VB qui parle.

Je pense aussi que je gère mal le handles (qui est nouveau pour moi).
+ le fait que je devrais effectivement ajouter 2 images pour un bouton plutôt qu'une seule et jouer avec la propriété .visible. Plus j'y pense plus je me dis que c'est une meilleure solution en tout point.

Merci =)
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
555
Bonsoir,

avec un point d'arrêt dans la méthode noraj_texte_MouseMove, est ça passe par là quand tu fais un mouse over?
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
555
On peut même optimiser un peu avec une requête Linq
        For Each Obj As System.Windows.Forms.PictureBox In Me.Controls.OfType(Of PictureBox).Where(Function(picBox) (picBox.Name Like "Image100*"))
            Call Me.test_couleur_bouton1(Obj)
        Next Obj


Voir ici, c'est en C#, mais tu peux passer les exemples dans un traducteur en ligne.
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Merci pour tes réponses.

Alors, déjà j'ai remplacé noraj_texte par norajtexte pour oublier l'underscore. J'ai peur d'un quelconque problème syntaxique.

Ensuite merci pour les astuces avec la déclaration dans le for each et pour le where. Je ne connaissais pas. Du coup j'ai gagné pas mal de ligne dans mon code et ça devient un peu plus clair. =)

Concernant mes MouseMove, je suis passé avec 2 images et je joue sur la propriété visible des 2 images. Même sans ça, mon erreur venait d'un de mes tests :
If noraj_texte.Tag Is Ctrl2.Tag Then
J'ai remplacé ça par
If noraj_texte.Tag.ToString = Ctrl2.Tag.ToString Then
et ça marche.


Nouveau soucis : Si je clique sur un bouton, l'action associé se fait en boucle, même pour un simple MsgBox.
    Private Sub noraj1_Click(sender As Object, e As EventArgs) Handles noraj1.Click

        If noraj1.Tag.ToString <> "" Then
            'Call Outils.analyse_tag(noraj1.Tag.ToString)
            MsgBox("test")
        End If

    End Sub


    Private Sub noraj2_Click(sender As Object, e As EventArgs) Handles noraj2.Click

        If noraj2.Tag.ToString <> "" Then
            'Call Outils.analyse_tag(noraj2.Tag.ToString)
            MsgBox("test")
        End If

    End Sub


Edit : après un pas à pas, je vois que la private sub du Click se fait en boucle. Mais des fois elle s'arrête au bout d'une dizaine de répétition... Je ne comprends pas pourquoi. Ce nombre de répétition ne correspond pas non plus au nombre total de bouton que j'invoque dans ma Form.
Messages postés
14492
Date d'inscription
mardi 11 mars 2003
Statut
Contributeur
Dernière intervention
15 juillet 2020
555
Là je ne sais pas trop.
Peux tu regarder, à chaque passage, si sender est toujours noraj1?
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

A chaque passage je vois que sender.Name = Image10006, ce qui correspond bien au bouton cliqué. J'ai également noraj1.Name = Image10006.

J'ai fait le test sur une ancienne version car je ne suis pas chez moi. A toute les répétitions j'ai le même résultat : http://hpics.li/fd16cfb
Pour noraj.Name j'ai la même chose. A chaque répétition il détecte un click.

Edit :
Même problème avec l'évènement MouseClick et MouseUp.

J'ai fait un test avec une PictureBox classique dans mon module de Form, l'évènement Click marche très bien (logique).
J'ai passé sa propriété name à PictureBox.Name = Image10010 (pour qu'il soit comme mes boutons), et là ça ne marche plus, j'ai le MsgBox en boucle.

Je pense qu'il y a quelque chose d'incorrect entre mon module de Form Outils et ma classe Classe1.

Dans ma Form j'ai ça :
    Public Collect As Collection
    Public Collect_texte As Collection

Après mon Form_Load :
    Private Sub Outils_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove

        Dim Ctrl As System.Windows.Forms.PictureBox
        Dim Ctrl_texte As System.Windows.Forms.Label
        Dim test3000 As Classe1
        Dim test5000 As Classe1

        Collect = New Collection
        Collect_texte = New Collection

        For Each Ctrl In Me.Controls.OfType(Of PictureBox)
            If Ctrl.Name Like "Image100*" Then
                test3000 = New Classe1
                test3000.noraj = Ctrl
                Collect.Add(test3000)
            End If
        Next Ctrl

        For Each Ctrl_texte In Me.Controls.OfType(Of Label)
            If Ctrl_texte.Name Like "Label100*" Then
                test5000 = New Classe1
                test5000.noraj_texte = Ctrl_texte
                Collect_texte.Add(test5000)
            End If
        Next Ctrl_texte

    End Sub



Dans ma classe :
    Public WithEvents noraj As System.Windows.Forms.PictureBox
    Public WithEvents noraj_texte As System.Windows.Forms.Label

Avec juste mes évènements (MouseMove et Click) :
    Private Sub noraj_Click(sender As Object, e As EventArgs) Handles noraj.Click

        'Call Outils.analyse_tag(noraj.Tag.ToString)
        MsgBox("test")

    End Sub
Messages postés
62
Date d'inscription
dimanche 4 janvier 2015
Statut
Membre
Dernière intervention
19 août 2015

Désolé pour le double post mais j'ai copié-collé mon projet pour m'en faire un doublon où je gère tout avec des Button.
+ j'ai changé d'évènement. J'utilise MouseEnter et MouseLeave ce qui me facilite la vie.

En gros ma classe c'est devenu :
Public Class Classe1

    Public WithEvents noraj As System.Windows.Forms.Button

    Private Sub noraj_MouseEnter(sender As Object, e As EventArgs) Handles noraj.MouseEnter
        Call Outils.test_couleur_bouton2(noraj)
    End Sub

    Private Sub noraj_MouseLeave(sender As Object, e As EventArgs) Handles noraj.MouseLeave
        Call Outils.test_couleur_bouton1(noraj)
    End Sub

    Private Sub noraj_Click(sender As Object, e As EventArgs) Handles noraj.Click
        'Call Outils.analyse_tag(noraj.Tag.ToString)
        MsgBox("test")
    End Sub

End Class
Tellement plus simple. Par contre je repasse sur un modèle où je recharge à chaque fois une image.

Dans ma Form :
    Private Sub Outils_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove

        Dim test3000 As Classe1

        Collect = New Collection

        For Each Ctrl As System.Windows.Forms.Button In Me.Controls.OfType(Of Button).Where(Function(button) button.Name Like "Boutton100*")
            test3000 = New Classe1
            test3000.noraj = Ctrl
            Collect.Add(test3000)
        Next Ctrl

    End Sub


Par contre j'ai toujours ce problème avec l'évènement Click. x)