XL 2010 alimenter Bdd avec userform

celine123

XLDnaute Junior
Bonjour,
J'ai un classeur avec un userform pour alimenter une BDD.
le sujet avait été suivit par Paf mais n'ayant plus de retour de sa part je pense qu'il doit être pas mal occupé(un grand merci pour le temps qu'il a consacré sur mon sujet)
c'est pour cela que j'en appelle a votre aide
j'ai un petite particularité c'est de pouvoir alimenter en deux fois mon formulaire
en gros j'aimerai pouvoir après avoir fait une première saisie (la partie hors frame) de pouvoir par rapport a la date et heure saisie en première partie pouvoir compléter pour la ligne correspondante la suite (frame) tout en pouvant ajouter un nouveau terme dans la colonne correspondante (si il n'existe pas) par la saisie dans les combobox
dans la trame du tableau la premiére partie se symbolise par la couleur orange et la deuxiéme par la couleur verte
petit point particulier si j'ai oui dans la combobox 25 la combobox 26 et visible sinon pas visible
Paf a déjà répondu pour ça:

Dans Private Sub UserForm_Initialize(), ajouter:
Code (Text):
ComboBox26.Visible = False
et dans Private Sub ComboBox25_Change()
Code (Text):
If UCase(ComboBox25) = "OUI" Then ComboBox26.Visible = True



il peut avoir des dates identiques
pour une date il peut avoir plusieurs heures
mais il ne peut pas avoir d'heures identiques
la combinaison date + heure ne peut être identique

voici le lien de la discussion déjà commencer qui concerne ce sujet et un sujet dans le même esprit
https://www.excel-downloads.com/threads/alimenter-bdd-avec-userform.20014041/
 

Pièces jointes

  • Copie de formulaire 2.xlsm
    21 KB · Affichages: 76

Dranreb

