I am creating a spreadsheet to track my habits through the coming year, and I want to be able to show both a simple count, and also a current streak for each habit. I've already searched and found one answer for counting a streak, but this answer does not work with a live tracker (increasing the end column by one each day), and also requires there to be no blank fields (1 or 0 entry).
=COUNTA(S$2:S$74)-MATCH(2, 1/(S2:S$74=0), 1)
If I switch the above from =0 to ="" in the match, it breaks pretty spectacularly, and in any case it fails completely for a range that includes 366 days, but the current day is <366. I would be tracking "current day" by a habit row labeled "logging" that I would populate each day, whether any other habits were logged or not. Is this something possible with formulas?
Using the suggestions I got to concat 1's and 0's to a string, I then got a successful streak formula using
=IFERROR((LEN(NG3)-SEARCH("0[^0]*$",NG3)),LEN(NG3))
Where NG is the column the concatenations exist in, and row 3 is the first row of data.
I then basically duplicated my calendar to allow for non-binary logging (converting any blank or 0 entry to a 0, all other entries to a 1), and contingent on the "logged" row being populated so that unlogged days are blank fields. Works like a charm now.
My interpretation of the algorithm for this:
If you had a 1 for each time same thing happened, and 0 when you did something different.
Then you concatenated all the 0 and 1 into one long string.
Then split the string into an array based on 0, removing all the zeros.
Then finally counted the maximum length of the array result
In formula put the following:
=MAX(LEN(SPLIT(B1,"0")))
Then either press Shift + Ctrl + Enter on Windows
Or Cmd + Shift + Enter on a Mac
This will convert formula into an ArrayFormula.
(You need to do this, because if you just entered
=SPLIT(B1)
in C1, it would generate a range of columns, one per array entry, filling C1, D1, E1 etc...).
Here are the formulae:
Here is the output:
Sample spreadsheet in GoogleDocs
You may be able to upload/download/convert it between Googledocs and LibreOffice.
Have not used that spreadsheet solution.
But most are pretty similar these days.
Related
I am new to excel please help me.
So the situation is we have two contact no column
contact no contact no 1
9864573828 0145883
9834765849 1923832
018294 9876547834
i want to merge two column into 1 having contact no of 10 digit.
contact no
9864573828
9834765849
9876547834
I'm using Excel 2013
In Excel 2013 this formula can be used to list the 10 digit numbers from the first and second range without gaps:
=IFERROR(IFERROR(INDEX(A:A,AGGREGATE(15,6,ROW(A:A)/(LEN(A:A)=10)/(ISNUMBER(--A:A)),ROW(1:1))),INDEX(B:B,AGGREGATE(15,6,ROW(B:B)/(LEN(B:B)=10)/(ISNUMBER(--B:B)),ROW(1:1)-SUMPRODUCT((LEN(A:A)=10)*(ISNUMBER(--A:A)))))),"")
It uses a lot of resources to calculate, so whole column references is highly discouraged. So use actual ranges instead like:
=IFERROR(
IFERROR(
INDEX(A:A,
AGGREGATE(15,6,
ROW($A$2:$A$5)
/(LEN($A$2:$A$5)=10)
/(ISNUMBER(--$A$2:$A$5)),
ROW(1:1))),
INDEX(B:B,
AGGREGATE(15,6,
ROW($B$2:$B$5)
/(LEN($B$2:$B$5)=10)
/(ISNUMBER(--$B$2:$B$5)),
ROW(1:1)
-SUMPRODUCT(
(LEN($A$2:$A$5)=10)
*(ISNUMBER(--$A$2:$A$5)))))),
"")
Note: I think (unable to verify myself) the formula needs entered with ctrl+shift+enter to make it an array formula.
What this formula does is get the first row of the first range where the string length is 10 and the string converted to a number does not produce an error (what would happen in case of text characters in the string).
When you drag down the formula it shows the second found, third, etc... until no values are found in the first range anymore.
In that case the IFERROR makes it look for the same logic in the second range.
As we want it to show the first found value first, we can't reset the ROW(1:1) * - that is used as a counter for the first smallest, second smallest, etc.. - * therefore we use the same counter and use SUMPRODUCT to subtract the total number of strings meeting the conditions in the first range. That way the counter will start at 1 for the second range and starts counting from there.
If no more values are found in the second range it will show a blank value.
So you can drag down the formula up to the first blank result to show each result.
It's probably still slow with actual range references. I highly advise to upgrade to Office 365.
Try the following formula-
=LET(x,TOCOL(A2:B13,1),FILTER(x,LEN(x)=10))
Since your excel version doesn't support TOCOL() and some other formulas you can use this simple solution:
=IF(LEN(A2)=10,A2,IF(LEN(B2)=10,B2,""))
Put it in C2 and drag id down for a result:
Since you didn't specify what to do if both columns has 10 digit number or both doesn't, in those cases it will return first 10 digit number or empty string.
EDIT: I have revived the source data source to remove the ambiguity of my last screen shots
I am trying to transpose spreadsheet data where there are many rows where the customer name may be duplicated but each row contains a different product.
For instance
revised original data source
to
revised proposed data format
I would like to do it with formulae if possible as I struggle with VB
Thank you for any help
I realise this is a huge answer, apologies but I wanted to be clear. If you need anything from me, drop me a comment and I'll help out.
Here's the output from my formula:
EDITED ANSWER - Named ranges used for ease of understanding:
These are just an example of a few of the named ranges I have used, you can reference the ranges directly or name them yourself (simplest way is to highlight the data then put the name in the drop down next to the formula bar [top left])
Be wary that as we will be using Array formulas for AccNum and AccType, you will not want to select the entire column and instead opt for either the exact data length or overshoot it by 100 or so. Large array formulas tend to slow down calculation and will calculate every cell individually regardless of it being empty.
First formula
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Account Number ",LEFT((COLUMN(A:A)+1)/2,1)),"")
This formula is identical to the one in the original answer apart form the adjusted heading title.
=IF(Condition,True,False) - There are so many uses for the IF logic, it is the best formula in Excel in my opinion. I have used to IF with COUNTIF to check whether there is more than 0 cells that are more than BLANK (or ""). This is just a trick around using ISBLANK() or other blank identifiers that get confused when formula is present.
If the result is TRUE, I use CONCATENATE(Text1,Text2,etc.) to build a text string for the column header. ROW(1:1) or COLUMN(A:A) is commonly used to initiate an automatically increasing integer for formulas to use based on whether the count increase is required horizontally or vertically. I add 1 to this increasing integer and divide it by 2 so that the increase for each column is 0.5 (1 > 1.5 > 2 > 2.5) I then use LEFT formula to just take the first digit to the left of this decimal answer so the number increases only once every 2 columns.
If the result is FALSE then leave the cell blank ,""). Standard stuff here, no explanation needed.
Second Formula
=CONCATENATE(INDEX(Forename,MATCH(Sheet4!$A2,Reference,0)))
=CONCATENATE(INDEX(Surname,MATCH(Sheet4!$A2,Reference,0)))
CONCATENATE has only been used here to force blank cells to remain blank when pulled by INDEX. INDEX will read blank cells as values and therefore 0's whereas CONCATENATE will read them as text and therefore "".
INDEX(Range,Row,Column): This is a lookup formula that is much more advanced than VLOOKUP or HLOOKUP and not limited in the way that they are.
The range i have used is the expected output range - Forename or Surname
The row is then calculated using MATCH(Criteria,Range,Match Type). Match will look through a range and return the position as an integer where a match occurs. For this I have set the criteria to the unique reference number in column A for that row, the range to the named range Reference and the match type as 0 (1 Less than, 0 Exact Match, -1 Greater than).
I did not define a column number for INDEX as it defaults to the first column and I am only giving it one column of data to output from anyway.
Third Formula
Remember these need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter)
=IFERROR(INDEX(AccNum,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0))),"")
=IFERROR(INDEX(AccType,SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))),"")
As you can see, one of these is used for AccNum and the other for AccType.
IFERROR(Value): The reason that this has been used is that we are not expecting the formula to always return something. When the formula cannot return something or SMALL has run out of matches to go through then an error will occur (usually #VALUE or #NUM!) so i use ,"") to force a blank result instead (again standard stuff).
I have already explained the INDEX formula above so let's just dive in to how I have worked out the rows that match what we are looking for:
SMALL(IF(Reference=Sheet4!$A2,ROW(Reference)-ROW(INDEX(Reference,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0))
The IF statement here is fairly self explanatory but as we have used it as an array formula, it will perform =Sheet4!$A2 which is the unique reference on every cell in the named range Reference individually. In your mock data this returns a result of: {FALSE;TRUE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} for the first entry (I included titles in the range, hence the initial FALSE). IF will do my row calculation* for every true but leave the FALSEs as they are.
This leaves a result of {FALSE;2;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE;FALSE} that SMALL(array,k) will use. SMALL will only work on numeric values and will display the 'k'th result. Again the column trick has been used but to cover more ground, I used another method: ROUNDDOWN(Number,digits) as opposed to using LEFT() Digits here means decimal places so I used 0 to round down to a whole integer for the same result. As this copies across the columns like so: 1, 1, 2, 2, 3, 3, SMALL will alternatively (as the formulas alternate) grab the 1st smallest AccNum then the 1st Smallest AccType before grabbing the 2nd AccNum and Acctype and so forth.
*(Row number of the match minus the first row number of the range then plus 1, again fairly common as a foolproof way to always get the correct row regardless of where the data starts; actually as your data starts on row 1 we could just do ROW(Reference) but I left it as is incase you had data in a different format)
ORIGINAL ANSWER - Same logic as above
Here's your solution in 3 parts
Part 1 being a trick for the auto completion of the titles so that they will hide when not used (in case you will just copay and paste values the whole lot to speed up use again).
=IF(COUNTIF(C2:C11,">""")>0,CONCATENATE("Product ",LEFT((COLUMN(A:A)+1)/2,1)),"") in C
=IF(COUNTIF(D2:D11,">""")>0,CONCATENATE("Prod code ",LEFT((COLUMN(B:B)+1)/2,1)),"") in D
Highlight both of the cells and drag across to stagger the outputs "Product " and "Prod code "
Part 2 would be inputting the unique IDs to the new sheet, I would suggest copying your entire column A across to a new sheet and using DATA > REMOVE DUPLICATES > Continue with current selection to trim out the multiple occurrences of unique IDs.
In column B use =INDEX(Sheet2!$B$1:$B$7,MATCH(Sheet4!$A2,Sheet2!$A$1:$A$7,0)) to get the names pulled across.
Part 3, the INDEX
Once again, we are doing a staggered input here before copying the formula across the page to cover the entirety of the data.
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(A:A)+1)/2,0)),1),"") in C
=IFERROR(INDEX(Sheet2!$C$1:$D$11,SMALL(IF(Sheet2!$A$1:$A$11=Sheet4!$A2,ROW(Sheet2!$A$1:$A$11)-ROW(INDEX(Sheet2!$A$1:$A$11,1,1))+1),ROUNDDOWN((COLUMN(B:B)+1)/2,0)),2),"") in D
The formulas of Part 3 will need to be entered as an array (when in the formula bar hit Ctrl+Shift+Enter) . This will need to be done before copying the formulas across.
These formulas can now be dragged / copied in all directions and will feed off of the unique ID in column A.
My Answer is already rather long so I haven't gone on to break the formula down. If you have any trouble understanding how this works, let me know and I will be happy to write up a quick guide, breaking it down chunk by chunk for you.
I'm having a nightmare trying to come up with a formula to solve the following issue. I have two columns 'Record Count' and 'Actual Hours', where record count is greater than 1 I need to sum the data in actual hours. If possible I only want to use one formula and the maximum record count that I can see is 5.
So if you check out the image below, for the rows where the are 5 records I want to see 15.75.
This would be the sum of 1.19, 1.75, 2.31, 3.5 and 7 as these all relate to a single client.
enter image description here
Looks like you want to get total time for each clientid. In that case it does not matter whether there is one or more records for the client. Assuming, clientid is column C and Actual hours column D, in B2 enter =SUMIF(C:C=C2, D:D). Copy all the way down.
Looks like a task for SUMIF():
=SUMIF(A:A,">1",B:B)
(assuming A:A is 'Recoud Count' column and B:B is 'Actual Hours')
This will get you the sum of hours where record cound is more than 1.
Starting from second record you can do partial sums. Here B is record count, C is client ID, D is actual hours. For second line (E2):
=IF(AND(B2>0,C2=C1),E1+D2,IF(C2>0,D2,0))
For A2:
=IF(C3=C2,"",E2)
It uses two formulas, requires to move whole table one row down and only places one entry against each client. If this is works for you - give it a try.
If you don't want to move data you can paste this formula in E2:
=IF(ROW(E2)==1,IF(B2>0,D2,IF(C2>0,D2,0)),IF(AND(B2>0,C2=C1),E1+D2,IF(C2>0,D2,0)))
If the row is first the rows above are ignored (avoiding nullPointerException). If the row is second or below it works does the comparison to see border of userid.
Not sure if I've worded the question correctly... but, I have a spreadsheet that imports data across with a 'transaction date' and on day 1 there may be 15 transactions, day 2 there may be 30 etc.
Now I already have a formula that is counting how MANY are imported each day
=SUMPRODUCT((MONTH('Further Evidence'!$A$2:$A$5000)=MONTH(DATEVALUE(Configuration!H2&" 1")))*('Further Evidence'!$A$2:$A$5000<>""))
That shows how many have come in that particular month, what I need to work out now is what the highest intake was during that month (and if possible, which day it was).
Rather than list 365 days of the year and doing a countif in every cell next to them, is there an intuitive way to only count values that exist in the list?
It will be simple for one of you, but I can't quite figure it out or what to google :)
edit -
=MAX(FREQUENCY('New Appeals'!A2:A5000,MONTH('New Appeals'!A2:A5000)))
This works for the whole list of dates, but how can I make it check months specifically, or pinpoint the specific day?
To find the max value within a given month you can use an array formula like below
I've used a sample range of rows 36 to 48. I've assumed that date is in column I and that transactions is in column J
=MAX(IF(TEXT($I$36:$I$48, "mmm")="jan", $J$36:$J$48, ""))
(To enter an array formula you have to press ctrl + shift + enter when you are in the cell)
This is restricting the MAX function to the month of jan.
You can then find the day associated to this max value by using another array formula that is a mix of first MATCH then INDEX. The MATCH first looks for the max value within the range of cells associated to the given month, then returns this position. This position is then used in the INDEX to return the date
=INDEX($I$36:$I$48, MATCH(K34, IF(TEXT($I$36:$I$48, "mmm")="jan", $J$36:$J$48, "")))
Please note that if you have two days within a month with the same max then it will just bring back the first one
Hope this helps
I am having no luck trying to count my non blank cells in excel. I have tried multiple formulas and I keep getting inaccurate data. Here is the situation:
I am creating a Preventative Care list for my physicians (I have 4) I created a list of all their patients that have received a letter re: Prev. Care and I am inputting who needs a second letter and who has results. Some results are negative, some are positive. I have the list set up in alphabetical order on patients last name and then I have their physician initials in the other column. I want to check to see what percentage of each doctors patients have done their prev. care. I want to calculate this separately. Unfortunately, the cells are no in order. I have tried everything to my knowledge.
Help!
This will give you how many blank cells you have. You can deduct this from the total number of cells in your column, or you could use this directly to compute your percentage as (1 - x) where x is percentage of blank cells.
=COUNTBLANK(<your column>)
E.g:
=COUNTBLANK(A1:A10)
If it's not immediately obvious how to count the total number of cells in a range, this formula should help explain, answering the original question fully. It works with ranges that span more than 1 column, too.
=ROWS(range)*COLUMNS(range)-COUNTBLANK(range)
You might try something like:
=IF(LEN(A1) > 0, 1, 0)
You can then sum that column or do whatever other calculation you need.
=COUNTIF(range,"<>"&"") will count all cells that do not have a value equivalent to "", so, basically anything that is not blank.