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 :

Fonction split sur une chaine issue d'un tableau (erreur 13) [XL-2010]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Homme Profil pro
    Ingénieur généraliste
    Inscrit en
    Avril 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur généraliste
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2014
    Messages : 3
    Par défaut Fonction split sur une chaine issue d'un tableau (erreur 13)
    Bonjour à tou(te)s,

    Je me débat depuis deux jours sur une fonction qui me semblait plutôt simple et je n'en vois pas le bout.

    Pour le contexte, dans un userForm je souhaite faire en sorte qu'a la modification d'une combobox (liste de produit) une listbox dans le même userform se mette a jour.

    J'ai tout d'abord déclaré des variables tableau "publique" (pdtTab, joinTabPdt, i, j, etc.)

    Dans un premier temps je construis la combobox, jusqu'ici pas de souci :
    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
     
    Private Sub UserForm_Initialize()
        '-------------------------------------------------------------------------------------------------------------------
        ' Remise a zero des valeurs dans l'IHM
        '-------------------------------------------------------------------------------------------------------------------
        ComboBox1.Clear
        ListBox1.Clear
     
        '-------------------------------------------------------------------------------------------------------------------
        ' Construction de la liste des produits dans la Combobox
        '-------------------------------------------------------------------------------------------------------------------
        For i = 0 To UBound(pdtTab)
            SelectProduct.ComboBox1.AddItem pdtTab(i, 1)
        Next i
     
    End Sub
    ensuite je veux traiter la listbox en fonction du changement dans la combobox :
    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
     
    Private Sub ComboBox1_Change()
     
        ListBox1.Clear
        Dim linkedProduct As String
     
        'traitement des produits lié
        With ComboBox1.Value
     
            For i = 0 To UBound(pdtTab)
                If pdtTab(i, 1) = ComboBox1.Value Then
     
                    linkedProduct = CStr(pdtTab(i, 3))       'Récupération dans le tableau d'origine du champs 3 ou se situe une chaine du type "1,2,14,25,29,31"
                    MsgBox (linkedProduct)                      ' La msgbox affiche bien la chaine
                    joinTabPdt = Split(linkedProduct, ",")   ' PAF... erreur 13 ???
     
                    For j = LBound(joinTabPdt) To UBound(joinTabPdt)
     
                        ListBox1.AddItem pdtTab(j, 1)
     
                    Next j
     
                    Exit For
                End If
            Next i
     
        End With
     
    End Sub
    sauriez vous me dire si j'ai raté une étape ? j'ai l'impression que le code est assez simple et je ne comprend pas d'ou cela peut provenir

    Merci !

  2. #2
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    Mars 2007
    Messages
    2 478
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 71
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    Par défaut
    Bonjour,
    Citation Envoyé par s3ph0ri4 Voir le message
    [...] J'ai tout d'abord déclaré des variables tableau "publique" (pdtTab, joinTabPdt, i, j, etc.) ....
    Regardes cette réponse de Pierre : https://www.developpez.net/forums/d2.../#post11121548

  3. #3
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 194
    Par défaut
    Bonjour,

    Citation Envoyé par s3ph0ri4 :
    J'ai tout d'abord déclaré des variables tableau "publique" (pdtTab, joinTabPdt, i, j, etc.)
    cela aurai été bien de nous montrer comment.

    Attention la variable "joinTabPdt" doit être déclarée en Variant et pas en String !!!

  4. #4
    Futur Membre du Club
    Homme Profil pro
    Ingénieur généraliste
    Inscrit en
    Avril 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur généraliste
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2014
    Messages : 3
    Par défaut
    Bonjour a vous,

    D'abord merci pour vos retours.

    Patrice740 : j'ai bien lu l'argumentaire qui globalement dit a quel point il ne faudrait pas user de variables publique. Si je comprend la démarche et ses raisons, n'étant pas un professionnel en programmation, je ne vois pas comment réaliser certaines fonction et suis vite bloqué si je ne m'en sers pas. C'est également pour moi un moyen de mettre a disposition de l'ensemble de mes modules des variables qui leur sont commune afin d'éviter de les répéter dans chacun d'eux. Une sorte d'initialisation de mes fonctions. Si jamais dans le code ci-dessous et précédemment envoyé vous identifiez des moyens/methodes me permettant de limiter encore un peu plus cette usage je suis preneur !


    Phil Free : j'ai effectivement déclaré ce tableau en tant que string. Mais malgré le changement de type en variant j'ai toujours le message d'erreur 13...

    Pour la "méthode", dans un module "DECLARATIONS" je pose les variables commune a l'ensemble de mes modules :
    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
     
    Option Explicit
    'DECLARATIONS DES VARIABLES COMMUNES A L'ENSEMBLE DES MODULES
     
        ' Déclaration des feuilles :
        Public ws_CONF As Worksheet            ' Configuration
        Public ws_ANA As Worksheet              ' Analyse : post-traitement
        Public ws_BDD As Worksheet             ' Base de Données générale
        Public ws_PDT As Worksheet              ' BDD Produits)
     
        'Déclaration des variables
        Public i, j, k, l, m, n As Integer
        Public pdtTab(), ownerTab() As String         ' Bases de données
        Public joinTabPdt() As String                      ' Tableaux de jointure
        Public choixPdt As String                           ' Produit sélectionné dans userForm "SelectProduct"
        Public productToAdd() As String                 ' Tableau des produits a ajouter 
     
    'ATTRIBUTIONS DES VALEURS
    Sub initVar()
        Set ws_CONF = ThisWorkbook.Worksheets("CONFIGURATION")
        Set ws_ANA = ThisWorkbook.Worksheets("ANALYSIS")
        Set ws_BDD = ThisWorkbook.Worksheets("BDD_GEN")
        Set ws_OWNER = ThisWorkbook.Worksheets("BDD_PORTEURS")
        Set ws_PDT = ThisWorkbook.Worksheets("BDD_PRODUITS")
    End Sub
    Ensuite j'ai créé un module "ADDPRODUCT" qui traite la création de mes tableaux et appel ensuite le userform :
    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
     
    Sub addProduct()
     
        On Error GoTo End_AddProduct
     
        '-------------------------------------------------------------------------------------------------------------------
        ' INITIALISATION DES VARIABLES GLOBALES
        '-------------------------------------------------------------------------------------------------------------------
       Call initVar
     
        '-------------------------------------------------------------------------------------------------------------------
        ' DECLARATIONS :
        '-------------------------------------------------------------------------------------------------------------------
            ' Produits
            Dim PDT_derLig, PDT_DerCol, OWNER_derLig, OWNER_derCol, As Integer
            Dim nbPDT, nbOwner As Integer
     
        '--------------------------------------------------------------------------------------------------------------------
        ' INITIALISATION DES VARIABLES GENERALES :
        '-------------------------------------------------------------------------------------------------------------------
            PDT_derLig = lastEmptyLine(ws_PDT, 2, "A")          'calcul de la dernière ligne vide
            PDT_DerCol = lastEmptyColumn(ws_PDT, 1, 1)          'calcul de la dernière colonne vide
            OWNER_derLig = lastEmptyLine(ws_OWNER, 2, "A")      'calcul de la dernière ligne vide
            OWNER_derCol = lastEmptyColumn(ws_OWNER, 1, 1)      'calcul de la dernière colonne vide
     
        '-------------------------------------------------------------------------------------------------------------------
        ' CREATION DES TABLEAUX
        '-------------------------------------------------------------------------------------------------------------------
        nbPDT = PDT_derLig - 2            'Nombre de produits en bdd
        nbOwner = OWNER_derLig - 2   'Nombre de porteur
     
        ReDim pdtTab(nbPDT, 5)          'redimensionnement du tableau des produits
        ReDim ownerTab(nbOwner, 2)  'redimensionnement du tableau des porteurs
     
        ' Construction du tableau des produits
        For i = 0 To nbPDT
            pdtTab(i, 0) = ws_PDT.Range("A" & i + 2).Value   ' ID
            pdtTab(i, 1) = ws_PDT.Range("B" & i + 2).Value   ' Type de produit
            pdtTab(i, 2) = ws_PDT.Range("C" & i + 2).Value   ' Famille Produit
            pdtTab(i, 3) = ws_PDT.Range("D" & i + 2).Value   ' Jointures produit
            pdtTab(i, 4) = ws_PDT.Range("E" & i + 2).Value   ' Jointures livrable
        Next i
     
        ' Construction du tableau des porteurs
        For i = 0 To nbOwner
            ownerTab(i, 0) = ws_OWNER.Range("A" & i + 2).Value   ' ID
            ownerTab(i, 1) = ws_OWNER.Range("B" & i + 2).Value   ' Porteur du KID
        Next i
     
        ' Appel de l'IHM
        SelectProduct.Show
     
        ' Récupération des informations user
        MsgBox ("Produit de tête : " & choixPdt)
        'MsgBox ("Produit lié : " & productToAdd(0))
     
        GoTo End_AddProduct
     
    '-----------------------------------------------------------------------------------------------------------------------
    ' Ré-initialisation des variables
    '-----------------------------------------------------------------------------------------------------------------------
    End_AddProduct:
        Erase pdtTab
        Erase kidTab
        Erase ownerTab
        Erase joinTabPdt
        Erase joinTabKid
        choixPdt = ""
        Erase productToAdd
     
    End Sub

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Février 2010
    Messages
    194
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 194
    Par défaut
    ah oui mais non

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public joinTabPdt() As String
    tu dimensionnes bien un tableau de string mais il est ici dit de taille dynamique donc on doit trouver un redim quelque part dans ton code et la je ne vois rien pour cette variable !

    avec un split le mieux est d'utiliser une variable déclarée en variant comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Public joinTabPdt As Variant
    pour plus d'info voir le tuto de silkyroad Utiliser les variables tableaux en VBA Excel

  6. #6
    Futur Membre du Club
    Homme Profil pro
    Ingénieur généraliste
    Inscrit en
    Avril 2014
    Messages
    3
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur généraliste
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Avril 2014
    Messages : 3
    Par défaut
    Pierre Fauconnier : Merci pour l'exemple ! la démarche me plait mieux effectivement.

    Phil Free : Effectivement le code copié sur le forum ne laissait pas apparaitre la modification que j'avais faite dans mon module et malgré ça cela ne fonctionnait pas.

    Par contre je me suis rendu compte que le sub "combobox1_Change()" était par défaut "private". J'ai donc rapatrié la variable "joinTabPdt as variant" au sein de la sub et tout fonctionne !! Effectivement elle n'avait pas besoin d'être public celle-ci !

    Merci beaucoup a tous !

  7. #7
    Expert confirmé
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Billets dans le blog
    7
    Par défaut
    Bonjour,

    Salut Pierre

    Perso, je n'utilise pas Initialize du userform. Je préfère travailler avec une procédure d'un module standard qui prépare le userform
    En quoi ce process diffère-t-il de l'évènement Initialize, s'il te plaît? Performance, souplesse?

    Pour ma part, comme pour les boutons de commande, je fais appel, dans cet évènement, à une suite de codes intégrés au module du formulaire.
    Je pilote le formulaire à distance lorsqu'il s'agit d'en obtenir une propriété (Property).

    Merci pour ton retour.

  8. #8
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut.

    Perso, je n'utilise pas Initialize du userform. Je préfère travailler avec une procédure d'un module standard qui prépare le userform puis l'affiche. Ici, la procédure alimente le combobox sur base d'une plage d'un tableau structuré, et alimente une propriété publique du userform qui est en fait un tableau (array) qui reçoit les données du tableau structuré qui devront être affichées dans le listbox.

    Note également que tu peux te passer d'une boucle pour alimenter un array sur base d'une plage de données. Regarde le code ci-dessous: le combobox est alimenté directement avec la plage grâce à List, et l'array qui sera utilisé pour alimenter le listbox est alimenté lui aussi directement et sans boucle avec une plage grâce à la propriété Value de la plage.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Sub Test()
      With UserForm1
        .cboProduits.List = Range("t_Produits[Produit]").Value
        .t_Mouvements = Range("t_Mouvements").Value
        .Show
      End With
      Unload UserForm1
    End Sub


    Dans le userform, on gère l'évènement Change du combobox en appelant une procédure de rafraîchissement du listbox. Voici le code du userform (déclaration de la propriété publique, gestion de l'évènement et préparation de la listbox). Tu remarqueras au passage qu'il n'y a aucune variable publique dans mon code.


    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
    Option Explicit
     
    Public t_Mouvements
     
    Private Sub cboProduits_Change()
      UpdateLboMouvements
    End Sub
     
     
    Sub UpdateLboMouvements()
      Dim Counter As Long
      lboMouvements.Clear
      For Counter = 1 To UBound(t_Mouvements)
        If t_Mouvements(Counter, 1) = cboProduits.Value Then
          lboMouvements.AddItem
          lboMouvements.List(lboMouvements.ListCount - 1, 0) = t_Mouvements(Counter, 1)
          lboMouvements.List(lboMouvements.ListCount - 1, 1) = t_Mouvements(Counter, 2)
          lboMouvements.List(lboMouvements.ListCount - 1, 2) = t_Mouvements(Counter, 3)
        End If
      Next
    End Sub

    L'exemple utilise un tableau structuré t_Produits et un tableau structuré t_Mouvements illustrés ci-dessous.

    Nom : 2019-12-05_094512.png
