Problème d'ajouts de références dans une base de données (VBA Excel)

Bonjour, je suis débutant avec excel VBA, j'ai donc quelques questions pour les experts que vous êtes.

Vous trouverez dans le fichier uploader la feuille base de données qui dans le futur permettra d'ajouter/modifier/supprimer des références.

Avec le bouton ajouter, je peux rentrer plusieurs infos concernant une nouvelle référence. Mais j'ai plusieurs soucies :

- Tout d'abord même avec un "Unload me", mon UserForm s'ouvre en étant déjà remplis et je voudrais qu'il soit vide

- Ensuite, j'ai essayé d'implémenter un remplissage automatique en fonction de la marque sélectionné

Cependant ayant voulu supprimer les doublons, je pense n'accès qu'à la première ligne de la marque sélectionné (Je vais donc devoir faire une combobox en cascade)

- Enfin, pour le trie, j'ai implémenté une seule option pour le moment (trie pas marque), cependant, je n'ai pas réussi dans le code à faire une boucle if en indiquant que le mot "Marque" avait été sélectionné dans ce même UserForm.

Dans l'attente de vos réponses.

Salut,

Pour le point 1.

Déclare, tout en haut de ton module :

Private InhibeEvent As Boolean

Ensuite, ton événement Combobox1_Change() :

Private Sub ComboBox1_change()
'permet le remplissage, suite à la sélection d'un item, de ses caractéristiques dans la boite d'ajout
Set ws = Sheets("Base_de_données")
Dim ligne As Long
    If Me.ComboBox1.ListIndex = -1 Then Exit Sub
    If Not InhibeEvent Then
        ligne = Me.ComboBox1.ListIndex + 2
        Me.TextBox2 = ws.Cells(ligne, "B")
        Me.TextBox3 = ws.Cells(ligne, "C")
        Me.TextBox4 = ws.Cells(ligne, "D")
        Me.TextBox5 = ws.Cells(ligne, "E")
        Me.TextBox6 = ws.Cells(ligne, "F")
    End If
End Sub

Et enfin Userform_Initialize()

Private Sub UserForm_Initialize()
'permet la sélection dans un menu déroulant des items déjà présent dans la base de données
Set ws = Sheets("Base_de_données")
Dim j As Integer
    InhibeEvent = True
    With Me.ComboBox1
        For j = 2 To ws.Range("A" & Rows.Count).End(xlUp).Row
            ComboBox1 = Range("A" & j)
            'Supprime les doublons de la colonne A dans le combobox1
            If ComboBox1.ListIndex = -1 Then ComboBox1.AddItem Range("A" & j)
        Next j
    End With
    InhibeEvent = False
End Sub

Pour le reste, je n'ai pas tout compris...

Pour le 2. Ajout d'un SpinButton horizontal :

Pour le 3. le + simple est d'utiliser le tri d'Excel non?

Salut,

Merci beaucoup pour tes retours.

-J'ai effectué les modifications et mon UserForm est bien vide lors de l'ouverture. Serait il cependant possible de n'afficher aucun marque de base dans la fenêtre?

-En ce qui concerne le tri, je pense utiliser les fonctions excels, et de les lier dans mon UserForm TRIER, j'aimerai donc savoir comment dans ma fonction qui suit, permettre au code de savoir quel trie faire.

'If "Marque" Then
With ActiveWorkbook.Worksheets("Base_de_données").Sort
    .SetRange Range("A1:F65536")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With
'End If

-Pour implémenter une fonction recherche (avec un pop-up) regroupant un tableau avec la marque ou le produit ciblé, quelles fonctions me recommenderais-tu?

Merci d'avance

Je viens de tester ton SpinButton, c'est excellent.

Cependant lorsqu'aucune marque n'est sélectionné, le Spin part en sucette, je regarde ce que je peux faire.

Pour éviter l'effet "sucette" :

Private Sub SpinButton1_Change()
Dim L As Long
    If ComboBox1.Text <> vbNullString Then
        L = SpinButton1.Value + 1
        If L >= LBound(FilteredDatas, 1) And L <= UBound(FilteredDatas, 1) Then
            Ligne = SpinButton1.Value + 1
            Me.TextBox2 = FilteredDatas(Ligne, 2)
            Me.TextBox3 = FilteredDatas(Ligne, 3)
            Me.TextBox4 = FilteredDatas(Ligne, 4)
            Me.TextBox5 = FilteredDatas(Ligne, 5)
            Me.TextBox6 = FilteredDatas(Ligne, 6)
        Else
            SpinButton1.Value = SpinButton1.Value - 1
        End If
    End If
End Sub

Par contre, il faudra changer le code de ton bouton "MODIFIER".

Qu'elles sont les valeurs susceptibles d'être modifiées?

En fait, avec tous les doublons, il faut que l'on puisse facilement déterminer la ligne. En général, pour cela, on utilise une colonne à droite avec un numéro unique...

A tester avec ID :

