Dynamically reference cell in different workbook - excel

I have two workbooks:
WorkbookToUpdate.xls
Workbook_for_20130901.xls
In the first workbook I have the following:
A1 ='[Workbook_for_20130901]Sheet1'!$C5
Now a month goes by and I want to update the first work to reference Workbook_for_20131001.xls without going cell by cell and changing the name of the workbook. My thought was to make the date portion of the workbook name a variable and simply change that variable, but that doesn't seem to be working.
EDIT: I don't want to use Excel's INDIRECT function because I don't want to open the reference workbook.

I found one solution to be Harlan Grove’s PULL function (code can be found here), which works similarly to the INDIRECT function except that it doesn't require the source workbook to be open. The other solution, which actually works out to be faster than the Pull function (its only downfall) is the one I was using originally - Good ol' "find & replace". I thought that that was slow, but after trying the Pull function, it's not too bad.
Another option is by changing the source through excel's Data links, but this doesn't allow you to choose which cells keep the old source and which cells use the new one (in my case, I need the old values as well).

Related

How to break links from activesheet and replace formulas pointing to other sheets with values?

I am looking to do two things with one macro:
1) Break external links.
2) Change formulas parts pointing to other sheets to values.
I can find macros to break external links, there are a few methods to do that, but I have a great issue with the second point.
For example - if I have such formula in my active worksheet:
"=K6*34+Sheet1!A1"
I would like it to be replaced by this:
"=K6*34+25"
So, Sheet1!A1 reference should be replaced with its underlying value.
I cannot provide any sort of half-decently reliable code. I cannot find anything on the web either, as everything relates to breaking links and things on a workbook level, not a worksheet.
Why do I need this? I want to "break" one of the worksheets in the workbook and send it via mail. I can do every part of the macro except reliably finding and replacing references with values.
Ok, so you should define a load of names for cells that 'export' a value off a sheet. Then when you want to breakaway then you loop through the names and replace with a constant.
So this way you won't need to parse the formulae which (as has been pointed out) would be very difficult.

Can I use another open workbook's VBA Functions in another open workbook within a Cell formula?

I have some VBA functions defined within my Personal.xlsb that I want to use in the Cell formulae for other opened workbooks. I can use these functions within Cell formulae within worksheets in Personal.xlsb, however I can't seem to use these within other opened workbooks... I get the #NAME errors whinging that it can't find the function name.
I hope I've just done something stupid..
FYI for example, one function accepts some arguments including a Cell, and returns an element from the cell's value at a particular position (say Cell.Value = This.Is.An.Example, the function might return "An") effectively replicating a split()[2]
Cheers
You need to reference functions in the Personal.xlsb with the filename, like this:
=PERSONAL.XLSB!myFunctionName(A1)
If you don't want to do that for each function, you can create a reference in your new workbook's VBE. Go Tools > References and find the workbook in the list.
See a walkthrough of the whole process here: https://www.myonlinetraininghub.com/creating-a-reference-to-personal-xlsb-for-user-defined-functions-udfs

How to reference a cell as table range when using vlookup

I have vlookups to pull specific data from a workbook and paste into a new workbook in the desired layout. The layout of the first workbook never changes however the name will change when i want to run this on a different file.
My current formula is =VLOOKUP(A3,[Workbook1.xlsx]Sheet1!$B$3:$XFD$7,2,FALSE)
I would really like it to reference A1 instead of Workbook1 so I could then just update the file name in A1 every time I want to analyse a different file. I should mention the Sheet name won't ever change.
I know you have to use INDIRECT but im unsure how it works. I did try =VLOOKUP(A3,INDIRECT(A1),$B$3:$XFD$7,2,FALSE) but then i'd too many arguments and when i removed the $B$3:$XFD$7 i lost the range i was searching in.
Thanks!
With INDIRECT you must create the whole string that denotes the range reference:
=VLOOKUP(A3,INDIRECT("'[" & A1 & "]Sheet1'!$B$3:$XFD$7"),2,FALSE)
One more note, that INDIRECT requires that the workbook be open to function, or will return an error.

Why can't Excel update some of the links in my workbook

I have a Master workbook in MS Excel that references data in 4 other workbooks.
When it opens I get the following message:
We can't update some of the links in your workbook right now.
You can continue without updating their values, or edit the links you think are wrong.
[Continue] [Edit Links...]
Each referenced workbook contains a N row, 365 column rectangular range that I have named 'DataRange'
My master workbook contains 4 lots of N row, 365 column ranges with Array Formula linked to these named ranges:
{='C:\Path\[Workbook1Name.xlsx]Sheet'![DataRange]}
It feels like i've come across an Excel bug.. Anyone know what I'm doing wrong?
Are you using MS Excel 2013, when you receive this error?
If so, it maybe due to the "3D reference in your named DataRange" in Excel 2013 or because you're referencing a range or cell in a closed workbook.
Excel allows the defining of names that refer to specific cells or ranges of cells in that workbook, similarly (using the Define Name tool in the Formulas tab) you can assign a formula to a name and then use that name in place of the formula.
The named formula or named data range is part of a collection in that workbook's (workbook1) objects and can be used in different workbook (workbook2), but the link to the defined name in the other workbook must be done one of two ways.
Link the defined name with a formula like this
='C:\Folder\Path\Workbook1.xls'!NamedFormula or NamedDataRange
Or Create a defined name in workbook2 (it can have the same defined name as workbook1's or a new name) and then refer workbook2's defined name to workbook1's defined name. Select Define Name on the Formula tab and copy a link like this in the Refers To Field:
='C:\Folder\Path\Workbook1.xls'!NamedFormula or NamedDataRange
Note these links will only work when being used in simple formulas which treat the link as a direct links. It will not work with more complex formulas when the original workbook (workbook1) is closed because the link is often treated as an indirect link in complicated formulas.
To work around this issue, use either of the following methods:
Save workbook1 and workbook2 as .xlsb files.
Do not add an external reference link to a defined name that refers to a 3D reference or named range.
Or open both workbooks
For more detail information, please refer to the following link:
https://support.microsoft.com/en-us/kb/2755120
If you're still receiving an error/ warning message after trying all my above suggestion. You might want to some troubleshooting.
Try this:
- Open Excel. Under Tools->Options->Calculation, select the Update remote
references box.
Open your workbook. Make sure the box the remote reference box is checked. Save your workbook this way after updating the link. Close workbook and Excel.Restart Excel and open your workbook.
- Look under defined names and delete all that you don't need or that have broken formulae. Run a FindLink search, to pin point the problem.
This process worked for one of workmates with this exact problem.
I hope this helps, if not let me know. There might be a 4th solution.
I finally solved this issue after going on a scavenger hunt. In my case, the reference was to an old file that no longer exists, and removing the reference was all that was needed. Unfortunately Excel does not pinpoint where the reference is, so it was a pain to look for the cell that was making the reference.
In my workbook, it was a reference as a part of a Data Validation. For others seeing the same error, I recommend using the Find & Select -> Go To Special feature (Home ribbon tab) then searching by Formula errors and and Data validation.
Open Excel
Go to "Inquire" tab page in the ribbon
Select "Workbook Analysis"
Check Items\Cells\With Validation Criteria items. In the "Validation Text" you might spot references to the extenal source.
The "Cell Address" column would give you the list of problematic cells.
Look around any other supsicious findings of the Workbook Analysis tool
Have you considered giving the data ranges different names? DataRange1, DataRange2 etc, or is this not possible due to other constraints. When excel says "some" of the links, how far has it got?
I got it working by ditching the FormulaArray and set the FormulaR1C1 for the entire range. Unfortunately the formula was a bit more complicated.
=INDEX(
'C:\Path\Workbook1Name.xlsx'!DataRange,
ROW() - ROW(Workbook1DataRange) + ROW('C:\Path\Workbook1Name.xlsx'!DataRange) - 5,
COLUMN() - COLUMN('C:\Path\Workbook1Name.xlsx'!DataRange) + 1)

Point to a relative other Sheet in Excel

I'm trying to find a way to from a Cell get the data from a cell in the Sheet that lies to the Left (down in the tray) of the current Sheet.
I know how to call to other sheets via
=Sheet1!A1
But now I need something best explained with
=Sheet[-1]!A1
Any ideas?
Using the tab order as a fundamental part of your calculations is a complicated and risky approach to Excel calculations. Excel offers many alternatives which you'd be better off using:
A simplified version of belisarius's suggestion is: =INDIRECT(A1 & "!A2") where cell A1 has the name of your datasource sheet and A2 has the name of your target cell in your datasource sheet. If you know the name of your sheet of interest (or can look it up in some way), use this method.
If you need to do this often, you might want to export the data into an actual database (i.e. MS Access). Then you can make standard SQL queries and import the results into your Excel file.
If you absolutely want to go the VBA route, then you'd have to write some code that:
3a. Grabs all the names of the active workbook and stores them in an array.
3b. Identifies the index number of the currently active workbook in that array. Subtract 1 from that index to get the sheet to the left.
3c. Gets the cell value from that sheet.
You can also get freaky with Named Ranges. In Excel 2003, go to Insert->Name->Define, add a new Named Range and you can use that name in your calculations instead of referring to the cell by row and column.
Edit
The whole Idea with this one, is that
you have the Sheets arranged, and are
able to move them around, and that
shall change the calculations. – Gnutt
1 hour ago
Please, please, don't do that. For starters, this isn't a standard method of interaction with a spreadsheet. Your end-users will likely be confused and may not even ask for clarification.
You'll want to explore the idea of data validation:
Using Data->Validation, make a drop-down menu listing all the sheets in the workbook (if the names of all the sheets are static, you can just hardcode them, otherwise, you'll need some VBA to pull them).
Then the user just picks the sheet of their choice and indirect() will automatically update everything.
Alternatively, you can also check out Tools->Scenarios. I don't know anybody who uses this feature, but you might be a good candidate for it. Basically, it lets you see the results of calculations using different datasets (i.e. "scenarios") so the user can go back and forth between them.
Using either of the 2 methods above, there's a good chance you can avoid VBA entirely, thus saving users that annoying warning message when they open your file.
=INDIRECT("Sheet"&TEXT(VALUE(MID(CELL("filename",A8),FIND("]",CELL("filename",A8))+1,256))-1,"#")&"!A1")
Caveats:
Your workbook must be saved previously
A8 may be replaced by a reference to ANY non-error cell
I know it's not seen here as good practice, but I want to do something similar. And it does replicate database functionality to an extent but I don't have the time or support to build one from scratch when there's something already half in place.
The reason I want to be able to do this is to create a summary table that links to all the worksheets in the workbook, and automatically extends if you insert a new worksheet. This is to manage a large sales / reporting spreadsheet with lots of different business units that all have the same structure (ie use the same worksheet format to report the same outcomes for different people. There is a high turnover. I want to have several summary sheets reporting different aspects of the source sheets. This is very time consuming to manage if recreating all of the tables each time.
You should be able to use the row() as an index marker to define the information that you want using something like REPLACE, OFFSET or INDEX but you can't as they only refer to 2D arrays.
Whereas Excel treats 3-D references as arrays for statistical functions it does not seem to do the same for reference functions. You might have SUM(sheetX:sheetY!A1) and be able to add a sheet in between, there is not (eg) a INDEX(sheetX:sheetY!A1,n) function. I've tried experimenting using these 2D functions as part of array formulas, and defining the 3D reference as an array or a named range... well it was worth a go :).
So I believe it's a valid action. I also believe there must be a way to do it, but for now I'm falling back on a UDF that has the risk of errors caused by calculation issues, or manipulating a Workbook_SheetChange function or similar. Or creating a single master sheet to control all the others which is populated by using a subroutine based on an array of all workbooks.
these functions work well for me. They get the worksheet index (the parent of
the range you call them with), add or subtract from that index, and then create
a range from that (relative) sheet and the address passed in.
Function relativeSheet(r As Range, iRelative As Integer)
Application.Volatile
relativeSheet = Sheets(r.Cells(1, 1).Parent.Index + iRelative).Range(r.Address)
End Function
Function prevSheet(r As Range)
prevSheet = relativeSheet(r, -1)
End Function
Function nextSheet(r As Range)
nextSheet = relativeSheet(r, 1)
End Function

Resources