[Excel-VBA] Base de données --> Formulaire [Résolu/Fermé]

Signaler
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
-
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
-
Bonjour tout le monde,

Tout d'abord j'espère avoir posté mon sujet dans la bonne catégorie, sinon je vous prie de m'en excuser.

J'ai créé un formulaire (UserForm1) sous VBA pour Excel.
Ce formulaire contient des textbox, combobox, checkbox et cases d'option.
Il me permet de remplir une base de données clients sous Excel en récupérant
-le contenu de mes textbox et combobox ;
-les captions des checkbox (plusieurs choix possibles) ou cases d'option (un seul choix possible).

Je cherche maintenant à créer un deuxième formulaire (UserForm2 et copie du UserForm1 pour faire la manipulation inverse :

1) Je demande à l'utilisateur de sélectionner la première cellule de n'importe quelle ligne dans la base de données. Cette cellule contient le nom d'un client pour lequel j'ai rempli le formulaire. Les cellules à droite de celle du nom correspondent donc aux différents champs du formulaire que j'ai rempli (textbox, combobox, checkbox et cases d'option).

2) Je voudrais pouvoir charger le UserForm2 rempli en fonction des données dans le tableau. Ainsi les bonnes checkbox seront cochées, les textbox remplies et les bonnes cases d'option cochées.

3) Je vais modifier des données et les ré-enregistrer à la place des précédentes sur la même ligne du tableau afin d'éviter les doublons.


Voici mon problème :

Je n'arrive pas à comparer le contenu des cellules de mon tableau avec les captions de mes checkbox.
Si le contenu de la cellule est identique au caption d'une ou plusieurs checkbox, il faut cocher les checkbox en question.

Même raisonnement pour les boutons d'option, je souhaiterais comparer le contenu de la cellule aux captions des cases d'option et sélectionner la bonne.


Enfin je voudrais pouvoir ré-enregistrer le contenu du UserForm2 sur la même ligne de mon tableau Excel en remplacement des valeurs précédentes.

Voici une trame de code que j'ai effectuée mais qui ne fonctionne pas; si vous pouvez m'aider ?

Pour le moment la macro demande de sélectionner une ligne.
Ensuite j'essaie de récupérer le contenu d'une cellule associée à une frame avec plusieurs checkbox et de cocher les bonnes checkbox.



Private Sub UserForm_Initialize()
'la macro se lance à l'ouverture du formulaire

'Sélection de la cellule du client auquel on souhaite apporter des modifications
Dim macellule As Range
Dim i As Byte

Set macellule = Application.InputBox("Sélectionnez la cellule avec le nom du client.", "Sélection de cellules", Type:=8)

'Remplir les checkbox
Dim cible As String
cible = "A,B,C,D"

'A B C D correspondent aux captions des checkbox

'ici j'ai essayé plusieurs syntaxe de code :

'If Not InStr(cible, macellule.Offset(0, 2)) = 0 Then
'If Not InStr(macellule.Offset(0, 2), cible) = 0 Then
If InStr(macellule.Offset(0, 2), cible) > 0 Then

With Me.frame1
For i = 6 To 10
'If .Controls("CheckBox" & i).Caption = cible Then
'If .Controls("CheckBox" & i).Caption = macellule.Text Then
If .Controls("CheckBox" & i).Caption = macellule Then
.Controls("CheckBox" & i).Value = True
End If
Next i
End With
End If

End Sub


Voilà j'espère avoir été clair dans mon problème.
Un grand merci à ceux qui se pencheront dessus :)

