I have Date and Time in one cell and I need to extract the decimal that excel uses for the time so that I can subtract time from that.
A cell has this value: 01.09.2020 7:01:21
I need to get the time 7:01:21
and then I need to extract the decimal which represents it, that is: 0,292604166666667 and store it in a variable in vba
I searched the internet extensively but everyone wants to do exactly the opposite and I am totally clueless.
Thank you for your help
Ok, I worked it out.
I am not entirely happy with the solution but it works. I am sure some of you guys can come up with a more elegant solution without having to use the variable.
Mine is this:
Dim NumericTime as Double
NumericTime = TimeValue("A1")
Debug.Print NumericTime
With data in A1, in C1 enter:
=TIMEVALUE(MID(A1,FIND(" ",A1)+1,99))
To extract a decimal, simply:
=MOD(A1,1)
Be sure to format the results as General or as Number with an appropriate number of decimal places
In VBA, the Mod function doesn't work with decimals, so the equivalent might be:
Function DecimalTime(tm As Date) As Double
DecimalTime = tm - Int(tm)
End Function
Related
The Problem:
I got two timestamps in Excel (German version) in this format:
2023-01-28-10.14.20.123456
2023-01-29-11.15.21.123456
and I need the difference of these two timestamps in seconds - which would be 90061.
What I tried:
To define a custom format for the timestamp:JJJJ-MM-TT-hh.mm.ss
To define a custom format for the timestamp:JJJJ-MM-TT-hh.mm.ss.000000 but I cannot define the .000000 for the nanoseconds because I get an Excel error that this format cannot be used
To use following formula =TEXT(D6-C6;"[mm]")
I tried to use the formula in this post which translates to =DATWERT(LINKS(C6;10))+ZEITWERT(TEIL(C6;12;8))-DATWERT(LINKS(D6;10))+ZEITWERT(TEIL(D6;12;8))
Nothing worked so far - any hints are appreciated - Thanks in advance
Or, a slightly shorter formula
i.e.
=86400*(VALUE(REPLACE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A3,"-","/"),".",":",1),".",":",1),11,1," "))-VALUE(REPLACE(SUBSTITUTE(SUBSTITUTE(SUBSTITUTE(A2,"-","/"),".",":",1),".",":",1),11,1," ")))
or, auf Deutsch
=86400*(WERT(ERSETZEN(WECHSELN(WECHSELN(WECHSELN(A3,"-","/"),".",":",1),".",":",1),11,1," "))-WERT(ERSETZEN(WECHSELN(WECHSELN(WECHSELN(A2,"-","/"),".",":",1),".",":",1),11,1," ")))
(changing the UI language doesn't update the , with ; though)
So, brutally long, but works based on what you gave.
I assume that that format and the number of characters will not change.
((LEFT(A3,10)-LEFT(A2,10))*86400)+(HOUR(TIME(MID(A3,12,2)-MID(A2,12,2),MID(A3,15,2)-MID(A2,15,2),MID(A3,18,2)-MID(A2,18,2)))*3600)+(MINUTE(TIME(MID(A3,12,2)-MID(A2,12,2),MID(A3,15,2)-MID(A2,15,2),MID(A3,18,2)-MID(A2,18,2)))*60)+(SECOND(TIME(MID(A3,12,2)-MID(A2,12,2),MID(A3,15,2)-MID(A2,15,2),MID(A3,18,2)-MID(A2,18,2))))+((MID(A3,21,6)-MID(A2,21,6))*1000)
One way to reduce it is to put the time calculation used in hour, minute and second into a separate cell.
I am using VBA to compare two times from a spreadsheet.
Im my example the actual value form the sheet is 23:00 in two cells. I use them for an if-statement, the values both come from two different arrays from the type Variant.
if dataArr(v1) = rowArr(v2) Then
If I debug the two values it shows the two value like this
0,958333333333333 / 0,958333333333333
They seem the same but the compare in the if-statement returns false
So I subtracted the two value to see if the result is zero.
dataArr(v1) - rowArr(v2)
In this case the result is not zero but
3,33066907387547E-16
So something is wrong with the compare or the two double values that represent the time.
The only working solution I found was to convert them to string values by
CStr(dataArr(v1)) = CStr(rowArr(v2))
which returns true as it should be.
I don't really like this solution because it is not really how it should work. I also investigated what happens to the values before they end up in the compare but I could not find any mistake . Actually all the values in the dataArr are coming from the spreadsheet (ListObject.DataBodyRange.Value) and then certain values are copied to the rowArr out of the dataArr so it really should be the same value.
Any suggestions? Thanks!
If the cells are actually formatted for time instead of a string, I would make the definition of my arrays a "Date" not a "Variant".
Then you would have all the date/time related functionality in VBA at your disposal (like DateDiff() ).
Sometimes floating point inaccuracies creep in. If you want to compare then take the Absolute Value (ABS) of the subtraction and see if it is below a tolerance level, say, 1E-7 (a millionth).
Thanks to Florent B I got a solution that works!
Florent B: To compare the equality of two dates, you need to round to the precision which is 24hrs x 60min x 60 sec
So the solution is:
If Round(dataArr(v1) * 86400) = Round(rowArr(v2) * 86400) Then
It makes perfektly sense. Thanks a lot!
What is the best way to find the right column for the travelled miles using visual basic coding or some excel function and return the price from that column? HLOOKUP can't be used here because the lookup value isn't exact and the ranges in the table are also not with specific intervals (If they were, I could use e.g. FLOOR(travelled miles/100)*100 and find the price with HLOOKUP). Obviously, it's easy to find the price manually with a small table but with a big table computer will be faster.
Note that, if x is between a and b, then MEDIAN(x,a,b)=x. Combine this with some nested IFs:
=IF(MEDIAN(B5,B1,C1-1)=B5,B2,IF(MEDIAN(B5,C1,D1-1)=B5,C2,IF(MEDIAN(B5,D1,E1-1)=B5,D2)))
I'm on my phone, so just done the first three cases, but hopefully you can see how it continues.
(should note you need to remove the dashes for this to work)
Edit:
I also want to answer your question in the comments above. You can use the following to keep the dash, but get a number to work with.
Assume cell A1 has got the value 10-. We can use the FIND function to work out where the - occurs and then use the LEFT function to only return the characters from before the dash:
=LEFT(A1,FIND("-",A1)-1)
This will return the value 10, but it will return it as a string, not a number - basically Excel will think it is text. To force Excel to consider it as a number, we can simply multiply the value by one. Our formula above therefore becomes:
=(LEFT(A1,FIND("-",A1)-1))*1
You may also see people use a double minus sign, like this:
=--LEFT(A1,FIND("-",A1)-1)
I don't recommend this because it's a bit complex, but combining with the formula above would give:
=IF(MEDIAN(B5,--LEFT(B1,FIND("-",B1)-1),--LEFT(C1,FIND("-",C1)-1)-1)=B5,B2,IF(MEDIAN(B5,--LEFT(C1,FIND("-",C1)-1,--LEFT(D1,FIND("-",D1)-1-1)=B5,C2,IF(MEDIAN(B5,--LEFT(D1,FIND("-",D1)-1,--LEFT(E1,FIND("-",E1)-1-1)=B5,D2)))
I have the following Excel code:
=IF(K4<=31/03/2014,TRUE,FALSE)
K4 contains a date:
01/01/2014
Yes, the code brings back FALSE, I have also tried =IF(K4<="31/03/2014",TRUE,FALSE) but with the same result.
Any ideas or suggestions as to where I am going wrong?
Use
=IF(K4<=DATE(2014,3,31),TRUE,FALSE)
You are testing an inequality with a Float <= String, which returns FALSE. The DATE(,,) fx gives you the required Float for equality comparison.
Alternatively, =K4<=DATE(2014,3,31) is a shorter way of achieving the same.
What K4<=31/03/2014 evaluates to is:
K4 <= (31/03)/2014
31/03 gives 10.333... and that divided by 2014 gives 0.005131... which is why it will always evaluate to false (01/01/2014 is equivalent to 41640, i.e. the number of days since '00/01/1900')
I don't know if it's a system thing, but =IF(K4<="31/03/2014",TRUE,FALSE) gives me TRUE, but then, so does =IF(K4<="31/03/2013",TRUE,FALSE).
A quick and dirty trick would be to multiply the string by 1:
=IF(K4<="31/03/2014"*1,TRUE,FALSE)
The multiplication tells excel to convert the string to a number, if it is parsable (You can also use any other numerical operation that doesn't change the value itself, such as +0).
Note: Excel dates and numbers are the same. Dates are just formatted differently so that a number with a specific format can appear as a date, time, or any other format you can have.
Also, if you really are using this IF construct, you are better of simply using the comparator:
=K4<="31/03/2014"*1
I had the same problem and found that excel was not recognizing one of my 2 columns as a date. (Try changing the date format to 14-Mar-12 to see if this is the case for you)
I am currently trying to convert yyyymmdd type of date to a ddmmyyy format.
I've tried using DATE function and something like this:
=DATE(LEFT(A3;4);MID(A3;5;3);RIGHT(A3;7))
Original date for this function is 20120401 but the formula returns: 16.12.2104.
I've tried using functions YEAR, MONTH and DAY instead of LEFT, MID and RIGHT but that's not the right way.
I also tried using DATEVALUE but since Excel probably doesn't recognize yyyymmdd as a date, it gives me a #VALUE! error.
I've found a couple of solutions for SQL but it isn't my strong side yet - and this should be achievable easily in Excel.
Is there a way to do this in Excel?
Applying =DATE(LEFT(A3;4);MID(A3;5;3);RIGHT(A3;7)) to 20120401 in A3 is effectively to reassemble the component characters as below on the left:
These effectively become converted as on the right.
The solution was simply to exclude the digits highlighted red with:
=DATE(LEFT(A3;4);MID(A3;5;2);RIGHT(A3;2))
but the locale might have been a factor and when dealing with date serial numbers and/or what appears to be a date but is a string various other issues might have been involved.
Consider:
=DATE(LEFT(A1,4),MID(A1,5,2),RIGHT(A1,2))