How do I reference the last row in a named Excel table? - excel

I am currently trying to format one column of my table so that if there are any names that match in another column, the cell in the original column will be highlighted. Here's an example of what I mean:
Row 10 has a prerequisite of the M6A1. However, row 11 has a name of M6A1. I would like the M6A1 in row 10 to be highlighted.
To do this, I figured I would use COUNTIF, with the range from the current row (10 in this case) down to the bottom row (14). I don't want to hard-code in 14 however, as the list length will change. Therefore, I thought that I could just call the last row in the table, but that's not a feature apparently. I would like to know either how to dynamically reference the last row in this table, or if there is a better way to do this.

If you consider using built-in Excel functions you can get the last row of the table or named range this way:
=ROW(NAMED_RANGE or TABLE_NAME)-1+ROWS(NAMED_RANGE or TABLE_NAME) - for the last row of the table;
=ROW(NAMED_RANGE or TABLE_NAME)-1+COUNT(NAMED_RANGE or TABLE_NAME) - for the last record in the table.

To get the last row of your table, use Range("A1").End(xlDown).Row, provided your "A" column does not have any blank cells. If it does, a better way to do it is to use Range("A1000000").End(xlUp).Row.
The .End(Direction) method goes to the last cell before a blank a cell in a given direction (Up, Down, Left or Right, preceded by xl), starting from the specified Range, and the .Row method gets the row number of a given Range/Cell.

I would suggest this code:
lastRow = ws.Range(affectedTable).Row + ws.Range(affectedTable).Rows.Count - 1

Expanding on a previous answer with what worked for me. Below is another solution that does not require VBA but will return the last populated row instead of the last row of the table area.
COUNT(TABLE_NAME) will return the total number of filled cells in the table. If there are blank cells, this may not work correctly.
Since we are trying to count rows, it makes more sense to use only one column of the table which will always be filled (in many cases the first column). Using the built-in COUNTA function, we can count only the cells that have a value. Use structured references to specify a single column in the table or named range:
=ROW(TABLE_NAME)-1+COUNTA(TABLE_NAME[COLUMN_NAME])

