Some of us have proposed great simple ways to define a set of columns in
Excel VBA, such as:
.Union(Columns("a"), Columns("b"), Columns("d"))
Those examples are using letters to refer to those columns.
I need to refer to my columns using numbers, such as in:
.Union(Columns(2), Columns(7), Columns(23)).
The later works great but what if I need to refer to columns using a range of columns such as in:
.Union(columns(2), columns(7), columns(9 to 23))
The idea being that I would not have to define the .Union with each column separately, which, in the present example would necessitate 17 columns(x) listing.
Not an elegant code. Furthermore, I need to use numbers because the column numbers are determined programmatically and are changing during execution.
Thanks for your input. Cheers
You would need to use RANGE():
.Union(.columns(2), .columns(7), .Range(.columns(9), .columns(23)))
set MyRange = worksheets("mySheet").range( columns(1), columns(5) ) works pretty well.
It actually select a range of columns from column 1 to column 5.
Further to that I can then use the Union to join other single columns.
Related
I would like to apply a Filter function on multiple columns ranging from A:G and only have columns B,D in the output. How can I do it?
For Example =FILTER($A$1:$G$7,$K$1:$K$7=$K$1) results in a spilled array of rows that match the condition, but the output will still have 7 columns(A:G). Can I choose to only output Column B & D?
TL;DR
Option1:
=FILTER(FILTER(A1:G7,K1:K7=K1),{0,1,0,1,0,0,0})
Option2: - Reference
=FILTER(INDEX(tblData,SEQUENCE(ROWS(tblData)),{4,3,5}),tblData[Customer Name]=I3)
Option3: - Answered by Rory
=FILTER(CHOOSE({1,2},B1:B7,D1:D7),$K$1:$K$7=$K$1)
Option4: - Commented by P.b
=FILTER(FILTER($A$1:$G$7,$K$1:$K$7=$K$1),(COLUMN(A:G)=COLUMN(B:B))+(COLUMN(A:G)=COLUMN(D:D)))
Explanation
Option 1
You can nest the original FILTER function inside another FILTER function and specify an array of 1's and 0's mentioning which column you need and which you don't.
For Example, in the above question if I want only Column B & D, I can do this:
=FILTER(FILTER(A1:G7,K1:K7=K1),{0,1,0,1,0,0,0})
Since B & D are the 2nd & 4th columns, you need to specify a 1 at that position in the array
Similarly if you want to filter columns from C:K and only output columns C, D & G, then your formula would be:
=FILTER(FILTER(C1:K7,M1:M7=M1),{1,1,0,0,1,0,0,0,0})
Pros & Cons - Option1
This formula is the simplest of all and easy to understand
You can NOT change the order of output. You can only hide/unhide in the original sequence
You can apply this on a Range of multiple columns without much change
Option2
Another way to do this which is complex looking is this:
Note that this method allows you to change the order of output columns. You can refer to following site for detailed explanation on how this works.
=FILTER(INDEX(tblData,SEQUENCE(ROWS(tblData)),{4,3,5}),tblData[Customer Name]=I3)
Pros & Cons - Option2
This formula looks complex, but is straight-forward once you understand the logic
You can change the order of output columns as required
You can apply this on a Range of multiple columns without much change
Options 3
This is actually the answer provided by Rory
=FILTER(CHOOSE({1,2},B1:B7,D1:D7),$K$1:$K$7=$K$1)
Pros & Cons - Option3
This formula is complex, especially for returning a range of continuous columns
You need to explicitly mention each output column individually
You can change the order of output columns as required
Applying this on to output multiple continuous ranges gets tricky (For Example you cannot replace B1:B7 with B1:C7 in above formula)
Options 4
Based on comment from P.b below
=FILTER(FILTER($A$1:$G$7,$K$1:$K$7=$K$1),(COLUMN(A:G)=COLUMN(B:B))+(COLUMN(A:G)=COLUMN(D:D)))
Pros & Cons - Option4
This formula is the simple and somewhat similar to option 1.
You can NOT change the order of output. You can only hide/unhide in the original sequence
You can apply this on a Range of multiple columns without much change
There's a similar question that's asked in reference to Google Sheet. But Google Sheet also has the Query function which explicitly supports choosing specific columns
You could also use CHOOSE like this:
=FILTER(CHOOSE({1,2},B1:B7,D1:D7),$K$1:$K$7=$K$1)
This also allows you to reorder columns in the output by changing their order in the CHOOSE function.
Try the new CHOOSECOLS function (beta channel at time of writing):
=CHOOSECOLS(filtered_array, {2,4})
I use option #2 exclusively these days, but using a range of cells instead of the array.
=FILTER(INDEX(tblZero,SEQUENCE(ROWS(tblZero)),A2:M2),tblZero[TakenBy]=A1)
Using the [#Headers] of my Table gives me column headings as well.
=FILTER(INDEX(tblZero[#Headers],SEQUENCE(ROWS(tblZero[#Headers])),A2:M2),'Zero Dollar Review Data'!A1<>"")
I use the row directly above the column headings to hold the column numbers. This way, I simply have to enter a column number and I get both the column heading and the data. I can also use some simple formulas in my column number cells to create outputs that are custom to the criteria used. So if I enter "TBT" as my TakenBy value I can display a set of columns unique for that particular Rep., then if I enter "DXD", I can display a different set of columns.
By far the easiest way of doing this.
Apply range, your selection of columns in the preferred order and with the option to work your way in from the right side with -
=CHOOSECOLS(FilteredRange,2,4)
=CHOOSECOLS(FILTER($A$1:$G$7,$K$1:$K$7=$K$1),2,4)
=CHOOSECOLS(FILTER($A$1:$G$7,$K$1:$K$7=$K$1),4,2) 'Custom order
=CHOOSECOLS(FILTER($A$1:$G$7,$K$1:$K$7=$K$1),-6,-4) 'From the right side
I want to ask whether it is possible to have excel print out a complete row of raw data using two variables. So like let say we have the following data:
What we wish to have is that based on the values "2018" and "A", excel should give out the complete row data automatically as done so in the yellow cells.
I know how to do it for one variable, where I have been using
Index(range,MATCH(value, range,0),column())
But I am having difficulty when there are two unique variables, based on which the row data must be extracted.
Currently, I do it in two steps. So I first filter out the year and then use the above formula to extract the row data for A or B. But it is not a very good approach and would appreciate if it can be done using a single formula.
Does anyone has any clue on how it can be done without using Pivot Table?
UPDATE
Regarding the suggestion of using VBA. Using the VBA is a good option, since then I can just use the autofilter command, but the problem is defining the cells in VBA and also how can I have one code for two different columns?
My vba code which I have used for filtering the tables is the following:
Sub Autofilter_Filter12()
Dim lo as ListObject
Dim iCol As Long
Set lo = Sheet3.Listobjects(1)
iCol = lo.ListColumns("Year").Index
with lo.Range
.Autofilter Field:=iCol, Criterial:="XXXX"
End Sub
Now the problem with the VBA code is:
it is only applied for one column and not both.
Instead of XXX, how can I define a cell into the VBA? I have tried but failed again and again.
Thank you for the help.
If range C:H is always numbers then you can use SUMPRODUCT.
=SUMPRODUCT(($A$2:$A$5=$A$7)*($B$2:$B$5=$B$7)*C2:C5)
parameter 1 parameter 2 Value to return
In C7, then select C7:H7 and press CTRL+R.
This results in this:
When this fails it will return 0.
Not very nice, but it could be partially solved with I7 =
=IFERROR(IF(SUM(C7:H7)=0,"Filter failed",""),"")
In EXCEL 365 with dynamic formula you can put multiple columns in MATCH formula by merging them with &
=MATCH(A7&B7,A1:A6&B1:B6,0)
So you can use index-match combination for your case (no matter if values are nubmers or not):
=INDEX(C$1:C$6,MATCH($A$7&$B$7,$A$1:$A$6&$B$1:$B$6,0))
I've a question regarding columns and finding non zero values with there labels.
Hopefully the pictures will make my problem/struggle a bit better to understand.
Basically, there are columns to the right that show labels and hours that a team loaned in or out.
The values are found through a formula that shows per label the totals amount of hours spent.
Now I want to have on my overview page the two columns to the right with only labels showing the labels that contain hours. I've tried to use multiple if variables but that didn't seem to work :(
So at the end it should show something like this (I now manually typed the labels and data):
I did a quick recreation of your data structure to test this.
Using Array Formulas should get you the desired results in the current structure of your worksheet:
For range Loaned in you'd need the formula to be
=IFERROR(INDIRECT(ADDRESS(SMALL(IF($I$4:$I$14>0,ROW($4:$14),""),ROW(A1)),8)),"")
Where 8 is a reference to the return column. For the range directly to the right, you'd use the same formula, just adjust 8 to 9. And for range Loaned Out you'd need
=IFERROR(INDIRECT(ADDRESS(SMALL(IF($K$4:$K$23>0,ROW($4:$23),""),ROW(A1)),10)),"")
And for the range directly to the right you would again change the 10 to a 11. Again, both of these are array formulas, so they have to entered slightly differently. See the link for further assistance with array formulas.
This is not trivial. If you cannot work with filtering or programming, you should make use of matrix formulas. I include an example with two formulas: 1st in D1:D5, 2nd in F2:G5. Enter them with Ctrl+Shift+Enter. Also, you should use an extra column to determine the "valid" rows. (You could put it all in one formula, but it would look even more complicated.)
Sorry for German excel. Wennfehler = iferror, kkleinste = small, zeile = row, wenn = if, bereich.verschieben = range.offset.
So I'm trying to count data over a large date range, lets say I only need May's data and only the data in May that has a field with a specific entry, I know I need to use COUNTA as the entry are words, but how would I organize the formula? IF (date matches range) then COUNTA IF (cell "X" = Yes) is the best I can come up with as the layout, any help would be appreciated!
Use =COUNTIFS(...). It allows you to use multiple sets of criteria.
For example, you could use something like this
=COUNTIFS(A1:A40,"Yes", B1:B40, ">"&C1)
It would tell you the number of fields with text "Yes" in A1:A40 that have a date in column B greater than the value of C1
You can use COUNTIF as per the screenshot below. This will give you the number of 'May' entries in Column A:
In case you need to find another data in some other columns based upon the condition in column A then it would be a different solution. You will need to explain the problem a bit more clearly with some sample data.
Hope this helps!
Use the following:
=COUNTIFS(Sheet2!$A$2:$A$5000,">="&DATE(2017,5,1),Sheet2!$A$2:$A$5000,"<="&DATE(2017,5,31),Sheet2!$B$2:$B$5000,"<>")
change A2:A5000 to your date column
B2:B5000 to your project column
instead of "<>" write the condition for project
I am trying to use Sumproduct dynamically on a sheet that will be updated regularly.
My motive is to not manually select the columns ( i.e. not to use the shift key and down key to select the range A2:A6 as seen in the attached snapshot)
I want to have the formula "=SUMPRODUCT(--(A2:A6="TX"))" pick up the A2:A6 dynamically since my data in worksheet say A is everchanging. So that when the data has grown to A8, it can be somehow picked up dynamically than manually using the keys.
Can this be done? Please let me know if my question is not clear.
Screenshot of my xls
Regards
SM
Yes, you could define the range dynamically. However, given your current formula, I see no reason why you should not switch to COUNTIF here, i.e.:
=COUNTIF(A:A,"TX")
a function for which the use of entire column referencing (A:A here) has no detriment to performance (which is not at all the case with SUMPRODUCT).
Regards
Shitty recommendations guy, here.
Can you insert a new line above all in your sheet? You could put it really wherever you want and you can even hide it, the first line just works for me.
If you can, just make it an "count.values" function on the entire column with an appropriated subtraction to adjust the count to the right length of your data. E.g. Removing this auxiliary cell value plus a header would be "=count.values(A:A)-2".
Later, on your VBA, you could retrieve this value to a variable and concatenate it to your main function. Lets say you made the auxiliary on cell A1 (coordinates 1, 1)
Dim auxLine As Integer
auxLine = cells(1, 1).value
whatever.formular1c1 = "=SUMPRODUCT(--(A2:A" & auxLine & ="TX"))"