I've got following data as result from a query. As example 2 rows but in total around 30000 rows.
Some timestamps are empty because no row in that table.
agr_no
timestamp1
timestamp2
timestamp3
00000080064
2005-08-17-09.29.01.427337
2005-08-17-09.29.01.351888
00000080065
2002-04-29-15.04.58.714606
2013-11-18-13.11.46.494690
I would like to have in the next column an indication about which timestamp is the greatest.
For example:
agr_no
timestamp1
timestamp2
timestamp3
Result
00000080064
2005-08-17-09.29.01.427337
2005-08-17-09.29.01.351888
TS1
00000080065
2002-04-29-15.04.58.714606
2013-11-18-13.11.46.494690
TS3
Tried many things but always in trouble with the format of the timestamp so no comparison is possible.
Thanks a lot.
This is quite ugly but,
You can convert your values to dates and then just take the max date, or in this instance, the index of the matched date.
="TS" & MATCH(MAX(IFERROR(DATEVALUE(LEFT(A2:C2,10))+TIME(MID(A2:C2,12,2),MID(A2:C2,15,2),MID(A2:C2,18,2)+(RIGHT(A2:C2,6)/1000)),0)),IFERROR(DATEVALUE(LEFT(A2:C2,10))+TIME(MID(A2:C2,12,2),MID(A2:C2,15,2),MID(A2:C2,18,2)+(RIGHT(A2:C2,6)/1000)),0),0)
Note this assumes the formats of the string dates are either blank OR in strictly in the below format which is consistent with the limited inputs you gave us
yyyy-mm-dd.hh.mm.ss.######
FYI - Your milliseconds value is strange. On your first row the milliseconds actually equates to minutes
Assuming your data is located at [A1:D27] and based on this formula to convert the string TimeStamp to a double:
= IFERROR( VALUE( SUBSTITUTE( SUBSTITUTE( SUBSTITUTE( B2,
"-", " ", 3 ), ".", ":" ), ":", ".", 3 ) ), 0 )
Enter this FormulaArray in E2, then copy E2 downwards till last row:
= "TS" & MATCH( MAX(
IFERROR( VALUE( SUBSTITUTE( SUBSTITUTE( SUBSTITUTE( B2:D2,
"-", " ", 3 ), ".", ":" ), ":", ".", 3 ) ), 0 ) ),
IFERROR( VALUE( SUBSTITUTE( SUBSTITUTE( SUBSTITUTE( B2:D2,
"-", " ", 3 ), ".", ":" ), ":", ".", 3 ) ), 0 ), 0 )
FormulaArray are entered holding down ctrl+shift+enter simultaneously, the formula would be wrapped within { and } if entered correctly.
Related
I got some data in Excel and most of them are in the format of hh:mm:ss. So I can use the formula like "=HOUR(A2)*3600 + MINUTE(A2)*60 + SECOND(A2)" to convert it.
But this does not work for the dd:hh:mm:ss format, since day() function does not work like hour()/minute()/second() here. Could anyone help me?
In Excel, time is expressed as days and fractions of a day.
There are 86400 seconds in one day.
It appears that your data is all text.
Text strings that include the dd parameter will not convert automatically; without that, it will as the result any mathematical operation.
So you can test for the error to treat the dd formatted strings differently
Multiply the value by 86400 => number of seconds
If there is an error, use LEFT to extract the dd portion; MID to extract the time portion; then add them together and multiply the summation by 86400.
Try:
=IFERROR(A14*86400,(LEFT(A14,FIND(":",A14)-1)+ MID(A14,FIND(":",A14)+1,99))*86400)
(If you want whole seconds, you can wrap the formula in a ROUND or INT function)
=IF(LEN(A2)-LEN(SUBSTITUTE(A2;":";""))=3;DAY(LEFT(A2;SEARCH(":";A2)-1))*24*3600+HOUR(RIGHT(A2;LEN(A2)-SEARCH(":";A2)))*3600+MINUTE(RIGHT(A2;LEN(A2)-SEARCH(":";A2)))*60+SECOND(RIGHT(A2;LEN(A2)-SEARCH(":";A2)));HOUR(A2)*3600+MINUTE(A2)*60+SECOND(A2))
OPTION WITH ALL DECIMALS: When you use SECOND, you are ignoring all decimals, that's why values like 12.9883 are being rounded to 13 seconds. If you need all decimals, you can do:
=IF(LEN(A1)-LEN(SUBSTITUTE(A1;":";""))=3;DAY(LEFT(A1;SEARCH(":";A1)-1))*24*3600+VALUE(RIGHT(A1;LEN(A1)-SEARCH(":";A1)))*24*60*60;VALUE(A1)*24*60*60)
And your output will be this:
As the strings represent time use the VALUE function to convert them to a time serial number, after that apply the
TEXT function to convert the time serial to seconds.
Also use the Left, Right and Substitute functions to separate the days, time and fraction of seconds.
This formula returns the total of seconds represented in column A
= IFERROR( --TEXT( VALUE($A1), "[ss]" ),
--TEXT( --LEFT( SUBSTITUTE( $A1, ":", REPT( " ", 25 ), 1 ), 25 )
--TRIM( RIGHT( SUBSTITUTE( $A1, ":", REPT( " ", 25 ), 1 ), 25 ) ), "[ss]" ) )
This formula returns the total of seconds with decimals represented in column A
= IFERROR( --TEXT( VALUE($A1), "[ss]" )
--RIGHT( SUBSTITUTE( $A1, ".", REPT( " ", 25 ) & ".", 1 ), 25 ),
--TEXT( --LEFT( SUBSTITUTE( $A1, ":", REPT( " ", 25 ), 1 ), 25 )
--TRIM( RIGHT( SUBSTITUTE( $A1, ":", REPT( " ", 25 ), 1 ), 25 ) ), "[ss]" )
--RIGHT( SUBSTITUTE( $A1, ".", REPT( " ", 25 ) & ".", 1 ), 25 ) )
You can use the following method to find diff in two cells of format YYYY-MM-DD hh:mm:ss.ms
( ex: if result is say 1.xx then xx is milliseconds )
=(a1-b1)*86400
note: before using this method ensure you convert the cell where the formula is written in to numbers
I have a named range by name 'AlgeriaBchar'. (Algeria-> countryname and Bchar-> statename)
I use constraint on city dropdown as content in country dropdown + state dropdown (i.e. E7 + F7).
But as we can see in img staename is 'Béchar' which i need to remove char 'é' as it doesnt fit in a-z, A-Z, 0-9.
I also need to remove any blank spaces, hiphns, square brackets, apostrophy marks in country and state dropdown contents
I m not getting in which sequence I should put these fucntions to get it to 'AlgeriaBchar'
For better understanding I provided indentation to data validation fucntion in excel.
I'll be putting this fucntion in city dropdown's validaity constraint.
I may need to evaluate each character in a string which will need for loop. MID( E7, 1 ,1 ) gives me only 1st chracter. How can I loop it till the length of the string.
can anyone suggest me.
=IF(
NOT(
AND( CODE( MID( E7, 1 ,1 ) ) >=65 , CODE( MID( E7, 1 ,1 ) ) <=90 )
)
AND(
NOT(
AND( CODE( MID( E7, 1 ,1 ) ) >=97 , CODE( MID( E7, 1 ,1 ) ) <=122 )
)
)
AND(
NOT(
AND( CODE( MID( E7, 1 ,1 ) ) >=48 , CODE( MID( E7, 1 ,1 ) ) <=57 )
)
)
, SUBSTITUTE( E7, MID( E7, 1 ,1 ), "" ) ,""
)
INDIRECT(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(
SUBSTITUTE(UPPER($E$7)," ","")
,"-","")
,"'","")
,"[","")
,"]","")
)
)
You may want to use a macro for that. Consider this one (based on this article from extendoffice.com)
1) Hold down the Alt + F11 keys in Excel, and it opens the Microsoft Visual Basic for Applications window.
2) Click Insert > Module, and paste the following macro in the Module Window.
Function StripAccent(thestring As String)
Dim A As String * 1
Dim B As String * 1
Dim i As Integer
Const AccChars = "ŠŽšžŸÀÁÂÃÄÅÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖÙÚÛÜÝàáâãäåçèéêëìíîïðñòóôõöùúûüýÿ-[]' "
For i = 1 To Len(AccChars)
A = Mid(AccChars, i, 1)
thestring = Replace(thestring, A, "")
Next
StripAccent = thestring
End Function
Function TrimmedConcat(A As String, B As String)
TrimmedConcat = StripAccent(A) & StripAccent(B)
End Function
Then in your document, click in a cell, and use TrimmedConcat as if it was a normal function, selecting the country name as the first argument and the city name as the second.
In your example =TrimmedConcat(E7,F7)
I hope that helps!
I am importing a csv-file containing a data column with semicolon separated bytes in hexadecimal format like this:
06;03;58;1C;05;F5;D2;70;05;F5;DF;...
(Yes, this is all one column in the comma separated file..)
I would like to parse this column into a number of columns with 32-bit values and convert them to decimal:
06;03;58;1C -> 0x0603581C -> 100882460
05;F5;D2;70 -> 0x05F5D270 -> 99996272 ...
Here is one of my first (futile) attempts to create the first column:
Integer(Concatenate("0x",
Mid([data], 1, 2),
Mid([data], 4, 2),
Mid([data], 7, 2),
Mid([data], 10, 2)))
Any suggestions on how to accomplish this?
I am trying to avoid the extra step of pre-processing the csv-file in Excel using this very similar calculation:
HEX2DEC(CONCATENATE(
MID($M2,1,2),
MID($M2,4,2),
MID($M2,7,2),
MID($M2,10,2)))
The easiest way is probably to use either IronPython or the R interface. However, here's a version using just calculated columns (quite ugly, but gets the job done):
extract the one-character substring for pos 1, 2, ...
replace each character with its numeric value, i.e. 'A' -> '10', 'B' -> '11', ...
convert it to an integer Int1, Int2, ...
compute the resulting value as ((Int1*16) + Int2)*16 + ...
Here are the column expressions for the calculated columns (I only did the first two characters):
Int1
Integer(
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
Mid([Input],1,1),
"A","10"),
"B","11"),
"C","12"),
"D","13"),
"E","14"),
"F","15"))
Int2
Integer(
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
Substitute(
Mid([Input],2,1),
"A","10"),
"B","11"),
"C","12"),
"D","13"),
"E","14"),
"F","15"))
Result
Integer(([Int1]*16) + [Int2])
I'm trying to write a linear regression function that dynamically references columns, can handle #N/A values, and will function as additional rows are added over time. Here is a sample dataset:
Date Value 1 Value 2
1/2/1991 #N/A #N/A
2/4/2002 276.36 346.31
1/7/2003 252 350
1/21/2004 232 345.5
1/6/2005 257 368
2/1/2006 278.24 390.11
2/23/2007 #N/A 380.46
2/11/2008 326.34 383.04
2/12/2009 #N/A 399.9
2/17/2009 334.39 #N/A
1/29/2010 344.24 400.83
1/27/2011 342.88 404.52
2/7/2012 379 417.91
1/23/2013 #N/A 433.35
Here is the function that I've developed so far, based on this forum post. It calculates the linear regression for Value 1.
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT("B2" & ":B" & COUNTA(B:B)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2" & ":B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT("B2:B" & COUNTA(B:B))),
ROW(INDIRECT("B2:B" & COUNTA(B:B))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT("B2:B" & COUNTA(B:B))))))), 0, 1)),
TRUE, FALSE))
With the way it is currently written, dragging my array to the right to solve for Value 2 requires some manual updating of the formula. Everything in quotes in the INDIRECT formulas must be manually changed from B to C. I have 40 columns of data, though, so I tried to make the formula entirely dynamic using ADDRESS, ROW, and COLUMN:
=TRANSPOSE(
LINEST(
N(
OFFSET(
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2))),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
N(
OFFSET(
INDIRECT("A2:A" & COUNTA($A:$A)),
SMALL(
IF(
ISNUMBER(
INDIRECT("A2:A" & COUNTA($A:$A)) *
INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))),
ROW(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT(INDIRECT("A2:A" & COUNTA($A:$A))),
COUNT(INDIRECT(ADDRESS(2, COLUMN(B2)) & ":" & ADDRESS(COUNTA(B:B), COLUMN(B2)))))))), 0, 1)),
TRUE, FALSE))
This gives me #REF!. When I do a step-by-step evaluation of the formula, it looks like the issue comes when Excel evaluates COLUMN. It introduces braces to the formula, which propagate through the rest of the INDIRECT evaluation. Here is a quick comparison:
Original formula:
INDIRECT("B2:B15")
Dynamic formula:
INDIRECT({"$B$2:$B$15"})
This evaluates as #VALUE, and at that point the rest of the formula is broken. Is there a way to force Excel to not use braces in this evaluation, or is there a better way of making this calculation?
Are you only trying to get the SLOPE from the linear regression? If so, you can just use the SLOPE function after converting the #N/A to blanks (using IFERROR in a formula). SLOPE will then just toss out the blanks. If you want the intercept as well, use the same formulas below and substitute INTERCEPT for SLOPE.
Picture of ranges
Formulas are array formulas (use CTRL+SHIFT+ENTER) and copied over. Given this arrangement, the simple formula (non-dyanmic) would be:
=SLOPE(IFERROR(B2:B15,""),$A$2:$A$15)
If you want these to be dynamic, you can use INDEX and COUNTA to get the dynamic range.
=SLOPE(IFERROR(B2:INDEX(B:B,COUNTA(B:B)),""),$A$2:INDEX($A:$A,COUNTA($A:$A)))
Use a Table instead
Even better, you could define this data inside a Table and then use the headers to pull in the whole column. That formula would look nice and copy easily.
Still using an array formula here, but the only variable is the column heading which is used to look into the Table1. This one would be more resistant to blanks in the data which will break the COUNTA used above.
=SLOPE(IFERROR(INDEX(Table1,,MATCH(M1,Table1[#Headers])),""),Table1[Date])
It appears you can use the following, shorter, non-volatile array formula**:
=LINEST(INDEX(B:B,N(IF(1,MODE.MULT(IF(ISNUMBER(B2:B15),{1,1}*ROW(B2:B15)))))),INDEX($A:$A,N(IF(1,MODE.MULT(IF(ISNUMBER(B2:B15),{1,1}*ROW(B2:B15)))))))
B2:B15 can be dynamically defined if desired as per Jeeped's solution.
Regards
You are going to want to get rid of the use of the INDIRECT function as much as possible; certainly as it pertains to substituting column references for string equivalents. It seems that many can be replaced with a form of INDEX/MATCH function pairs.
=TRANSPOSE(
LINEST(
N(
OFFSET(B2:INDEX(B:B, MATCH(1E+99,$A:$A )),
SMALL(
IF(
ISNUMBER(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )) *
B2:INDEX(B:B, MATCH(1E+99,$A:$A ))),
ROW(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT($A2:INDEX($A:$A, MATCH(1E+99,$A:$A ))),
COUNT(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))))))), 0, 1)),
N(
OFFSET(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )),
SMALL(
IF(
ISNUMBER(
$A2:INDEX($A:$A, MATCH(1E+99,$A:$A )) *
B2:INDEX(B:B, MATCH(1E+99,$A:$A ))),
ROW(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))) - ROW(B2)),
ROW(INDIRECT("1:" & MIN(
COUNT($A2:INDEX($A:$A, MATCH(1E+99,$A:$A ))),
COUNT(B2:INDEX(B:B, MATCH(1E+99,$A:$A ))))))), 0, 1)),
TRUE, FALSE))
Fill right as necessary and have column A locked while column B cell range references will shift to column C, D, etc.
Further function replacement could likely exchange at least some of the OFFSET functions use for an appropriate INDEX function but the formula seems to work well as it is now.
I have gone through the variations on these and each has a different solution depending on how the names are in a cell. Let me make it clear. I have an excel sheet containing the names of my colleagues from my college days. The names are in no particular format. The "Name" column has the names like:
1) Dipak C. Chopra
2) Amar D Pathak
3) Lara Naik
4) Reshma Laxman Bhavsar
So as can be seen, some have simply a middle initial, some have it with a period and some have it missing while some have a full middle name. What I wish to do is to rewrite these names in another column by last name so that it turns out like:
1) Chopra Dipak C.
2) Pathak Amar D
3) Naik Lara
4) Bhavsar Reshma Laxman
I can do it but I have to use formulae with variations depending the name in the cell: e.g.
=TRIM(RIGHT(B2,LEN(B2)-FIND(" ",B2)) & " " & LEFT(B2,FIND(" ",B2))) for the 3rd entry
=TRIM(RIGHT(B4,LEN(B4)-FIND(" ",B4)-1) & " " & LEFT(B4,FIND(" ",B4)+1)) for the 2nd entry
=TRIM(RIGHT(B13,LEN(B13)-FIND(" ",B13,FIND(" ",B13)+1))&" "&LEFT(B13,FIND(" ",B13,FIND(" ",B13)+1))) for the 4th entry.
My question is how can I revise this formula to give me the desired result in all the cases mentioned above?
=IF(ISERROR(FIND(" ",B2)),B2,RIGHT(B2,LEN(B2)-FIND("~",SUBSTITUTE(B2," ","~",LEN(B2)-LEN(SUBSTITUTE(B2," ","")))))&" "&LEFT(B2,FIND("~",SUBSTITUTE(B2," ","~",LEN(B2)-LEN(SUBSTITUTE(B2," ",""))))-1))
It involves doing a reverse string search to find the last space and then uses its position to cut the last name off and then add on the rest of the string to the end, if there is no spaces in the string it will just return the value is B2
Beautified
=IF(
ISERROR(
FIND(
" ",
B2
)
),
B2,
RIGHT(
B2,
LEN(
B2
) -
FIND(
"~",
SUBSTITUTE(
B2,
" ",
"~",
LEN(
B2
) -
LEN(
SUBSTITUTE(
B2,
" ",
""
)
)
)
)
) & " " &
LEFT(
B2,
FIND(
"~",
SUBSTITUTE(
B2,
" ",
"~",
LEN(
B2
) -
LEN(
SUBSTITUTE(
B2,
" ",
""
)
)
)
) - 1
)
)