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 :

VB.Net : Formules dans DatagridView


Sujet :

VB.NET

  1. #1
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut VB.Net : Formules dans DatagridView
    Bonjour à tous,

    J'ai pas mal cherché et rien trouvé (visiblement ca n'interesse personne...) concernant la possibilité de mettre des formules dans certaines cellules d'un datagridview (facon Excel).
    Comme dans Excel, on pourrait soit voir la formule soit le résultat.

    Tout aide sera fortement appréciée.
    Mille merci.

  2. #2
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    Oula ! Tu vas déjà avoir besoin d'une sorte d'Eval pour évaluer tes formules.

    J'avais trouvé ce code pas mal du tout :
    http://www.codeproject.com/KB/recipe...ew=Quick&fr=51

    Ensuite, le mieux me semble de créer un type de contrôle d'édition personnalisé de type Textbox.
    Tu dois créer ton control d'édition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    Friend Class EvalTextBoxEditingControl
        Inherits TextBox
        Implements IDataGridViewEditingControl
    ...
    Dans ce control, tu géres la saisie et la transformation de la formule en valeur affichable.
    Tu ajoutes aussi un propriété "Formula" pour stocker ta formule.

    Puis un type de cellule qui utilise ce contrôle d'édition :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Public Class EvalTextBoxCell
        Inherits DataGridViewTextBoxCell
    ...
    Ta propriété "Formula" étant un propriété de la cellule devra être redescendu ici.

    Et enfin un type de colonne qui utilise ce type de cellule.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    Public Class EvalTextBoxColumn
        Inherits DataGridViewColumn
    ...
    Il y a de nombreux exemple de création de cellule personnalisée pour un DGV.

    Par exemple :
    http://msdn2.microsoft.com/en-us/library/7tas5c80.aspx

    Voilà, c'est une solution.

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  3. #3
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Tout d'abord, MERCI de ta réponse.
    Ensuite, un ENORME merci pour le premier lien (super dll qui répond exactement à ce que je veux faire.)

    Il faut que je creuse les bouts de codes que tu m'as envoyés et notamment le point sur les "formulas" qui je pense permet de gérer un "double affichage" : soit la formule soit la valeur... (je débute en .net)

    J'aurai encore surement des questions mais ce début de solution m'aide incroyablement !

    Encore merci !

  4. #4
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Olsimare,

    Pourrais-tu m'expliquer succintement le principe pour stocker à la fois la formule et son résultat ?

    Merci.

  5. #5
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    En me relisant, je me suis dit qu'il y avait plus simple ...

    En fait, le mieux reste de faire l'eval au besoin pour l'affichage. Donc dans la value de la cellule, on stocke soit une formule, soit une valeur formelle.

    Donc pas besoin de EditingControl.

    Un 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
    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
     
    Option Strict On
    Option Explicit On
     
    Public Class FormulaDGVColumn
        Inherits DataGridViewTextBoxColumn
     
        Public Sub New()
            MyBase.New()
            MyBase.CellTemplate = New FormulaDGVCell
        End Sub
        Public Overrides Property CellTemplate() As DataGridViewCell
            Get
                Return MyBase.CellTemplate
            End Get
            Set(ByVal value As DataGridViewCell)
                If Not (value Is Nothing) AndAlso _
                    Not value.GetType().IsAssignableFrom(GetType(FormulaDGVCell)) _
                    Then
                    Throw New InvalidCastException("Le template n'est pas de type FormulaDGVCell")
                End If
                MyBase.CellTemplate = value
            End Set
        End Property
     
    End Class
     
    Public Class FormulaDGVCell
        Inherits DataGridViewTextBoxCell
     
        Protected Overrides Function GetFormattedValue( _
        ByVal value As Object, _
        ByVal rowIndex As Integer, _
     ByRef cellStyle As DataGridViewCellStyle, _
        ByVal valueTypeConverter As System.ComponentModel.TypeConverter, _
        ByVal formattedValueTypeConverter As System.ComponentModel.TypeConverter, _
        ByVal context As DataGridViewDataErrorContexts _
    ) As Object
            If Me.RowIndex < 0 Then Return Nothing
     
            Dim s As String = CStr(Me.Value)
     
            If Left(s, 1) = "=" Then
                Return "Eval(" & Mid(s, 2) & ")"
            Else
                Return s
            End If
        End Function
     
        Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
     
            MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
     
            Dim dgvtb As DataGridViewTextBoxEditingControl = CType(DataGridView.EditingControl, DataGridViewTextBoxEditingControl)
     
            dgvtb.Text = CStr(Me.Value)
     
        End Sub
     
    End Class
    Dans une form tu fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            Dim c As New FormulaDGVColumn
            Me.DataGridView1.Columns.Add(c)
            Dim c1 As New FormulaDGVColumn
            Me.DataGridView1.Columns.Add(c1)
    C'est tout bête et ça ne joue plus que sur l'affichage.

    Nota : je te laisse le soin de cabler l'utilisation de l'Eval avec la gestion des erreurs potentielles.

    EDIT : Ah oui, j'avais oublié initialement le InitializeEditingControl qui permet de ne pas passer bêtement le texte affiché dans la cellule au control d'édition (teste sans tu verras tout l'intérêt).

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  6. #6
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Bonjour olsimare,

    Merci encore pour ton aide et ta patience.

    Effectivement cette solution ma parait plus simple (d'autant que je débute.)
    J'étais parti sur une autre piste encore plus simple mais surement bricol' :

    2 datatable en parallèle l'une affichant les valeurs l'autre les formules... ca marchait pas mal mais c'est long (400 000 cellules environ...)
    Donc je préfère ta solution.

    Le seul soucis, il faut que je gère certains trucs : j'avais écrit ca :


    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
    Private Sub DGV_CellEndEdit(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGV.CellEndEdit
     
            If DGV.Item(e.ColumnIndex, e.RowIndex).Value.ToString = "=" Then
                DGV.ReadOnly = True
                DGVCol = e.ColumnIndex
                DGVLine = e.RowIndex
                boolEgal = True
                StrCal = ""
            End If
     
        End Sub
     
        Private Sub DGV_CellClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.DataGridViewCellEventArgs) Handles DGV.CellClick
     
            If boolEgal Then
                DGV.Item(DGVCol, DGVLine).Value &= DGV.Columns(e.ColumnIndex).HeaderText
                StrCal &= CInt(DGV.Item(e.ColumnIndex, e.RowIndex).Value)
     
            End If
     
     
        End Sub
     
        Private Sub DGV_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles DGV.KeyPress
     
            If boolEgal = True Then
                If e.KeyChar = Microsoft.VisualBasic.ChrW(Keys.Return) Then
     
                    People1.Rows(DGVLine).Item(DGVCol) = DGV.Item(DGVCol, DGVLine).Value
                    Me.CalculCell()
     
                    boolEgal = False
                    DGV.ReadOnly = False
                Else
                    DGV.Item(DGVCol, DGVLine).Value &= e.KeyChar
                    StrCal &= e.KeyChar
                End If
            End If
     
        End Sub
     
        'Test Validité + Calcul
        Public Sub CalculCell()
     
     
            DGV.Item(DGVCol, DGVLine).Value = Evl.Parse(StrCal).value
        End Sub

    qui lors de la saisie d'un "=" mettait le DGV en lecture seule et me permettait de saisir tout dans la cellule de départ.

    A l'arrivée après avoir fait "Enter", j'avais une cellule contenant :

    "=Tarif A*Degressif B"

    et une strCal : "23*0.1" que je calculait grâce à Eval3.

    ... Avec ton systeme, je ne sais pas ou caser ce code...


    On avance on avance...

  7. #7
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    Hop hop hop ... calmons nous !

    Ca sent un peu l'usine à gaz tout ça ... revenons au but premier.

    C'est quoi exactement que tu veux interpréter ? Si ton Eval rend exactement ce que tu veux, cable le dans le GetFormattedValue. Et évites de jouer avec des cellendedit, keypress et autre.

    Attention toutefois, avec ma méthode, tu ne stockeras en base ou autre que la formule et pas la valeur.

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  8. #8
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Bonjour Olsimare,

    le but premier était de pouvoir comme dans Excel, cliquer sur une cellule (A,A), y saisir "=" et qu'à cet instant, lorsqu'on clique sur une autre cellule B,B), sa valeur (ou ses coordonnées) s'affichent dans cette même cellule (A,A), à la suite du "=", tout comme les signes mathématiques...
    On obtient donc à la fin, qqchose comme :

    "=(B,B)*(C,C)/(D,D)" jusqu'à ce qu'on tape "Enter", où la le résultat s'affiche.

    Il faut donc que pendant les clics sur les cellules, ces cellules ne recoivent pas le focus.

    Pour l'instant avec ton code, dès que je tape "=" et que je sors de la cellule pour cliquer une autre cellule, je me retrouve avec "Eval()"...

    Tu vois ce que je veux dire ?

  9. #9
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    Ok. Je comprends mieux le but.

    Et je bloque... je vois pas de solution "simple".

    Donc l'usine à gaz...

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  10. #10
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Hello,

    J'ai pourtant le sentiment qu'on n'est pas loin : ma partie gère très bien l'ENREGISTREMENT de la formule dans la cellule et sa transformation (et c'est pas non plus trop répugnant comme code, en tout cas c'est stable...) et ta partie gère très bien l'alternance de l'AFFICHAGE...

    On doit y arriver.
    Je vois ce que je peux trouver et je te tiens au courant.
    Bon WE.

  11. #11
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Hello,

    J'ai donc opté pour un panaché des 2 méthodes qui fonctionne très bien.
    Comme ca n'est pas du super code je verrai plus tard s'il est possible de l'optimiser.

    Olsimare, il me reste une dernière question de fond : je n'ai pas compris le fonctionnement des 2 fonctions / procédures suivantes :


    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
    Public Class FormulaDGVCell
        Inherits DataGridViewTextBoxCell
     
        Protected Overrides Function GetFormattedValue( _
        ByVal value As Object, _
        ByVal rowIndex As Integer, _
     ByRef cellStyle As DataGridViewCellStyle, _
        ByVal valueTypeConverter As System.ComponentModel.TypeConverter, _
        ByVal formattedValueTypeConverter As System.ComponentModel.TypeConverter, _
        ByVal context As DataGridViewDataErrorContexts _
    ) As Object
            If Me.RowIndex < 0 Then Return Nothing
     
            Dim s As String = CStr(Me.Value)
     
            If Left(s, 1) = "=" Then
                Return "Eval(" & Mid(s, 2) & ")"
            Else
                Return s
            End If
        End Function
     
        Public Overrides Sub InitializeEditingControl(ByVal rowIndex As Integer, ByVal initialFormattedValue As Object, ByVal dataGridViewCellStyle As DataGridViewCellStyle)
     
            MyBase.InitializeEditingControl(rowIndex, initialFormattedValue, dataGridViewCellStyle)
     
            Dim dgvtb As DataGridViewTextBoxEditingControl = CType(DataGridView.EditingControl, DataGridViewTextBoxEditingControl)
     
            dgvtb.Text = CStr(Me.Value)
     
        End Sub
     
    End Class

    Qu'est ce qui les déclenche et comment agissent-elles ?
    Encore merci.

  12. #12
    Membre chevronné
    Avatar de olsimare
    Inscrit en
    Décembre 2006
    Messages
    1 179
    Détails du profil
    Informations forums :
    Inscription : Décembre 2006
    Messages : 1 179
    Points : 1 776
    Points
    1 776
    Par défaut
    Bonjour.

    InitializeEditingControl est déclenché lorsqu'une cellule passe en mode d'édition (par click souris, entrée de texte ou par code avec datagridview.beginedit). C'est utilisé comme le nom l'indique pour initializer le control d'édition (il ne faut pas oublier que le control d'édition peut être de n'importe quel type).

    GetFormattedValue est utilisé directement par le DGV pour récupérer la valeur à afficher dans la cellulle.

    Cdt.
    Bon à savoir : la touche F1 ne sert pas à commander des places pour le grand prix de Belgique.

  13. #13
    Membre habitué
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    306
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 306
    Points : 164
    Points
    164
    Par défaut
    Ok.
    Merci beaucoup, Olsimare, pour toutes ces précisions... j'ai pu bien avancer.

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

Discussions similaires

  1. Pb date dans datagridview [vb.net] [sql server 2008]
    Par RATIER dans le forum Windows Forms
    Réponses: 4
    Dernier message: 22/10/2009, 10h00
  2. [VB.NET] Checkbox dans DataGridView
    Par horzy dans le forum Windows Forms
    Réponses: 6
    Dernier message: 09/02/2009, 15h24
  3. Selection d'une plage de cellules dans DatagridView [Vb.Net]
    Par papy75 dans le forum Windows Forms
    Réponses: 4
    Dernier message: 17/06/2008, 12h03
  4. [VB.net] Exécuter code après ajout dans datagridview
    Par collaud_vb dans le forum Windows Forms
    Réponses: 1
    Dernier message: 27/09/2006, 11h45
  5. [VB.NET] Calculs dans une colonne d'un datagridview
    Par boulete dans le forum Windows Forms
    Réponses: 3
    Dernier message: 31/03/2006, 15h11

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