Affichages : 415
Taille : 11,8 Ko
    Fichiers attachés Fichiers attachés
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  9. #9
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    Salut Marcel,

    Voici ce qui me fait préférer un code d'amorçage en dehors du userform.

    Ce sont tout d'abord les règles qui président à la POO d'une part et, partant de là, le gain de souplesse dans le code (et dans sa réutilisation); les règles de bonne architecture, aussi, si l'on souhaite peu ou prou une architecture "trois tiers" et, partant de là, souplesse également, mais aussi gain en maintenabilité et en évolutivité.

    La POO fait appel à une notion qui en est un des socles, l'encapsulation. Derrière ce terme se cache l'idée que ce qui rentre dans un objet ne peut y rentrer que par des "sas" prévus pour. C'est le rôle du constructeur que l'on retrouve en POO mais qui est absent du VBA, et c'est le rôle des fonctions/procédures paramétrées et des propriétés en écriture.

    Dans le code que j'ai donné ici et qui manipule un userform (un objet, donc), on retrouve l'array t_Mouvements qui est en fait une propriété en lecture/écriture (auto implémentée car elle se passe des Property Get/Let). C'est donc une "porte d'entrée" valide qui n'enfreint pas la règle d'encapsulation et ce "sas" est utilisé sur la ligne .t_Mouvements = Range("t_Mouvements").Value. J'aurais pu créé une procédure Init qui recevait les deux tableaux en paramètres et qui les affectaient à l'intérieur du code du userform.

    Le code du userform serait alors adapté comme suit (la propriété publique disparaît au profit d'une variable privée, la procédure Init est ajoutée et sur l'évènement Change, on utilise la variable privée et plus la propriété publique).
    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
    Private mMouvements
     
    Sub Init(Produits, Mouvements)
      cboProduits.List = Produits
      mMouvements = Mouvements
    End Sub
     
    Private Sub cboProduits_Change()
      UpdateLboMouvements
    End Sub
     
     
    Sub UpdateLboMouvements()
      Dim Counter As Long
      lboMouvements.Clear
      For Counter = 1 To UBound(mMouvements)
        If mMouvements(Counter, 1) = cboProduits.Value Then
          lboMouvements.AddItem
          lboMouvements.List(lboMouvements.ListCount - 1, 0) = mMouvements(Counter, 1)
          lboMouvements.List(lboMouvements.ListCount - 1, 1) = mMouvements(Counter, 2)
          lboMouvements.List(lboMouvements.ListCount - 1, 2) = mMouvements(Counter, 3)
        End If
      Next
    End Sub
    Le code qui initialise tout cela est adapté lui aussi dans la procédure d'appel
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Sub Test()
      With UserForm1
        .Init Range("t_Produits[Produit]").Value, Range("t_Mouvements").Value
        .Show
      End With
      Unload UserForm1
    End Sub
    Ce faisant, on respecte l'encapsulation. Rien ne rentre dans le userform par ailleurs que par ce qui est prévu pour. Dès lors, le userform est "autonome" par rapport à l'application qui le manipule.

    Lorsque l'on place le code de préparation dans l'évènement Initialize du userform, on enfreint le principe d'encapsulation et on crée un "couplage fort" entre le userform et l'application. Avec le code suivant, mon userform impose qu'il ait une plage t_Produits dans le classeur actif, qui n'est pas forcément celui qui contient le userform, notamment si c'est un xlam, c-à-d un addin. L'utilisation d'un xlam pour découpler les données de l'appli imposent d'ailleurs pratiquement qu'on laisse tomber le initialize
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub UserForm_Initialize()
      cboProduits.List = Range("t_Produits")
    End Sub
    Dès lors, pour moi, l'initialize ne sert pas à grand chose, voire à rien. Il pourrait, à la limite, servir à initialiser des variables ou des contrôles tels qu'un contrôle qui contiendrait par exemple la date du jour par défaut. C'est à peu près le seul cas où je pourrais envisager d'utiliser Initialize. Et encore, je prévoirais une propriété publique pour pouvoir modifier cette valeur par défaut lors de la préparation du userform.


    Je parlais également d'architecture "trois tiers". Dans un "trois tiers", le code est découpé (rangé) selon ce qu'il fait. On a une couche qui gère les interactions avec l'utilisateur (c'est la Presentation Layer ou PL), une couche qui gère les interactions avec les systèmes de stockage de données (c'est la Data Access Layer ou DAL) et au milieu de la lasagne, on a le code qui gère le métier (c'est la Business Layer ou BL). Le Userform est clairement dans la PL, alors que l'acquisition des données en provenance d'un tableau structuré est clairement du ressort de la DAL. Utiliser un Range dans le Initialize amène à foutre par terre l'architecture trois-tiers, qui est garante d'un code fonctionnel, évolutif, maintenable et facilement déboguable. En Excel, il peut paraître illusoire de programmer en "trois tiers", et pourtant, j'encourage vraiment à architecturer son code de cette manière. C'est pour cela que, normalement, la validation "métier" des données ne devrait jamais se trouver dans le userform (PL) mais dans un module standard qui servirait de BL. Par contre, on retrouverait dans le userform la vérification sur le type de données saisie dans un contrôle.

    Par exemple, si un contrôle sert à saisir une date, il est de la responsabilité du userform (sous-couche de la PL) de vérifier que l'on a saisi une date (ou plutôt, du texte qui pourra être traduit en date). Par contre, si cette date doit être contenue dans une période donnée, c'est du domaine de la BL de le vérifier, car il s'agit d'une règle de gestion (une règle "métier" donc Business Layer). Si l'on ne peut pas sortir du userform lorsque la valeur saisie n'est pas validée "côté métier" (BL, donc), on passera au useform le nom de la fonction BL qui (in)valide la valeur, et on lui passera la (les) valeur(s) à tester. J'illustre cela dans ce billet de blog.

    En respectant les règles de la POO (et notamment l'encapsulation) et en tendant vers une architecture Trois-Tiers dans la création de code VBA, on gagne en temps, on diminue le risque d'erreurs et de plantage, on favorise la réutilisation du code par l'emploi de procédures/fonctions que a testées et que l'on rend générique autant qu'il est possible de le faire.


    My (a lot of) 2 cents
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  10. #10
    Expert confirmé
    Avatar de MarcelG
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Juillet 2009
    Messages
    3 449
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Maine et Loire (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2009
    Messages : 3 449
    Billets dans le blog
    7
    Par défaut
    Merci, Pierre, pour cette - complète - information.

    N'étant pas informaticien de métier, mais autodidacte en bureautique, je ne suis pas sûr d'avoir cerné ton raisonnement dans son intégralité.
    J'en retiens, malgré tout, les grandes lignes.

    Maintenant,si l'on va plus loin.

    1 - Les fonctionnalités relatives au formulaire (ajustement à la taille d'écran, croix de fermeture inactive...), pour ma part, doivent-elles être intégrées dans le formulaire à l'évènement Initialize?
    Je me lance: oui.

    2 - De même, le rattachement des contrôles (Boutons de commande et autres) à une classe d'objet gérant les évènements.
    Idem?

    A plus tard.

    PS: Que signifie
    My (a lot of) 2 cents
    En italien, bon sang!

  11. #11
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    il mio lotto di due centesimi (en français= mon (tas de) grain(s) de sel )
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

  12. #12
    Rédacteur/Modérateur


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    Novembre 2003
    Messages
    19 125
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 58
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur et développeur chez EXCELLEZ.net
    Secteur : Enseignement

    Informations forums :
    Inscription : Novembre 2003
    Messages : 19 125
    Billets dans le blog
    131
    Par défaut
    D'accord avec toi pour les points 1 et 2 dont tu parles. Ce qui fait partie des interactions avec l'utilisateur se rattache à la PL (Couche de présentation ou d'interactions avec l'utilisateur). Or, redimensionner un userform et gérer les évènements sur les boutons, c'est bien gérer les interactions avec l'utilisateur.

    Mais normalement, le code des évènements de boutons ne devraient rien faire d'autre que d'appeler des procédures/fonctions (du userform ou pas, comme je l'illustre dans le billet cité plus haut).

    Mais bon, on empiète un peu sur sur le sujet initial...
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    Mes billets de blog sur DVP
    Mes remarques et critiques sont purement techniques. Ne les prenez jamais pour des attaques personnelles...
    Pensez à utiliser les tableaux structurés. Ils vous simplifieront la vie, tant en Excel qu'en VBA ==> mon tuto
    Le VBA ne palliera jamais une mauvaise conception de classeur ou un manque de connaissances des outils natifs d'Excel...
    Ce ne sont pas des bonnes pratiques parce que ce sont les miennes, ce sont les miennes parce que ce sont des bonnes pratiques
    VBA pour Excel? Pensez D'ABORD en EXCEL avant de penser en VBA...
    ---------------

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

Discussions similaires

  1. fonction max() sur une chaine (string)
    Par speedev dans le forum Requêtes
    Réponses: 5
    Dernier message: 10/03/2009, 11h30
  2. fonction split sur une url
    Par Sh4dow49 dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 21/10/2008, 16h42
  3. [2.0] Split sur une chaîne et non un tableau de caractères
    Par franculo_caoulene dans le forum VB.NET
    Réponses: 5
    Dernier message: 11/06/2008, 11h50
  4. fonction replaceFirst sur une chaine de caractere
    Par marcxa44 dans le forum Langage
    Réponses: 1
    Dernier message: 08/10/2007, 13h22
  5. [debutant]fonction "split" avec une chaine comme m
    Par EpOnYmE187 dans le forum Débuter
    Réponses: 2
    Dernier message: 07/11/2005, 22h46

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