Reputation: 506
I have a spreadsheet that has many rows of data. I would like to be able to click on a cell that will run a macro using the data from that row. Since the number of rows will always be changing, I though a hyperlink for each row might be the best way.
ROW MeterID Lat Long ReadX ReadY ReadZ CoeffA CoeffB CoeffC
2 10f62gs 34.1 33.3 102.2 231.3 382.2 4.34 22.1 0.002
3 83gs72g 34.4 31.4 109.2 213.1 372.1 2.23 12.7 0.023
4 43gS128 33.3 32.2 118.8 138.7 241.8 1.94 5.08 0.107
Is there a way to run a vba macro from clicking on a hyperlink and being able to know the row of the cell that clicked on the hyperlink?
Upvotes: 18
Views: 78021
Reputation: 42236
The more interesting way of hyperlink to run a macro, looks to be the next approach (Hyperlink formula). It does not need any event:
Sub testCreateHyperlinkFunction()
'Very important to have # in front of the function name!
Range("A1:A5").Formula = "=HYPERLINK(""#MyFunctionkClick()"", ""Run a function..."")"
End Sub
A more spectacular use will be the next approach, able to keep the initial cells value of the processed range ("A1:A5" in example):
Sub testCreateHyperlinkFunctionBis()
Dim rng As Range, arr As Variant, c As Range, i As Long
Set rng = Range("A1:A5")
arr = rng.Value
For i = 1 To UBound(arr, 1)
Range("A" & i).Formula = "=HYPERLINK(""#MyFunctionkClick()"", " & _
IIf(IsNumeric(arr(i, 1)), arr(i, 1), """" & arr(i, 1) & """") & ")"
Next i
End Sub
Function MyFunctionkClick()
Set MyFunctionkClick = Selection 'This is required for the link to work properly
MsgBox "The clicked cell addres is " & Selection.row
End Function
Do note the Set MyFunctionkClick = Selection line really is needed. The function needs to know, somehow, to what cell the code is referring. If this is missing, the function is called twice and you get a "Reference is invalid" error.
MyFunctionkClick()
runs...Edited:
As I said in my comment a Sub
cannot be called from a cell/hyperlink but it is a way to do it overpassing the limitations Microsoft documented for a UDF function. So, please use the next code to create such a hyperlink in "A1" of the active sheet. Its final goal is to color the interior of "A2" cel from the next sheet and return its value in a MsgBox
. This is done in a Sub
. The problem of this calling way is that any error is not described and the line containing the problem is not yellow highlighted... The return error is all the time: "Reference isn't valid.":
Sub testCreateHyperlinkFunction_Sub()
Range("A1").Formula = "=HYPERLINK(""#MyFunctionSub()"", ""MySub|A2"")"
End Sub
The next function (MyFunctionSub()
called from hyperlink) is able to call a Sub
but not directly. It uses Worksheet.Evaluate
. It also has some returned strings in Immediate Window
:
Function MyFunctionSub()
Set MyFunctionSub = Selection
Dim sh As Worksheet, mySubName As String, cellAddr As String
Set sh = Selection.Parent.Next
Debug.Print sh.Name
mySubName = Split(MyFunctionSub.value, "|")(0)
Debug.Print mySubName
cellAddr = CStr(Split(MyFunctionSub.value, "|")(1))
Debug.Print cellAddr
Dim rng As Range
Set rng = sh.Range(cellAddr)
Debug.Print rng.address
sh.Evaluate """" & mySubName & "(" & sh.Name & ", " & cellAddr & ")"""
MySub sh.Name, cellAddr
End Function
And the called sub looks like this:
Sub MySub(shName As String, cAddr As String)
Debug.Print shName & " from sub..."
With Worksheets(shName).Range(cAddr)
.Interior.Color = vbYellow
MsgBox "Next sheet, range " & cAddr & " value is " & .value & vbCrLf & _
"and now its interior color is yellow!", vbInformation, "Calling a Sub"
End With
End Sub
Now, click the cell keeping the created hyperlink and see the result.
It is good to know that using this method you cannot do whatever you are able to do using VBA. There are a lot of limitations. You can discover them only playing with the code and see what works and what does not...
Upvotes: 20
Reputation: 11
Tried to use a VBA macro which is called by a hyperlink.
It's task is to insert one row below the row containing the =HYPERLINK.
VBA seems to ignore .Insert
Function HyperlinkFnc_AddRow()
Set HyperlinkFnc_AddRow = Selection
MsgBox "Next line of code: Adding a row below selected row " & Selection.Row
Rows(Selection.Row + 1).Insert Shift:=xlShiftDown, CopyOrigin:=xlFormatFromLeftOrAbove
End Function
Sub Button_AddRow()
ActiveSheet.Shapes(Application.Caller).TopLeftCell.Select
HyperlinkFnc_AddRow
End Sub
Observation
When HyperlinkFnc_AddRow() is invoked by a hyperlink function
(e.g. =HYPERLINK("#HyperlinkFnc_AddRow()";"Invoking Function ""HyperlinkFnc_AddRow()"" by this hyperlink should add row below"):
Invoking Sub Button_AddRow() by a button shows, that the code in function "HyperlinkFnc_AddRow" works as intended (a row gets inserted).
Getting this solved would be helpful.
Upvotes: 0
Reputation: 21
Just played with =HYPERLINK() approach and found, that this code will work to create hyperlinks in Excel cells:
Sub testCreateHyperlinkFunction()
Dim r As Range
Set r = Range("A1")
' use SubAddress arg of Hyperlinks.Add method to link our function
r.Hyperlinks.Add _
Anchor:=r, _
Address:=vbNullString, _
SubAddress:="MyFunctionkClick()", _
TextToDisplay:="Hyperlink text"
' note: TextToDisplay arg is desirable here,
' otherwise Excel will insert MyFunctionkClick() here
End Sub
Function MyFunctionkClick()
Set MyFunctionkClick = Selection ' required!
MsgBox "The clicked cell addres is " & Selection.row
End Function
Advantages:
Disadvantages:
Upvotes: 0
Reputation: 5293
I'd just like to add another approach inspired by one of the answers here, that I've used in the past. It means you don't have to create hyperlinks or a helper column to initiate processing the row, you can just double click on any cell in the row you want to process:
On the sheet you want to have the double-clicking work use this:
Private Sub Worksheet_Activate()
Application.OnDoubleClick = "Module1.ProcessRow"
End Sub
Private Sub Worksheet_Deactivate()
Application.OnDoubleClick = ""
End Sub
And then in Module1
have a routine that will process the active cell:
Sub processRow()
MsgBox "Row " & ActiveCell.Row & " on " & ActiveSheet.Name & " was clicked"
End Sub
You should also disable the Excel double-click method in the workbook events:
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Application.OnDoubleClick = ""
End Sub
I find the double-click method is really, really handy and intuitive for a lot of processes e.g. bringing up a UserForm with data populated from the row or transferring that data to another sheet maybe with calcs or formatting etc.
Upvotes: 5
Reputation: 161
Yes you can, follow the below Simple Steps to do so:
Assign Macro to a Hyperlink
Note: Clicking on this Hyperlink, will do nothing because it is assigned to the same Cell Address.
Run Excel Macro by Clicking on a Hyperlink
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
'Check if the Target Address is same as you have given
'In the above example i have taken A4 Cell, so I am
'Comparing this with $A$4
If Target.Range.Address = "$A$4" Then
'Write your all VBA Code, which you want to execute
'Or Call the function or Macro which you have
'written or recorded.
MsgBox "Write your Code here to be executed"
Exit Sub
End If
End Sub
In the Above Code we are comparing the Cell Address and then Executing a Set of Code or Function. There is another way of doing this also. We can Compare with the Target Name and execute the Code. In the above Example as i have given the Name of the Hyperlink Target as MyMacro.
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
'Check if the Target Name is same as you have given
'In the above example i have given the Name of the HyperLink
'is MyMacro.
If Target.Name = "mymacro" Then
'Write your all VBA Code, which you want to execute
'Or Call the function or Macro which you have
'written or recorded.
MsgBox "Write your Code here to be executed"
Exit Sub
End If
End Sub
Upvotes: 14
Reputation: 5770
I think rather than go through the hassle of creating a hyperlink for each cell, you would be better off creating a macro that references the Activecell
property. Next, create a keyboard shortcut for the macro to run. To do so:
Options
If you already have hyperlinks, triggering a macro using the Hyperlink_Follow
event may be best. If not, then consider my recommendation.
Upvotes: 3
Reputation: 2859
This will work for you
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
MsgBox "Row " & ActiveCell.Row & " is clicked"
End Sub
Upvotes: 20