Bonjour fronck , Bonjour Bidouille,
Je suis un inconditionnel du formulaire sur onglet, plus simple en mise en place.
Voici un exemple génétique ...
Toutes les zones de saisie comportent un nom du type _colXX où XX est la colonne du tableau de données.
Il n'y a que les 3 constantes de la macro à mettre jour si nécessaire.
Tout se déroule en "transparence".
Tape par exemple 1 ou 2 comme identifiant dans la zone jaune.
Option Explicit
Const prefixe = "_col" ' le nom de la zone doit être suivi du n° de colonne dans la base de données, exemple _col21
Const BdD = "BD" ' onglet où se trouve la base de données
Const ID = "ID" ' nom donné au champ clé dans le formulaire, en colonne A de la BdD obligatoirement
Private Sub Worksheet_Change(ByVal Target As Range)
Dim nom As Name, colonne As Long, ligne As Long
Application.EnableEvents = False
On Error GoTo fin
With Sheets(BdD)
ligne = lig(True)
Application.StatusBar = ""
If Not Intersect(Target, Range(ID)) Is Nothing Then
If ligne = 0 Then
If MsgBox("Etes-vous certain de vouloir ajouter le Code """ & Range(ID).Value & """ inconnu ?", vbYesNo, "Demande de confirmation") = vbYes Then
ajouter Range(ID).Value
ligne = lig(True)
renseigner True
MsgBox "Code """ & Range(ID).Value & """ ajouté !"
Else
Application.Undo
End If
Else
renseigner True
End If
ElseIf lenom(Target) Like prefixe & "*" Then
.Cells(ligne, col(lenom(Target))) = Target.Cells(1).Value
Application.StatusBar = "Mise à jour pour " & Range(ID).Value & " ok :: " & Target.Cells(1).Value
End If
End With
Application.EnableEvents = True
Exit Sub
fin:
MsgBox "Erreur n° " & Err.Number & vbLf & Err.Description
Application.EnableEvents = True
End Sub
Private Sub Worksheet_Activate()
Application.EnableEvents = False
Application.StatusBar = ""
On Error GoTo fin
If lig(True) = 0 Then
Range(ID).Value = "" ' le code a été supprimé - on efface tout !
renseigner False
Else
renseigner True
End If
Application.EnableEvents = True
Exit Sub
fin:
MsgBox "Erreur n° " & Err.Number & vbLf & Err.Description
Application.EnableEvents = True
End Sub
Private Function lenom(cel As Range) As String
' donne le nom affecté à la zone éventuellement fusionnée ou à défaut son adresse
lenom = cel.Address
On Error Resume Next
lenom = cel.Cells(1).Name.Name
End Function
Private Function col(chaine As String) As Long
' donne le numéro de colonne issu du nom de la zone
col = Val(Mid(chaine, Len(prefixe) + 1, Len(chaine) - Len(prefixe)))
End Function
Private Function lig(ok As Boolean) As Long
' donne la ligne où se trouve l'ID dans BD, 0 si pas trouvé !
Dim trouve As Range
lig = 0
Set trouve = Sheets(BdD).Columns("A").Find(what:=Range(ID).Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not trouve Is Nothing Then lig = trouve.Row
End Function
Private Sub renseigner(ok As Boolean)
' ok false = effacer, true = remplir
Dim nom As Name
For Each nom In ThisWorkbook.Names
If nom.Name Like prefixe & "*" Then
If ok Then
Range(nom.Name).Value = Sheets(BdD).Cells(lig(True), col(nom.Name))
Else
Range(nom.Name).Value = ""
End If
End If
Next
End Sub
Private Sub ajouter(cetID As Variant)
Sheets(BdD).Cells(Rows.Count, "A").End(xlUp).Offset(1, 0).Value = cetID
End Sub