Clacul VBA

Bonjour à tous,

Je cherche à faire un programme VBA qui calcule l'age automatiquement.

Dans la colonne A j'ai des dates de naissances, le programme doit mettre l'age en colonne B dès qu'il trouve une date en A. et si c'est possible d'ajouter le mot "ans" (23 ans par exemple)

Merci d'avance..

Bonjour Emma,

Pas besoin de VBA :

Si ta première date de naissance est en A1, en B1 rédiges la formule suivante :

=SI(ESTNUM(A1);ENT((AUJOURDHUI()-A1)/365.25))

A la colonne B sera appliqué le format :

# ##0" ans"

Tirer la formule vers le bas pour calculer les âges de toute ta liste...

A+ Daniel

Bonjour Daniel,

Merci pour ta réponse, mais j'ai une obligation de passer par VBA..

Dan42153 a écrit :

Bonjour Emma,

Pas besoin de VBA :

Si ta première date de naissance est en A1, en B1 rédiges la formule suivante :

=SI(ESTNUM(A1);ENT((AUJOURDHUI()-A1)/365.25))

A la colonne B sera appliqué le format :

# ##0" ans"

Tirer la formule vers le bas pour calculer les âges de toute ta liste...

A+ Daniel

Bonjour,

j'ai une obligation de passer par VBA..

Cela n'a jamais rien d'obligatoire !

Au cas particulier, ce type de calcul se fait plus facilement par formule. Faire ce calcul au moyen d'une procédure VBA classique demeure par conséquent plus lourd et nettement moins optimal. Ce qui peut justifier l'utilisation de VBA, c'est avoir une formule moins longue et plus facile à mettre en oeuvre, soit une fonction personnalisée qui fait le calcul et la mise en forme qu'on souhaite.

Function AGE(dn, Optional aff As String = "a", Optional df)
    Dim d, hui, a%, m%, j%, agr$
    Application.Volatile
    On Error Resume Next
    If IsMissing(df) Then
        hui = Date
    Else
        hui = CDate(df)
        If CLng(hui) > 0 And CLng(hui) < 60 Then hui = hui + 1
    End If
    d = CDate(dn)
    If CLng(d) > 0 And CLng(d) < 60 Then d = d + 1
    If hui < d Then GoTo errdate
    On Error GoTo errdate
    a = DateDiff("yyyy", d, hui)
    If DateAdd("yyyy", a, d) > hui Then a = a - 1
    agr = a & IIf(a > 1, " ans", " an")
    If UCase(aff) = "M" Or UCase(aff) = "J" Then
        d = DateAdd("yyyy", a, d)
        m = DateDiff("m", d, hui)
        If DateAdd("m", m, d) > hui Then m = m - 1
        agr = agr & " " & m & " m."
        If UCase(aff) = "J" Then
            d = DateAdd("m", m, d)
            j = DateDiff("y", d, hui)
            agr = agr & " " & j & " j."
        End If
    End If
    AGE = agr
    Exit Function
errdate:
    AGE = CVErr(xlErrNA)
End Function

Tu peux essayer celle-ci, elle s'utilise comme les fonctions intégrées d'Excel : elle comporte un argument obligatoire et 2 optionnels.

Argument obligatoire : la date de naissance. Utilisée sans autre argument, la fonction affiche l'âge à la date d'aujourd'hui en ajoutant "ans" au nombre (ex.: 63 ans).

Le 2e argument (optionnel) permet un affichage plus complet : avec "m" (à mettre avec guillemets), affichage en années et mois (ex.: 63 ans 3 m.) ; et avec "j", en années, mois, jour (ex.: 63 ans 3m. 25j.)

Le 3e argument (optionnel) permet de calculer un âge, non plus à la date aujourd'hui mais à une date fournie. Ce qui de fait permet d'utiliser la fonction pour le calcul d'une durée entre 2 dates.

Cordialement

Ferrand

Edit : Oublié de signaler : elle n'est pas limitée par le 1/1/1900, elle calcule également sur des dates antérieures.

Bonjour MFerrand,

Merci pour ta réponse,

Pour le code je le met où? et comment lancer le programme? peux tu me mettre un fichier avec le code?

MERCI D AVANCE..

Emma :

Peut-être une précaution oratoire avant de tout boucler :

