2016-02-18 15 views
6

Ieri sera mi sono imbattuto in qualcosa che mi ha fatto impazzire per un buon dieci, quindici minuti prima che me ne rendessi conto. Ma non capisco perché è così, quindi spero che qualcuno qui possa chiarire.Uscita di formato da una stringa

Dalla finestra immediata in VBA:

?Format(0.5, "HH:MM AM/PM") 
12:00 PM 
?Format("0.5", "HH:MM AM/PM") 
12:05 AM 
?Format(CDbl("0.5"), "HH:MM AM/PM") 
12:00 PM 

Da this page vedo che 0,5 dovrebbe corrispondere al 12:00, dal momento che uno ora è 0,04,166 mila ... ((12 * (1/24) = 0.5)). E come puoi vedere, lo fa se passo un numero a Format() ma non se passo lo stesso numero di una stringa.

Per le informazioni dalla stessa pagina, 1 minuto è 0.00069444 ... ((1/(24*60))), ovvero le 12:05 devono essere memorizzate in Excel come 0,003472222 ((0 * (1/24)) + (5 * (1/(24*60)))). E, in effetti:

?Format(0.003472222, "HH:MM AM/PM") 
12:05 AM 

Alcune altre stranezze non capisco:

?Format(2.5, "HH:MM AM/PM") 
12:00 PM 
?Format("2.5", "HH:MM AM/PM") 
02:05 AM 

Ma ...

?Format(2.523, "HH:MM AM/PM") 
12:33 PM 
?Format("2.523", "HH:MM AM/PM") 
12:33 PM 

Tutto ciò che posso trovare nella documentazione dice che "I tempi sono memorizzato come parte di un numero reale.I valori a destra del decimale rappresentano l'ora.Ad esempio, mezzogiorno (12:00 PM) è rappresentato da 0.5. " (Dal glossario VBE incorporato in Excel 2010) Quindi 2.5 dovrebbe risultare in un orario di 12:00 poiché la parte a destra del decimale è 0.5 e 2.523 dovrebbe risultare in 12:33 PM dal 0.523 = (12 * (1/24)) + (33 * (1/(24*60))). Ma VBA restituisce solo il risultato corretto per uno di questi.

Così qualcuno può spiegare perché VBA mostra ciò che sembra essere un comportamento incoerente? O c'è qualche ruga che mi manca?

Questo è stato testato in Excel 2010 e il 2013.

+1

E questo è il motivo per cui i tipi espliciti sono importanti e lasciando VBA fanno conversioni implicite per voi, rende la lingua un headscratcher per tante persone. Bel post! –

risposta

4

si aspetta Format convertire 0,5 a un doppio, ma non è così. Secondo https://msdn.microsoft.com/en-us/library/ee198964.aspx, la stringa da Data conversione implicita let va

  • Se è una data/ora, il tempo, o la data (in questo ordine), convertirlo in una data.
  • Se è nell'intervallo di un doppio, convertirlo in un doppio quindi in una data.
  • Se nessuno di questi, restituisce un errore.

Poiché non sta convertendo in un doppio, deve essere convertito sul primo punto. E questo è. Supponendo che "0.5" sia un tempo. Secondo https://msdn.microsoft.com/en-us/library/dn528865.aspx, un punto decimale è un separatore di tempo valido.

time-separator = *WSC (":"/".") *WSC 
+0

Link eccellenti che spiegavano perfettamente il comportamento che stavo vedendo, grazie! –

2

La differenza è che si sta chiedendo VBA per formattare un Double e String. Ti aspetti che VBA interpreti il ​​valore della stringa allo stesso modo del doppio valore.

Se si dispone di una stringa che rappresenta la mezzanotte, può essere 12:00 AM o 00:00 (nel formato 24 ore). VBA sta interpretando il separatore come : o . nello stesso modo. Quindi, per un String formattato per rappresentare cinque minuti dopo la mezzanotte, è possibile scrivere 12:05 AM, 00.05, 0.5, 0:05 o 0:5. Guarda anche la funzione CDATE.

Tutte le corde, una volta convertito in Double dare lo stesso risultato:

?Cdbl(CDate("00.05")) 
3.472222222222222E-02