I'd like the count the frequency of identical values in a row. The value must occupy at least two cells and must be beside each other.
I'd like to post the image here but i do not have enough reputations. Anyway, screenshot can be found here: https://www.dropbox.com/s/1em9ltssc1ruw0u/stackOverflow_excelIssue_Countfrequencyofsimilarvaluesinbetweenblankcells.jpg?dl=0
J7:BE7 is where a person will type in the values - it correspond to time, in 30mins increment.
On a different part of the same sheet, in this case DD7:EY7 is where i have the formulas running.
This formula is on (first column) DD7 -- COUNTIF(J7:$BE7,J7)
This formula is on (last column) EY7 -- COUNTIF(BE7:$BE7,BE7)
The formula on DD7 counts the number of times the value on J7 appears across row 7 from column J to BE.
scenario 1: This formula works great if "orange" will only appear once. on my example from K7:L7.
scenario 2: The problem is when "orange" appears again on a non consecutive cell. what i mean is, "orange" appears on K7:L7, then it appears again on P7:Q7.
on scenario 1, the result of the formula in checking K7:L7 is 2, which is the desired value.
on scenario 2, the result of the formula in checking K7:L7 is 4, because it will also count "orange" that appears on K7:L7.
I was hoping the counting will stop if M7 has a different value. K7:L7 contains "orange" and M7:N7 has "apple". or the counting will stop if there's an empty cell in between, like U7:V7 contains "guava", and T7 is empty, then X7:Y7 again has "guava".
the fruits may occupy two to forty-eight columns of each row.
I know this is wordy, but i can't find other ways to explain it, english is not my first tongue.
Thank you in advanced.
~mark
I agree that the question could have been worded a little better, but I think I understand what you're looking for. I can't think of a good way to do it with built-in Excel functions, but if you're willing to make a little use of VBA, you can make a custom function that you can use just like it was a normal function in Excel. You'd just need to add something like this into a new module:
Public Function NumInARow(r As Range) As Variant
Dim i As Integer
If r.Value = "" Or r.Value = Empty Then
NumInARow = ""
Exit Function
End If
If r.Column > 1 Then
If r.Offset(0, -1).Value = r.Value Then
NumInARow = ""
Exit Function
End If
End If
i = 1
Do While r.Offset(0, i).Value = r.Value
i = i + 1
Loop
NumInARow = i
End Function
This function looks at the cell you pass as a parameter, and looks at the cells to the right until it finds a different one and counts the number of identical cells it comes across. For example, if cells A1-C1 all say "Bob" and D1 is blank or has a different value, then if you put =NumInARow(A1) in cell A2, then A2 would show a value of 3. You could drag that formula along the whole cell. The formula leaves the cell blank if the cell it's looking at is not the first in a sequence or if the cell it's looking at is blank. For example, if you put =NumInARow(B1) into cell B2 from the above scenario, B2 would appear blank because the second "Bob" was not the first in the sequence. I hope someone else can think of a way to do this with built-in Excel functions, but this may be an option for you. Here's a WikiHow article to show you how to make/where to put user-defined functions. It's pretty simple if you already have the code.
http://www.wikihow.com/Create-a-User-Defined-Function-in-Microsoft-Excel
The answer which I accepted - using formula - is from G-Man of superuser.com
The thread can be found on this link:
MS Excel: Count frequency of similar values in between blank cells
https://superuser.com/questions/806427/ms-excel-count-frequency-of-similar-values-in-between-blank-cells
This is verbatim of his words:
If I understand your request correctly, the following formulas will work. My solution requires a dummy column and a helper row, but they can be hidden. Further, you can probably eliminate the dummy column with a little bit of work, and you can put the helper row anywhere.
I’ll assume that your client names are in row 2. I’ll use column A as the dummy column, so the appointment data start in column B. Row 3 will be the helper row. In cell B3, enter the formula:
=IF(B2="", "", IF(B2<>C2, 1, C3+1))
Meaning:
If B2="", the client name for this timeslot is blank, so this is an idle timeslot, so display blank.
Otherwise, if B2<>C2, this timeslot and the next have different clients (C2 may or may not be blank), so this is the last timeslot for this appointment. Represent it as 1. Otherwise, count backwards, so the second-to-last timeslot for this appointment is 2, the third-to-last timeslot is 3, etc.
In cell B4, enter:
=IF(A2<>B2, B3, "")
If A2<>B2, this timeslot and the previous one have different clients (A2 may or may not be blank), so this is the first timeslot for this appointment. Display B3, which shows how many timeslots (half hours) there are in this appointment. Otherwise, display blank.
you can find more of his answers on the link I have provided.
Thank you for everyone's help.
Best Regards,
~mark
Related
So this needs a bit of detail:
n,X,X,X,n is in cells B5 to F5
I need to get the following output:
1n,3x,1n
for this particular row.
Now the n's and X's represent stitches in knitting with the "n" being the background color and the "x" being the front color.
There is an array of cells B5:F12 representing the rows and stitches, so each row will have a different arrangement of stitches or background color.
I need to avoid vba as this needs to be as stable as possible with the user being my Mum who is 90 years old :) and all she needs is a place to enter the name and the layout (which I have done) and a pattern list for each row (also sorted).
I have started to consider things like:
if(B5=C5,1&B5,"")
But given the n umber of combinations that becomes very long.
Any ideas? Cheers.
You could try:
Formula in H5:
=BYROW(B5:F12,LAMBDA(x,LET(z,REDUCE(VSTACK(TAKE(x,,1),1),DROP(x,,1),LAMBDA(a,b,IF(b=#TAKE(a,,-1),IF(COLUMNS(a)=1,VSTACK(b,TAKE(a,-1)+1),HSTACK(DROP(a,,-1),VSTACK(b,DROP(TAKE(a,,-1),1)+1))),HSTACK(a,VSTACK(b,1))))),TEXTJOIN(",",,DROP(z,1)&TAKE(z,1)))))
I'll see if I can golf the bytecount down a bit...
EDIT:
After a considerable amount of golfing (came down to 119), I came up with:
=BYROW(B5:F12,LAMBDA(x,MID(REDUCE("",x,LAMBDA(a,b,IF(RIGHT(a)=b,LEFT(a,LEN(a)-2)&1+LEFT(RIGHT(a,2)),a&",1")&b)),2,99)))
Though less dynamic than the 1st one, but possible due to the fact there are only <10 columns for each knitting pattern.
If your mother doesn't have the latest Excel (with LAMBDA etc), here is an alternative to #JvdV's answer which only uses LET,SEQUENCE and FILTER.
It only accepts a single row, so you'd need to fill the formula down.
=LET(p,LOWER(B5:F5),c,COLUMNS(p),s,SEQUENCE(,c),
a,IF(s=c,c,IF(INDEX(p,,s)<>INDEX(p,s+1),s,0)),
b,FILTER(a,a>0),t,SEQUENCE(,COLUMNS(b)),
n,IF(t=1,INDEX(b,,t),INDEX(b,,t)-INDEX(b,,t-1)),
TEXTJOIN(",",TRUE,n & INDEX(p,,b)))
I might add that it allows for adding more than one colour into the pattern ...
and with a bit of conditional formatting, the good lady can design her own multicolour patterns!
This is just a start of a solution, but in cell "B6" you can put the formula:
=(IF(B5=A5,A6+1,1))
This will generate following list:
B C D E F
5: n x x x n
6: 1 1 2 3 1
From there, you can try to get the Subtotals feature to work, based on the Max formula, ... (as I said, this is just a start).
If you are willing to spread the logic over multiple sheets, it's quite easy to come up with a way to do this. Consider a workbook with three sheets:
Pattern
EqualPrevCol, where each cell of Pattern is checked for equality against the previous column of the same row.
The formula for cell EqualPrevCol!D3 is:
=Pattern!D3=Pattern!C3
And finally PatternResult, where most of the logic resides:
Consider one row of EqualPrevCol:
At every FALSE column, we want to know how many columns until the next FALSE. To do this, we want to find the next exact MATCH for D3 in the rest of the row:
=MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0)
If no match is found, that means the rest of the row is all TRUE. In this situation, we want to return the length of the rest of the row plus this current cell.
=IFNA(MATCH(...), COLUMNS(D3:$H3))
And finally, we append this to the current character:
=IFNA(...) & Pattern!D3
Also, if the 7 row at this column is TRUE, we want to keep this blank:
=IF(EqualPrevCol!D3, "", IFNA(...) & ...)
The full formula of cell PatternResult!D3 is:
=IF(EqualPrevCol!D3, "", IFNA(MATCH(EqualPrevCol!D3, EqualPrevCol!E3:$H3, 0), COLUMNS(D3:$H3)) & Pattern!D3)
Finally, the pattern is condensed to the Pattern sheet. The Pattern!B3 cell contains:
=TEXTJOIN(", ", TRUE, PatternResult!D3:$H3)
To scale this up, you simply need to change all occurrences of $H in the formulas (this was a reference to the last column) and re-fill the cells on the latter two sheets.
I have multiple rows of students on a spreadsheet and their grades across the top as column headers. Not all students do every subject I have listed so therefore some columns will be blank. I am trying to use these grades as a range and have the populated cells appear all next to each other at the end of the spreadsheet. I will hen need the subject header to come with the non-blank cells data.
See the screenshot below to understand what data needs to go where:
I found a kind of answer on stack but its totally the wrong way round to how I have to work (see the image below). So, please help me flip this around so names would go down column A and subjects along the first row. (This is in a Google Sheet).
Lee
Here is a mock up of what I am trying to achieve, all data will likely be on one student row, but I have organised like this for the screenshot.
Based on your annotated screenshot, here's how to get from the top table to the bottom table.
Put your Subject 1, etc. headings in manually.
Put ={G13:G16} into G20 to copy your student names.
In H20 use =INDEX(FILTER($H$12:$O$12, $H13:$O13 <> ""), 1, 1) to grab the first heading in $H$12:$O$12 that is over a non-blank cell in $H13:$O13.
In the above formula, FILTER() grabs all the headings over non-blank cells in the range, while INDEX() is used to grab the first result.
Repeat the formula for H21:H23 (letting Sheets update the references that aren't fixed with a $ prefix.)
In I20 use =INDEX(FILTER($H13:$O13, $H13:$O13 <> ""), 1, 1) to grab the first non-blank value in $H13:$O13.
Repeat the formula for I20:I23.
Moving right, just copy the formulas, but update the values for INDEX() but increase the column argument by one. eg. J20 would contain =INDEX(FILTER($H$12:$O$12, $H13:$O13 <> ""), 1, 2) and K20 would contain =INDEX(FILTER($H13:$O13, $H13:$O13 <> ""), 1, 2).
This should get you well on your way.
Happy spreadsheeting!
I'm working on a budget for a project with multiple phases. There is a possibility that not all phases will be worked on so I've added some lookups and SUMIF formulas so that I can get a summary of my included and excluded effort and dollar amounts. That all works fine. Now I'd like to hide my row of lookups (row 1), but still have a way of identifying which phases of the project are included and which are excluded. Obviously I could manually concatenate them together, but if the phases being included/excluded change then I need to remember to update those formulas (and it's not nearly as fun as doing all in a formula). Here's how my sheet looks:
The TEXTJOIN function seems like it should work (i.e. =TEXTJOIN(CHAR(10), TRUE, C2:N2)), but I can't wrap my head around how to make the range parameter dependent on my lookup row. I played around with INDEX using something like =TEXTJOIN(CHAR(10), TRUE, INDEX(A2:M2,,(A1:M1="Yes")*COLUMN(A1:M1))), but didn't have any luck. At the end of the day I want to have something like:
Phase 1 Phase 2 Phase 5
Please note that the above data should all appear in the same cell - using the line feed character, CHAR(10), as the delimiter in the TEXTJOIN function will make all of the phases appear on a new line within a single cell. I do not want to fill formulas through multiple cells. Thanks in advance for any help.
Please take a look at the picture. I had a similar issue in the past (and brought it to StackOverflow, at which point I was helped by #ScottCraner, original post here:
Doing an array formula lookup
Basically,
1) You set up the array you are looking through - in my case, its $A$2:$A$6, in your case it will be $B$2:$M$2.
2) You then nest the COUNTIFS function inside of a match function. The function does the following:
A) It checks whether the name of phase X has already shown up in column E when you are copy/pasting down
B) If it has, move on to the next one
C) If it hasn't, output
3) Of note: this is an array formula, so the formula itself is checking through every cell. So it looks at cell A2; if the cell in B2 is "Yes", and "Phase 1" isn't in range in column E, then put in phase 1. Because it is, its there. Then it looks at cell A3; if the cell in B3 is "Yes", the same thing for phase 2. Then it looks at cell A4; because B4 is "No", the *(B2:B6="Yes") will throw an error. and so on
4) Place error catching brackets around the function.
A less elegant way to go about this, which doesn't require array formulas would be to use the secondary column's "Yes/No" as an index. This assumes the value in the secondary column is redundant- and repeating the primary column's "Yes" or "No."
In C1: =CONCATENATE(B1,COUNTIFS($A$1:B1,B1)) -
Repeat relatively for E1, G1, etc.
Somewhere separate (the below formula assumes Row 1 of the same worksheet), you could then use: =IFERROR(INDEX($2:$2,MATCH(CONCATENATE("Yes",ROW()),$1:$1,0)-1),"")
To look up "Yes1", returning "Phase 1" and autofill downward. IFERROR is used here to return blank when you run out of "Yes" results.
Hi all,
I have this excel where by I need to find the location of the item if they are found in column B.
So In my F column, I tried to write ifelse formula which didnt work.which is
=IF(D2="NULL","NONE",C((D2))).
My idea is if D2 is not null, use the value in D column to find the location in C column. In this example, fish no 4, so it is found, my F column should show the value "C" using the value shown in D column and use it as Row no in C column
I hope you guys get the idea and help me out a newbie in excel. Thanks in advance
=vlookup($D2,$A$2:$C$6,3,0)
you can use that in column F. Place that formula in F2 and copy down.
you could technically use it in column E as well, but you would need to change the 3 to a 2.
you did not say what you wanted to do if the D value was "Null" so I am going to take a stab at the dark and wrap you lookup formula in an if statement that will deal with "Null" or empty cells
=IF(OR($D2="NULL",$D2=""),"",VLOOKUP($D2,$A$2:$C$6,3,0))
That is the alternative formula to place in F2 and copy down.
Use the formula:
=IF(D2<>"NULL",VLOOKUP(D2,A2:C6,3,FALSE),"Value is NULL")
Here is the working example:
Put formula in cell F2 and drag it down.
[edit]to pull proper location column, not just the row #[/edit]
Seems like a job for MATCH+OFFSET
Try this formula in cell F2:
=OFFSET($C$1, MATCH(E2,B:B,0)-1, 0, 1, 1)
Match is used to locate the value in the first argument (ie E2) within the range specified in 2nd argument (ie B:B). I use B:B but you could also use range B2:B30 or whatever more specific range you want. (I prefer the more generic B:B, though :) )
Third paramter "0" just indicates "Exact match".
This function will retun "#N/A" if nothing found.
OFFSET takes the result from MATCH to pick out the Location you want. The first parameter in OFFSET is the rows below (or above if negative) from the base row (in this case $C$1). the next is the column: 0 since we're in the column we want to be in. The last two are the size of the range: 1,1 is a 1x1 cell, so just 1 cell. If we did ...,2,3), that would be 2 rows high and 3 columns wide - or a 6 cell range. We're just after 1 cell here.
I've always preferred MATCH + OFFSET to other options, I just found they held up more robustly to changes in a sheet (ie new rows/columns added). So it's mostly personaly preference over VLOOKUP and INDEX. I honestly have never compared their actual performance, however, I've never had any issues with MATCH+OFFSET running slowly :)
I have an excel spreadsheet with text and $ amounts in column A, but in different rows. I would like to move only the $ amounts to the adjacent column B. For example, the column looks like this.
The Pool Apache
Frontis
$2,000
1
White River
xiv
$3,0001
So I would want to move only the $ amounts to the adjacent column.
I'm pretty sure this could be done with a formula, and have read a number of similar posts, but can't quite work out the correct formula.
=if(isnumber(A1),A1,"")
That will pull only numbers to the adjacent columns which means the $2000 and the 1 would come over. So assuming the pattern is blank cell, money amount, integer blank cell we can modify the formula to:
=if(AND(isnumber(A2),A1=""),A2,"")
Now that formula has to go in cell B2 and gets copied down. Its limitation is that the first A1 can't be the money.
Now if the money is stored as a string life might get a little easier.
=IF(left(A1,1)="$",A1,"")
That formula can go in B1 and get copied down. That will pull all strings starting with $ over to the adjacent column. And the icing on the cake is if you need to turn that string into a number we wold toss in a few more functions to the previous formula and wind up with:
=IF(left(A1,1)="$",SUBSTITUTE(SUBSTITUTE(A1,"$",""),",",""),"")
UPDATE
After coming back from lunch and seeing the new info, I agree with Bruces statement and will give two options. The first is based on length of the value in A1, and the second will be on the breakpoint of 20.
=if(AND(isnumber(A1),len(A1)>2),A1,"")
OR
=if(AND(isnumber(A1),A1>20),A1,"")
OR
=if(AND(isnumber(A1),A1>=100),A1,"")
'I prefer this one as it is a direct check on your criteria for money being no less than $100
All those fomulas can be placed in B1 and copied down.
Until we can determine a way to detect which cells are currency or not with a formula, you can use you can use this Function, if a VBA solution is okay. (Note: Place in a Workbook Module)
Function is_Currency(ByVal target As Range)
If VarType(target) = vbCurrency Then
is_Currency = target.Value
Else
is_Currency = ""
End If
End Function
Edit: Per #ForwardEd, you could also create this isCurrency() UDF, and use it like isNumeric():
Public Function isCurrency(ByVal Target as Range) as Boolean
If varType(Target) = vbCurrency Then isCurrency = TRUE
End Function
Then just put this in your column B: =If(isCurrency(A1),A1,"").