14 réponses

Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Bonsoir alecomte,
Le but est donc de remplir le UserForm depuis le tableau sur le Feuil2 du classeur Excel : fait
les retours à la ligne Chr(10) me posent problème : c'est normal .. je suis à la version 2003, donc, pour moi, un retour de ligne, ce n'est chr(10) mais plutôt "vbcrlf" !! à retenir !
Private Sub UserForm_Initialize()
    'L'idée est de REMPLIR LE FORMULAIRE DEPUIS LA BASE DE DONNEES
    Dim macellule As Range
    ' sélection de la feuille où se trouve les clients "Feuil2"
    Worksheets("Feuil2").Activate
    'Sélection de la cellule du client auquel on souhaite apporter des modifications
    Set macellule = Application.InputBox("Sélectionnez la cellule avec le nom du client.", _
                                         "Sélection de cellules", _
                                         Type:=8)
    If (macellule = "") Then UserForm_Initialize
    '
    ' remplir le formulaire
    With ComboBox1
        .Clear
        .AddItem macellule
        If ComboBox1.ListCount >= 1 Then
            .ListIndex = 0
        End If
    End With
    ' raisons
    CheckBox6.Value = IIf(InStr(1, macellule.Offset(0, 1), "A", vbTextCompare) > 0, True, False)
    CheckBox7.Value = IIf(InStr(1, macellule.Offset(0, 1), "B", vbTextCompare) > 0, True, False)
    CheckBox8.Value = IIf(InStr(1, macellule.Offset(0, 1), "C", vbTextCompare) > 0, True, False)
    CheckBox9.Value = IIf(InStr(1, macellule.Offset(0, 1), "D", vbTextCompare) > 0, True, False)
    ' sexe
    OptionButton7.Value = IIf(macellule.Offset(0, 2) = "Homme", True, False)
    OptionButton8.Value = IIf(macellule.Offset(0, 2) = "Femme", True, False)
    '
End Sub
2
Merci

Quelques mots de remerciements seront grandement appréciés. Ajouter un commentaire

CCM 76687 internautes nous ont dit merci ce mois-ci

Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Super merci !!

Du coup je voudrais vous exposer 3 autres soucis que je rencontre svp ?


Pour commencer, voici le nouveau fichier obtenu grâce à ton aide :
https://www.cjoint.com/?BLkaGRE1C3j


Sur mon fichier d'origine, j'ai 2 formulaires :
- le premier UserForm1 rempli le tableau
- le deuxième UserForm2 sert à modifier des données (en chargeant les données du tableau vers la base de données grâce à ton code précédant notamment :)

Voici les différents problèmes que je souhaiterais résoudre :




souci 1) Dans le UserForm1

J'ai un code qui doit me permettre de récupérer les noms des clients dans le tableau Excel et les intégrer dans une ComboBox1: ça j'ai trouvé mais....

Mais je voudrais trier les noms dans la ComboBox1 par ordre alphabétique
et là ma macro ne fonctionne pas.

Par ailleurs sur le UserForm1, j'ai un bouton qui me permet de transférer les données dans le tableau, en l'occurrence le nom du client.
Je voudrais que la ComboBox1 se mette à jour avec le nom du nouveau client toujours par ordre alphabétique.

Mon code ne fonctionne pas. Mais si tu trouves l'erreur je suis preneur :)




souci 2) Tu remarqueras que j'ai ajouté une ComboBox2 "fréquence" sur les deux formulaires.

Dans le UserForm1, la ComboBox2 offre un certain nombre d'options.

Je voudrais que lorsqu'on charge le UserForm2, les options soient toutes présentes dans la ComboBox2 mais que la fréquence présente dans le tableau Excel soit sélectionnée par défaut (puisqu'on charge les données depuis le tableau).




souci 3) A l'ouverture du UserForm2, (UserForm2 Initialize)
on demande de sélectionner une cellule avec le nom du client auquel on souhaite apporter les modifications.
Donc cela nécessite de modifier les données du formulaire puis, via un bouton sur le formulaire,
de lancer une macro qui va aller modifier les données.

Private Sub CommandButton1_Click()
'comment référencer ici macellule sélectionnée dans la macro UserForm_Initialize ?
End Sub

Seulement est-il possible de référencer dans cette macro le nom de la cellule qu'on est allé sélectionner dans la macro précédente (UserForm2 Initialize) afin d'apporter les modifications souhaitées sur la même ligne du tableau Excel ?



Merci encore pour ton aide !!
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Pour le souci 3)
j'ai pensé autrement à refaire une recherche dans le tableau

Set Recherche = Sheets("Feuil2").Columns("A").Find(Me.ComboBox1)
If Not Recherche Is Nothing Then

