Effacer une date dans un enregistrement [Résolu]

Signaler
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013
-
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
-
Bonsoir à tous,


J'ai un problème avec un controle ADO: Sur une form, j'ai des textboxes qui sont liés à une BDD via une connexion ADO (la BDD est Access97).
Un de ces textboxes contient une date. Pas de problème si je veux la modifier, mais impossible de la supprimer (la remettre à NULL). J'ai toujours le message "Operation was canceled".
Si je tape du code (dans la fenêtre d'exécution), ca fonctionne:
PrimaryRS!Date1=NULL
PrimaryRS.Update
PrimaryRS.Requery
Le problème est que l'utilisateur travaille en direct sur le recordset, et je ne sais pas ou mettre ce code
Quelqu'un peut-il me dire pourquoi, et comment résoudre ce problème ?
-------------------
Autre petite question: quelle est la différence entre Null et vbNull ?
Si, dans le code ci-dessus, je mets vbNull, la date devient 31/12/1899 ??

Merci de votre aide
Jessica 

18 réponses

Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
non non non Jessica !!!
tu n' a suivi mon conseil qu' à moitié.
ne mets aucun TextBox lié au champ LaDate.Sinon tu auras
toujours à faire à un changement suite à une affectation indirexte ,
à savoir :TextBoxMachin.Text=Null et WillChange et Will et Will...etc...
Pour sauvegarder ta valeur ancienne à la quelle tu te référeras pour
comparer suite à une modification,utilise la propriété Tag de ton TextBox
(non lié), tu procèderas ainsi :


TextBox.Text=RecordSet![LaDate]
TextBox.Tag=RecordSet![LaDate]


Si une Modification survient dans Key_Up  (et non dans Change car cette
dernière est déclechée par des tas d' événement , alors que KeyUp, elle
n' est déclenché que lorsque l' utilisateur intervient),


If TextBox.Text<>TextBox.Tag Then
 If TextBox.Text="" then   =>un changement est survenu
     'Tu Update ton champ LaDate avec Null
     'et tu remet ton TextBox.Tag=""
      'pour qu' il coincide avec TextBox.Text
 Else
    'si une autre valeur non valide
     'tu récupères l' ancienne valeur
    TextBox.Text=TextBox.Tag
    
     'si une autre date valide
     'Tu Update ton champ LaDate avec la nouvelle date
      directement dans la table par requete.
     'et tu remet ton TextBox.Tag=la nouvelle date
      'pour qu' il coincide avec TextBox.Text
  End if
End If


Et oublies le lien au champ LaDate !


chaibat
   




 
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
^^donc si un changement ne survient que dans un contrôle non lié, le DataControl ne met pas à jour le recordset !


Que tu remets à jour le recordset  ou pas tes controles coincident
toujours avec ta table (au moins en ce qui concerne le champ LaDate)
puisque tu fais en sorte que les valeurs concordent.
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Bonjour,
C' est encore moi !
Comme tu vois , je n' abandonne jamais à mi-chemin
Voilà ce que j' ai trouvé en dernier lieu.


*Gardes ton :
Private Sub Text4_KeyUp(KeyCode As Integer, Shift As Integer)
  If KeyCode = vbKeyReturn Then SendKeys "{tab}"
End Sub


''Ajoutes
Private Sub Text4_Validate(Cancel As Boolean)
 If Text4.Text <> Text4.Tag Then
   If Text4.Text = "" Then
        Adodc1.Recordset!Ladate = Null
        Text4.Tag = ""
   Else
      Dim cNewDate As Date
     's' il ne peut pas convertir (Text4.Text ) en Date
       On Error GoTo err_Date
       cNewDate = CDate(Text4.Text)
     'si date valide
        Adodc1.Recordset!Ladate = cNewDate
        Text4.Tag = Text4.Text
  End If
End If
 Exit Sub
err_Date:
 Cancel = True
 MsgBox  Err.Description, vbOKOnly + vbInformation, "Erreur..."
 End Sub


Je crois que cette fois, le compte est bon  !


Amicalement


chaibat
Messages postés
6786
Date d'inscription
vendredi 16 décembre 2005
Statut
Membre
Dernière intervention
21 décembre 2011
18
Salut,

essaie peut-être avec 0 (ou vbEmpty) au lieu de Null
sans garantie !

++
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Non, j'ai essayé avec 0: seul le Null fonctionne; mon problème est de savoir où mettre ces 3 lignes dans le code de la form si l'utilisateur efface la date de la textbox.
Jessica
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Bonsoir,
Et si tu insères ton code :
dans
Sub TextBox_Validate
 If TextBox.Text="" Then
   PrimaryRS!Date1=NULL
   PrimaryRS.Update
   PrimaryRS.Requery
  'ou PrimaryRS.UpdateControls
End If
End Sub
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonjour,
Le message d'erreur change: "Multiple-step operation generated errors. Check each status value" et le débogeur coince sur Update.
En plus, je ne crois pas que ce soit le bon endroit, puisque la BDD serait mise à jour dès que le contrôle perd le focus. Or cette mise à jour ne peut se faire que lorsqu'on change d'enregistrement (par exemple en cliquant Next sur le controle data).
De plus, l'utilisateur doit conserver la possibilité d'annuler ses modifications: s'il clique sur le bouton "Annuler", tous les autres champs reviendraient à leur valeur initiale, sauf celui-là !
A noter que l'erreur survient quand je clique sur le controle data (next ou previous), pas quand je met le textbox à jour!
Y a pas moyen avec un des events du controle data (WillChangeField ou WillChangeRecord ou ...) ?
Merci
Jessica
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

J'ai trouvé que cette erreur se produit lorsque le contenu du textbox (un string par défaut) ne correspond pas au type de champs de la BDD (numérique ou date).
Si au moins je pouvais mettre un ON ERROR quelque part !!!
HEEEEELP !!!!
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Bonjour,
C' est le NULL qui ne correspond pas
TextBox.Text=NULL est erroné.
Pour la question de l' emplacement du code il faut chercher
quel événement se déclenche en premier entre  WillChangeRecord,
WillChangeField, Will.........etc...
il y' en a tant qui cause la validation.
Et donc il faut tester à ce moment la.
Mais le grand problème réside dans l' annulation et la récupération
de la valeur prédédente (l' OldValue) et aussi dans le rafraichissement
Essaies de voir avec
On error goto err_Update
.......


err_Update:
RecordSet.CancelUpdate .
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonjour,
La séquence des événements est la suivante:
Adodc1_WillMove
Adodc1_WillChangeRecord
Adodc1_WillChangeField
Adodc1_FieldChangeComplete
Adodc1_RecordChangeComplete
Adodc1_MoveComplete
Chose étonnante, il a déclanché ces 6 événements 39 fois (!) avant de s'arrêter dans MoveComplete, sur la ligne Adodc1.Recordset.MoveNext.
Pour tester, j'ai codé les sub WillChangeRecord, WillChangeField, ... tous!
Pour qui veut m'aider, voici mon code:
Option Explicit
Private Sub Adodc1_Error(ByVal ErrorNumber As Long,   Description As String, ByVal Scode As Long, ByVal   Source As String, ByVal HelpFile As String, ByVal   HelpContext As Long, fCancelDisplay As Boolean)
  If ErrorNumber = 3617 Then
    fCancelDisplay = True
  End If
  End Sub




Private Sub Adodc1_MoveComplete(ByVal adReason As ADODB.EventReasonEnum, ByVal pError As ADODB.Error, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
  If adStatus = adStatusErrorsOccurred Then
    Adodc1.Recordset.CancelUpdate
    Adodc1.Recordset.MoveNext
  End If
  End Sub





Private Sub Adodc1_WillChangeRecord(ByVal adReason As ADODB.EventReasonEnum, ByVal cRecords As Long, adStatus As ADODB.EventStatusEnum, ByVal pRecordset As ADODB.Recordset)
  If adReason = adRsnUpdate Then
    If MsgBox("Save changes", vbYesNo) = vbNo Then
      adStatus = adStatusCancel
    End If
  End If
  End Sub

Ma table Access contient 3 champs: nom(charactère), code(numérique) et LaDate(date)




Les sub que j'utilise vraiment sont Adodc1_Error, MoveComplete et WillChangeRecord. Je ne vois pas ou je peux mettre un test qui dit que si TxbLaDate.text="" then Adodc1.RecordSet!LaDate=NULL. Ce doit pourtant être faisable. Je ne crois pas être la première à vouloir remettre un champs date à blanc
Merci de votre aide
Jessica
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Et si tu ne lie pas le TextBox au champ Date de ta table ?
Contente toi d' afficher la date de l' enregistrement courant.
avec TextBox.Text=RecordSet![Date].Mais ça tu dois le faire
après chaque mouvement.
Si le contenu de ton TextBox change, tu testes sur son contenu,
tu fais une requete mis à jour du champ et tu réactulises ton
RecordSet.
Tu éviteras alors
   Adodc1_WillMove
   Adodc1_WillChangeRecord
   Adodc1_WillChangeField
   Adodc1_FieldChangeComplete
   Adodc1_RecordChangeComplete
   Adodc1_MoveComplete
relatifs à ce champ.
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonsoir Chaibat05
J'ai suivi ton conseil: un textbox qui n'est pas lié à la BDD et que je mets à jour après chaque mouvement (facile: dans MoveComplete) , et un autre textbox, invisible, qui lui est lié à cette BDD: cela me permet de tester si l'utilisateur a changé la date. Ne pas oublier qu'il s'agit de contrôles liés à un ADODC, donc si un changement ne survient que dans un contrôle non lié, le DataControl ne met pas à jour le recordset !
Dans WillMove, je teste si la date a changé. Si oui, j'appelle manuellement le sub WillChangeRecord (Call Adodc1_WillChangeRecord(...paramètres...)).Finalement, dans la fonction WillChangeRecord, je vérifie si la date est vide, auquel cas je mets NULL dans le champs, sinon, j'y mets CVDate(text4.text)
Reste cependant encore un problème de taille: dans WillMove, je fais un appel à la sub WillChangeRecord, et le ControlDate le fait également ! Je reçois donc deux fois le message "Save changes ?" si (et seulement si) la date a changé.
Tu n'aurais pas encore une petite idée ?
Merci de ton aide précieuse
Jessica
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonsoir Chaibat
CA MARCHE !!!
Private Sub Text4_KeyUp(KeyCode As Integer, Shift As Integer)
If KeyCode = 13 Then
If Text4.Text <> Text4.Tag Then
If Text4.Text = "" Then
Adodc1.Recordset!Ladate = Null
Text4.Tag = ""
ElseIf Not IsDate(Text4.Text) Then
Text4.Text = Text4.Tag
Else
Adodc1.Recordset!Ladate = CVDate(Text4.Text)
Text4.Tag = Text4.Text
End If
End If
SendKeys "{Tab}"
End If
End Sub
Reste à peaufiner qq détails (une validation de la date un peu plus sérieuse, et surtout le fait que l'utilisateur soit obligé de faire Enter) mais le principal, c'est que la BDD soit correctement mise à jour, tout en conservant la posibilité de faire Undo.
Mille fois merci à toi.
Jessica
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Bonsoir Jessica,
Content pour toi que ça a marché.

Pour la question de la validation ,
(et je ne voudrais pas tout gâcher, 
et donc tu peux accepter ma suggestion
ou  continuer sur ta lancée).

je te propose alors de supprimer le test :
If KeyCode = 13 Then
Ainsi (toujours dans Key_Up) quelque soit la touche appuyée
(signe que l' utilisateur tente de modifier le contenu du TextBox),
tu  intercèptes.(ça fera au max 10 testes avec par exemple 12/09/2006)
Et tu ajoutes un dernier dans TextBox_Validate.
Ainsi, l' utilisateur n' est pas obligé de taper Enter.

Mais bon, à toi de voir !
Quoi qu' il en soit, je pense que le plus dur a été fait

Bonne continuation.
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Tu sais quoi ! Je viens de m' apercevoir d' une chose.

Avec ElseIf Not IsDate(Text4.Text) Then
tu compliqueras la vie à l' utilisateur.
(Il n' aura même pas le temps de taper le 12) !

Mets tout ça dans TextBox_Validate c' est mieux.
If Text4.Text <> Text4.Tag Then
      If Text4.Text = "" Then
        Adodc1.Recordset!Ladate = Null
        Text4.Tag = ""
      ElseIf Not IsDate(Text4.Text) Then
        Text4.Text = Text4.Tag
        Cancel=True   'l' obliger à rester dans le TextBox
       Else
        Adodc1.Recordset!Ladate = CVDate(Text4.Text)
        Text4.Tag = Text4.Text
      End If
    End If

A+
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonjour Chaibat05


Il t'arrive de dormir ??
Tes dernière propositions semblent plus qu'intéressantes, mais je ne peux les essayer pour l'instant, mon PC sur lequel est installé VB ayant rendu l'âme ! Je te tiens au courant dès que je le récupère.
En tout cas, merci d'avance pur ton opiniâtreté
Jessica
Messages postés
116
Date d'inscription
mardi 8 août 2006
Statut
Membre
Dernière intervention
29 septembre 2013

Bonsoir Chaibat,
J'espère que tu es toujours là !
J'ai enfin récupéré ma machine: chère cette réparation (et longue) !!
J'ai modifié mon prog. en fonction de ton dernier post (avec le validate) et  ...  CA MARCHE SUPER !!!
Merci beaucoup pour ton aide.
Jessica
Messages postés
1883
Date d'inscription
samedi 1 avril 2006
Statut
Membre
Dernière intervention
20 novembre 2007
2
Bonsoir Jessica,

Mais bien sûr que je suis là
Content de te lire de nouveau,
et bon retour parmis nous.


Maintenent que ton Ordi est réparé, fais le travailler au max !

Amicalement