If you want that inside the table (totals cell for example), just use offset (no empty rows of course):
[code]=OFFSET(tblName[[#Totals],[ColName]],-1,0)[/code]
If it is out of table, there are many good solutions.

Related

"Get Unique Values" formula adds a row of "0"'s to the end of the table

I was trying to implement this formula into my book to condense a larger table into a list format. I cannot use pivot tables because I need to do complicated calculations in later columns after I have achieved this condensed list.
The table looks like:
The Row# Column is filled by an Array Formula:
{=IFERROR(MATCH(0,COUNTIF(INDIRECT("$F$1:$F$" & ROW(E3)-1),$A$1:$A$4000),0),"")}
which translates to: "Get the row # of the first item in column A that isnt found in Column F above my current position"
The other three columns are filled by: =IFERROR(INDIRECT("A" & $E2),"")
My problem is that the last row of the table is always filled with 0,0,0 because for some unknown reason it matches the first blank row as a unique value.
My question is: How do I add a criteria that the unique value is not blank or 0?
As for clamping the search range, the table is generated by a program and has a variable and unknown number of rows so I cannot manually set the table range to the last non-blank row. I put $A$1:$A$4000 so that I won't miss any of the table's entries.
If there is a way to automatically determine the last row, that would also solve the problem.
Edit: I also realize that the list is not being condensed properly, I'm working towards getting it to compare all three values instead of just the first value.
Edit2: I got it to compare all three values, but the 0,0,0 problem is still there if anyone has ideas about that.
{=IFERROR(MATCH(0,COUNTIF(INDIRECT("$F$1:$F$" & ROW(E2)-1),$A$1:$A$4000)*COUNTIF(INDIRECT("$G$1:$G$" & ROW(E2)-1),$B$1:$B$4000)*COUNTIF(INDIRECT("$H$1:$H$" & ROW(E2)-1),$C$1:$C$4000),0),"")}
Since you are dealing with Excel 2007, and want a table of unique values, I suggest the Advanced Filter.
Setup your Data as a Table
Navigate to the worksheet where you want the results of the "filter"
Then Data=>Advanced Filter
Voila!
If you have more than three columns, but you only want to apply the unique filter on the first three, you can use a formula for the filter criteria.
For example:
A1: Unique Formula
A2: =COUNTIFS($A$7:$A7,$A7,$B$7:$B7,$B7,$C$7:C7,$C7)=1
you can visualize the effects of this filter by entering it into some helper column, adjacent to the table in row7, and then filling down the length of the table. If you did this, you could use the autofilter, and just filter on 1
Voila!

Import data from nth columns to another sheet

I'm trying to import all data from nth columns, starting from the 3rd row, from one worksheet ('Dataimport') to another ('Cleaned Data') in the same spreadsheet, but so far I have only managed to get a specific cell from every nth column:
=INDEX(Dataimport!$C$3:$HI$3;(ROWS($A$1:A1)*6)+1)
Right now I'm doing it manually, using =TRANSPOSE(IMPORTRANGE("1yyb1k0uAdN1XcLWBhNq4jA0eInnePRoUt9IbuXDmfEU";"Dataimport!I3:I300")) in every cell, so that the column data is imported horizontally (this is how it's supposed to look like):
The sheet with data looks like this. Here I want to retrieve data from every 7th column starting from column C:
Any idea how I do this?
Public link:
https://docs.google.com/spreadsheets/d/1hXFiSoduVjcZ6fbOcyp-BfI7m4So-01umLS0kBm-lVI/edit?usp=sharing
Proposed solution
Given your attempt =INDEX(Dataimport!$C$3:$HI$3;(ROWS($A$1:A1)*6)+1), I would suggest using the Google Sheets Formula OFFSET that allows specifying indexes as mathematical operations.
You will be able to specify the column offset with a simple mathematical operation in order to get the next needed indexes for the rows below.
Here is an example:
=TRANSPOSE(OFFSET(Dataimport!C$2:C$199;1;(ROW()-1)*6;199;1))
With this formula you can obtain the right column form the Dataimport Worksheet and then transpose it in order to fit it in a row.
Putting this formula in the Clean Data "D2" Cell will compute a column offset of 6 starting from the 3rd column ("C") considered in the OFFSET formula. Dragging down the formula will adjust the column offset index to the needed 7 columns range.
Reference
OFFSET
I think I have a solution.
I've build a spreadsheet with dummy data and then I made a formula that takes every nth column from the table.
Here is my solution:
https://docs.google.com/spreadsheets/d/1J6x4H_cNczRRo40Ri6Nwa-YnZOISpxZmG4-JZ7tA1kA/copy
First I make an ID column to both tables to let vlookup work
I use vlookup and arrayformula formula for this:
For grabbing multiple columns I use sequence formula within vlookup.
This makes an array of numbers with defined step. So if you can have every 6th column you define step as 6. Here step is defined in cell c23
=ArrayFormula(vlookup(A24:A43,A2:AB21,sequence(1,5,4,C23),false))
Of course it can work in multiple sheets or files. You just need to use importranges instead of standard references to a range.

Table Auto-Expand Changes Formula Range

The attached image is a table in a workbook I'm working out of. It's pretty self explanatory if you read the column headers. The Week number has a simple count formula to count the number of Week Ending dates in the range from the top of the data to that specific row. i.e - for Row one of the data the count range is $B$2:B2, for row 27 of the data the range is $B$2:B28
The issue is that when a new row is added the range for the new row is correct, $B$2:B29, but the range in row 27 changes to the exact same range, hence the 2 rows with a 28 count. I can't ferret out an answer from google and as far as Excel is concerned it's formula is fine... Can anyone provide some insight on this?
The formula is =COUNT($B$2:B##) depending on what row its on for those who want to see it.
Use table references instead of cell references:
=COUNT(Table1[[#Headers],[Week Ending Date]]:[#[Week Ending Date]])
This will count from the header down to the current row.
You could use INDEX:
=COUNT($B$2:INDEX(B:B,ROW()))
The issue is in the old last row Excel thinks that you want to include the whole data set as it refers to such. So when the new row is added it adds to the formula automatically.
With the formula above it will not do that.
Although this question has already been answered/solved, will leave an alternative approach in case it is of use to someone else:
=ROUNDUP((B2-$B$2)/7,0)+1
This assumes that the date in B2 is effectively "week 1".
I agree with this answer, in that it is preferable to use Excel table nomenclature where possible.

EXCEL: Searching a table of data with two criteria and outputting the rows to a new table

I have a table of data (Data!$A$8004:$F$10430) within an excel sheet which I need to search for all of the rows that contain the date displayed in cell: Data!Q27 (e.g may-2017) in column F of the table of data. And then output in a new table all of the rows which match that specific date (Data!Q27 changes, but is always in the MMM-YYYY format)
I created a similar solution for another table which worked, however for this data table it is not working. The working solution is shown below:
=IF(ISERROR(INDEX(Data!$A$1:$K$7523,SMALL(IF(RIGHT(Data!$A$1:$A$7523,7)=Data!$Q$25,ROW(Data!$A$1:$K$7523)),ROW(1:1)),1)),"",INDEX(Data!$A$1:$K$7523,SMALL(IF(RIGHT(Data!$A$1:$A$7523,7)=Data!$Q$25,ROW(Data!$A$1:$K$7523)),ROW(1:1)),1))
(This differs slightly as the date format in the table and Data!Q25 is /mmm/yy, but it successfully creates the new table which changes values dependent on the value in Data!Q25)
The format of the date in column F is e.g 09-May-2017 and is classified as 'general' type.
I have used this formula, and I get no error or value on the cell that this code is on:
{=IF(ISERROR(INDEX(Data!$A$8004:$F$10430,SMALL(IF(RIGHT(Data!$F$8004:$F$10430,8
)=Data!$Q$27,ROW(Data!$A$8004:$F$10430)),ROW(1:1)),1)),"",INDEX(Data!$A$8004:$F
$10430,SMALL(IF(RIGHT(Data!$F$8004:$F$10430,8)=Data!$Q$27,ROW(Data!$A$8004:$F$1
0430)),ROW(1:1)),1))}
The formula is formatted as an array, and therefore I believe this code should work, returning the first A column value of a row which fits the criteria of having, for example: "***May-2017" in its F column. However it doesn't.
Unfortunately due to corporate protection I am unable to share the spreadsheet, but if the information supplied in this isn't clear enough I could supply a new excel sheet to show my example?
https://drive.google.com/open?id=1NpS0_Bsy8XuicrPl8oy5tAswEa9QZ9X2 <- here is a spreadsheet that I have recreated to show the issue. The real spreadsheet is different, but this shows the purpose of my problem. Regardless of there being values which should be picked up on the tab names 'Data for normal user', no data is shown.
Thank you for your time!
Your formula is correct, however you haven't offset the rows.
Your INDEX() is starting at row 8 so this will be the first indexed row. SMALL() is building an array of the exact row numbers so row 8 in SMALL() is row 1 in the index, therefore no results are showing.
You simply need to update the IF() within SMALL() to handle this offset: (This formula has been updated to respond to formula dragging, i will include your original after)
=IFERROR(INDEX(ConfidentialLiveData!A$8:A$14,SMALL(IF(RIGHT(ConfidentialLiveData!$F$8:$F$14,8)=ConfidentialLiveData!$C$2,ROW(ConfidentialLiveData!$A$8:$A$14)-7),ROW(1:1))),"")
Or
=IF(ISERROR(INDEX(ConfidentialLiveData!$A$8:$J$14,SMALL(IF(RIGHT(ConfidentialLiveData!$F$8:$F$14,8)=ConfidentialLiveData!$C$2,ROW(ConfidentialLiveData!$A$8:$J$14)-7),ROW(1:1)),1)),"",INDEX(ConfidentialLiveData!$A$8:$J$14,SMALL(IF(RIGHT(ConfidentialLiveData!$F$8:$F$14,8)=ConfidentialLiveData!$C$2,ROW(ConfidentialLiveData!$A$8:$J$14)-7),ROW(1:1)),1))
A quick tip for error handling formulas is to use F9 when highlighting sections of your formula to show what that is calculating. For example i highlighted IF(RIGHT(ConfidentialLiveData!$F$8:$F$14,8)=ConfidentialLiveData!$C$2,ROW(ConfidentialLiveData!$A$8:$J$14)) and saw that that calculated as {8;FALSE;10;11;FALSE;FALSE;FALSE} so the match was being found just that the row numbers being returned were not what we were looking for.
Update:
So your formula is starting on row 8004, that row in the index is row 1. To get that row returned you need to take away 8003 from the 8109 to give you the 106th indexed row. A common way to do this is to take away the starting row and add 1 which in your original formula would be: {=IF(ISERROR(INDEX(Data!$A$8004:$F$10430,SMALL(IF(RIGHT(Data‌​!$F$8004:$F$10430,8 )=Data!$Q$27,ROW(Data!$A$8004:$F$10430)-ROW(Data!$A$8004)+1)‌​,ROW(1:1)),1)),"",IN‌​DEX(Data!$A$8004:$F $10430,SMALL(IF(RIGHT(Data!$F$8004:$F$10430,8)=Data!$Q$27,RO‌​W(Data!$A$8004:$F$1 0430)-ROW(Data!$A$8004)+1),ROW(1:1)),1))}

Shortcut for adding product of two cells along a table row?

I have a cell which wants to be a total of a table row multiplied by reference cells above the table. For example, $F$2 * F4 + $G$2 * G4 + $H$2 * H4. The table extends for about 100 columns which is why I'd like an automatic way to do this (also in case the table ever expands).
To clarify, I know my example works, but I want an automatic way (where I can specify two rows, like f2:bz2 as the 'reference' row and f4:bz4 as the other row) to do this. Since the second row is in a table, it would be ideal if the solution allowed for adding another column to the table too.
If you want something that expands automatically with your table, may be this:
=SUMPRODUCT(Table1[#]*OFFSET(Table1[#Headers],-1,0))
which assumes that your fixed coefficients are one row above the headers of the table. But it also assumes that you're entering the formula on the same row that you want to process. Unfortunately, if you have the formula to process a different row, you will need to wotk with normal ranges, such as the formula suggested by #pnuts in the comments section. But then it will not scale automatically as your table grows (unless you expand it by insertion of columns).
If you use:
=SUMPRODUCT(($F$2:$XFD$2)*(F4:XFD4))
You will both:
avoid REALLY long formulas
have a formula that automatically incorporates new columns of data as you add them

Resources