- si le code ou la formule retenu écrit dans la cellule une valeur alphanumérique ("33 ans" par exemple), il ne sera plus possible de faire des calculs sur l'âge : pas de moyennes, pas de tris fiables, pas de filtrages faciles, etc...

Du coup, quelque soit la solution adoptée, il sera souvent préférable d'utiliser un format de nombre personnalisé pour la colonne Age, ce qui permet de conserver une valeur numérique sur laquelle toutes ces fonctionnalités resteront possibles...

Espérant avoir aidé,

A+ Daniel

Comme tout code "standard", se place dans un module standard...

Voilà un classeur avec quelques exemples.

La remarque de Dan est exacte. Avec ce type de fonctions, on obtient une durée exprimée en valeur texte. Pour d'autres calculs, on repart de la date de naissance.

J'avais fait ça sur une demande, et j'avais l'intention de l'étoffer d'un certain nombre d'autres fonctions (que je n'ai pas trouvé le temps de faire, à part une petite calculant la date du prochain anniversaire).

Cordialement

87age.xlsm (16.88 Ko)

C'est très intéressant comme fonction, et elle présente le mérite d'être déjà écrite !

Ceci dit, c'est la première fois que je vois des âges exprimés d'une autre manière qu'en années révolues, c'est-à-dire sous forme d'un entier... Souvent, quand on a (réellement) besoin de connaître l'âge d'un individu, c'est son nombre d'anniversaires fêtés qui compte !

Le droit de voter, de conduire, de regarder certains films, etc...

Bon, après tout, cela doit bien être utile à quelqu'un, sans doute pas un gestionnaire, mais il n'y a pas que la gestion dans la vie !

C'est vrai qu'en général on se contente d'un entier...

quoique mes souvenirs d'enfance lors de fins de repas de famille (étendue) (après digestif) me font remonter des séquences complexes de calculs (mentaux) sur les âges des uns et des autres (détaillés, révolus ou non, ...), et ça s'enlisait parfois dans de multiples considérations...

Ceci dit tant qu'à faire une fonction, autant qu'elle puisse avoir une utilisation un peu plus étendue. Et ce type de calcul est courant pour les calculs d'ancienneté.

Salut !

Re,

Sur ta feuille l'age est calculé par des formules et non le code?! sinon je n'ai pas compris comment ça marche...

Si tu peux m’éclaircir stp.

MFerrand a écrit :

Comme tout code "standard", se place dans un module standard...

Voilà un classeur avec quelques exemples.

La remarque de Dan est exacte. Avec ce type de fonctions, on obtient une durée exprimée en valeur texte. Pour d'autres calculs, on repart de la date de naissance.

J'avais fait ça sur une demande, et j'avais l'intention de l'étoffer d'un certain nombre d'autres fonctions (que je n'ai pas trouvé le temps de faire, à part une petite calculant la date du prochain anniversaire).

Cordialement

Il s'agit d'une fonction personnalisée, soit une fonction écrite en VBA.

Son utilisation est identique aux fonctions intégrées d'Excel. Tu tapes un signe =, le nom de la fonction, les arguments. Et elle fournit un résultat.

Ah ok d'accord...

en fait je cherche à ce que la fonction soit appliqué automatiquement, ça veut dire que quand je rentre une date de naissance dans la colonne A par exemeple j'aurai automatiquement l'age en B. c'est possible?

merci encore.

MFerrand a écrit :

Il s'agit d'une fonction personnalisée, soit une fonction écrite en VBA.

Son utilisation est identique aux fonctions intégrées d'Excel. Tu tapes un signe =, le nom de la fonction, les arguments. Et elle fournit un résultat.

C'est un exercice imposé !

Je suppose que tu sais, dès lors que tu parles d'"automatisme", qu'il s'agit d'une action exécutée par l'application elle-même lorsqu'un évènement survient, déclenchée par une action de l'utilisateur (mais ce n'est pas l'utilisateur qui lance l'exécution de la macro.

Il te faut donc écrire la procédure évènementielle qui opèrera cette action "automatique". En as-tu déjà fait ?

Elle peut effectivement utiliser la fonction pour calculer le résultat.

Non je ne sais meme pas ce que ça veut dire sinon je sais pas si on peut intégrer ta formule dans un code où il teste si on a une date de naissance et il calcule automatiquement l'age? une macro qui s'execute tout le temps?

MFerrand a écrit :

C'est un exercice imposé !

Je suppose que tu sais, dès lors que tu parles d'"automatisme", qu'il s'agit d'une action exécutée par l'application elle-même lorsqu'un évènement survient, déclenchée par une action de l'utilisateur (mais ce n'est pas l'utilisateur qui lance l'exécution de la macro.

Il te faut donc écrire la procédure évènementielle qui opèrera cette action "automatique". En as-tu déjà fait ?

Elle peut effectivement utiliser la fonction pour calculer le résultat.

Et l'idée t'est venue comme ça ?

Je comprendrais pour réaliser un exercice d'entraînement à la réalisation de procédure évènementielle, sinon cela ne présente qu'un intérêt limité, reste contraignant et n'offre pas la souplesse d'utilisation autonome des fonctions...

Private Sub Worksheet_Change(ByVal Target As Range)
    If Target.Column = 1 Then
        With Target.Cells(1, 1)
            If IsDate(.Value) Then .Offset(0, 1).Value = AGE(.Value)
        End With
    End If
End Sub

Enfin, voilà ce que tu peux faire, par exemple.

Bonjour MFerrand,

Je te remercie infiniment, ça marche très bien.

J'ai 2 questions, est ce qu'on peut simplifier le code, il me parait un peu long.. etr je n'ai besoin que de la fonction qui permet d'afficher l'ange en "ans".

Et pour adapter le code à n'importe quel fichier, si je change par exemple de feuille ou de colonne pour les dates de naissance, faut modifier le code de ton dernier post ou le code de la fonction (module)?

merci encore.

La fonction renvoie toujour la valeur demandée.

La macro par contre et à réajuster chaque fois que tu changes de position.

(Quand je disais que ça manquait de souplesse....)

Re,

Je n'arrive pas à changer mon code pour que la date de naissance soit en colonne F et l'age s'affiche en I.

Voici mon code, c'est bien ça?

Private Sub Worksheet_Change(ByVal Target As Range)

If Target.Column = 1 Then

With Target.Cells(2, 6)

If IsDate(.Value) Then .Offset(0, 3).Value = AGE(.Value)

End With

End If

End Sub

Target étant la cellule modifiée :

tu dis : si Target est en A => je considère la cellule en B 5 lignes plus bas (soit si Target =A1, il s'agit de B6), si elle contient une date, j'inscris l'âge dans la cellule décalée de 3 colonnes (soit en E6 si B6 contient une date lorsque tu modifies la valeur de A1).

Je ne suis pas certain que ce soit ce que tu voulais faire.

Dans une évènementielle (surtout Change) :

1) On délimite la zone dans laquelle la procédure doit agir : soit en utilisant Intersect pour voir si le changement est dans la zone autorisée, soit en identifiant ligne ou colonne, soit une cellule précise.

1bis) [car peut selon le cas intervenir avant le 1] dans la plupart des cas on définit une action pour un changement affectant une seule cellule, et si la plage modifiée comporte plusieurs cellules, voire une colonne ou une ligne entière, le résultat risque d'être inattendu, donc si plusieurs cellules sont concernées soit on met fin à la procédure sans agir, soit on annule carrément la modification ayant touché plusieurs cellules et on ne fait rien d'autres [ces deux réponses se situent généralement en préalable avant le 1], ou bien dans le cas où même si plusieurs cellules sont concernées, il n'y a pas de risque à intervenir sur la cellule active, il n'est alors même pas utile de savoir si plusieurs cellules sont touchées, on limite l'intervention à Target.Cells(1, 1), cellule supérieure gauche de la plage affectée et normalement cellule active.

2) C'est logiquement, sauf cas particuliers, la cellule modifiée que l'on teste pour savoir si la modification apportée permet l'action prévue. Au cas particulier, il faut savoir s'il s'agit d'une date (s'il s'agit d'autre chose, on n'intervient pas, ou on annule si on a prévu que rien d'autre ne devait figurer à cet emplacement)

3) Action prévue si la condition le permet : à l'emplacement qu'on souhaite (défini en général par rapport à la cellule modifiée dont on connait l'emplacement).

Cordialement

RE,

Merci bcp je comprends mieux maintenant. Mais le code ne s’exécute que si on a modifié la colonne des dates. Pour les dates existante le calcule ne se fait pas. Peut-on régler ce problème.

Rechercher des sujets similaires à "clacul vba"