Oui je comprends que le bouton modifier n'est pas optimisé. pour le numéro "unique", penses-tu qu'il faudrait une base du style 001 pour la marque KIMO par exemple et 00001 pour cibler que c'était la première référence ajouter? ce qui donnerrai dans une colonne 00100001.

Cela permettrait peut-être pour de futurs évolutions une recherche assez poussé dans la base de données.

Ou un numéro basique en fonction de son moment d'ajout suffira (0001, 0002, etc)

A terme, tu prévois combien de lignes dans ta bdd?

Pour moi : un numéro basique en fonction de son moment d'ajout suffira (0001, 0002, etc)

EDIT : Quelques modifications mineures dans le code :

Re Franck,

Pour ce qui est de la taille des bdd, elles n'auront jamais plus de 2000 ref car je les scinderai en plusieurs feuilles suivant différents types.

Tu as répondu à mes questions de mon premier poste et je t'en suis très reconnaissant.

Si je souhaite poursuivre avec un item et des questions sur la recherche de données dans mon tableau, dois-je recréer un sujet ou poursuivre ici?

Il reste la partie trie, oops

En exemple le trie par marque mais j'aimerai aussi implémenter le tri par produit et ID. La sélection des colonnes j'en fais mon affaire, mais la prise en compte de ces différentes options avec les indicateurs "Marque" etc ..., j'ai besoins d'aide.

'If "Marque" Then
With ActiveWorkbook.Worksheets("Base_de_données").Sort
    .SetRange Range("A1:F65536")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With
'End If

Bonjour,

Voici le code de l'UserForm de tri :

Private Sub ComboBox1_AfterUpdate()
Dim Datas, DL As Long
    With ThisWorkbook.Worksheets("Base_de_données")
        DL = .Range("B" & .Rows.Count).End(xlUp).Row
        Datas = .Range("A2:G" & DL).Value
        If ComboBox1.ListIndex <> -1 Then
            QuickSortArray Datas, LBound(Datas, 1), UBound(Datas, 1), ComboBox1.ListIndex + 1
            .Range("A2").Resize(UBound(Datas, 1), UBound(Datas, 2)).Value = Datas
        End If
    End With
End Sub

Private Sub CommandButton1_Click()
'ferme la fenetre en vidant son contenu
Unload Me
End Sub

Private Sub CommandButton2_Click()
'rafraichir la fenetre de saisie
    ComboBox1.Text = vbNullString
End Sub

Private Sub UserForm_Initialize()
Dim i As Long
    'permet la sélection dans un menu déroulant des items déjà présent dans la base de données
    With ThisWorkbook.Sheets("Base_de_données")
        For i = 1 To 7
            ComboBox1.AddItem .Cells(1, i).Value
        Next
    End With
End Sub

Private Sub QuickSortArray(ByRef SortArray As Variant, Optional lngMin As Long = -1, Optional lngMax As Long = -1, Optional lngColumn As Long = 0)
    On Error Resume Next
    'Sort a 2-Dimensional array
    ' SampleUsage: sort arrData by the contents of column 3
    '   QuickSortArray arrData, , , 3
    'Posted by Jim Rech 10/20/98 Excel.Programming
    'Modifications, Nigel Heffernan:
    '       ' Escape failed comparison with empty variant
    '       ' Defensive coding: check inputs
Dim i As Long, j As Long, varMid As Variant, arrRowTemp As Variant, lngColTemp As Long
    If IsEmpty(SortArray) Then
        Exit Sub
    End If
    If InStr(TypeName(SortArray), "()") < 1 Then  'IsArray() is somewhat broken: Look for brackets in the type name
        Exit Sub
    End If
    If lngMin = -1 Then
        lngMin = LBound(SortArray, 1)
    End If
    If lngMax = -1 Then
        lngMax = UBound(SortArray, 1)
    End If
    If lngMin >= lngMax Then    ' no sorting required
        Exit Sub
    End If
    i = lngMin
    j = lngMax
    varMid = Empty
    varMid = SortArray((lngMin + lngMax) \ 2, lngColumn)
    ' We  send 'Empty' and invalid data items to the end of the list:
    If IsObject(varMid) Then  ' note that we don't check isObject(SortArray(n)) - varMid *might* pick up a valid default member or property
        i = lngMax
        j = lngMin
    ElseIf IsEmpty(varMid) Then
        i = lngMax
        j = lngMin
    ElseIf IsNull(varMid) Then
        i = lngMax
        j = lngMin
    ElseIf varMid = "" Then
        i = lngMax
        j = lngMin
    ElseIf VarType(varMid) = vbError Then
        i = lngMax
        j = lngMin
    ElseIf VarType(varMid) > 17 Then
        i = lngMax
        j = lngMin
    End If
    While i <= j
        While SortArray(i, lngColumn) < varMid And i < lngMax
            i = i + 1
        Wend
        While varMid < SortArray(j, lngColumn) And j > lngMin
            j = j - 1
        Wend
        If i <= j Then
            ' Swap the rows
            ReDim arrRowTemp(LBound(SortArray, 2) To UBound(SortArray, 2))
            For lngColTemp = LBound(SortArray, 2) To UBound(SortArray, 2)
                arrRowTemp(lngColTemp) = SortArray(i, lngColTemp)
                SortArray(i, lngColTemp) = SortArray(j, lngColTemp)
                SortArray(j, lngColTemp) = arrRowTemp(lngColTemp)
            Next lngColTemp
            Erase arrRowTemp
            i = i + 1
            j = j - 1
        End If
    Wend
    If (lngMin < j) Then Call QuickSortArray(SortArray, lngMin, j, lngColumn)
    If (i < lngMax) Then Call QuickSortArray(SortArray, i, lngMax, lngColumn)
End Sub

Bonjour, c'est exactement ce que je voulais faire avec cette option de tri.

Depuis ce matin, je me suis lancé dans une fenêtre/formulaire permettant une recherche et un affichage des résultats au seins de la même fenêtre.

Je me retrouve à faire un deuxième tableau sur une deuxième feuille pour ensuite le reporter dans mon UserForm de recherche. Yaurait-il possibilité de faire autrement?

Je vais reUploader mon fichier pour montrer mon avancement.

Merci d'avance.

Tu avais quasiment toutes les fonctions utiles.
Suffisait de comprendre le principe avec les Array et modifier la fonction filtr.

Je t'ai mis les fonctions utiles dans un module à part.

Voici ton fichier :

J'aimerai rendre les entêtes visibles dans mon UserForme recherche. J'ai réussis à les fixer, mais encore faut-il les remplir.

Private Sub ComboBox1_Change()
    inhibeEvent = True
    Me.TextBox1.Value = ""
    Set bddFeuil1 = Feuil1.[A1].CurrentRegion
    Me.ListBox2.ColumnHeads = True
    'Me.ListBox2.
    inhibeEvent = False
    Call FillEntireDatas(bddFeuil1)
    If ComboBox1.ListIndex <> -1 Then
        colonne = ComboBox1.ListIndex + 1
    End If
End Sub

Et je n'ai pas tout compris dans la fonction recherche encore, je vais me pencher dessus car 3 petits problèmes subsistes.

Pas de détection des chiffres pour les recherche, ni de minuscules et l'ordre des lettres inscrites dans la textebox n'importent pas pour le moment ce qui est un peu embêtant.

Je pensais que le symbole "*" permettait d'afficher des résultats sans mots entier et non pas une recherche par caractère.

Merci pour tes retours en tout cas :)

Je viens de comprendre que le mot clé était forcément lié au critère MARQUE, donc les chiffres et minuscules sont bien pris en comptes.

Pour ce qui concerne la recherche, j'ai volontairement choisi de ne pas considérer l'ordre des caractères saisis.

De plus, la casse était prise en compte. Si tu ne souhaites que les majuscules, aucun souci.

Remplace, dans le module de l'UserForm de recherche, la code de TextBox1_Change() par :

Private Sub TextBox1_Change()
    If Not inhibeEvent Then
        If ComboBox1.ListIndex <> -1 Then
            If colonne > 0 Then
                TbFiltre = filtr(bddFeuil1, 2, TextBox1.Text & "*")
                If IsArrayAllocated(TbFiltre) Then
                    ListBox2.List = TbFiltre
                End If
            End If
        End If
    End If
End Sub

Pour la propriété ColumnHeads, la solution est de passer par un RowSource. Et donc, une feuille supplémentaire pour les filtres...

Sinon, plus simple, tu places des Labels au dessus de ta ListBox, avec, dans leurs propriétés Caption, les entêtes de tes colonnes...

C'est ce que j'étais de train de faire, c'est rustique d'un côté mais j'aurais un seul tableau.

Par contre saurais-tu pourquoi ma recherche une fois ma combobox remplis ne prend en compte que "MARQUE qu'importe l'item sélectionné dans cette même combobox? C'est comme si il ne lisait que la colonne B.

Oups. Pardon... J'ai omis d'intégrer le numéro de colonne...

Remplacer, à nouveau, le TextBox1_Change() par : (modif : colonne au lieu de 2 dans l'appel du filtre)

Private Sub TextBox1_Change()
    If Not inhibeEvent Then
        If ComboBox1.ListIndex <> -1 Then
            If colonne > 0 Then
                TbFiltre = filtr(bddFeuil1, colonne, TextBox1.Text & "*")
                If IsArrayAllocated(TbFiltre) Then
                    ListBox2.List = TbFiltre
                End If
            End If
        End If
    End If
End Sub

Aucune raison d'être désolé, c'est plutôt moi qui le suis avec mes questions bête ou simple, tout dépend le point de vue!

Un grand merci en tout cas, tout est fonctionnel.

Bonne continuation

Rechercher des sujets similaires à "probleme ajouts references base donnees vba"