Voir le flux RSS

Pierre Fauconnier

VBA: Convertir du texte en date (1)

Noter ce billet
par , 16/10/2019 à 09h00 (141 Affichages)
Salut.

On lit de ces horreurs, parfois, sur nos forums.

A propos des dates, par exemple, j'ai lu dans une discussion que "l'anglophonisme de VBA a de grande chance de transformer le 3 février en 2 mars et réciproquement" (sic)... Wouah, voilà que transformer du texte en date est une question "de chance"...

Dans une autre, je lis que "les dates et les TextBox [...], ça ne fait pas bon ménage. A moins de prendre de grandes précautions, c'est la cata garantie." Houlà, mais ça va faire fuir les gens, ce genre de trucs... Au secours, on ne sait pas gérer les dates saisies dans des textbox...

Allons allons, un peu de sérieux s'il vous plait. Qu'est-ce qu'il ne faut pas lire. La programmation, ce n'est pas une question de chance, et il est légitime de douter qu'il soit si compliqué de transformer du texte en date, pour autant bien sûr que la saisie n'ait pas été ésotérique. Je ne parle pas ici de tentatives, évidemment infructueuses, de pouvoir transformer n'importe quoi en date comme je l'ai vu sur le forum Excel/Contribuez, mais bien d'une approche rigoureuse de la transformation d'une saisie textuelle supposée correcte en date.

Préambule

Avant d'approcher les deux fonctions qui vont nous aider à réaliser ce transtypage sans problèmes, il est utile de s'intéresser aux paramètres régionaux et à la façon dont VBA les comprend et les gère.

Il y a plusieurs formats de saisie selon que l'on souhaite 1 ou 2 chiffres pour les valeurs inférieures à 10 relatives aux jours et aux mois, et il faut compter sur la possibilité de saisir l'année sur 2 ou 4 chiffres. Mais il y a aussi, plus important pour nous, la séquence de saisie. VBA (et les paramètres régionaux) reconnaissent 3 séquences possibles:
  1. m/d/y, mois - jour - année;
  2. y/m/d, année - mois - jour;
  3. d/m/y, jour - mois - année.


En se positionnant sur la séquence définie par les paramètres régionaux, VBA va tester les trois séquences dans l'ordre ci-dessus. Cela signifie que, pour "notre" paramètre régional continental d-m-y, VBA va tester les séquences dans l'ordre d-m-y => m-d-y => y-m-d. Si les paramètres régionaux utilisent la séquence m-d-y, VBA va tester m-d-y => y-m-d => d-m-y.

Un petit exemple?

Avec la séquence d-m-y dans les paramètres régionaux, "13/12/30" est considéré comme le 13 décembre 1930. Avec m-d-y comme paramètres régionaux, "13/12/30" est considéré comme le 30 décembre 2013, car m-d-y ne fonctionnant pas (pas de mois n° 13), VBA utilise la séquence suivante dans sa liste, soit y-m-d.


Test de date et conversion

Note: Ce qui suit s'appuie sur des paramètres régionaux utilisant la séquence d-m-y.

Convertir une date s'effectue en utilisant la fonction CDate(Value) qui renvoie... une date . Encore faut-il que la saisie puisse être interprétée comme telle, car dans le cas contraire, la fonction lèvera une exception 13 - incompatibilité de type.

Nom : 2019-10-14_194640.png
Affichages : 40
Taille : 7,5 Ko



Pour tester, nous avons la fonction IsDate(Value) qui va tester que Value est une date ou est susceptible d'être transformée en date.

Test Valeur Commentaire
isdate("Pierre") Faux Pierre ne peut évidemment pas être converti en date
isdate("02/03/19") Vrai VBA considère la séquence d-m-y, celle des paramètres régionaux => 02 mars 2019
isdate("12/30/19") Vrai la séquence d-m-y n'est pas bonne, Excel essaie avec la séquence m-d-y => 30 décembre 2019
isdate("80/12/30") Vrai d-m-y et m-d-y ne fonctionnent pas, VBA essaie avec la séquence y-m-d => 30 décembre 1980
isdate("80/30/12") Faux Aucune séquence ne fonctionne, la saisie n'est pas une date

La conversion avec CDate fonctionne de la même façon, en interprétant les dates selon le schéma des séquences vu plus haut. En tenant compte que la saisie est effectuée selon les paramètres régionaux, ce qui me semble cohérent, on peut donc convertir du texte en date grâce au test avec IsDate puis, s'il valide la saisie, à la conversion avec CDate. On réalisera bien entendu cela dans une fonction perso que l'on sauvegardera dans son module Tools:
Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
Function StringToDate(Value As String) As Date
  If IsDate(Value) Then StringToDate = CDate(Value)
End Function

Il ne faut pas utiliser CDate sans avoir testé avant avec IsDate, car comme nous l'avons vu, cela pourrait lever une exception, déroutant le process du processeur vers le gestionnaire d'exception. La tentation serait grande alors de contourner cela avec un On Error... (une sorte de Try Catch Finally à la VBA), mais c'est pour moi une mauvaise approche: On ne programme pas par la gestion des exceptions. Cette possibilité de gérer l'exception est uniquement là pour tout ce que l'on ne peut gérer autrement. Or, on peut prévoir l'exception éventuellement levée par CDate, et la contourner, en utilisant IsDate.

Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Viadeo Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Twitter Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Google Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Facebook Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Digg Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Delicious Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog MySpace Envoyer le billet « VBA: Convertir du texte en date (1) » dans le blog Yahoo

Mis à jour 16/10/2019 à 12h56 par Pierre Fauconnier

Catégories
VBA , MS Office

Commentaires