Posez votre question Signaler

Problème code VBA sous access

Shifty62 - Dernière réponse le 10 juin 2009 à 17:33
Bonjour,
Voila je suis actuellement en stage de développement informatique. Ma mission consiste a créer un logiciel sous access 2000 (eh oui ça arrive ^^) qui ferait de la relance client. J'ai déjà pas mal avancer dans mon projet mais la je suis bloqué...
Je vous explique : J'ai un formulaire relance client avec dedans tous mes sous formulaires répartis dans des onglets. Dans un onglet "facture", j'ai donc un sous-formulaire "facture" avec le code facture comme clé primaire et ses autres champs (date facture, montant...) et dans un autre onglet "gammes" j'ai un sous-formulaire "liste des actions" (de la gamme) avec également le code facture comme clé primaire et aussi d'autres champs (code action,date action...).
A savoir bien sur que mes 2 tables (facture et liste action) sont bien liées entre elles dans mon modèle relationnel via le code facture (1 facture peut avoir plusieurs actions possibles).
Ce que je veux faire : j'aimerai, grâce à un double clic sur le code facture que j'aurai taper moi même dans le sous-formulaire facture, insérer ce fameux code facture directement dans le sous-formulaire liste action. J'espère que je me suis fait comprendre XD
Ainsi j'ai donc créer une procédure événementielle pour taper le code sous VBA. Et c'est là que les ennuis commencent...
J'ai récupérer le code d'un collègue qui ne peut pas vraiment m'aider à dire comment il fonctionne ni comment l'adapter (vous savez, c'est un ami d'un ami d'un ami qui m'a refiler le code ;) ).
Je l'ai récupérer et "essayer" de l'adapter à mon formulaire, le voici :
Private Sub CODE_FACTURE_DblClick(Cancel As Integer)
Dim nom_facture As Integer
Dim NOMBRE As Integer
nom_facture = Me.Form.Recordset.Fields("Code_Facture").Value
[Form_Gestion Relance Client].CtlTab21.Value = 0
[Form_Gestion Relance Client].Recordset.MoveLast
NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount
Dim Rs As DAO.Recordset
Set Rs = [Form_Gestion Relance Client].RecordsetClone
Rs.MoveFirst
For i = 1 To NOMBRE
If Rs.Fields("CODE_FACTURE").Value = nom_facture Then
GoTo valid
Else
Rs.MoveNext
End If
Next
valid:
[Form_Gestion Relance Client].Recordset.Absolute = i + 1
End sub
Je vous avouerai que je ne comprend pas la moitié, VB n'étant pas vraiment ma tasse de thé ^^
Après quelques manip' et résolutions d'erreurs, le code ne fonctionne toujours pas.
Mon problème est cette ligne qui ne veut pas s'exécuter :
[Form_Gestion Relance Client].Recordset.Absolute = i + 1 (c'est la dernière ligne du code)
Le message d'erreur est : propriété ou méthode non gérée par cette objet.
Ma petite idée sur cette erreur serait que ce code n'envoie pas sur le bon onglet et donc le bon formulaire.
Au cas où je vous met l'ordre des onglets : clients(avec 2 sous-formulaires) - factures(avec sous 1 formulaire) - gammes(avec 1 sous formulaire)
Voilà j'espère avoir été assez clair dans mon explication !!!
En vous remerciant d'avance pour vos réponses,
Alex
Lire la suite 

Problème code VBA sous access »

20 réponses
Réponse
+0
moins plus
Bonjour,

Non expert de VBA Access, et ne pouvant tester le code, voici tout de même un suggestion :

Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer, NOMBRE As Integer
    Dim Rs As DAO.Recordset

    nom_facture = Me.Form.Recordset.Fields("Code_Facture").Value
    [Form_Gestion Relance Client].CtlTab21.Value = 0
    [Form_Gestion Relance Client].Recordset.MoveLast
    [Form_Gestion Relance Client].Recordset.MoveFirst
    NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount

    Set Rs = [Form_Gestion Relance Client].RecordsetClone

    For i = 1 To NOMBRE
        If Rs.Fields("CODE_FACTURE").Value <> nom_facture Then
            Rs.MoveNext
        Else
            Exit For
        End If
    Next
    [Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1
    
End Sub
'

Lupin
Shifty62 - 21 janv. 2009 à 14:54
Bonjour Lupin ! Merci pour ta réponse ;)

Donc j'ai essayer ton code et maintenant je n'ai plus le même problème ^^

Je t'explique Lupin :
Dès que je double clic sur un numéro de facture (n'importe lequel) il me renvoie sur l'onglet client (le 1er onglet) au lieu de me renvoyer sur l'onglet gamme (le 3e onglet). Je réessaye donc une 2e fois la même manip' et là il me renvoie un message d'erreur '3021' : "Aucun enregistrement en cours". Le message d'erreur ne survient que quand je clic une 2e fois sur le même code facture.

Dès lors, il me renvoie sur mon code (enfin le tient lupin ;) ) et il me montre que l'erreur se trouve dans cette ligne :

nom_facture = Me.Form.Recordset("CODE_FACTURE").Value (la 3e ligne)

Maintenant je suis à peu près sur que c'est un problème de position des onglets.
nivek - 10 juin 2009 à 17:33
Salut Shifty, je suis actuellement en stage, et nous devons faire des relances clients, mon patron ma demander de voir si je pouver automatiser ces lettres, et la seul solution possible avec les logiciels de la boites est access, je voudrais donc savoir si tu a réussi a terminer ton logiciel, et si tu pourrais me conseiller.
Ajouter un commentaire
Réponse
+0
moins plus
re:

Je pense que l'erreur vien du fait que tu nomme 2 fois l'objet !

nom_facture = Me.Form.Recordset("CODE_FACTURE").Value

Si tu utilise le mot clé [ Me ], c'est que tu veux adresser le
formulaire actif, donc après le [ Me ] il te faut adresser directement
un objet de la form (du formulaire).

L'instruction se lit donc :

nom_facture = Me.Recordset("CODE_FACTURE").Value

et je crois avoir inverser le test dans la boucle :

Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer, NOMBRE As Integer
    Dim Rs As DAO.Recordset

    nom_facture = Me.Recordset.Fields("Code_Facture").Value
    [Form_Gestion Relance Client].CtlTab21.Value = 0
    [Form_Gestion Relance Client].Recordset.MoveLast
    [Form_Gestion Relance Client].Recordset.MoveFirst
    NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount

    Set Rs = [Form_Gestion Relance Client].RecordsetClone

    For i = 1 To NOMBRE
        If Rs.Fields("CODE_FACTURE").Value = nom_facture Then
            Exit For
        Else
            Rs.MoveNext
        End If
    Next
    [Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1
    
End Sub
'



C'est comme si tu utilisait :

Me.[Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1

mauvaise syntaxe !

Lupin
Shifty62 - 22 janv. 2009 à 15:44
Bonjour lupin !

J'ai changé l'expression et j'ai toujours la même erreur au niveau de cette ligne de code.

Ce que je trouve vraiment bizarre, c'est que lorsque je clic sur la facture en question, il me renvoie vers l'onglet "client" au lieu de "gamme" et après un 2e clic il m'envoie l'erreur...
Ajouter un commentaire
Réponse
+0
moins plus
re:

nom_facture = Me.Form.Recordset.Fields("Code_Facture").Value

Donc la variable [ nom_facture ] devrait prendre la valeur du champs sur lequel
tu viens de double-cliquer.

essaie simplement :

nom_facture = Me.Value

Lupin
Ajouter un commentaire
Réponse
+0
moins plus
re:

Ou, je n'ai pas accès à Access, mais de mémoire :

nom_facture = Me.CODE_FACRURE.Value

nom_facture = Me.CODE_FACRURE.Text

Lupin
Shifty62 - 23 janv. 2009 à 09:02
Rebonjour lupin !!

J'ai donc retester le code et voila où il en ai :

Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

Dim nom_facture As Integer, NOMBRE As Integer
Dim Rs As DAO.Recordset

nom_facture = Me.CODE_FACTURE.Value
[Form_Gestion Relance Client].CtlTab21.Value = 0
[Form_Gestion Relance Client].Recordset.MoveLast
[Form_Gestion Relance Client].Recordset.MoveFirst
NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount

Set Rs = [Form_Gestion Relance Client].RecordsetClone

For i = 1 To NOMBRE
If Rs.Fields("CODE_FACTURE").Value = nom_facture Then
Exit For
Else
Rs.MoveNext
End If
Next
[Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1

End Sub
'

Donc maintenant quand je double clic sur le code facture, il me lance toujours sur le mauvais onglet (client) et c'est seulement après avoir cliqué plusieurs fois sur les différents codes facture qu'il m'envoie une erreur qui se trouve sur la ligne :

If Rs.Fields("CODE_FACTURE").Value = nom_facture Then

J'ai l'impression que petit à petit, on y arrive ^^
Ajouter un commentaire
Réponse
+0
moins plus
re:

Alors voici une autre possibilité !

Il m'est difficile de coder sans voir la BD !!!

Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer, NOMBRE As Integer

    nom_facture = Me.CODE_FACTURE.Value
    [Form_Gestion Relance Client].CtlTab21.Value = 0
    [Form_Gestion Relance Client].Recordset.MoveLast
    [Form_Gestion Relance Client].Recordset.MoveFirst
    NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount

    For i = 1 To NOMBRE
        If Me.CODE_FACTURE.Value = nom_facture Then
            Exit For
        Else
            Me.Recordset.MoveNext
        End If
    Next
    If (i < NOMBRE) Then
        [Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1
    End If
    
End Sub
'


Lupin
Shifty62 - 23 janv. 2009 à 15:59
Salut lupin !

Bon il semble maintenant qu'il ne me met aucune erreur quoique je fasse.
Le problème est toujours celui de l'onglet.

Peut être que le problème pourrait être au niveau du MoveFirst ou du MoveNext ???
Ajouter un commentaire
Réponse
+0
moins plus
re:

Je ne crois pas, j'ai toujours du appliquer cette séquence pour obtenir le nombre d'enregistrement :
[Form_Gestion Relance Client].Recordset.MoveLast
[Form_Gestion Relance Client].Recordset.MoveFirst
NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount


Question :

Est-ce que le champs [ CODE_FACTURE ] est bien sur le formulaire [Form_Gestion Relance Client]?
Je ne crois pas selon tes dire :

<Citation>
Ce que je veux faire : j'aimerai, grâce à un double clic sur le code facture que j'aurai taper moi même dans le sous-formulaire facture, insérer ce fameux code facture directement dans le sous-formulaire liste action.
<Fin citation>



Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer, NOMBRE As Integer

    nom_facture = [Form_Facture].CODE_FACTURE.Value
    [Form_Gestion Relance Client].CtlTab21.Value = 0
    [Form_Gestion Relance Client].Recordset.MoveLast
    [Form_Gestion Relance Client].Recordset.MoveFirst
    NOMBRE = [Form_Gestion Relance Client].Recordset.RecordCount

    For i = 1 To NOMBRE
        If [Form_Gestion Relance Client].CODE_FACTURE.Value = nom_facture Then
            Exit For
        Else
            [Form_Gestion Relance Client].Recordset.MoveNext
        End If
    Next
    If (i < NOMBRE) Then
        [Form_Gestion Relance Client].Recordset.AbsolutePosition = i + 1
    End If
    
End Sub
'


n.b. si tu n'as pas de données confidentielles dans ta BD, place le fichier
Access sur [ ci-joint.fr ] ou [ ci-joint-com ], je pourrai ainsi voir directement
le problème.

Lupin
Shifty62 - 26 janv. 2009 à 09:43
re lupin,

Bon j'ai décidé de t'envoyer ma BDD pour que tu ais vraiment le problème devant les yeux. Attention c'est une version Access 2000 !!

http://www.cijoint.fr/cjlink.php?file=cj200901/cijiVRNMID.zip

J'ai pris soin de supprimer les informations confidentielles donc rien n'est vrai dans la base ;)
Ajouter un commentaire
Réponse
+0
moins plus
re:

voilà, j'ai pris le fichier, je regarde et te reviens la dessus :-)

Lupin
Ajouter un commentaire
Réponse
+0
moins plus
re :

alors, si je comprends bien ce que tu tente de faire et je suis pas sur !

n'ayant pas suffassament de données pour obtenir le sous-formulaire facture !

Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer
    
    nom_facture = Val(Me.CODE_FACTURE.Value)
    [Form_Gestion Relance Client].CtlTab21.Pages("Clients").SetFocus
 
    With CodeContextObject
        DoCmd.GoToControl "MNEMO"
        DoCmd.FindRecord nom_facture, acEntire, False, , False, , True
        DoCmd.GoToControl "MNEMO"
    End With

    [Form_Gestion Relance Client].Recordset.MoveNext
    
End Sub
'


n.b. il n'y a aucune requete de créer dans ta base, tes formulaires me semblent pourtant
accrocher sur des requêtes codé en dur ! Il serait souhaitable de les accrocher sur des requêtes.


Lupin
Shifty62 - 27 janv. 2009 à 09:32
Salut lupin !

Donc après avoir changer le code, j'ai toujours le même problème (décidément...).
Tu l'a tester le code toi ? il marche pour toi ?

Pour les requêtes si j'ai bien compris, il serait plus judicieux de les taper sous forme de code ?

Merci lupin pour l'aide que tu m'apportes ;)
Ajouter un commentaire
Réponse
+0
moins plus
re:

non, je n'ai pas testé, je n'ai pas encore tout compris la mécanique,
probablement qu'il manque des données, car je n'accède pas au
sous-formulaire facture.

Je vais devoir scruter plus la BD, en attendant, regarde les requêtes
que j'ai fait dans ta BD !

http://membre.oricom.ca/lupin/util/relance.zip

Lupin
Shifty62 - 28 janv. 2009 à 09:21
Ok lupin, j'attendrai ta réponse !

Si tu as des questions n'hesite pas !!!
Ajouter un commentaire
Réponse
+0
moins plus
re :

voilà, j'ai avancé dans mes observations et c'est bien ce que je pensais,
l'utilisation d'onglets sous access rend certaines méthodes innaccessible.
J'ai déjà fait l'expérience sous VB et j'ai changé mes méthodes à cause
de cela.

comme :
    With CodeContextObject
        DoCmd.GoToControl "MNEMO"
        DoCmd.FindRecord nom_facture, acEntire, False, , False, , True
        DoCmd.GoToControl "MNEMO"
    End With


mais comme dit le proverbe, tous les chemins menent à Paris :-)

La solution est de contourner en lançant une routine déclarer dans [ Form_Client ].

Donc en résumé, si je comprends bien :

Un double clic sur le champ [ CODE_FACTURE ], doit capturer sa valeur,
rendre le focus au sous-formulaire [ Clients ] et trouver l'enregistrement
correspondant au code [ CODE_FACTURE ] récupéré dans une variable.

Première étape :
Aller sur le sous-formulaire [ Clients ], cibler le premier champs, ouvrir
la fenêtre des propriétés, choisir l'onglet évènement, choisir l'évènement
[ Sur clic ] , entrer dans la procédure événementiel.

Vous obtiendrai une routine du style [ Private LeChamps_Click() ]
Vous devriez à ce moment être dans le module [ Form_Clients ].

Remplacer le nom de la routine par :

[ Public ChercheCode(Byval Nom_Fact As String) ]


dans le routine :
Private Sub CODE_FACTURE_DblClick(Cancel As Integer)

    Dim nom_facture As Integer

    nom_facture = Val(Me.CODE_FACTURE.Value)
    [Form_Gestion Relance Client].CtlTab21.Pages("Clients").SetFocus

    Call ChercheCode (nom_facture)

End Sub
'


en gros ça ressemble à ça !

Ce soir je déposerai une version de votre BD avec ce code sur mon site !

Si vous réussissez à utiliser les requêtes, je pourrai aussi vous montrer
comment changer ces requêtes par programmation de façon à accélerer
les recherches.

Lupin
Ajouter un commentaire
Réponse
+0
moins plus
re:

voilà, j'ai installer le code VBA dans la BD, et j'ai joint un tutoriel
(je ne connais pas tes connaissances de l'environnement, alors ... )
qui démontre que dans cette BD le formulaire [ Gestion Relance Client ]
est accroché sur une requête SQL. [ Requete_Form_Gestion_Relance_Client ]

En fait ce ne sont pas ces requêtes globales que je modifie mais les requêtes qui vont
cherché directement un enregistrement souhaité, c'est exactement ce que tu cherche
à faire mais c'est plus puissant.

Alors, examine bien le requête [ Requete_Form_Gestion_Relance_Client ] en mode SQL !

C'est une chaine de caractères qu'il est simple de reconstituer par programmation :-)

Le fichier :

http://membre.oricom.ca/lupin/util/Relance2.zip

( n.b. le lien précédent est mort )
( et celui-ci aussi n'aura qu'une durée très limité).

Lupin
Shifty62 - 29 janv. 2009 à 09:47
Je te remercie beaucoup lupin ! Je vais étudier cela de pret ;)

A bientot !

Alex
Ajouter un commentaire
Ce document intitulé « Problème code VBA sous access » issu de CommentCaMarche (www.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.
Dossier à la une
Passage au tout numérique : quel coût pour les particuliers ?