IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VBA Access Discussion :

Erreur compilation: end sub attendu [AC-2010]


Sujet :

VBA Access

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut Erreur compilation: end sub attendu
    Bonjour,

    Peut-on insérer une fonction dans un sub? Le msg ci-dessus s'affiche dès l'exécution la 1ère ligne du code évènementiel:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Private Sub Form_BeforeInsert(Cancel As Integer)
    Function nomfct()
    Merci à vous,

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut commentaires attendus après...
    Rebonjour,

    En fait, il faut mettre le end sub juste après le sub. Maintenant, j'ai un autre msg: erreur de compilation commentaires attendus après end sub end function...
    Quelqu'un sait?
    Merci

  3. #3
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,

    Non, il faut l'insérer à l'extérieur.

    Exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Sub MaSub1()
    ... code de MaSub1 ...
    End Sub
    
    Sub MaSub2()
    ... code de MaSub2 ...
    End Sub
    
    Function nomfct()
    ... code de nomfct ...
    End Function
    
    Sub MaSub3()
    ... code de MaSub3 ...
    End Sub
    On ne peut pas insérer une sub à l'intérieur d'une sub, ni à l'intérieur d'une fonction.
    On ne peut pas insérer une fonction à l'intérieur d'une sub, ni à l'intérieur d'une fonction.

    Le début et la fin d'une sub sont identifiés par Sub et End Sub.
    Le début et la fin d'une fonction sont identifiés par Function et End Function.

    A+

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut Appel function
    Salut,

    Merci beaucoup pour la réponse. Le VBA fonctionne par module en fait.
    J'ai une autre question. Je veux appeler la function dans un champ du formulaire pour que la valeur calculée de la fonction s'affiche dans ce même champs:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Commande_Enter()
    Call nomfunction
    End Sub
    Seulement, ça me demande d'entrer la valeur dans la champ alors que je voudrais que ce la se fasse automatiquement. Peut-être, est-ce dans un autre évènement que je dois insérer l'appel ou au niveau du formulaire???
    Quelqu'un pourrait me dire?
    Merci à vous

  5. #5
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    3 849
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 849
    Par défaut
    Bonjour,

    La fonction s'utilise dans la propriété Source Contrôle de la zone de texte par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     = NomFonction(Arg1,...)
    comme toutes les autres fonctions intégrées VBA.
    Attention à son statut Public ou Privée !!

    Bonne continuation

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut
    Merci du retour.
    Ça n'a pas l'air de fonctionner. J'ai mis l'appel de la fonction dans l'évènement du champ 'ENVOI' du formulaire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub ENVOI_Enter()
    = nomfunction(ENVOI)
    End Sub
    Est-ce parce que je ne sais pas utiliser private/public? je n'ai pas défini la function ainsi. Faut-il la définir private/public aussi?
    Merci de votre aide,

  7. #7
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,

    La proposition de madefemere est valable pour un contrôle indépendant.
    Indépendant veut dire que le contrôle n'est pas lié à un champ d'une table ou d'une requête.
    En d'autre termes sa propriété «Source Contrôle» ne contient un champ de la liste déroulante.

    1) Ta fonction nomfunction doit être déclaré Public
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Public Function nomfunction() 
    ... code de la fonction...
    End Function
    2) Pour utiliser ta fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub ENVOI_Enter()
    Me.NomDuContrôle = nomfunction()
    End Sub
    3) La fonction a-t-elle des arguments ?
    Exemple de fonction avec deux arguments:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Fonction fnMax(dblN1 as Double, dblN2 as Double) As Double
    Dim dblMax as Double
     
    If dblN1 > dblN2 Then
        dblMax = dblN1
    Else
        dblMax = dblN2
    End If
    ' Retourner la valeur
    fnMax = dblMax 
    End Function
    Dans cet exemple, dblN1 et dblN2 sont les arguments de la fonction fnMax.

    A+

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut Appel function
    Merci pour l'explication. Je viens de mettre en public et d'utiliser le Me.class
    Voici le code de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Function nextnum()
    Dim curAnnee As String
    curAnnee = Format(Date, "yyyy")
     
    lastnum = DMax("ENVOI", "Table", "ENVOI like '" & curAnnee & "*'")
     
    If IsNull(lastnum) Then 'pas de n° pour cette année
       newnum = curAnnee & "-0001"
    Else
       newnum = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
    End If
    End Function
    J'appelle la fonction au niveau du champ ENVOI (déclaré comme texte dans table):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub ENVOI_Enter()
    Me.ENVOI = newnum()
    End Sub
    C'est pas encore OK. Comment je peux faire?
    Merci

  9. #9
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Ton erreur vient du fait que tu utilises deux noms différents pour ta fonction.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Function nextnum()
    Dim curAnnee As String
    curAnnee = Format(Date, "yyyy")
     
    lastnum = DMax("ENVOI", "Table", "ENVOI like '" & curAnnee & "*'")
     
    If IsNull(lastnum) Then 'pas de n° pour cette année
       newnum = curAnnee & "-0001"
    Else
       newnum = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
    End If
    End Function
    Pour éviter ce genre de souci, je te propose d'activer la «déclaration explicite des variables».
    Pour activer l'option, aller dans l'éditeur Visual Basic.
    Depuis le menu principal, Outils > Options...
    Cocher «Déclaration des variables obligatoire»

    Cette option ajoute Option Explicitdans l'en-têtes des nouveaux modules de code.
    Pour les modules existants, il faut coller cette ligne à la main, en dessous de Option Compare Database.
    Cette option force le compilateur à vérifier tous les noms (variables, fonctions, sub).
    La contre-partie est que tu dois toujours déclarer (Dim) toutes tes variables.
    Il faut donc déclarer la variable lastnum dans ta fonction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Public Function newnum()
    Dim curAnnee As String
    Dim lastnum As Long
     
    curAnnee = Format(Date, "yyyy")
     
    lastnum = DMax("ENVOI", "Table", "ENVOI like '" & curAnnee & "*'")
     
    If IsNull(lastnum) Then 'pas de n° pour cette année
       newnum = curAnnee & "-0001"
    Else
       newnum = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
    End If
    End Function
    A+

  10. #10
    Expert confirmé

    Homme Profil pro
    Inscrit en
    Mai 2012
    Messages
    3 849
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Madagascar

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 849
    Par défaut
    Re-,

    Peut-être parce que t'es trop pressé.
    Ta fonction ne renvoie rien en résultat si son nom change dans le code. Tu veux nextnum ou newnum

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Function nextnum()
    Dim curAnnee As String
    curAnnee = Format(Date, "yyyy")
     
    lastnum = DMax("ENVOI", "Table", "ENVOI like '" & curAnnee & "*'")
     
    If IsNull(lastnum) Then 'pas de n° pour cette année
       newnum = curAnnee & "-0001"
    Else
       newnum = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
    End If
    End Function
    @+

    EDIT : Grillé

  11. #11
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut champ vide
    Bonjour,

    Ah oui. Merci aussi pour l'astuce. Je viens de corriger et d'insérer les lignes Option Compare Database et Option Explicit. Le champ ENVOI de la table reste vide après avoir saisi mes enregistrements. D'ailleurs même en mettant le format de ce champ dans la table à 0000-0000, le champ reste vide.
    Je ne sais pas pourquoi... Merci de me dire comment faire.

    Bonne journée

  12. #12
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut
    Salut,

    En changeant l'évènement de l'appel fonction, une erreur d'exécution 13 apparaît à cette ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    Option Compare Database
    Option Explicit
     
    Public Function newnum()
    Dim curAnnee As String
    Dim lastnum As Long
     
    curAnnee = Format(Date, "yyyy")
     
    lastnum = DMax("ENVOI", "table", "ENVOI like '" & curAnnee & "*'")
     
    If IsNull(lastnum) Then 'pas de n° pour cette année
       newnum = curAnnee & "-0001"
    Else
       newnum = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
    End If
    End Function
     
     
    Private Sub Form_Current()
    Me.ENVOI = newnum()
    End Sub
    Ne serait-ce pas lié à une déclaration manquante????
    Si vous savez....
    Merci

  13. #13
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,

    Oui je sais pourquoi C'est ma faute
    Il faut déclarer lastnum de type Variant
    Pour deux raisons:
    1. Ton champ est de type String et non pas Long
    2. DMax peut retourner Null et seul le type Variant accepte la valeur Null.

    Par contre je suppose que tu ne veux générer un nouveau numéro que pour un nouvel enregistrement.
    Donc j'écrirai le code de l'événement «sur activation» comme ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Private Sub Form_Current()
    If Me.NewRecord Then
       If Len(Nz(Me.ENVOI, "")) = 0 Then
          Me.ENVOI = newnum()
       End If
    End If
    End Sub
    Ou bien encore, tu peux choisir l'événement "Avant insertion" et mettre le contrôle ENVOI en lecture seule (propriété «Vérrouillé» à Oui).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Form_BeforeInsert(Cancel As Integer)
    Me.ENVOI = newnum()
    End Sub
    A+

  14. #14
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut
    Super, ça fonctionne très bien. Juste un point: ce n° ENVOI s'incrémente une fois tant que la date saisie = date jour. Ca signifie qu'à chaque saisie du jour, ce n° est incrémenté une fois et reste le même. Lorsque j'ouvre le formulaire pour une nouvelle saisie le lendemain par ex, ce n° s'incrémente de nouveau et reste le même durant les enregistrements de la date du jour.
    Je sais pas vraiment comment faire?
    Merci beaucoup,

  15. #15
    Expert confirmé
    Avatar de LedZeppII
    Homme Profil pro
    Maintenance données produits
    Inscrit en
    Décembre 2005
    Messages
    4 485
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Maintenance données produits
    Secteur : Distribution

    Informations forums :
    Inscription : Décembre 2005
    Messages : 4 485
    Par défaut
    Bonjour,
    Citation Envoyé par zoe_top Voir le message
    Juste un point: ce n° ENVOI s'incrémente une fois tant que la date saisie = date jour. Ca signifie qu'à chaque saisie du jour, ce n° est incrémenté une fois et reste le même. Lorsque j'ouvre le formulaire pour une nouvelle saisie le lendemain par ex, ce n° s'incrémente de nouveau et reste le même durant les enregistrements de la date du jour.
    Je sais pas vraiment comment faire?
    L'idéal serait sans doute de stocker le numéro dans une table, laquelle aurait un champ Date pour également mémoriser la date de génération du numéro.

    Table : T_NumRef
    • Nom (Texte + indexé sans doublons)
    • StrVal (Texte)
    • GenereLe (Date/Heure)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Nom    StrVal     GenereLe
    ENVOI  2013-0001  02/08/2013
    Nouveau code de newnum() pour n'incrémenter qu'une fois pas jour:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    Public Function newnum()
    Dim db As DAO.Database, rs As DAO.Recordset, sSql As String
    Dim curAnnee As String
    Dim lastnum As Variant
    Dim sValeurRetour As String
     
    curAnnee = Format(Date, "yyyy")
     
    ' Ouverture d'un jeu de données sur la table T_NumRef
    ' filtré sur le nom du compteur (WHERE [Nom]='ENVOI')
    Set db = CurrentDb
    sSql = "SELECT [Nom], [StrVal], [GenereLe] FROM T_NumRef WHERE [Nom]='ENVOI'"
    Set rs = db.OpenRecordset(sSql, dbOpenDynaset)
     
    ' Si pas d'enregistrement on en crée un
    If rs.EOF Then
       rs.AddNew
       rs("Nom") = "ENVOI"
       rs("StrVal") = "1999-0000"
       rs("GenereLe") = #1/1/1999#
       rs.Update
       rs.MoveFirst
    End If
     
    ' Lire la valeur courante du compteur
    lastnum = rs("StrVal")
     
    ' Faut-il générer un nouveau numéro ?
    If Not (rs("StrVal") Like curAnnee & "-*") Then
       ' Oui, car changement d'année
       rs.Edit
       rs("StrVal") = curAnnee & "-0001"
       rs("GenereLe") = Date
       rs.Update
    ElseIf rs("GenereLe") <> Date Then
       ' Oui, car pas généré aujourd'hui
       rs.Edit
       rs("StrVal") = curAnnee & "-" & Format(Right(lastnum, 4) + 1, "0000")
       rs("GenereLe") = Date
       rs.Update
    End If
     
    ' Memoriser valeur compteur
    sValeurRetour = rs("StrVal")
    ' Fermer le jeu de données
    rs.Close
     
    newnum = sValeurRetour
    End Function
    A+

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Juillet 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2013
    Messages : 21
    Par défaut
    Waouh, c'est du haut de gamme! Merci LedZeppII! Ca fonctionne même mieux de que ce j'avais prévu puisque je peux ouvrir le formulaire plusieurs fois le même jour sans que le n° change.
    Bon, je vais tenter d'approfondir mes connaissances du modèle DAO.
    Merci beaucoup!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Erreur compilation : Sub ou Fonction non définie
    Par DSE76 dans le forum Macros et VBA Excel
    Réponses: 12
    Dernier message: 02/07/2013, 15h41
  2. Réponses: 2
    Dernier message: 27/02/2013, 22h25
  3. Réponses: 3
    Dernier message: 18/03/2008, 12h04
  4. ca fonctionne mais erreur compilation déclaration sub
    Par petitours dans le forum VBA Access
    Réponses: 2
    Dernier message: 19/12/2007, 19h30
  5. Erreur compilation DX8.1 VC++ 6
    Par d.vidal dans le forum DirectX
    Réponses: 1
    Dernier message: 10/09/2003, 10h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo