Problem: When creating a VBA script to dynamically insert formulas into a sheet's cells, I've chosen to use R1C1 notation for the cell references in the current sheet (because their locations aren't fixed between files used), and a fixed reference to a specific column in a separate workbook. This fails because Excel is adding unexpected parentheses around the column letters of the external workbook location.
EXAMPLE:
Range(FormulaCol & FormulaRow).FormulaR1C1 = "=IFERROR(MATCH(RC[-4],'[" & ExternalFileNameVariable & "]Sheetname'!B:B,0),"""")"
When the formula is output into my target sheet the script is working on, the formula comes out looking like this:
=IFERROR(MATCH(BG44,'[filename.xlsx]sheetname'!B:(B),0),"")
The B:(B) ultimately results in the formula failing. I cannot use a variable reference since the location of the columns in my working spreadsheet will vary, but the columns' location in the external worksheet will be fixed.
I have to do this for several formulas. The only alternatives I can think of to address this are to create dedicated variables for the columns in the working spreadsheet I'm referencing and using FIND methods to locate each column's header and saving its column location to a variable... but I swear, there's got to be a better way.
Related
I'm hoping someone can help me make better use of the INDIRECT formula.
I have a list of sheet names in a table and an INDIRECT formula that uses that list to return a value in a specified cell - the list of sheet names is just an easier way for me to drag the formula down the table and read the appropriate cells without having to manually link each sheet.
=INDIRECT("'"&A2&"'!"&"K10")
This works fine for single cells as the range ref is simply stated as the text in the formula (K10), the problem arises when I need to start referring to a range such as K10:K15 and summing the values.
The range K10:K15 will inevitably have new rows added or deleted on the relative tab and as INDIRECT is using text as the reference it means the range doesn't automatically adjust - this is as I understand it one of the 'benefits' of INDIRECT but in this case is actually holding me back.
Also worth noting that the range (K10:K15) may move as rows are added/deleted above this, as this range is part of a larger table.
In simplistic terms I want to achieve the same result as a standard reference to a range on another sheet, e.g. =sum(sheet1!K10:K15) (as this will adjust when rows are added/deleted) but I just want to be able to dictate which sheet is referred to via a list I have in a table on a summary sheet.
How do I either write INDIRECT so the range adjusts when new rows are added/deleted or is there a different formula I should be using that achieves this?
Any advice greatly appreciated :)
=INDIRECT("'"&A2&"'!K"& MATCH(TRUE,INDIRECT("'"&A2&"'!K:K")<>"",0)&":K"&MAX((INDIRECT("'"&A2&"'!K:K")<>"")*(ROW(INDIRECT("'"&A2&"'!K:K")))))
This indirectly references the rows from the first non empty cell up to the last non empty cell in given sheet in column K. Not sure if you need to enter with ctrl + shift + enter (not in the app version).
Note: If the range contains empty cells in between the first and last non empty cell it will be included as value 0
Or in office 365 use the following:
=FILTER(INDIRECT("'"&A2&"'!K:K"),INDIRECT("'"&A2&"'!K:K")<>"")
I am trying to list all sheets in an Excel workbook with a method that works for macro-free workbooks such as .xlsx files.
I am aware of the following options although both require the workbook to be saved in a file format that allows macros:
Method 1: Excel 4 Function
See this answer I posted.
Method 2: VBA
See this answer posted by another user.
Is there any option to list all sheets? If not is there any formula that names any sheet beyond the sheet containing the formula?
If you have the flexibility, you can use the formula from #urdearboy in e.g. A1 on each sheet, then use a 3D reference to collect them together e.g. =TEXTJOIN(CHAR(10), FALSE,'FirstSheet:LastSheet'!A1) and then extract from the string.
It's a big kludge but it does work. (But at the moment I'm happy with all the sheets listed in 1 cell; A1 contains sheetname + description)
Caveat - FirstSheet & LastSheet must obviously span the range of sheets to be listed, and if they get moved around, the 3D reference may be inappropriate or break
This is a great question in the context of building macro-free workbooks.
To make an contents list of sheetnames, the formula from #urdearboy can be pasted in cell A1 of each sheet being indexed:
=MID(CELL("filename",A1),FIND("]",CELL("filename",A1))+1,255)
If cell A1 of each of these sheets is made a named range, using foo_1, foo_2, foo_3 etc as the names, the index is simply =foo_1 in the first cell of the contents range, or better =indirect("foo_", 1), with 1 replaced by a cell reference to a number sequence.
The content list stays up-to-date, even if the sheet names are changed.
I have a sheet with 6 different tables (and then multiple sheets (20 copies) that are similar but under different names). The tables are long (columns B to Az).
I want to put a link in each table that will jump to column W. I am trying to avoid make 6 different cell references hyperlinks on each sheet. Is there a way to get this down besides the manual hyperlinking each one of those?
This sheet is going to be used on Excel Online, so cannot use any VBA. (If I have to run a VBA code to make it happen then remove the VBA that works, but end product wont support any VBA)
I am not sure what you mean with "without specifying a row" - but jumping to a column without naming the sheet can be done with the HYPERLINK formula
Just insert into a cell
=HYPERLINK("#W1","Click here to jump to W1")
You can then paste this formula to all sheets
But i think you would need to name the range you want to jump to. It would also be possible to select the whole column
=HYPERLINK("#W:W","Click here to jump to W")
And of course, dynamic links are also possible and can be very useful - jump to the first empty row of a given sheet, for example.
I have the following search function:
=ALS((VERT.ZOEKEN(B6;'Raw Data'!$H$1:$BB$3000;21;ONWAAR))=100;"Winkel";
ALS((VERT.ZOEKEN(B6;'Raw Data'!$H$1:$BB$3000;21;ONWAAR))=400;"Woning";
ALS((VERT.ZOEKEN(B6;'Raw Data'!$H$1:$BB$3000;21;ONWAAR))=500;"Parkeerplaats";
ALS((VERT.ZOEKEN(B6;'Raw Data'!$H$1:$BB$3000;21;ONWAAR))=200;"Kantoor";
ALS((VERT.ZOEKEN(B6;'Raw Data'!$H$1:$BB$3000;21;ONWAAR))=600;
"Antenne";"Overig")))))
But when I change and delete some of the columns in the range of the Vlookup search with a macro (Vert.Zoeken=Dutch for Vlookup) The Range specified within the formula changes.
Why does it do that, and how do i stop it? I Couldn't find a clear answer anywhere else.
(The macro code just deletes some columns, and doesn't do anything else really)
Cell ID vs Cell Location
One of Excel's primary mechanics is that each cell effectively has its own "ID", which is represented by that the location of that cell at the time that it was referenced. The location of that cell can change, when columns & rows are manipulated.
For example: in A1, make the formula
=B5+D3
Then insert a row above row 3, and a column to the left of B. Your formula will now read:
=C6+E3
You'll notice that because the locations of the unique cells was changed, the formula accounted for that. This feature is incredibly useful, as otherwise, even simply formulas would need to be completely re-written if a new header was inserted above some numbers.
If you want the position of a reference to be "absolute" in the sense that it always points to the same location instead of the same cell ID, then you have a few options:
VBA solution to ignore this feature
By its nature, VBA code does not automatically adjust when cell references change. If you have a formula which references Range("B5"), then it will still say Range("B5") after you insert a new column to the left of B. In this way, you could use VBA to build the formulas within your worksheet. ie: VBA could re-write the formulas to reference the columns you want it to.
Excel solution to ignore this feature
To solve this without VBA, meaning your VBA code would not need to re-write the formulas, you could use the INDIRECT function. INDIRECT allows you to dynamically determine what a cell reference is, based on building a text string of a location. For example:
=VLOOKUP(A1,INDIRECT("B"&5+10&":D100"),2,0)
This will create the text string "B15:D100", and that will be the range referenced by VLOOKUP. Because you have entered the "B" & "D" as text values, they will not change when you insert rows/columns.
I have a gantt chart that has some conditional formatting in it. The problem im having is that I cannot see where the "ganttTypes" array is stored in my excel sheet.
=IF($N$2=INDEX(ganttTypes,1),IF(AND(H$5>=$C6,H$5<=$C6+$D6),IF($C6+$D6*$G6>H$5,$Y$2,""),""),IF(AND(H$5>=$E6,H$5<=$E6+$F6),IF($E6+$F6*$G6>H$5,$Y$2,""),""))
From looking at different sources online there is an indication that "gantTypes" is a particular cell and the "1" next to it indicates the row next to that cell - - here is an example where it explains that
I assume ganttTypes refers to a named range, in which case you should be able to locate it by using the Names Manager, which lists all the named ranges and their location, in Formulas / Defined Names.