'FIXER LA CELLULE où le nom du client à été trouvé COMME CELLULE DE DÉMARRAGE pour les modifications et ensuite je modifie toutes les colonnes avec la fonction Offset

mais dans ce cas-là : comment fixer la cellule comme cellule de "démarrage" ?

Merci :)
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
toujours pour le souci 3)
on doit pouvoir utiliser

Set Recherche = Sheets("Feuil2").Columns("A").Find(Me.ComboBox1)
If Not Recherche Is Nothing Then
Recherche.Address = Me.ComboBox1

puis ActiveCell.Offset ...
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
souci 2 = résolu
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Nouveau souci sur mon fichier :

J'ai quatre formulaires.
Et sur les quatre je voudrais utiliser une même macro pour enregistrer.

J'ai tapé ma macro sur un des modules du projet

Sub enregistrer ()
...
End Sub



Et sur mes quatre formulaires, j'ai ajouté un bouton "Enregistrer" avec
un macro associée :

Sub enregistrer_Click ()
Call enregistrer
End Sub

Seulement Excel me renvoie

"Erreur de compilation :
Utilisation incorrecte de la propriété"

Et je ne comprends pas ce qui ne fonctionne pas.
Au départ la macro figurait dans le module du UserForm1 et elle fonctionnait parfaitement. Et je précise qu'elle ne fait appelle à aucune variable définie dans le module de mon UserForm !


Merci de votre aide
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Sub enregistrer () 
... 
End Sub

Essaie en "Public Sub Enregistrer, mais logiquement ce n'est pas la cause .. Je rechercherai ce soir

Edit:
Nom du bouton "Enregistrer" .. Nom de la procédure "Enregistrer"
Moi, compilateur, le prend lequel ?
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Bonjour alecomte,
Pour y voir plus clair, ce serait bien que tu dépose ton fichier sur un site de dépôt, tel que https://www.cjoint.com/ en prenant garde de supprimer toutes données sensible !
Puis, tu nous met le lien dans ton prochain message en soulignant les questions !
Merci
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Pour info, le bouton sur la feuil1 me servira à lancer le formulaire (mais ça je sais le programmer ;)
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Bonjour Heliotte*

Il semble que mon premier message ne soit pas passé.

Donc voici le lien https://www.cjoint.com/?BLjoUkvp1Fd

Le but est donc de remplir le UserForm depuis le tableau sur le Feuil2 du classeur Excel


Pour l'instant j'ai essayé de cocher les cases checkbox associées aux données dans la colonne "raisons".
J'ai plus détaillé les macros dans le fichier en téléchargement ci-avant.

J'ai fait plusieurs essais de code mais les retours à la ligne Chr(10) me posent problème.

Merci pour ton aide
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Bonjour alecomte,

J'ai fait un certain nombre de choses, surtout pour l'UserForm2
Teste-le et rapporte-moi tes prochain souhaits.

Essaie d'être un peu plus précis et concis, merci.
Pour la précision, parles des objets tel qu'ils sont. Exemple tu dis "bases de données .. en fait tu parles de la feuille .. on ne peut pas appeler cela une base de données.

Il faut savoir qu'une base de données est faites, en règle générale de plusieurs "tables" .. une feuille est une table .. donc, pas une base de données, merci.

Ah oui, j'oubliais le principal ! Le classeur, version 2003, se trouve ici : http://cjoint.com/12dc/BLklruMuPYG.htm
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Bonjour Heliotte,
Alors oui c'est presque ça.

Problème1 : tri alphabétique sans tenir compte des majuscules/minuscules

Actuellement la comboBox1 des noms de clients fait un tri alphabétique mais en tenant compte des caractères majuscules et minuscules ; par exemple :

AnThoNy
ONG Frederic
Vincent
XENA
alex
henri
marie

Je voudrais avoir :

alex
AnThoNy
henri
marie
ONG Frederic
Vincent
XENA

Donc les noms avec l'orthographe saisie exactement.
Donc je suppose que ça exclut l'utilisation des fonctions UCase, LCase, NProper etc. ?


Problème2 : avec la ligne de code des cases d'option

Supposons qu'au lieu d'avoir le choix entre deux sexes (Homme et Femme), je veuille rajouter une troisième case d'option "Troisième sexe".

