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

VB.NET Discussion :

Ecrire du code avec une variable


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2015
    Messages
    7
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Bâtiment

    Informations forums :
    Inscription : Mars 2015
    Messages : 7
    Par défaut Ecrire du code avec une variable
    Bonjour à tous,

    après quelques recherches sur le net et sur ce très bon site, je cherche toujours une solution a mon problème.

    Petite mise en situation,
    je suis actuellement en train de coder un programme de calculs électrique en vb.net sur visual studio 2019.
    Ce programme manipule de nombreuses formules mathématique exécutées via des Public Function et des variables publiques.

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
        Public Pa As Single
        Public Un As Single
        Public In_recepteur As Single
        Public racine3 As Single = 1.73205
        Public cosphi As Double
     
        Public Function Puissance_absorbée()
     
            Pa = Un * In_recepteur * racine3 * cosphi
     
            Return Pa
     
        End Function
    Je défini les variables avec des textbox et autres contrôles mais cela n'a pas une grande importance ici.
    Je voudrais pouvoir modifier la formule Pa =Un * In_recepteur * racine3 * cosphi dans une textbox (en faisant attention à l'orthographe ).
    quelque chose qui ressemblerai a ca :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
     
            Public Function Puissance_absorbée()
     
            Dim formule As ????????
     
            formule = Page_acceuil.tb_test.Text   ' textbox dans laquelle je souhaite modifier la formule
     
            Pa = formule   
     
            Return Pa
        End Function
    Je ne sais pas si cela est possible mais si ça l'est, je pense que le problème vient du fait que je ne donne pas le bon type a ma variable formule.

    Je ne suis pas sur d'avoir été très clair mais si vous avez besoin de plus d'infos faites moi signe

    Merci d'avance à tous ceux/toutes celles qui prendront un peu de temps pour réfléchir à mon problème.

  2. #2
    Membre Expert Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Par défaut
    Bonjour,

    Ta question devrait plutôt être : Comment passer le corps d'une fonction sous forme de chaine pendant l'exécution ?
    Je crois me souvenir qu'il existait une possibilité en Basic (Basica ou GwBasic) dans les années 80 ...

    Mais sous VB.Net, je ne connais pas. Peut-être quelqu'un t'aidera.

    Perso, je vois 2 approches possibles :

    Si dans une TextBox, tu introduis dans le bon ordre les valeurs requises par une formule donnée, en les séparant par un caractère spécial de ton choix (le tilde, ASCII 126, par exemple), il est très facile d'extraire ces valeurs dans le code avec la méthode Split de la classe String.

    Une autre approche est d'écrire un interpréteur de formules. Là, tu pourras encoder dans la TextBox n'importe quelle formule avec ses valeurs et ses opérateurs, dans le bon ordre bien sûr, comme nous le faisons dans une cellule XLS, ou sur certaines calculettes.

    Bonne journée,


  3. #3
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 570
    Par défaut
    Bonjour,
    je ne sais pas ce que ça vaut!

    https://www.codeproject.com/Articles...ator-in-VB-NET

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    je vois au moins 2 solutions

    la plus simple c'est un évaluateur sql, pas forcément besoin de base de données y avoir accès
    le langage sql est prévu pour évaluer du texte et l'exécuter, et peut gérer des variables
    si on donne select @var1 + @autre en fournissant @ar1 et @autre ca retourne le résultat
    si tu as une base de données à disposition c'est simple, si non je crois que les objets .net de stockage des données arrivent à faire quelque trucs (genre datatable)

    sinon tu peux compiler du code à la volée avec codedom et vbcodeprovider
    tu lui envoies le code .net généré, ou écrit par l'utilisateur, le mieux étant de le limiter à la formule avec des noms de variables autorisés et toi tu enrobes de ce qu'il faut
    le code doit être une classe avec le membre
    ensuite tu récupère le type généré dans la dll générée en mémoire et tu peux ensuite chercher le pointeur vers la fonction et l'appeler
    (dim formule as func<double> = directcast(letype.GetMethod(nom_function_créée), func<double>) + dim resultat = formule())
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Candidat au Club
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut Un doux mélange
    Bonjour,

    Ce que tu veux faire, c'est ajouter du code à interpréter à un programme exécutable qui a été compilé et linké.
    C'est évidemment impossible sous cette forme puisqu'on ne peut compiler un code qui ne sera connu qu'au moment de l'exécution ! Phil Rob, qui a parlé d'une vieille version de Basic qui permettait cela, a raison. C'était possible AVANT quand Basic était un langage interprété.

    Donc tu n'as plus que deux types de solutions :

    Ecrire un éditeur/compilateur de formule, c'est la solution qu'a proposé Thumb Down, code assez complexe car quasiment toutes les possibilité d'opérateurs mathématiques sont supportées (mais il suffit de coder la fonction tel quel et de tester l'appel après) ...
    ou
    Transmettre ta formule à un interpréteur qui la comprendra, la vérifiera et l'exécutera, à charge pour toi de récupérer le résultat après,
    rien de simple à priori ... mais c'est un peu ce que l'on fait avec SQL (je n'ai pas d'expérience à transmettre).

    La première solution me semble la plus simple à tester.
    Bon courage.

  6. #6
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 197
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 197
    Par défaut
    Citation Envoyé par Pebehem Voir le message
    Ce que tu veux faire, c'est ajouter du code à interpréter à un programme exécutable qui a été compilé et linké.
    C'est évidemment impossible sous cette forme puisqu'on ne peut compiler un code qui ne sera connu qu'au moment de l'exécution !
    c'est étrange, j'ai justement proposé ce qui est impossible juste au dessus…
    car oui en .net on peut compiler du code .net depuis un exe .net avec du code connu seulement au moment de l'exécution, que ca soit à partir de vb.net/c# sous forme de string ou d'IL directement
    c'est d'ailleurs bien pratique ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  7. #7
    Candidat au Club
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Décembre 2019
    Messages : 4
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    c'est étrange, j'ai justement proposé ce qui est impossible juste au dessus…
    car oui en .net on peut compiler du code .net depuis un exe .net avec du code connu seulement au moment de l'exécution, que ca soit à partir de vb.net/c# sous forme de string ou d'IL directement
    c'est d'ailleurs bien pratique ...
    Salut Pol63,
    J'ai répondu directement à l'exemple de Volgore qui voulait intégrer à son code source un morceau qui venait d'une boîte texte, ce qui reste bien impossible. Beaucoup de programmeurs débutants confondent compilation, Link et exécution ... Par contre, tu as raison, et ceci est équivalent à ce que j'ai appelé "appel d'un interpréteur", en encore plus puissant, le dispositif "codedom" permet effectivement de traiter un bout de code à compiler/linker à la volée. J'avoue que je n'avais pas regardé et que les quelques 6 pages de l'exemple de code de la doc m'ont un peu affolé ... Pratique, d'accord, mais complexe !
    Mon propos était juste plus général, sans contrarier le tien. .

  8. #8
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 570
    Par défaut
    Bonsoir,

    Je suis pas certain de comprendre!

    Voir ScriptControl.

  9. #9
    Membre Expert Avatar de Thumb down
    Homme Profil pro
    Retraité
    Inscrit en
    Juin 2019
    Messages
    1 570
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juin 2019
    Messages : 1 570
    Par défaut
    Bonjour,
    je relance et je vois!
    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
    27
    28
    29
    30
    31
    32
    33
    Imports MSScriptControl
    Public Class Form1
        Sub Test()
            Try
                Dim sc As New MSScriptControl.ScriptControl
                sc.Language = "VBScript"
                sc.AddObject("TextBox1", Me.TextBox1, True)
                ' Ajoute un module.
                Dim M As MSScriptControl.Module = sc.Modules.Add("Module1")
     
     
                M.AddCode(EnregitrementTable) ' Ajoute du code au module.
     
     
                M.Run("MacroName", "toto") ' Exécute le script.
            Finally
     
     
            End Try
        End Sub
        Private Function EnregitrementTable() As String
            Dim Macro As String = ""
            Macro += "Sub MacroName(toto)" & Environment.NewLine
            Macro += "TextBox1.Text=toto " & Environment.NewLine
            Macro += "End sub"
            Return Macro
        End Function
     
     
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Test()
        End Sub
    End Class

  10. #10
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonkour

    Comme dit par Pol63,tu peux générer du code à la volée par CodeDom.
    Mais ,alas ,comme tu as une intention plus ambitieuse à savoir le modifier ,CodeDom ne peut modifier un fichier .vb ou un Assembly (dll) qu'en l’écrasant (en générant un nouveau fichier .vb).

    L'exemple suivant illustre le processus:
    Il faut creer 2 projets winforms pour eviter des confusions et "saisir le processus"
    1/ projet 1: un form d'exemple :
    - txtInput est charger de collecter la formule user
    - txtOutput affiche le résultat de calcul après modif de formule

    -ce form génère un Class d'exemple "Test" à la volée muni de ta fonction qui est fourni "inline" .
    -fournit la "nouvelle formule magique" à affecter à la variable Pa(puissance apparente au lieu de la formule initiale ou puissance active)
    - ajuste les paramètres d'appel (2) au lieu de (4)

    code .vb:
    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
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    Imports System.CodeDom.Compiler
    Imports System.Reflection
     
    Public Class Form1
        Private stringFormule As String
        Private stringParamFn As String
        Private Sub Form1_Load(sender As Object, e As System.EventArgs) Handles Me.Load
            inputFormule.Text = "Un*In_recepteur" 'puissance apparente en KVA  
        End Sub
     
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            If stringFormule.Length = 0 Then Return
            Dim inputData As String = "txtOutput.Text = Puissance_Absorbe(220,5)"
     
            Dim code As Object = <code>  
                           Imports System  
                           Imports System.Windows.Forms  
     
                           Public Class Test 
     
                               Public Pa As Double
                               Public Un As Double
                               Public In_recepteur As Double
                               Public racine3 As Double = 1.73205
                               Public cosphi As Double 
                               Public Sub UpdateText(ByVal txtOutput As TextBox)  
                                 <%= inputData %>  
                               End Sub  
                            Public Function Puissance_Absorbe(<%= stringParamFn %> ) as Double
                               Pa = Un * In_recepteur * racine3 * cosphi
                                Dim formule As Double = <%= stringFormule %> 'on court-circuite le code precedent 
                                Pa = formule   
     
                                Return Pa
                            End Function
                            End Class
                       </code>
     
            Dim provider As New VBCodeProvider()
     
            Dim vbParams = New CompilerParameters()
            ' Add referenced assemblies.  
            vbParams.ReferencedAssemblies.Add("mscorlib.dll")
            vbParams.ReferencedAssemblies.Add("System.dll")
            vbParams.ReferencedAssemblies.Add("System.Windows.Forms.dll")
            vbParams.GenerateExecutable = False
            vbParams.GenerateInMemory = True
            vbParams.OutputAssembly = "LibFonctions"
            Dim compilResults As CompilerResults = provider.CompileAssemblyFromSource(vbParams, code.Value)
     
            If compilResults.Errors.Count > 0 Then
                ' Show each error.  
                For Each er In compilResults.Errors
                    MessageBox.Show(er.ToString())
                Next
     
            Else
     
                txtSourceCode.Text = code.value
                Dim obj As Object = compilResults.CompiledAssembly.CreateInstance("Test")
     
                Dim args() As Object = {Me.txtOutput}
                ' Execute the method by passing the method name and arguments.  
                obj.GetType().InvokeMember("UpdateText", BindingFlags.InvokeMethod, Nothing, obj, args)
     
            End If
        End Sub
     
        Private Sub inputFormule_TextChanged(sender As System.Object, e As System.EventArgs) Handles inputFormule.TextChanged
            If inputFormule.Text.Length = 0 Then Return
            stringFormule = inputFormule.Text
     
            Dim arr() As String = inputFormule.Text.Split(New Char() {"+", "-", "*", "/", "(", ")"}, StringSplitOptions.RemoveEmptyEntries)
            For Each item As String In arr
                stringParamFn += "ByVal " + item + " as Double ,"
            Next
            stringParamFn = stringParamFn.TrimEnd(New Char() {","})
     
        End Sub
     
     
    End Class

    1/ projet 2: référence la "dll" générée par le 1er projet et appelle la fonction modifié.
    code .vb:
    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
     
    Imports System.Text
     
    Public Class Form2
        Private test As Test
        Private sb As StringBuilder
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
            sb = New StringBuilder()
            Test = New Test
            sb.AppendLine(test.Puissance_Absorbe(220, 5).ToString())
            sb.AppendLine(test.Puissance_Absorbe(380, 15).ToString())
     
     
            TextBox1.Text = sb.ToString()
     
        End Sub
    End Class
    N.B.
    le code génère est "immutable" comme le type string ou "sculpté dans le granit d'or"...tel que spécifié par l'API du Compilateur Roslyn (la Roseline de Microsoft).
    Le seul moyen de le modifier est d'en créer un nouveau..ce que l'API désigne pudiquement par "transformation de code"!!!
    ce lien sur Roslyn explique les possibilités de cet API et renvoi vers d'excellent tutos

    https://tomassetti.me/getting-starte...orming-c-code/

    bon scripting...

  11. #11
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2007
    Messages
    871
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Février 2007
    Messages : 871
    Par défaut
    il y a plein de solutions pour jouer une formule sans avoir a utiliser roslyn ou meme codedom, sql est une solution, mais js est encore plus simple :

    installe le package nuget Jint, puis dans ton code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Engine engine = new Engine();
    string result = engine.Execute("function calcul() { return"+maFormule+"; }").GetValue("calcul").Invoke().AsString();

  12. #12
    Membre extrêmement actif
    Inscrit en
    Avril 2008
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Âge : 65

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 573
    Par défaut
    bonjour mermich .
    En fait le gars va vite en besogne ,non seulement il veut un scripting des formules ce qui n'est pas donné dans l'API .Net ,mais en relisant son post attentivement,je me suis rendu compte qu'il voulait "coder" une seule fonction modifiable à volonté .
    Même en js il n'existe pas de commandes pour demander à la machine virtuelle (interpréteur ,comme en IL) de supprimer un code existant et le remplacer .

Discussions similaires

  1. Rafraichissement avec une variable
    Par niceday dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 22/08/2005, 10h08
  2. Réponses: 5
    Dernier message: 25/06/2005, 11h35
  3. Réponses: 2
    Dernier message: 14/05/2004, 14h32
  4. Comparaison d'un registre 8 bits avec une variable 32 bits
    Par tupperware dans le forum x86 32-bits / 64-bits
    Réponses: 3
    Dernier message: 15/10/2002, 10h25
  5. Désigner une variable avec une variable?
    Par littleman dans le forum Paradox
    Réponses: 4
    Dernier message: 12/08/2002, 11h21

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