I'm trying to create a dynamic link in Excel 2010. Below I have created a function that gives me the parent folder workbook to reference. When I try and add ' to the LEFT keyword excel does not accept it. What I'm trying to do is reference workbook in parent folder and want to make sure when the parent folder is moved all files stay linked.
My question is how to create a Link from the LEFT function below. Thanks
=LEFT(CELL("filename"),LARGE((MID(CELL("filename"),ROW(1:255),1)="\")*IFERROR(SEARCH("\",CELL("filename"),ROW(1:255)),0),2)) & CONCATENATE("[Book1.xlsx]Sheet1'!$A$1")
This should work, assuming your left formula is correct (not tested):
=INDIRECT("'["& LEFT(CELL("filename"),LARGE((MID(CELL("filename"),ROW(1:255),1)="\")*IFERROR(SEARCH(" \",CELL("filename"),ROW(1:255)),0),2))&"Book1.xlsx]Sheet1'!$A$1")
To create a link to a file you need to enter the full path and reference directly into a formula (INDIRECT won't work). One way to put a link to the parent folder in the active cell is with this VBA command:
activecell = "='" & activeworkbook.path & "\..\[Book1.xlsx]Sheet1'!$A$1"
Paths are stored relative to the workbook as stated in the response to your previous linked question. It's also possible to retrieve values from closed workbooks using a udf such as:
Function Eval(Text As String)
Set xl = CreateObject("excel.application")
eval = xl.ExecuteExcel4Macro(Application.ConvertFormula(Text, xlA1, xlR1C1, True))
Set xl = Nothing
End Function
or by downloading Laurent Longre's Morefunc.xll free add-in which has a function INDIRECT.EXT, (beware however that these methods are less efficient and links aren't created so won't update when folders are moved).
Related
Could anyone from this group can offer some advice on the problem I'm trying to solve? I was attempting to open a PDF document to a specific page using the Excel Hyperlink function. I tried to solve this mystery but to no avail. Hope someone can provide me their thoughts and ideas.
I tried Google and Youtube but only few were related to my issue and the solution discussed was not working on my situation... or maybe i missed something. This will be a great help for me once the issue is solved. Thank you in advance.
Using a macro enabled workbook you can hi-jack the hyperlink open event but it isn't as dynamic as we would hope it to be. Unfortunately, we cannot cancel any followed hyperlink using Worksheet_FollowHyperlink so we need to find a way around following a direct hyperlink.
We can create a hyperlink which goes nowhere by referencing itself then set the text to display as "Follow Link". Because the cell reference is then in the hyperlink, we can use an offset from that to get the desired address and sub address from the column before it; which then allows us to open the PDF at the desired place.
Unfortunately, the hyperlink if copied down will still reference the original cell, so each link would need to be edited separately. To date I haven't found a way to use the HYPERLINK function successfully.
The hyperlink format in the cell to the left would need to be the full path appended with "#page=" and the relevant page; e.g. C:\links\blah.pdf#page=6
In the worksheet module
Const AcrobatReader = "C:\Program Files (x86)\Adobe\Acrobat Reader DC\Reader\AcroRd32.exe"
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
If Target.TextToDisplay = "Follow Link" Then
Dim Ref As String: Ref = Range(Target.SubAddress).Offset(0, -1).Text
Dim URL() As String: URL = Split(Ref, "#page=")
If UBound(URL) > 0 Then Call OpenPDFtoPage(URL(0), CLng(URL(1)))
End If
End Sub
Function OpenPDFtoPage(FilepathPDF As String, page As Long)
Dim Path As String: Path = AcrobatReader & " /A ""page=" & page & """ " & FilepathPDF
Shell Path, vbNormalFocus
End Function
The AcroRd32.exe path may need updating for specific installations
Maybe having just one "Follow Link" hyperlink where the URL in the cell next to it is more dynamic may allow this to be a bit more useable.
I'm making a macro in excel 2010 and my goal is that everyone can use this macro for their own work. Therefore I have to make it very flexible.
Everyone names their own workbook (I've solved this in the macro by using ThisWorkbook), but everyone also names their own extraction file (from where the new data comes).
However, almost no-one knows how to work with VBA so it's not possible to adjust this reference in the code every time.
Therefore, I've added a new sheet: 'Personalize'
In here, the person can add the name of the extraction file in a specific cell.
Unfortunately I don't know how to open a workbook that has the name of a specific cell in the current workbook.
I tried, for example, Windows("ThisWorkbook.Sheets("Personalize").Range("B3")").Activate but it didn't work.
The same thing with sheets that can be named differently, I don't know how to adjust them in the macro without using VBA in every case.
Does anyone have any ideas or suggestions?
Thank you so much in advance!
Kind Regards,
Hendrik
If you want to open a workbook that's closed you need the full path:
dim wkb as workbook
dim wbPath as String
wbPath = ThisWorkbook.Sheets("Personalize").Range("B3").value
Set wkb = Workbooks.Open(wbPath )
If you want to activate a workbook that's already opened, you don't need the full path but the workbook's name (such as "Workbook1.xlsx"). For this you can shave off the path before reaching "Workbook1.xlsx" (alternatively if the workbook is always going to be opened first, just have them enter the workbook's name directly and skip taking out the rest of the path):
dim wbname as String
wbname = ThisWorkbook.Sheets("Personalize").Range("B3").value
Do until Instr(wbname, "\") = 0
wbname = Mid(wbname, instr(wbname, "\") + 1) 'I didn't test this, just going off the top of my head
Loop
Workbooks(wbName).Activate
Be sure to handle your errors properly. For reference: VBA Excel simple Error Handling
Test what happens when you try to input a name that's incorrect, for example. You want to handle those errors with appropriate messageboxes or the users may feel like your program doesn't work.
The setup
I have an Excel workbook stored on my hard drive.
The structure is such that on the first sheet I have a list of the names of the other sheets in the same workbook (...which can be created or deleted).
All the names on the list, on the first sheet, are supposed to be hyperlinks to the corresponding sheet in the workbook. So, by clicking the name on the first sheet you jump to the corresponding sheet.
When a new sheet is created a macro creates also the new name on the list on the first sheet and makes a hypelink of it. This works.
...BUT...
The links point to the stored version of the file, not to the open workbook! Clicking the links opens the stored file and not the one which is under work.
QUESTION: How to create a hyperlink that always points to the same open workbook and not to the stored copy of it?
Try this:
ActiveSheet.Hyperlinks.Add Anchor:=Selection, Address:="", SubAddress:= _
"Sheet3!", TextToDisplay:="Link to sheet #3"
Address is the URL and SubAddress is a localtion of the page (or a sheet or a range in excel workbooks).
You may try creating the hyperlink as a formula (via VBA, as you need).
I am using the parameters you posted, this may need a little adjustment.
Dim rngsrc as Range, rngtrgs as String
Set rngsrc = Worksheets("Summary").Cells(Cell.Row, 5)
Set rngtrg = "'" & sSheetName & "'!B5"
rngsrc.FormulaR1C1 = "=HYPERLINK(" & rngtrgs & "," & sSheetName & ")"
See
Official documentation
Example 1
Example 2
This (hopefully) answers your question. As a separate note, it still remains to be clarified why you see the behavior you see.
It seems that the problem comes from the following fact: My file is in a SharePoint folder. If I open it just for reading, the hyperlinks work fine. If I open the file for editing, a copy of the SharePoint file is placed on my hard disk, on a specified location. So, the path to the file is not the same as it would be if I open it read-only. Should I use hyperlink.follow to solve this?
So, this all comes down to the question: In VBA/Excel, can I create a hyperlink which always points to a location in the same opened file so that the hyperlink ignores the storage path of the corresponding file? Using empty string (or BLANK) doesn't help as the address parameter in hypelinks.add as Excel seems to automatically fill in the whole storage path.
I upgraded to Office 2013 and "PADAM": The problem vanished! It seems that there was a bug in Excel/VBA in this in the 2007 version.
I have an Excel sheet that draws data from other, closed Excel workbooks. Currently it works fine when I list out the closed workbook's entire path, but I'd like to use a variable, stored in a separate cell, as part of the path name.
For example, I am trying to reference a workbook called
workbook12.10.12.xls
In a separate workbook (we'll say the "active" workbook), I have a cell with formula
=INDEX('C:\Path[workbook12.10.12.xls]SHEET1'!$B$1:$B$5, MATCH("match text", 'C:\Path[workbook12.10.12.xls]SHEET1'!$A$1:$A$5, 0))
which finds the value in workbook12.10.12's B column corresponding to the cell in the A column that contains "match text." This works fine; however, I have a cell in the active workbook with the value
12.10.12
and would like to somehow reference this value in the INDEX function.
I can't have the other workbooks open, so the INDIRECT function won't help. Googling seems to suggest that Excel doesn't have a simple one-stop solution for this kind of thing... can someone help please? Thanks!
From Frank Kabel's 2004 post at Dicks Blog you could
Use Laurent Longre has developed the free add-in MOREFUNC.XLL which includes the function INDIRECT.EXT
Use SQL.REQUEST as described here *does not appear to be supported anymore and I am not clear if this could handle your INDEX\MATCH request
Use Harlan Grove’s PULL function
In addition you could:
Create a "dirty link" directly via code that enters a formula referring to the workbook you need
For pulling values - but not for working with ranges - you could use Walkenbach's ExecuteExcel4Macro XLM method
I think what you what to do is to find the specific record in the specific file (date named).
You may do it by a simple VBA code.
Suppose you are going to search for a record# say REC001 in A1, date file 12.10.12 at cell C1, and have the result to be display at cell A7
On the worksheet you want to enter input and get output, rightclick the sheet tab and select 'View code' and paste the following code:
Private Sub Worksheet_Change(ByVal Target As Range)
If Intersect(Target, Range("C1")) Is Nothing Then Exit Sub
Range("A7").Formula = "=INDEX('C:\TEMP\[workbook" & Range("C5").Value & ".xls]SHEET1'!$B$1:$B$5, MATCH(" & Range("A1").Value & ", 'C:\TEMP\[workbook" & Range("C5").Value & ".xls]SHEET1'!$A$1:$A$5, 0))"
End Sub
Then every time you edit C1, the formula will be updated.
Actually I don't think you should use INDEX function in your case. It is more simple to use a VLOOKUP. E.g.:
Range("A8").Formula = "=vlookup(" & Range("A1").Value & ",'C:\TEMP\[workbook" & Range("C5").Value & ".xls]SHEET1'!$A$1:$B$5,2,false)"
You will have to note on a few points:
1. you paste the code on the Sheet1 object (or the sheet name) but not to insert a new module
2. your path and filename for the target file is correct, including the .xls and .xlsx
3. your original file only cover to $B$5
4. on VBA, recommend you to save the file as .xlsm format
You can store a full reference including the file path to a range in a closed file in a name in excel (either directly or via VBA based on selections in different cells and using the Worksheet_Change procedure as above) and then refer to the file using the name in a formula as normal. This gets over the limitation in the INDIRECT function.
The VBA is very simple:
New_Ref = Sheets("Wells").Range("K6")
ActiveWorkbook.Names("MyWorkbook").RefersTo = "=" & New_Ref
The only trick is to be sure to include "=" in the name.
Names have a huge number of uses once you spot this. I have used this to get data from a closed file on a remote sharepoint site without any difficulty - I assume sharepoint deals with all the permissions.
First: I'm using Excel 2007, but the code has to work for Excel 2003 as well.
My problem is the following: I need to access cells in a different workbook, which may be closed. The following code can be found all around the web:
Function Foo()
Dim cell As Range
Dim wbk As Workbook
Set wbk = Workbooks.Open("correct absolute path")
' wbk is Nothing here so the next statement fails.
Set cell = wbk.Worksheets("Sheet1").Range("A1")
Foo = cell.Value
wbk.Close
End Function
sadly, wbk is Nothing after the open statement (I'd love to give a better error message, but no idea how I'd do that; what I'd give for a real IDE and an useful language :/). The absolute path is correct and points to a valid excel xlsx file.
Also I assume the best way to do this, is to "cache" the workbook and not open/close it every time the function is called? Any possible problems with that (apart from having to handle the situation when the workbook is already open obviously)?
Image while stepping through:
I can reproduce this problem. It only happens to me when I attempt to paste this code into a user-defined function.
I believe this is by design (the quote is for XL 2003, but the same thing happens to me on XL 2010)
Using VBA keywords in custom functions
The number of VBA keywords you can use in custom functions is smaller than the number you can use in macros. Custom functions are not allowed to do anything other than return a value to a formula in a worksheet or to an expression used in another VBA macro or function. For example, custom functions cannot resize windows, edit a formula in a cell, or change the font, color, or pattern options for the text in a cell. If you include "action" code of this kind in a function procedure, the function returns the #VALUE! error.
http://office.microsoft.com/en-us/excel-help/creating-custom-functions-HA001111701.aspx
The only workaround I've found is to call this kind of code via a normal macro. Something like selecting the cells to apply it to, then looping over Selection or the like.
You can use this (similar to what Bruno Leite proposed, but much simpler to write):
Dim excelApp As New Excel.Application
excelApp.Visible = False
Set WB = excelApp.Workbooks.Open(FileName, xlUpdateLinksNever, True)
As UDFs are called repeatedly, you should make sure to do an excelApp.Quit before exiting the function (and a WB.close(False) before) to avoid having countless Excel instances running on your box.
I spent some thoughts on it and came to the conclusion that you cannot mess around with the workbooks of the current instance of excel while executing a UDF. On the other hand, opening a second instance of excel will do the job without interference.
To get data from Workbook without is open, you can use this, with ADO connection.
To use in Excel 2007 change this
Microsoft.Jet.OLEDB.4.0
to
Provider=Microsoft.ACE.OLEDB.12.0
and
Extended Properties=\"Excel 8.0;HDR=Yes;\
to
Extended Properties=\"Excel 12.0;HDR=Yes;\
[]'s
The workaround of putting my routine into a separate macro in the workbook module, and calling that macro from the Workbook_BeforeSave code, seems to have done the trick.
I've had a similar issue, but in my case it's a "Workbooks.Open(filename)" command at the start of a small routine embedded in Workbook_BeforeSave. VBA just skips right over the line of code as if it weren't there, it doesn't even report an Err.Code or Err.Description.
The only clue for me was that it's part of the Workbook_BeforeSave routine, and the limits with Functions above seem to indicate that could be a possible cause. So I dug around further to find more details.
It seems that Workbook_BeforeSave disables Excel from opening more files, and I guess there's a good reason for doing that, since the File > Open option is still visible in the File menu, but it can't be clicked. Strangely, the Open toolbar icon/button still works, and so whilst I can manually open the file from there, I wonder if it's because it's impossible to call this action from VBA code and that's why they allowed it?
You don't have to "Set" a cell, It's part of the workbook class (as far as I know). Just use the following...
foo = wbk.Worksheets("Sheet1").Range("A1").Value
I would suggest that you open you the new workbook upon opening the calling workbook, in the worbook_open event.
You then store the new workbook reference in a global variable.
Then the function called by your cell uses the said global variable instead of trying to open a new workbook. This way you go around the limitations.
PS : Of course global variable are to be avoided, some sort of container would be better than a direct global variable.
You can check the error in a proper way by using the following code:
filelocation = c:\whatever\file.xlsx
On Error GoTo Handler 'this is key as if the next row returns an error while opening the file it will jump to the Handler down there.
Set wkb2 = Workbooks.Open(filelocation, ReadOnly)
Handler:
MsgBox "File " & filelocation & " does not exist or cannot be reached, please review and try again"
I know that this does not answer the question (that's why I also landed in this thread, as I cannot open the file and can't understand why is that so)
Cheers,
RV