Quelles sont les modifications à opérer sur cette ligne (sous-jacente au UserForm2) ?

MaCellule.Offset(0, 2) = IIf(OptionButton7.Value = True, "Homme", "Femme")

car je ne pense pas que je puisse avoir :

MaCellule.Offset(0, 2) = IIf(OptionButton7.Value = True, "Homme", "Femme","Troisième sexe")

Merci !
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Re-plusieurs_fois bonjour alecomte,

Problème 1 : c'est très simple. Dans le module "Module1", après "Option Explicit", tu écris "Option Compare Text" et là .. miracle .. l'ordre alphabétique se réalise sans tenir compte des minuscules/majuscules.

Problème 2 : D'abord, le toisième sexe est "Ange" .. trève de plaisanterie. Si il y a plus que deux éléments, il est plus élégant d'utiliser un "If/Else/EndIf" ou un "Select Case". Cela donnerais quelque chose comme Non Fonctionnel:
Select Case (OptionButton7.Value) 
 Case = True 
  MaCellule.Offset(0, 2) = "Homme" 
 Case = False 
  MaCellule.Offset(0, 2) = "Femme" 
 Case = NiTrueNiFalse 
  MaCellule.Offset(0, 2) = "Ange" 
End Select

J'ai pris cet exemple qui ne fonctionnera jamais car un "OptionButton" n'a que 2 états "True" ou "False", mais fonctionnerais super bien pour un TextBox, et il faudrait écrire:
Select Case (Val(TextBox1.Text)) 
 Case = 1 
  MaCellule.Offset(0, 2) = "Homme" 
 Case = 2 
  MaCellule.Offset(0, 2) = "Femme" 
 Case = 3 
  MaCellule.Offset(0, 2) = "Ange" 
 Case Else 
  MaCellule.Offset(0, 2) = "néant" 
End Select

Résumé : je pense que tout est ok maintenant !
edit: faute d'orthographe
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Oui je pense que tout est ok grâce à toi.
Je vais finaliser mon fichier et je te dirai si je rencontre d'autres problèmes.
En attendant je clôture le topic.
Et je te dis vraiment un grand MERCI ! :)
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Tout le plaisir est pour moi,
@ très bientôt alors .. bonne programmation,
Heliotte
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Bonjour Heliotte,
J'ai rencontré un autre problème avec des macros servant à ajouter des boutons agrandir / réduire au formulaire.
J'ai créé un autre sujet sur le site : https://forums.commentcamarche.net/forum/affich-26657368-vba-excel-boutons-reduire-et-agrandir-pour-userform car je pense qu'il peut servir à d'autres personnes.
Si toutefois tu as une idée, je suis preneur ;)
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Comment appelles-tu les UserForm .. du code
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Pardon, c'est une erreur, sur mon code j'ai bien
Public Sub enregistrer
mais on peut le remplacer par Public Sub sauvegarder pour une meilleure lisibilité.

Par contre je crois que par défaut Sub = Public Sub (sauf précision en Private Sub)

Pour les formulaires, je les appelle simplement :
UserForm1
UserForm2
UserForm3
UserForm4
(Enfin je fais bien sûr ici allusion à la propriété Name et non pas Caption.)


Mais je crois voire où tu m'emmènes :
j'avais bien pensé à les appelés en faisant

Dans mon module :

Public Sub sauvegarder (Usf as Userform)
...
End Sub


et dans les boutons de mes formulaires par exemple :

Sub enregistrer_Click (UserForm1)
Call enregistrer (UserForm1)
End Sub

