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

  1. #1
    Membre à l'essai
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    août 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Contrôleur de Gestion
    Secteur : Bâtiment

    Informations forums :
    Inscription : août 2019
    Messages : 10
    Points : 13
    Points
    13
    Par défaut Help: Incrémenter une ligne d'un objet Tableau + Modification d'une base via une recherche
    Bonjour à tous,

    Tout d'abord, un grand merci si vous lisez mon message.

    Voici ma problématique: j'ai créé un fichier pour le suivi de mes sous-traitants. Sur ce fichier, il y a deux onglets:

    - FORM: qui sert à l'enregistrement d'un sous Traitant ET (mais je n'y arrive pas) à modifier une ligne d'un sous Traitant existant
    - BDD: qui est ma base de donnée

    Utilisation: le but est donc de saisir les différents champs dans "FORM". Quand je clique sur le bouton "Créatin", une ligne va venir s'incrémenter dans mon onglet BDD.

    1er problématique: cela fonctionne mais je souhaite que ma base de donnée dans l'onglet BDD soit sous forme de l'outil TABLEAU. Or, la ligne qui vient s'incrémenter se rajoute en dessous du Tableau créé et non dans le Tableau. Comment pourrais je faire? Cela me permettrait notamment de faire glisser mes formules sur l'onglet BDD entre les colonnes V et AH.

    2eme problématique: Sur l'onglet FORM, je souhaite pouvoir modifier une ligne existante. Mon souhait serait donc de sélectionner un sous Traitant sur la cellule N7 de l'onglet FORM et que les informations apparaissent sur les différents champs de mon "formulaire". Une fois que j'apporte mes modifications, celles-ci doivent être mise à jour dans ma base de données.
    Mais là, idem, je pense être trop débutant pour savoir faire cela. Pourriez vous m'aider?

    Je vous remercie beaucoup pour votre aide.

    Je vous mets mon fichier actuel en PJ.

    Bien à vous,

    Laurent
    Fichiers attachés Fichiers attachés

  2. #2
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    novembre 2003
    Messages
    17 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

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

    Informations forums :
    Inscription : novembre 2003
    Messages : 17 148
    Points : 49 407
    Points
    49 407
    Billets dans le blog
    92
    Par défaut
    Salut

    Voici un exemple à adapter à ton cas.

    Au départ, un tableau t_contacts, une zone de saisie (En B1, B3 et B5) nommée Saisie composée des cellules nommées Saisie_ID, Saisie_Nom, Saisie_Prénom (ici sur la même feuille pour les besoins de l'illustration, mais tu remarques que nul part je ne parle de la place des cellules, l'utilisation des alias et références structurées permettant de les déplacer sans toucher au code). Deux boutons connectés aux procédures Save et Retrieve sont placés sur le "formulaire"

    Nom : 2021-04-07_152319.png
Affichages : 27
Taille : 50,3 Ko




    Voici un code très simple qui utilise Excel( références structurées, fonction EQUIV - Match en anglais) (D'abord penser EXCEL avant de penser VBA)

    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
    Option Explicit
     
    Sub Save()
      Dim Index As Long
     
      Index = Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
      If Index = 0 Then Index = Range("t_Contacts").ListObject.ListRows.Add.Index
      WriteData Index
    End Sub
     
    Sub WriteData(Index As Long)
      Range("t_Contacts[ID]")(Index).Value = Range("Saisie_ID").Value
      Range("t_Contacts[Nom]")(Index).Value = Range("Saisie_Nom").Value
      Range("t_Contacts[Prénom]")(Index).Value = Range("Saisie_Prénom").Value
      Range("saisie").ClearContents
    End Sub
     
    Sub Retrieve()
      Dim ID As Long
      ID = Range("saisie_id").Value
      If ReadData(ID) = 1 Then MsgBox "Identifiant inexistant", vbExclamation, "Recherche d'un contact"
    End Sub
     
    Function ReadData(ID As Long) As Long
      Dim Row As Long
      Dim Source As Range
     
      Row = Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
      If Row > 0 Then
        Range("saisie_Nom").Value = Range("t_Contacts[Nom]")(Row).Value
        Range("saisie_Prénom").Value = Range("t_Contacts[Prénom]")(Row).Value
      Else
        ReadData = 1
      End If
    End Function
    Ici, j'ai montré le mécanisme général, pas les vérifications d'usage, dont par exemple le fait d'avoir bien saisi un ID numérique en B1. C'est à toi d'adapter.


    Si on a beaucoup de paires cellules/colonnes, on pourrait se baser sur un array de paires Clés/Valeurs ou une table de mappage (cfr ce message).
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    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...
    ---------------

  3. #3
    Membre à l'essai
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    août 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Contrôleur de Gestion
    Secteur : Bâtiment

    Informations forums :
    Inscription : août 2019
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Bonjour Pierre,

    Merci pour cet exemple. Je suis en train de le décortiquer. L'avantage en plus est que cela passerait par une base en format Tableau.

    Pour la partie "Save", je pense avoir bien saisi la mécanique et je vais pouvoir l'adapter à mon fichier.

    Là je bloque sur la partie

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Sub Retrieve()
      Dim ID As Long
      ID = Range("saisie_id").Value
      If ReadData(ID) = 1 Then MsgBox "Identifiant inexistant", vbExclamation, "Recherche d'un contact"
    End Sub

    En effet, cela ne semble pas fonctionner quand je lance la Macro. Je vais creuser.

    Si je peux me permettre, est-ce qu'il y aurait un moyen de ne pas pouvoir ajouter de ligne si le sous traitant est déjà dans ma base? En fait, je souhaiterais que, quand on tape l'ID (dans ton exemple), si celui si se trouve dans la base, alors un message apparait pour m'en informer et cela stop la macro.

    Bien à toi

    Laurent

  4. #4
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    novembre 2003
    Messages
    17 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

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

    Informations forums :
    Inscription : novembre 2003
    Messages : 17 148
    Points : 49 407
    Points
    49 407
    Billets dans le blog
    92
    Par défaut
    Dans une autre discussion, j'avais repris le code que je t'ai donné et je l'avais commenté. Le voici.

    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
    Sub Save()
      ' Cherche si l'identifiant saisi existe grâce à la formule EQUIV (englobée dans un SIERREUR)
      Dim Index As Long
     
      Index = Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)") ' Renvoie la ligne du tableau si ID existe, sinon 0
      If Index = 0 Then Index = Range("t_Contacts").ListObject.ListRows.Add.Index ' Si 0, crée une nouvelle ligne dans le tableau structuré
      WriteData Index ' Appelle la procédure WRITE en lui passant le numéro de la ligne à modifier
    End Sub
     
    Sub WriteData(Index As Long)
      ' Transfère les données du formulaire dans la ligne du tableau souhaitée, cellule par cellule
      Range("t_Contacts[ID]")(Index).Value = Range("Saisie_ID").Value ' Transfère le contenu de la cellule du formulaire qui contient l'ID sur la ligne souhaitée, dans la colonne de l'ID
      Range("t_Contacts[Nom]")(Index).Value = Range("Saisie_Nom").Value ' Idem pour le nom
      Range("t_Contacts[Prénom]")(Index).Value = Range("Saisie_Prénom").Value ' Idem pour le prénom
      Range("saisie").ClearContents ' Nettoie la zone de saisie
    End Sub
     
    Sub Retrieve()
      ' Récupère le numéro de la ligne de l'ID pour les données que l'on veut transmettre au formulaire
      ' Transfère la ligne de l'ID si trouvée, sinon on affiche un message d'erreur
      Dim ID As Long
      ID = Range("saisie_id").Value ' Récupération de l'identifiant saisi dans le formulaire
      If ReadData(ID) = 1 Then MsgBox "Identifiant inexistant", vbExclamation, "Recherche d'un contact" ' appelle la fonction ReadData en lui passant l'ID et teste le résultat. Si 0, OK, si 1, affichage du message
    End Sub
     
    Function ReadData(ID As Long) As Long
      ' Recherche l'ID dans la colonne ID du tableau et si trouvé, transfère les données dans le formulaire et renvoie 0. Si pas trouvé, renvoie 0
      Dim Row As Long
      Dim Source As Range
     
      Row = Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)") ' Recherche de la cellule qui contient l'ID avec une formule EQUIV (MATCH en anglais)
      If Row > 0 Then ' SI le numéro de la ligne est >0, l'ID existe et on transfère
        Range("saisie_Nom").Value = Range("t_Contacts[Nom]")(Row).Value ' Transfert du contenu de la colonne Nom du tableau pour la ligne trouvée
        Range("saisie_Prénom").Value = Range("t_Contacts[Prénom]")(Row).Value ' Idem pour le prénom
      Else ' La ligne n'a pas été trouvée car l'ID n'existe pas dans le tableau
        ReadData = 1 ' ReadData renvoi1 pour informer la procédure appelante que le transfert n'a pas pu être effectué
      End If
    End Function


    Citation Envoyé par laurentdx59 Voir le message
    [...]
    En effet, cela ne semble pas fonctionner quand je lance la Macro. Je vais creuser.[...]
    Il faut noter qu'avec Evaluate, on recompose les arguments de la fonction EQUIV (MATCH) comme en Excel, donc en différenciant les valeurs de type texte et de type numérique. On pourrait remplacer les Evaluate... par Application.Match(Range("saisie_ID").Value, Range("t_Contacts[id]"), 0) 'Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    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...
    ---------------

  5. #5
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    novembre 2003
    Messages
    17 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

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

    Informations forums :
    Inscription : novembre 2003
    Messages : 17 148
    Points : 49 407
    Points
    49 407
    Billets dans le blog
    92
    Par défaut
    Si on veut tendre vers du générique, les WriteData et ReadData devraient recevoir l'index de la ligne en entier long, à charge pour les procédures qui les appellent de déterminer l'index de la ligne. Ca correspondrait mieux à une architecture "bonnes pratiques" ou une fonction n'a qu'un seul rôle...

    Dès lors, Save et Retrieve ont comme rôle de rechercher l'index voulu et d'appeler la procédure qui transfère les données dans un sens ou dans l'autre. Voici un code qui respecte mieux cela:

    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
    Sub Save()
      Dim Index
     
      Index = Application.Match(Range("saisie_ID").Value, Range("t_Contacts[id]"), 0) 'Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
      If IsError(Index) Then Index = 0
      If Index = 0 Then Index = Range("t_Contacts").ListObject.ListRows.Add.Index
      WriteData CLng(Index)
    End Sub
     
    Sub WriteData(Index As Long)
      Range("t_Contacts[ID]")(Index).Value = Range("Saisie_ID").Value
      Range("t_Contacts[Nom]")(Index).Value = Range("Saisie_Nom").Value
      Range("t_Contacts[Prénom]")(Index).Value = Range("Saisie_Prénom").Value
      Range("saisie").ClearContents
    End Sub
     
    Sub Retrieve()
      Dim ID
      ID = Application.Match(Range("saisie_ID").Value, Range("t_Contacts[id]"), 0) 'Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
      If ReadData(CLng(ID)) = 1 Then MsgBox "Identifiant inexistant", vbExclamation, "Recherche d'un contact"
    End Sub
     
    Function ReadData(Index As Long) As Long
      Dim Source As Range
     
      If Index > 0 Then
        Range("saisie_Nom").Value = Range("t_Contacts[Nom]")(Index).Value
        Range("saisie_Prénom").Value = Range("t_Contacts[Prénom]")(Index).Value
      Else
        ReadData = 1
      End If
    End Function
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    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...
    ---------------

  6. #6
    Responsable
    Office & Excel


    Homme Profil pro
    Formateur et développeur chez EXCELLEZ.net
    Inscrit en
    novembre 2003
    Messages
    17 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : Belgique

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

    Informations forums :
    Inscription : novembre 2003
    Messages : 17 148
    Points : 49 407
    Points
    49 407
    Billets dans le blog
    92
    Par défaut
    Citation Envoyé par laurentdx59 Voir le message
    [...]
    Si je peux me permettre, est-ce qu'il y aurait un moyen de ne pas pouvoir ajouter de ligne si le sous traitant est déjà dans ma base? En fait, je souhaiterais que, quand on tape l'ID (dans ton exemple), si celui si se trouve dans la base, alors un message apparait pour m'en informer et cela stop la macro.[...]
    Normalement, c'est le fonctionnement de mon code, puisque l'index de la ligne sur laquelle pousser les données est calculé par EQUIV (en VBA) pour retrouver la ligne existante ou créer la nouvelle. Cela permet de mettre à jour les données du contact.

    Voici en exemple la procédure Save adaptée pour demander à l'utilisateur s'il veut remplacer les données... Tu remarqueras que l'architecture découpée en fonctions "monorôle" permet de ne modifier que cette procédure...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Sub Save()
      Dim Index
      Dim Answer As VbMsgBoxResult
     
      Index = Application.Match(Range("saisie_ID").Value, Range("t_Contacts[id]"), 0) 'Evaluate("iferror(match(" & Range("saisie_ID").Value & ",t_Contacts[ID],0),0)")
      If IsError(Index) Then Index = 0
      If Index = 0 Then
        Index = Range("t_Contacts").ListObject.ListRows.Add.Index
        Answer = vbYes
      Else
        Answer = MsgBox("Ce contact existe. Voulez-vous remplacer les données", vbQuestion + vbYesNo, "Enregistrement")
      End If
      If Answer = vbYes Then WriteData CLng(Index)
    End Sub
    "Plus les hommes seront éclairés, plus ils seront libres" (Voltaire)
    ---------------
    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...
    ---------------

  7. #7
    Membre à l'essai
    Homme Profil pro
    Contrôleur de Gestion
    Inscrit en
    août 2019
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Contrôleur de Gestion
    Secteur : Bâtiment

    Informations forums :
    Inscription : août 2019
    Messages : 10
    Points : 13
    Points
    13
    Par défaut
    Bonjour Pierre,

    Merci beaucoup pour cette aide. Je suis en train de rebâtir mon fichier en partant de tes instructions pour comprendre le code et son fonctionnement. (Je suis néophyte donc je ne comprends pas tous les termes employés )

    Je te tiens au courant de mon avancée

    Bonne journée

Discussions similaires

  1. [XL-2016] Pb plantage avec insertion ligne en fin objet tableau
    Par thefamille dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 02/05/2020, 15h43
  2. Réponses: 17
    Dernier message: 01/01/2013, 19h10
  3. Incrémenter les lignes d'un tableau excel par une variable
    Par lucien(67) dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 10/02/2008, 18h10
  4. [HTML] Se placer à une ligne précise dans un tableau
    Par seb55555 dans le forum Balisage (X)HTML et validation W3C
    Réponses: 3
    Dernier message: 28/10/2004, 15h06
  5. [VB.NET] Quel objet tableau pour une recherche indexée ???
    Par Kitano dans le forum Windows Forms
    Réponses: 7
    Dernier message: 02/09/2004, 09h38

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