Variables identiques mais pas égales

Salut,

Je suis tombé sur quelque chose de curieux....

Dans une cellule j'ai une date en texte au format jj/mm/aaaa hh:mm:ss. Je la convertis en valeur numérique avec la fonction DateSerial et j'extrais le jour en prenant la partie entière et l''heure (00:30:00 dans ce cas) en prenant la partie décimale et je mets cette heure dans la variable HeureAReporter

J'ai un tableau avec la journée sur les lignes et les heures dans les colonnes, 00:30 dans ce cas, cette heure est mise dans la variable HeureTable...

Pour savoir dans quelle case du tableau je dois reporter ma valeur je compare les 2 variables mais le test ressort négatif

sans titre

En creusant un peu, même si les heures sont les mêmes, définies à partir des mêmes données (00:30:00 dans chaque cas) les valeurs numériques sont différentes : 0.02083333333576 pour la variable HeureAReporter et 0,02083333333333 pour la variable HeureTable.

C'est une simple division (1/1440 x 30), pourquoi est ce qu'il y a une différence ? Elle est insignifiante, c'est très loin de fausser l'heure ne serait ce que d'une seconde, mais ça fait quand même planter les comparaisons

Manu

Bonjour,

Si vous pouviez partager votre fichier source et le code VBA pour regarder. C'est peut-être dû à une conversion de type. C'est aussi probable que cela vienne de vos données d'entrées qui "semblent" égales mais ne le sont pas.

TLDR :

En général il est préférable de passer par les fonctions VBA Hour, Minute et Second ainsi que Year/Month/Day pour travailler avec des dates, plutôt que d'utiliser des opérateurs mathématiques sur les valeurs brutes.

Le pourquoi :

Dans Excel (comme dans de nombreux programmes informatiques) les dates sont stockées sous forme de nombre donc on peut avoir envie de "sauter" certaines étapes pour faire des vérifications qui paraissent simples (égalité, différences, etc.) mais c'est un risque. Le nombre contenant votre Date+Horaire n'a qu'un espace mémoire limité qui lui est alloué, et donc puisque la partie horaire est stockée dans la partie décimale du nombre, cela veut dire que toutes les secondes ne peuvent pas être parfaitement représentées/"uniques" (les fractions ne tombent pas toutes "juste" => nombres irrationnels).

La solution :

Les fonctions VBA listées plus haut sont là pour pallier ce problème : elles vous permettent d'extraire des infos fiables de vos nombres. Ainsi pour tester une égalité horaire vous devez regarder Hour(val1)=Hour(va2) et de même pour minutes et secondes. Cela vous résoudra automatiquement votre problème. C'est un peu plus long à écrire mais c'est la méthode courante en programmation.

Alternativement si vous êtes vraiment à fond dans la performance vous pourriez comparer Abs(val1-val2) < ε (avec ε petit du type 1E-8) mais on perd en lisibilité.

" C'est aussi probable que cela vienne de vos données d'entrées qui "semblent" égales mais ne le sont pas. "

J'ai creusé un peu plus. Les données viennent du téléchargement de ma conso électrique sur le site d'Enedis où l'heure est en texte au format jj/mm/aaaa hh:mm:ss. Je la convertis en valeur numérique en extrayant, avec une combinaison de Left et Right, chaque valeur jour, mois, année, heure et minute que je recombine avec DateAComparer = DateSerial(Année, Mois, Jour) + Heures / 24 + Minutes / (1440).

Dans mon cas la date est 06/12/2024 00:30:00, ce que DateSerial(2025, 12, 06) + 0/24 + 30/1440 calcule à 45632.0208331597 en valeur numérique. Le problème vient du fait que 30/1440 ça fait 0.0208333333 et pas 0,208331597. Par contre si je saisis manuellement 06/12/2024 00:30:00 dans la cellule la valeur numérique est bien 45632.0208333333 comme attendu.

La Fonction DateSerial ne donne pas la même valeur qu'une saisie manuelle.

Et pire, pour créer le tableau qui me permet de faire un graphique journalier (une ligne par jour et une colonne par heure) je reprends la date enregistrée dans la cellule, j'en extrais le jour par un DateAReporter = WorksheetFunction.RoundDown(Valeur de la cellule où est stockée la date, 0).

Dans mon cas, c'est la capture d'écran de l'espion du premier post, DateAReporter est bien de 45632 comme prévu mais HeureAReporter est 0.02083333333576 au lieu de 0.0208331597.

A partir d'une seule donnée d'entrée VBA abouti à 2 valeurs différentes, qui sont elles mêmes différentes de la valeur attendue.

Bref, je vais arrondir les valeurs à la deuxième décimale. Il n'y aura plus d'écart entre les données calculées et les données saisies (j'ai testé, 30 minutes c'est arrondi à 0,02 ou 0,03), mais c'est quand même hallucinant que VBA ne puisse pas calculer correctement 30/1440.

Manu

bonjour Manu31, salut Saboh12617 ,

il faut arrondir vers & utiliser le format "hh:mm:ss" pour les demie-heures, voir PJ

5manu31.xlsb (19.50 Ko)

Bonjour à tous,

Oui, comme le dit @BsAlv et comme vous l'avez remarqué, il faut passer par des arrondis/troncature si vous souhaitez travailler avec les valeurs "brutes". Mais attention, plus il y a d'opérations et plus les erreurs s'accumulent…

Pour info vous devriez regarder du coté de PowerQuery, a mon avis votre "workflow" actuel pourrait passer par une requête, et pas besoin de VBA. En plus, vous obtiendrez un tableau structuré donc le graph correspondant s'actualiserait automatiquement.

Bonjour

Pour info vous devriez regarder du coté de PowerQuery, a mon avis votre "workflow" actuel pourrait passer par une requête

Je confirme : je traite mes propres relevés Enedis par PowerQuery...

Bonjour,

Je commence par dire que je suis sur smartphone et que je ne peux pas ouvrir le fichier. Je vais donc peut-être répondre à côté de la plaque...

Tu dis que tu utilises les f9nctions gauche(), droite(). À savoir que ces fonctions retournent une valeur au format texte. Faire ensuite un calcul dessus n'est donc pas glop.

Par défaut quand je me sers de ces fonctions pour retourner des valeurs numériques au format numérique je fais * 1 sur le résultat de ces fonctions.

À voir.

Rechercher des sujets similaires à "variables identiques pas egales"