Mais ici je veux enregistrer tout le classeur (et non pas seulement le formulaire ; ce qui semble impossible en fait)
donc je ne vois pas l'utilité de référencer les UserForm en variables ?
(Ceci je n'ai pas essayé mais je ne saisis pas la logique dans ce cas ?)
Messages postés
1491
Date d'inscription
vendredi 26 octobre 2012
Statut
Membre
Dernière intervention
28 janvier 2013
84
Public Sub ou Private Sub : une bonne pratique, sinon c'est pris pour de la négligence, manque de rigueur !

Oui, quand uniquement "Sub", elle est publique.

On attaque le morceau !
Pour chaque UserForm:
Option Explicit
Private HandleUF&
'
Private Sub UserForm_Initialize()
    Const WS_MAXIMIZEBOX& = &H10000, _
        WS_MINIMIZEBOX& = &H20000, GWL_STYLE& = -16&
    HandleUF = FindWindow(vbNullString, Me.Caption)
    SetWindowLong HandleUF, GWL_STYLE, _
        GetWindowLong(HandleUF, GWL_STYLE) Or WS_MAXIMIZEBOX Or WS_MINIMIZEBOX
    BaseUFProc = SetWindowLong(HandleUF, GWL_WNDPROC, BaseUFProc)
End Sub
'
Private Sub UserForm_Terminate()
    SetWindowLong HandleUF, GWL_WNDPROC, BaseUFProc
End Sub
'
Private Sub Enregistrer_Click()
    Call EnregistrerX
    Unload Me
End Sub

Dans un module:
Option Explicit

Public Declare Function FindWindow& _
    Lib "user32" Alias "FindWindowA" _
    (ByVal lpClassName$, ByVal lpWindowName$)

Public Declare Function GetWindowLong& _
    Lib "user32" Alias "GetWindowLongA" _
    (ByVal hwnd&, ByVal nIndex&)

Public Declare Function SetWindowLong& _
    Lib "user32" Alias "SetWindowLongA" _
    (ByVal hwnd&, ByVal nIndex&, ByVal dwNewLong&)

Private Declare Function EnableWindow& _
    Lib "user32" _
    (ByVal hwnd&, ByVal fEnable&)

Private Declare Function CallWindowProc& _
    Lib "user32" Alias "CallWindowProcA" _
    (ByVal lpPrevWndFunc&, ByVal hwnd&, ByVal Msg&, ByVal wParam&, ByVal lParam&)

Public Const GWL_WNDPROC& = -4&, WM_SYSCOMMAND& = &H112&

Public BaseUFProc&, BaseXLProc&, AncState&

Function UFProc&(ByVal hwnd&, ByVal uMsg&, ByVal wParam&, ByVal lParam&)
    Dim HwndXL&
    Const SC_MINIMIZE& = &HF020&
    If uMsg = WM_SYSCOMMAND Then
            If wParam = (SC_MINIMIZE And &HFFF0&) Then
                HwndXL = FindWindow("XLMAIN", Application.Caption)
                EnableWindow HwndXL, True
                UserForm1.Hide
                AncState = Application.WindowState
                Application.WindowState = xlMinimized
                BaseXLProc = SetWindowLong(HwndXL, GWL_WNDPROC, AddressOf XLProc)
                UFProc = 1&
                Exit Function
            End If
    End If
    UFProc = CallWindowProc(BaseUFProc, hwnd, uMsg, wParam, lParam)
End Function


Function XLProc&(ByVal hwnd&, ByVal uMsg&, ByVal wParam&, ByVal lParam&)
    Const SC_MAXIMIZE& = &HF030&, _
        SC_RESTORE& = &HF120&, SC_CLOSE& = &HF060&
    If uMsg = WM_SYSCOMMAND Then
            If wParam = (SC_MAXIMIZE And &HFFF0&) Or wParam = (SC_RESTORE _
                And &HFFF0&) Or wParam = SC_CLOSE Then
                SetWindowLong hwnd, GWL_WNDPROC, BaseXLProc
                Application.WindowState = AncState
                UserForm1.Show
                XLProc = 1&
                Exit Function
            End If
    End If
    XLProc = CallWindowProc(BaseXLProc, hwnd, uMsg, wParam, lParam)
End Function
'
Public Sub EnregistrerX()
    ActiveWorkbook.Save
    MsgBox "Enregistrement effectué !", vbInformation, "Etat de la procédure ""Sauvegarder"" !"
End Sub
Voilà !
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Merci pour ta réponse, je regarde ça et je te tiens au courant ;)
Messages postés
33
Date d'inscription
lundi 3 mars 2008
Statut
Membre
Dernière intervention
14 décembre 2012
8
Encore une fois, ça me convient très bien. T'es au top ;)