Fonction IsDate renvoie des résultats inattendus
Comment se IsDate("13.50")
retourne True
mais IsDate("12.25.2010")
retourne False
?
Vous devez vous connecter pour publier un commentaire.
Comment se IsDate("13.50")
retourne True
mais IsDate("12.25.2010")
retourne False
?
Vous devez vous connecter pour publier un commentaire.
Je suis fauché par une petite "feature" récemment et je voulais sensibiliser à certaines des questions entourant la
IsDate
fonction en VB et VBA.Le Cas Simple
Que vous vous attendez,
IsDate
retourneTrue
lorsqu'il est passé d'un type de données Date etFalse
pour tous les autres types de données à l'exception des Cordes. Pour les Cordes,IsDate
retourneTrue
ouFalse
basé sur le contenu de la chaîne:IsDateTime?
IsDate
devrait être plus justement nomméIsDateTime
parce qu'elle renvoieTrue
pour les chaînes formatées que les temps:Remarque sur les deux derniers exemples ci-dessus que
IsDate
n'est pas parfait validateur de fois., Gotcha!
Non seulement
IsDate
accepter de fois, il accepte à la fois dans de nombreux formats. L'une de qui emploie une période (.
) comme séparateur. Cela conduit à une certaine confusion, parce que la période peut être utilisé comme un séparateur de temps, mais pas un séparateur de date:Cela peut être un problème si vous êtes l'analyse d'une chaîne et d'exploitation sur elle repose sur son type apparent. Par exemple:
Les Solutions De Contournement
Si vous testez une variante pour les sous-tendent ce type de données, vous devez utiliser
TypeName(Var) = "Date"
plutôt queIsDate(Var)
:Si, toutefois, vous traitez avec des chaînes qui peuvent être des dates ou des nombres (par exemple, l'analyse d'un fichier texte), vous devriez vérifier si c'est un numéro avant de vérifier pour voir si c'est une date:
Même si tout ce qui vous intéresse est de savoir si c'est une date, vous devriez assurez-vous que ce n'est pas un nombre:
Particularités de la fonction CDate
Comme @Deanna souligné dans les commentaires ci-dessous, le comportement de
CDate()
est pas fiable ainsi. Ses résultats varient selon qu'il s'est passée une chaîne de caractères ou un nombre:De fuite et des zéros sont significatifs si un nombre est passé comme une chaîne de caractères:
Le comportement change aussi que la partie décimale d'une chaîne approches les 60 minutes de marque:
La ligne de fond est que si vous avez besoin de convertir des chaînes de date/heure vous devez être au courant de ce format vous vous attendez à être et puis de le re-formater de façon appropriée avant de compter sur
CDate()
pour les convertir.?cdate("0.59") = 00:59:00
?cdate("0.60") = 14:24:00
Tard pour le jeu ici (mwolfe02 répondu à cette question, il y a un an!) mais le problème est réel, il existe d'autres approches qui mérite d'être examiné, et StackOverflow est l'endroit pour les trouver: voici donc ma propre réponse...
Je suis fauché par VBA.IsDate() sur cette question il y a quelques années, et codé en place d'une étendue pour couvrir les cas que VBA.IsDate() gère mal. Le pire est que les flotteurs et les nombres entiers return FALSE de IsDate, même si la date de périodiques sont souvent transmis en Double (pour le type DateTime) et les Entiers Longs (pour les dates).
Un point à noter: votre mise en œuvre ne nécessite pas la possibilité de vérifier le tableau des variantes. Sinon, n'hésitez pas à dépouiller le code dans le bloc indenté qui suit
Else ' Comment this out if you don't need to check array variants
. Cependant, vous devez être conscient que certains systèmes tiers (y compris en temps réel des données de marché les clients) le retour de leurs données dans des tableaux, même de simples points de données.Plus d'informations dans les commentaires de code.
Voici le Code:
Une Astuce pour les gens toujours à l'aide d'Excel 2003:
Si vous (ou vos utilisateurs) vont appeler IsDateEx() à partir d'une feuille de calcul, mettre ces deux lignes, immédiatement au-dessous de la tête de la fonction, à l'aide d'un éditeur de texte dans un exportés .fichier bas et la réimportation du fichier, car VB Attributs sont utiles, mais ils ne sont pas accessibles à l'éditeur de code dans Excel VBA IDE:
C'est sur une seule ligne: attention aux sauts de lignes insérées par le navigateur! ...Et cette ligne, qui met isDateEX dans l'Assistant fonction dans les "Informations" de la catégorie, aux côtés de ISNUMBER(), ISERR(), ISTEXT() et ainsi de suite:
Utilisez le "w\n2" si vous préférez le voir sous le Jour & fonctions de Temps: bat l'enfer outta perdre dans le bourbier de l' "Utilisé Défini" les fonctions à partir de votre propre code, et tous ceux des tiers add-ins développés par des gens qui ne font pas assez assez pour aider les utilisateurs occasionnels.
Je n'ai aucune idée si cela fonctionne encore dans Office 2010.
en outre, vous pourriez avoir besoin de la source pour ArrayDimensions:
Cette API déclaration est requise dans l'en-tête du module:
...Et voici la fonction elle-même:
Veuillez garder les remerciements dans votre code source: alors que vous progressez dans votre carrière en tant que développeur, vous allez apprécier vos propres cotisations d'être reconnu.
Aussi: je vous conseille de garder cette déclaration privé. Si vous devez faire un public Sub dans un autre module, insérez le
Option Private Module
instruction dans l'en-tête du module. Vous vraiment ne voulez pas que vos utilisateurs d'appeler une fonction avec CopyMemoryoperations et l'arithmétique des pointeurs.