XLDnaute Barbatruc
Lorsque vous avez un arrêt sur erreur, allez en débogage, vérifiez les valeurs de expressions impliquées. Parfois une infobulle s'affiche tout seul, si ce n'est pas le cas mettez des espions (sélectionnez l'expression, menu Débogage, Ajouter un espion…).
Mettez par exemple un espion sur Feuil2.UsedRange.Address
puis sur Feuil2.UsedRange.Resize(, 2).Address
puis sur TE
sur UBound(TE, 1) etc. jusqu'à ce que vous trouviez ce qui ne va pas en amont.
 
Dernière édition:

celine123

XLDnaute Junior
l'idée et que je puisse saisir en 2 fois si besoin donc que lorsque je sélectionne dans la combobox date heure une date/heure j'ai la partie déjà saisie qui alimente les combobox tout en laissant la possibilité des réponse de la feuille paramètre
 

Dranreb

XLDnaute Barbatruc
Bonjour.
Vous voulez bien me virer cette satanée Sub Ini complètement débile ?!
Je ne sais pas ce qu'elle sème comme bazar mais en tout cas elle fusille la ComboBox1.List initialisée par la UserForm_Initialize !
Ensuite, dans la Sub ComboBox1_Change() vous faites LCou = ComboBox1.ListIndex + 1 ça c'est bien, mais vous ne faites rien d'autre. Ça ne suffit pas: il faut encore verser les valeurs dans vos contrôles. Comme ça :
VB:
Private Sub ComboBox1_Change()
LCou = ComboBox1.ListIndex + 1
If LCou > 0 Then
   VLgn = Feuil2.Rows(1 + LCou).Resize(, 30).Value
Else
   ReDim VLgn(1 To 1, 1 To 30) ' Comme ça les instructions après vident les contrôles
   End If
ComboBox2.Text = VLgn(1, 2)
ComboBox3.Text = VLgn(1, 3)
etc.
End Sub
En tête :
VB:
Option Explicit
'Dim WS As Worksheet ' Pas besoin, il existe déjà un objet Worksheet de la rubrique Microsoft Excel Objets _
   qui représente auprès de VBA la feuille Excel "PARAMETRE": c'est Feuil3 (À votre place je le renommerais FParam)
Private LCou As Long ' Numéro de la ligne courante. Vaut 0 si création en cours.
Private VLgn() As Variant ' Valeurs de la lignes en cours de mise à jour.
 

celine123

XLDnaute Junior
Bonjour Dranreb

alors ça marche en partie:
j'ai les dates heures qui s'ajoute en feuille paramètre et non en feuille BDD
les liste déroulante des combobox ne sont pas alimenté par la feuille paramètre
Code:
Option Explicit
Dim WS As Worksheet

'Dim WS As Worksheet ' Pas besoin, il existe déjà un objet Worksheet de la rubrique Microsoft Excel Objets _
   qui représente auprès de VBA la feuille Excel "PARAMETRE": c'est Feuil3 (À votre place je le renommerais FParam)
Private LCou As Long ' Numéro de la ligne courante. Vaut 0 si création en cours.
Private VLgn() As Variant ' Valeurs de la lignes en cours de mise à jour.


Private Sub BoutQuitte_Click()
Unload Me

End Sub

Private Sub CmdAjout_Click()
Dim CTRL As Control 'Variable pour la collection des controls
Dim L As Integer, y As Integer 'Variable pour connaitre le numéro de derniere ligne vide
Dim LeChoix As String
Dim Ctr As Control, col As Integer, lig As Long
With Worksheets("PARAMETRE")
For Each Ctr In Me.Controls
    If TypeName(Ctr) = "ComboBox" Then
        If Ctr.ListIndex = -1 And Ctr.Value <> "" Then
            col = Right(Ctr.Name, Len(Ctr.Name) - 8)
            lig = .Cells(Cells.Rows.Count, col).End(xlUp).Row + 1
            .Cells(lig, col) = Ctr
        End If
    End If
Next
End With

L = ThisWorkbook.Worksheets("BDD").Range("A65536").End(xlUp).Row + 1 ' On identifie la dernière ligne vide en partant du bas


  For y = 2 To 30
Select Case y
Case 1 To 10
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
Case 11
LeChoix = Switch(Me.OptionButton4, "oui", Me.OptionButton5, "Non")
Feuil2.Cells(L, y) = LeChoix
Case 12
LeChoix = Switch(Me.OptionButton10, "Homme", Me.OptionButton11, "Femme")
Feuil2.Cells(L, y) = LeChoix
Case 13
LeChoix = Switch(Me.OptionButton12, "Homme", Me.OptionButton13, "Femme")
Feuil2.Cells(L, y) = LeChoix
Case 14 To 26
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
Case 27
LeChoix = Switch(Me.OptionButton14, "Conforme", Me.OptionButton15, "Non Conforme")
Feuil2.Cells(L, y) = LeChoix
Case 28
LeChoix = Switch(Me.OptionButton16, "Conforme", Me.OptionButton17, "Non Conforme")
Feuil2.Cells(L, y) = LeChoix
Case 29 To 30
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
End Select
  Next y

End Sub


Private Sub ComboBox1_Change()
LCou = ComboBox1.ListIndex + 1
If LCou > 0 Then
   VLgn = Feuil2.Rows(1 + LCou).Resize(, 30).Value
Else
   ReDim VLgn(1 To 1, 1 To 30) ' Comme ça les instructions après vident les contrôles
  End If
ComboBox2.Text = VLgn(1, 2)
ComboBox3.Text = VLgn(1, 3)
ComboBox4.Text = VLgn(1, 4)
ComboBox5.Text = VLgn(1, 5)
ComboBox6.Text = VLgn(1, 6)
ComboBox7.Text = VLgn(1, 7)
ComboBox8.Text = VLgn(1, 8)
End Sub

Private Sub ComboBox25_Change()
If UCase(ComboBox25) = "OUI" Then ComboBox26.Visible = True
End Sub

Private Sub UserForm_Activate()
Me.ComboBox1.SetFocus
End Sub
Private Sub UserForm_Initialize()
Dim TE(), TS(), L As Long
TE = Feuil2.UsedRange.Resize(, 2).Value
ReDim TS(0 To UBound(TE, 1) - 2)
For L = 2 To UBound(TE, 1)
   TS(L - 2) = Format(TE(L, 1) + TE(L, 2), "dd/mm/yyyy hh:mm")
   Next L
Me.ComboBox1.List = TS

ComboBox26.Visible = False
End Sub
 

Dranreb

XLDnaute Barbatruc
Mettez plus d'une date dans BDD parce qu'avec une seule cellule ça coince parce que ça ne forme pas un tableau VBA. Ou alors faites sur cette plage une mise en forme de tableau, comme ça on pourra bénéficier des facilités du ListObject.

Pour l'instant, en résumé, le début devrait être à peu près comme ça :
VB:
Option Explicit
Private LCou As Long ' Numéro de ligne courante. Vaut 0 si création en cours.
Private VLgn() As Variant ' Valeurs de la ligne en cours de mise à jour.
Private Sub UserForm_Initialize()
Dim L As Long, NbL As Long, C As Long
' Attention: l'instruction suivante devra aussi être exécutée après chaque ajout ou suppression d'une date/heure.
With Feuil2.UsedRange: Me.ComboBox1.List = .Cells(2, 1).Resize(.Rows.Count - 1).Value: End With
For C = 2 To 31
   Select Case C
      Case 2 To 10, 14 To 26, 29 To 30
         NbL = Feuil3.Cells(Feuil3.Rows.Count, C).End(xlUp).Row - 1
         If NbL > 0 Then
            Me("ComboBox" & C).List = Feuil3.Cells(2, C).Resize(NbL).Value
         Else: Me("ComboBox" & C).Clear: End If
      End Select: Next C
ComboBox26.Visible = False
End Sub
 

celine123

XLDnaute Junior
Bonjour Dranreb
j'ai encore plusieurs petit souci
j'ai un décalage au niveau de l'alimentation des combobox (combobox "intitulé 3 est alimenté par intitulé 4...)
j'ai un décalage au niveau de l'ajout de terme dans la feuille paramètre (+1)
et j'ai la date de la combobox date heure qui ce saisie toujours sur la feuille paramètre et non sur la feuille bdd
je te joint le fichier je pense que ce sera plus claire pour toi
un gros merci pour le temps que tu passe sur mon fichier en tout cas

Code:
Option Explicit
Private LCou As Long ' Numéro de ligne courante. Vaut 0 si création en cours.
Private VLgn() As Variant ' Valeurs de la ligne en cours de mise à jour.


Private Sub BoutQuitte_Click()
Unload Me

End Sub

Private Sub CmdAjout_Click()
Dim CTRL As Control 'Variable pour la collection des controls
Dim L As Integer, y As Integer 'Variable pour connaitre le numéro de derniere ligne vide
Dim LeChoix As String
Dim Ctr As Control, col As Integer, lig As Long
With Worksheets("PARAMETRE")
For Each Ctr In Me.Controls
    If TypeName(Ctr) = "ComboBox" Then
        If Ctr.ListIndex = -1 And Ctr.Value <> "" Then
            col = Right(Ctr.Name, Len(Ctr.Name) - 8)
            lig = .Cells(Cells.Rows.Count, col).End(xlUp).Row + 1
            .Cells(lig, col) = Ctr
        End If
    End If
Next
End With

L = ThisWorkbook.Worksheets("BDD").Range("A65536").End(xlUp).Row + 1 ' On identifie la dernière ligne vide en partant du bas


  For y = 2 To 30
Select Case y
Case 2 To 10
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
Case 11
LeChoix = Switch(Me.OptionButton4, "oui", Me.OptionButton5, "Non")
Feuil2.Cells(L, y) = LeChoix
Case 12
LeChoix = Switch(Me.OptionButton10, "Homme", Me.OptionButton11, "Femme")
Feuil2.Cells(L, y) = LeChoix
Case 13
LeChoix = Switch(Me.OptionButton12, "Homme", Me.OptionButton13, "Femme")
Feuil2.Cells(L, y) = LeChoix
Case 14 To 26
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
Case 27
LeChoix = Switch(Me.OptionButton14, "Conforme", Me.OptionButton15, "Non Conforme")
Feuil2.Cells(L, y) = LeChoix
Case 28
LeChoix = Switch(Me.OptionButton16, "Conforme", Me.OptionButton17, "Non Conforme")
Feuil2.Cells(L, y) = LeChoix
Case 29 To 30
With Feuil2
.Cells(L, y) = Me.Controls("ComboBox" & y).Value
End With
End Select
  Next y

End Sub

Private Sub ComboBox1_Change()
LCou = ComboBox1.ListIndex + 1
If LCou > 0 Then
   VLgn = Feuil2.Rows(1 + LCou).Resize(, 30).Value
Else
   ReDim VLgn(1 To 1, 1 To 30) ' Comme ça les instructions après vident les contrôles
  End If
ComboBox2.Text = VLgn(1, 2)
ComboBox3.Text = VLgn(1, 3)
ComboBox4.Text = VLgn(1, 4)
ComboBox5.Text = VLgn(1, 5)
ComboBox6.Text = VLgn(1, 6)
ComboBox7.Text = VLgn(1, 7)
ComboBox8.Text = VLgn(1, 8)
End Sub

Private Sub ComboBox25_Change()
If UCase(ComboBox25) = "OUI" Then ComboBox26.Visible = True
End Sub

Private Sub UserForm_Activate()
Me.ComboBox1.SetFocus
End Sub
Private Sub UserForm_Initialize()
Dim L As Long, NbL As Long, C As Long
' Attention: l'instruction suivante devra aussi être exécutée après chaque ajout ou suppression d'une date/heure.
With Feuil2.UsedRange: Me.ComboBox1.List = .Cells(2, 1).Resize(.Rows.Count - 1).Value: End With
For C = 2 To 31
   Select Case C
      Case 2 To 10, 14 To 26, 29 To 30
         NbL = Feuil3.Cells(Feuil3.Rows.Count, C).End(xlUp).Row - 1
         If NbL > 0 Then
            Me("ComboBox" & C).List = Feuil3.Cells(2, C).Resize(NbL).Value
         Else: Me("ComboBox" & C).Clear: End If
      End Select: Next C
ComboBox26.Visible = False
End Sub
 

Pièces jointes

  • formulaire 2.xlsm
    32.8 KB · Affichages: 52

Dranreb

XLDnaute Barbatruc
Continuez sur le modèle commencé: Utilisez les noms d'objets Worksheet de la rubrique Microsoft Excel Objets du projet VBA et travailez avec le tableau VLgn plutôt que directement sur les cellules.
VB:
Private Sub ComboBox1_Change()
LCou = ComboBox1.ListIndex + 1
If LCou > 0 Then
   VLgn = Feuil2.Rows(1 + LCou).Resize(, 30).Value
   CmdAjout.Caption = "Modifier"
Else
   ReDim VLgn(1 To 1, 1 To 30) ' Comme ça les instructions après vident les contrôles
   CmdAjout.Caption = "Ajouter"
  End If
ComboBox2.Text = VLgn(1, 2)
ComboBox3.Text = VLgn(1, 3)
ComboBox4.Text = VLgn(1, 4)
ComboBox5.Text = VLgn(1, 5)
ComboBox6.Text = VLgn(1, 6)
ComboBox7.Text = VLgn(1, 7)
ComboBox8.Text = VLgn(1, 8)
End Sub

Private Sub CmdAjout_Click()
Dim CTRL As Control 'Variable pour la collection des controls
Dim L As Long, C As Long 'Variable pour connaitre le numéro de derniere ligne vide
Cel As Range
Dim LeChoix As String
Dim Ctr As Control
For Each Ctr In Me.Controls
    If TypeName(Ctr) = "ComboBox" Then
        If Ctr.ListIndex = -1 And Ctr.Value <> "" Then
            L = Ctr.ListCount + 1: C = Mid$(Ctr.Name, 9)
            Feuil3.Cells(L, C) = Ctr.Text
            Ctr.AddItem Ctr.Text ' <--- Vous aviez oublié ça me semble t-il
        End If
    End If
Next
If LCou = 0 Then
   LCou = Feuil2.[A1000000].End(xlUp).Row
   VLgn(1, 1) = ComboBox1.Text
   End If
For C = 2 To 30
   'puis écrivez le reste dans les VLgn(1, C) plutôt que dans des .Cell(L, C)
   Next C
'terminez par:
Feuil2.Rows(1 + LCou).Resize(, 30).Value = VLgn
With Feuil2.UsedRange: Me.ComboBox1.List = .Cells(2, 1).Resize(.Rows.Count - 1).Value: End With
'Puis enfin soit CmdAjout.Caption = "Modifier" soit ComboBox1.ListIndex = -1
À tester.

Remarque: on pourrait avoir une programmation plus homogène si la BDD était entièrement mise sous forme de tableau Excel
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Ah oui, j'ai enfin compris votre histoire de décalage. Ben c'est parce qu'il y a un décalage entre les intitulés de BDD et ceux de PARAMETRE. Peut être auriez vous intérêt à ne mettre que les numéros des ComboBox effectivement concernées en titres de votre feuille paramètre. Ou encore mieux un titre significatif devant lequel on ajoutera CBx pour former le nom du contrôle concerné. Parce qu'avec For Each Ctr In Me.Controls on prend aussi ComboBox1 qui n'a rien à voir.

Je joins la version avec ListObject
 

Pièces jointes

  • UFmMàJCeline123.xlsm
    32 KB · Affichages: 91
Dernière édition:

celine123

XLDnaute Junior
Bonjour Dranreb je reviens vers toi un peut tard (j’étais en déplacement)
j'ai une question: lors de la sélection d'une date j'ai bien les info de la ligne correspondante de la feuille BDD qui alimente les combobox mais et il possible d'alimenter les options bouton ?
ma deuxième question et sur les optionbouton: lorsque aucun option bouton n'est sélectionné dans l'userform si je clic sur ajouter j'ai un message d'erreur
 

Dranreb

XLDnaute Barbatruc
Boujour.
Oui, par exemple :
VB:
OptionButton4.Value = VLgn(1, 11) = "Oui": OptionButton5.Value = VLgn(1, 11) = "Non"
Pour éviter le plantage, terminez par 2 paramètres supplémentaires les Switch( … , True, "?")
Ou Empty au lieu de "?" si vous préférez.
 

Dranreb

XLDnaute Barbatruc
Non, if faut alterner condition et valeur correspondante, la dernière condition (et donc avant dernier paramètre) toujours vraie étant True pour que la fonction ne puisse plus renvoyer Null, je crois, quand aucune n'est vraie.
 
Dernière édition:

Discussions similaires

  • Question
Microsoft 365 webbrowser
Réponses
20
Affichages
855

Statistiques des forums

Discussions
311 720
Messages
2 081 889
Membres
101 831
dernier inscrit
gillec