There are a lot of similar questions on here about VBA and hyperlink in excel, but nothing that I could modify to my own situation.
On one sheet I have a column of names (E:E), and on another I have a cell (D13).
What I want to do is hyperlink each cell in column (E:E) such that, when clicked, the hyperlink not only takes me to cell (D13) but also populates cell (D13) with the name that I clicked on.
So, click "John Smith" (Sheet1!E1) ---> (Sheet2!D13) = "John Smith"
First you need a tiny piece of code in a standard module to install the hyperlink in Sheet1:
Sub MakeLink()
Sheets("Sheet1").Hyperlinks.Add Anchor:=Range("E1"), Address:="", SubAddress:="Sheet2!D13", TextToDisplay:="Stuff"
End Sub
Then you need an event macro in the worksheet code area to do the content transfer:
Private Sub Worksheet_FollowHyperlink(ByVal Target As Hyperlink)
ActiveCell.Value = Sheets("Sheet1").Range(Target.Parent.Address).Value
End Sub
I think the best solution may be to use VBA. If you're unsure on how to do that, record s macro that selects a cell in e, then goes to D13 and updates its value, then look at the code that was recorded and use those snippets to create your code. At a high level you'd want to trigger a macro on click of any cell in column E that does something like:
Dim e_value = <value of selected cell in column E>
ThisWorkbook.Sheets("name of sheet 2").Range("D13") = e.value
Application.Goto Reference:=Worksheets("Sheet2").Range("D13"), Scroll:=False
Note that the above contains pseudocode, but it should give you a general idea on how you could proceed.
Related
I am writing an Excel macro to send emails from data in a spreadsheet. The data are in a table with each column providing different variables to create the email (to:, cc:, subject, attachments, etc).
I've got the macro to do what I want on one line of the table. My question is:
How do I scale the VBA code to work for each line of my table? I would like a hyperlink in each row to run the macro using the data in that row. Below is a small snippet of my code as an example:
Sub SendMail()
Dim xContractNumber As String
xContractNumber = Worksheets("Program Info").Range("L10").Value
End Sub
In the above example, I would like a hyperlink that runs the macro using the data in row 10 of the 'Program Info' sheet... And another button or link that would run the macro using data in row 11, and so on.
This answer attempts to combine many of the good answers and comments everyone has already given. The code below contains the functionality for both buttons and hyperlinks in a condensed way.
This code could go in one separate module:
Sub SendMailByButton()
SendMailForRow ActiveSheet.Buttons(Application.Caller).TopLeftCell.Row
End Sub
Sub SendMailForRow(ByVal r As Long)
If r < 1 Then Exit Sub 'Failsafe in case the row number is invalid
Dim xContractNumber As String, xValueInColumnM As String, xValueInColumnN As String
xContractNumber = ActiveSheet.Cells(r, 12).Value 'Col 12 is col "L"
xValueInColumnM = ActiveSheet.Cells(r, 13).Value
xValueInColumnN = ActiveSheet.Cells(r, 14).Value
'...etc.
'...Rest of code to send the actual email
End Sub
If buttons are used, SendMailByButton must be attached to every button's click event, and the above code would be enough.
If manually-added hyperlinks are used, the above code would need to be complemented with the following code in the sheet module for every sheet that uses the hyperlinks (in your case, you may only need to add this code in one sheet's module) ...
'This event is fired when the hyperlink is clicked
Private Sub Worksheet_FollowHyperlink(ByVal target As Hyperlink)
On Error Resume Next
SendMailForRow target.Range.Row
End Sub
Each manual hyperlink would have to link to the same cell it is sitting on (i.e. to a "Place in This Document" with the cell reference set to its current cell).
The problem remains that you will need to manually create a button or hyperlink for every row in your table, which can be a hassle, especially if there are many rows or if the number of rows can grow in future.
A way to circumvent this problem is to have an extra button at the top of the table that allows the user to automatically create the buttons and/or hyperlinks for each row of data (removing excess buttons or hyperlinks if the table shrinks in size). This may require that you post a separate question.
Another way to circumvent this problem is to forego buttons altogether and, instead, use Excel formulas with the native HYPERLINK function (replacing the "regular" links). In that case, the FollowHyperlink event handler above would no longer be needed, but you would need to add the following function (which can go in the same module where SendMailForRow would reside) ...
Function SendMailByHLink()
SendMailForRow ActiveCell.Row
Set SendMailByHLink = ActiveCell
End Function
You would then have to create an Excel formula such as the following in each row (in the column where you want the hyperlink) ...
=HYPERLINK("#SendMailByHLink()", "Send email")
Entering this formula will auto-generate a hyperlink in the cell, and it will tell Excel to execute function SendMailByHLink when the hyperlink is clicked. The function after the "#" is supposed to return the link's target, which is why SendMailByHLink returns ActiveCell to ensure that the focus remains on that cell (if you prefer, you could return another cell such as ActiveCell.Offset(, -2) so that the user is taken to the cell 2 columns back in the same row after the link is clicked). Before returning ActiveCell to Excel, SendMailByHLink will execute the email-sending code.
The nice thing about using a HYPERLINK formula is that you can easily copy/paste the formula up and down the all the rows in the table. Therefore, if your table increases in size, all the user has to do is to copy/paste the HYPERLINK formula into the new rows. The user can also delete excess HYPERLINK formulas if the table shrinks. It may even be possible to have Excel automatically copy the formula if the data is sitting on an official Excel table by using a calculated column.
Sorry for all the extra explanation. If you focus on the code blocks, you will see that the solution is simpler than it looks.
I have a cell whose value is constantly changing through a feed. I want to develop a macro which when activated records the cell value at that instant and pastes it in another cell. Tried finding some formula to do that but no success.
You won't be able to do that with a formula. However, you can write a macro that checks if your cell was changed:
Private Sub Worksheet_Change(ByVal Target As Range)
...
End Sub
If you don't want this type of automation, you could simply add a button to your worksheet which triggers a macro when clicked and does what you are looking for.
To copy the value of a cell into another one, you could use this simple solution:
Range("B1").Value = Range("A1").Value
This will copy the value of cell A1 into cell B1.
I have a document that needs to generate a hyperlink to a cell in the same workbook by getting the address from another cell. Here's what I have right now:
=hyperlink(CELL("address",INDEX('Budget Record'!C3:C105,MATCH(Y73,'Budget Record'!C3:C105,0),1)))
This displays the appropriate location:
'[Calendar Budget.xlsx]Budget Record'!$C$3
However, when clicked, it says that Excel cannot open the specified file.
I have tried manually creating a hyperlink to that value, and it still doesn't appear to work:
=hyperlink('[Calendar Budget.xlsx]Budget Record'!$C$3)
However, if I plug that into the goto dialogue box, it has no problems with it.
Am I missing an extra step?
After looking into all of the built-in hyperlink options that Excel offers, I could not find a way to have Excel link you to a dynamic/ changing cell reference. Naturally, I turned to VBA :)... this is a very simple macro with only a few lines of code. Give it try:
Press Alt + 11 to open the Visual Basic Editor (VBE)
If your project explorer is not already open, click this icon:
Double click the worksheet tab that you want the hyperlink to work on:
Paste the following code into the white space:
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
'check if user is selecting the 'hyperlink' cell
If Target.Address = "$A$1" Then
'run the 'selectCell()' subroutine
Call selectCell
End If
End Sub
Sub selectCell()
Dim goToAddress As String
'get cell address
goToAddress = Range("A2").Value
'send user to this cell
Range(goToAddress).Select
End Sub
Go to your worksheet and test the script by typing G3 in cell B1.
Select cell A1. The macro should have automatically selected cell G3.
Hope this helps!
(Posted on behalf of the OP).
I have identified a solution. Basically it looks like the problem was in the formatting.
Basically I needed three steps. The first one is getting the location of the cell returned as a full address (including the file, sheet, and Cell). I do that with this:
=CELL("address",INDEX('Budget Record'!C3:C105,MATCH(Y73,'Budget Record'!C3:C105,0),1))
Here's a sample of what that results in:
'[Calendar Budget.xlsx]Budget Record'!$C$3
The problem with this is that the apostrophe at the beginning is in the wrong spot. To work as a hyperlink, the string should be this:
[Calendar Budget.xlsx]'Budget Record'!$C$3
So, I have a step where I remove the first 22 characters of the starting string:
=RIGHT(Z73,LEN(Z73)-23)
This results in the following:
Budget Record'!$C$3
Next, I need to add on this to the start of the string:
[Calendar Budget.xlsx]'
I do that with the following:
=HYPERLINK("[Calendar Budget.xlsx]'"&AA73)
The resulting output looks like this:
[Calendar Budget.xlsx]'Budget Record'!$C$3
So, we have a hyperlink to a cell in another sheet that dynamically changes depending on the initial referenced cell.
Good day,
I a new to VBA/Macro's and I am working in Excel. What I need to do is take a value in a specific cell (A4) and use that obtained value to go to a sheet in the same workbook with the same name. Thus in my dropdown in cell A4 I have 8 different options and dependent on this I need to go to a sheet with the same name.
Please help.
Assuming it is a Data Validation DropDown placed in the Excel Worksheet cell "A4", refer to the following VBA code snippet to achieve the result (i.e. switch to the Worksheet on DropDown select event):
Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$4" Then
Worksheets(Range("$A$4").Value).Select
End If
End Sub
Hope this may help.
I am trying the folowing since a few days but due to my lack of VBA skills don't get it working.
Scenario:
User: Selects a value from dropdown list (cells allow only a list
defined in another sheet).
Code: Copy the value left to the appropriate list value. (This is a list of names.)
Code: Paste the value into a specific field in sheet one.
Example:
The user is picking the value "Team One" from a dropdownlist in A1 in sheet one. This list is defined on sheet two. Next to each item of the list on sheet two is a cell with a comma separated list of names.
After the user has picked a team from the dropdown list, the corresponding list of names is copied into the field B1 in sheet one.
This procedure should only be fired when A1 is changed.
Hope I could make myself clear. If I finally find the solution myself, I will post it here.
Thank you for reading this.
You can do this without VBA. In the field you want the list of names pasted into enter this formula:
=IF(ISBLANK(<address of dropdown on Sheet1>),"",INDEX(<address of list to left of values on Sheet2>,MATCH(<address of dropdown on Sheet1>,<address of dropdown values on Sheet2>,0)))
This will be blank when nothing is selected from the dropdown and will display the appropriate list of names when a value is selected.
For example, if the dropdown is in B1 on Sheet1, the dropdown values are in B1:B9 on Sheet2, and the corresponding list of names are in A1:A9 on Sheet2, you would use this formula:
=IF(ISBLANK(Sheet1!B1),"",INDEX(Sheet2!A1:A9,MATCH(Sheet1!B1,Sheet2!B1:B9,0)))
EDIT (per comment):
To use this in VBA, you'll need to do something similar to what #chris neilsen suggested. In the Worksheet module, you'll need to create a sub for a change event:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Range("B1")) Is Nothing Then
Range("A1").Formula = "=INDEX(Sheet2!A1:A9,MATCH(Sheet1!B1,Sheet2!B1:B9,0))"
If IsError(Range("A1").Value) Then
Range("A1") = ""
Else
Range("A1").Value = Range("A1")
End If
End If
End Sub
To remove any confusion, A1 is the cell that will display the output.
To do this as VBA, you would do something like the following. Per your original question, there is a list on Sheet2 that corresponds to the selection from the dropdown box and populates on Sheet1.
In the VBA editor:
In Sheet1, add the following methods
Private Sub ComboBox1_Change()
If ComboBox1.Text <> "Select" Then
Dim selVal As String
selVal = ComboBox1.Text
Range("B1").Value = GetList(selVal)
End If
End Sub
Public Function GetList(ByVal Value As String) As Variant
Dim result As Variant
result = Application.VLookup(Value, Worksheets("Sheet2").Range("A1:B100"), 2, False)
GetList = result
End Function
In the workbook object code, enter the following method:
Private Sub Workbook_Open()
With ThisWorkbook.Worksheets("Sheet1").ComboBox1
.AddItem "Team One"
.AddItem "Team Two"
.AddItem "Team Three"
.AddItem "Team Four"
.AddItem "Team Five"
.Text = IIf(.Text = "", "Select", .Text)
End With
Worksheets("Sheet1").Activate
End Sub
I should note that you could do this without any vba by simply using a a list control found in the Data Validation option in Excel. When you make a selection change in that, you would then use a standard VLookup in cell B1 to grab the corresponding value(s).
To implement this in VBA, use a Change event to monitor the data entry cell.
Assuming you have named your validation data range as ListData, put his in the module for Sheet1
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$A$1" Then
[B1] = Application.WorksheetFunction.VLookup(Target.Value, [ListData].Resize(, 2), 2, 0)
End If
End Sub
I would advocate an approach similar to the one that Excellll described, but with VLOOKUP rather than MATCH. To do this, you'd need to have your lists of names to the right of each team's name. For example:
| A | B
1 |Team 1 |Albert, Beth
2 |Team 2 |Carlo, Delia
3 |Team 3 |Egbert, Frederika
Now, if the team's name is at cell B7, you could use this formula to get the associated list of names:
=VLOOKUP(B7, Sheet2!$A$1:$B$3, 2, FALSE)
EDIT
See Doug Glancy's comment below explaining why Excellll's solution is better than using VLOOKUP.