VBA - GoTo Command - excel

I'm trying to use the GoTo command in Excel to GoTo a variable cell value, but I'm struggle how to get the cell address into VBA, any thoughts?
Within my Excel document I have defined the name of a cell (i.e. created a range), lets call it "x" for ease, that contains the cell address, for example $B$3. However it's important to note the value within the range changes as I modify the document, it's not static.
I have tried
Application.GoTo Range("x")
and
Application.GoTo Range("x").value
but neither of these seem to work.
Can I achieve what I need to using GoTo or should I be using a different command entirely?
The context should it help is that I have created a task list tab and when selecting that tab I want to GoTo the latest actionable task. I understand what this is, I just can't reach it!

You set a string variable to the cell location, and then use GoTo with Reference - see example below:
Dim myCell As String
myCell = Range("A3").Value
Application.GoTo Reference:=Range(myCell)

The GoTo statement is used for branching in the code only. It doesn't interact with the cells at all. See the Microsoft docs here.
As findwindow says in the comments, you need to use the Range.select method. MSDN here

Related

Clicking on a dynamic hyperlink with VBA to jump to a new position within the same sheet

I have a large chunk of VBA code that generates a result sheet. It's fairly large, and in order to better, faster dig through it, I've added a dynamic hyperlink at the top of the sheet, with a drop-down menu next to it. Drop down the item, click the hyperlink, and you get whooshed over to the part of the spreadsheet you want to get to.
I've been asked to make it even easier, and when you select an item from the drop down menu, to auto-whoosh you to the correct location. So an on-trigger macro to click a dynamic hyperlink.
Ok, so far, so good. Do some googling, and I end up with the following:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("HyperlinkType")) Is Nothing Then ClickHyperlink
End Sub
Private Sub ClickHyperlink()
ThisWorkbook.Names("HyperLinkTotal").RefersToRange.Hyperlinks(1).Follow
End Sub
Unfortunately, this results in a subscript out of range, which apparently can happen with dynamic hyperlinks.
The hyperlink formula for reference:
=IFERROR(HYPERLINK("#Totals!B"&MATCH(HyperlinkType,B:B,0),"Jump to "&HyperlinkType),"Please enter a valid type")
1) How do I fix the subscript out of range issue?
2) Is there a better way than hyperlink(1)? It almost looks to me like it's indexing the hyperlink, and I'm not sure that's exactly what I'm looking for - I'm looking for the hyperlink in the cell, not the first in the workbook. I may be misunderstanding.
Previous instances of this, and similar question on stack overflow:
Excel Macro executing Hyperlink shows 'Subscript out of range error' - no answer
Hyperlinks.Follow error: Run-time error '9': Subscript out of range - completely different method used to solve that particular issue (XY problem)
Hyperlink code shows Subscript out of range error vba excel - used a reserved word as a variable
VBA to open Excel hyperlink does not work when hyperlink generated with a formula - Seems to be promising, I think this might solve it.
Thanks to #Forward Ed, I was able to get it working with select.
Forgive the lazy lack of variables:
Option Explicit
Private Sub Worksheet_Change(ByVal Target As Range)
If Not Intersect(Target, Me.Range("HyperlinkType")) Is Nothing Then ClickHyperlink (Me.Range("HyperlinkType").Value)
End Sub
Private Sub ClickHyperlink(ActuarialString As String)
Dim ResultRow As Long
ResultRow = Me.Range("B:B").Find(ActuarialString).Row
Me.Cells(ResultRow, 2).Select
End Sub
To put it another way: If you want to click on a dynamic hyperlink, you're probably running into the XY problem. Step back, figure out exactly what you're trying to accomplish, and use one of VBA's other tools to do it.

Is it Possible to View Microsoft VBA Code for Their Standard Excel Formulas?

I am creating several User Defined Functions (UDF's). I'm proficient enough that I can write most of the code on my own. However, there are some situations where I am interested in seeing how Microsoft handles inputs, defends against errors, and optimizes performance. Does anyone know where I could find the exact Visual Basic syntax that Microsoft uses to write their standard Excel formulas?
To illustrate, below is a UDF I have created to mimic Vlookup and I'd like to compare it to Microsoft's function. For example, how does Microsoft's code analyze the first column? Does it use a cell loop or a Match function? How does it handle errors?
Public Function VLookupPGCodeRider(TextInput As String, SearchRange As Range, _
ColumnIndex As Integer, PartialMatch As Boolean) As String
Dim WS As Worksheet, Rcell As Range
Set WS = Sheets(SearchRange.Parent.Name)
On Error GoTo BadResult
If TextInput = "" Or SearchRange Is Nothing Or Not (IsNumeric(ColumnIndex)) Then
GoTo BadResult
End If
On Error GoTo 0
'I would like to see how MS sets up this loop, or maybe they use match?
'But then how does match work??
For Each Rcell In Intersect(SearchRange.Columns(1), WS.UsedRange).Cells
If Not (PartialMatch) Then 'how 99.9% of users use Vlookup
If Rcell.Value = TextInput Then
VLookupPGCodeRider = Intersect(Rcell.EntireRow, SearchRange.Columns(ColumnIndex)).Value
Exit Function
End If
Else
'what is considered a partial match??
End If
Next Rcell
'if nothing found or error in the beginning of formula...
BadResult:
VLookupPGCodeRider = "#NA"
End Function
Again, I'm not looking for answers to Vlookup specifically, I just want to see Microsofts' method to handling similar formula challenges I'm facing with a variety of my UDF's.
I have checked in the Excel VBA Object Browser (2013) and I see the below screenshot, which is not very helpful. When I look through my Excel installation folder, I'm not finding anything that corresponds with the naming structure of the worksheetfunction.
I suppose it's possible that MS intentionally does not want to share this information, which would be disappointing, but I'd appreciate confirmation if anyone is certain.
Thank You.
The code for Excel.WorksheetFunction.VLookup, etc, is not written in VBA. It would be written in something like C++. Just as the VLOOKUP functionality used by a formula in Excel itself would be.

Using # in a path name for a hyperlink in excel vba

I am creating a vba For loop to cycle through cells in a range and creating a hyperlink to file folders based on the text within the cell. See below:
Set rng = Worksheets("Sheet1").Range("A1:A100")
For Each cell In rng
address1 = "C:\Users\Desktop\Tests\Comm Review\Item #" &
cell.Text
If Not IsEmpty(cell) Then
Worksheets("Sheet1").Hyperlinks.Add Anchor:=cell, Address:=address1, TextToDisplay:=cell.Text
End If
Next cell
The cell value will be something like 1001.T0502 and the actual folder name that I am linking to will be Item #1001.T0502. So in my address1 variable i create the path to the folder.
However, when I do this it creates the path with everything but #1001.T0502 and ends up stopping at "\Item". If I were to drop the number sign(#) though it includes the number and ends up being Item 1001.T0502. For some reason the number sign stops it from making the correct path. What am I missing here? There are already 200 folders with the number sign in the folder name so going back now and taking it out would be too much work.
Any help would be appreciated. Thanks!
You cannot use a pound character in a file name for a hyperlink in an Office program. See official Microsoft documentation here:
https://support.microsoft.com/en-us/help/202261/you-cannot-use-a-pound-character-in-a-file-name-for-a-hyperlink-in-an
Seems totally wacko if you ask me, but alas, I think you're trying to solve an unsolvable problem.
But, fear not, I did think of a potential work around. Instead of making the cells actual hyperlinks, you could just recolor the cell to blue with an underline and then use this little trick to capture when the cell is selected and open Windows Explorer to the corresponding file path.
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
If Selection.Count = 1 Then
If Not Intersect(Target, Range("A1:A100")) Is Nothing Then
Shell "explorer ""C:\Users\Desktop\Tests\Comm Review\Item #" & Target.Value & """", vbNormalFocus
End If
End If
End Sub
The only downside I can see here is that selecting the cell with the arrow keys also opens the corresponding folder. There may be a work around to that, but I don't have time at the moment to research it.
I hope this helps!

Calling a custom built VBA function when an Excel cell is changed

I'd like to preface this question by saying that I am an undergrad in college who knows C++ and has a very rudimentary understanding of VBA.
Now then, as stated in the title I need some help configuring some VBA code for an Excel worksheet so that whenever a cell in a column (specifically the D column) is modified it will automatically update other cells within the same row.
Essentially I want this to work such that when user Bob modifies cell D26 (for example) it will call a custom function I built and insert that code into cell B26 and then repeat with a different function for cell C26.
However, this function needs to be such that if cell D27 is modified it will only modify other cells in row 27, leaving row 26 and prior or subsequent rows alone until such a time as this function is called in D28 and so on.
I'm not entirely sure if this is even possible but I'd be gracious if anybody could help me configure this.
The code I built/scavenged from the internet for my custom function is this:
http://pastebin.com/RE0V2nrT
The second function I want to call for this project is the =TODAY() function built into Excel.
The code I have scraped together so far for checking if the cell has changed is this:
http://pastebin.com/S5E8cmty
If anybody could help me understand how to write what I'm looking for it would be much appreciated. If you have a different approach to solving the issue I would also love to hear it... as long as you could help me then enact your solution, haha!
Anyways, thanks to anybody who replies.
Have a look at the worksheet events available within the Excel namespace.
For this, you would use the Change event
If you double click on the worksheet you want to monitor, you can insert a Worksheet_Change sub. Then you can use the intersect function to check if the changed cell was within your range you want to monitor (e.g. D:D).
You can specify which cells you want to change. Here I just gave an example based on what you asked. This will put the output of your function into cell B[R] and put the current date into cell C[R]. Note that I'm using the Now() function since there is no Today() function in VBA. Since this returns both date and time, I'm using the Format function to get just the date.
Just for fun, let's go a little further into the object model and first get the Worksheet object to which the target range belongs. This is not 100% necessary - you could just rely on ActiveSheet. Now, you probably don't need to do this, and it's mostly just for fun, but it's also worth noting that if you were programmatically making changes to this sheet, but had not activated this sheet first (so another sheet was active) and you had not turned off EnableEvents you would get some strange results :)
Private Sub Worksheet_Change(ByVal Target As Range)
Dim TargetSheet As Worksheet
Set TargetSheet = Target.Parent
With TargetSheet
If Not Application.Intersect(Target, .Range("D:D")) Is Nothing Then
.Cells(Target.Row, 2) = ExtractWindowsUser()
.Cells(Target.Row, 4) = Format(Now(), "YYYY-MM-DD")
End If
End With
End Sub
Explanation
Worksheet change sub is declared like this. The Worksheet objects have pre-defined method stubs for events. Kind of like an interface, though not listed as an interface in the documentation. If you think of it in that concept, this is your event handshake. See the link I posted above for a list of the worksheet events available.
Private Sub Worksheet_Change(ByVal Target As Range)
In the next lines we are getting the worksheet object to which the object named Target belongs. You can see in the sub declaration that Target is declared as an object of the type Range. If you check out the Worksheet object (linked above) or the Range object documentation you'll see that the range object is a member of the worksheet object, and the documentation kind of sucks here, but FYI the worksheet object is contained within the Parent property. Now, originally I had my code using the ActiveSheet member of the Application object - but I've edited it for the reasons given in my answer above.
Dim TargetSheet As Worksheet
Set TargetSheet = Target.Parent
I use With Blocks to save typing the same Worksheet reference in multiple places. A With block just lets me access the members of the namespace specified (in this case members of the object TargetSheet) by typing .SomeMember. The compiler understands that every reference like this refers to whatever is specified in the opening With .... statement. I personally like this for readability, but I also recommend it for maintenance (change reference one place vs many). Also having a single reference gives a tiny, insignificant, probably not worth mentioning performance boost over multiple references as well.
With TargetSheet
Next we check whether or not Target is within the range of cells we want to watch. The If....Then should look familiar enough. For our condition we use the boolean operator Not to check if the result of the intersect function (linked above) Is Nothing. The reason we do this is to check if the return is allocated. If an object is allocated the Not SomeObject Is Nothing condition will evaluate to False. If the object is not allocated (i.e. our Intersect function failed to return anything) then the statement evaluates to True. So, from the Intersect function documentation we know that if our return is allocated, the ranges intersect and the intersecting range object was returned. Thus if we want to know if they intersect, we can just check for the opposite of a failure.
If Not Application.Intersect(Target, .Range("D:D")) Is Nothing Then
The next lines then just execute some code on cells within the same row as Target. We use the Cells member of the worksheet object to specify what cells to modify. Per the documentation, the default property for Cells is Item which lets us access a range object through a row and column index like this: .Cells[Row,Column]. So, I simply use the row of our Target object and the column you wanted (column "A" =1, "B"=2, etc. You can see this by changing excel properties to R1C1 reference style if you are interested).
.Cells(Target.Row, 2) = ExtractWindowsUser()
And I think the Format() and Now() functions are pretty well explained in the documentation.

Creating a custom hyperlink function in excel

I have searched far and wide, but can't find an answer to this simple question. I want to make a custom function in excel which will create a hyperlink.
Excel has a built in hyperlink function that works like this:
=Hyperlink(link_location, display_text)
I want to create a function called CustomHyperlink which takes one parameter, and returns a hyperlink to a google query with that parameter. Just for the sake of the question, lets assume that the passed parameter is a alphanumeric string, with no spaces.
Essentially, calling
=CustomHyperlink("excel")
should be the same as calling
=Hyperlink("http://www.google.com/search?q=excel", "excel")
This seems like such a simple task, but I absolutely cannot find a way to make this function.
Can anyone offer some quick help?
I can offer a partial solution, one that will update an existing hyperlink. This only makes sence if you are using it like, say
CustomHyperlink(A1)
were A1 contains the required serch term
To use,
enter your UDF formula in a cell, eg =CustomHyperlink(A1)
create a hyperlink on the cell (right click, Hyperlink...) . This can be any hyperlink, valid or invalid
put the required search term in the referenced cell, eg in A1 put excel
When the UDF runs it will update the hyperlink to Google the entered search term
Function CustomHyperlink(Term As String) As String
Dim rng As Range
Set rng = Application.Caller
CustomHyperlink = Term
If rng.Hyperlinks.Count > 0 Then
rng.Hyperlinks(1).Address = "http://www.google.com/search?q=" & Term
End If
End Function
In VBA editor you can use
ThisWorkbook.FollowHyperlink Address:=(strWebsite), NewWindow:=True
Which will take you to that specific website, and just build a function around that to navigate you to the site you need.
Nice idea although this isn't possible.
You seem to want to have the formula of the cell as one thing (your custom function call) and yet have the value as another (the hyperlink / URL) which simply isn't possible.
The correct way through VBA to add a hyperlink is to use the Hyperlinks property but it is not possible to call this property, through a Worksheet UDF (because of the reason above).
What is wrong with just using the the built-in =Hyperlink() worksheet function? You could effectively parameterise your URL as follows (where cell A1 = Excel):
=HYPERLINK("http://www.google.com/search?q="&A1)
You can't do this directly for the reasons creamyegg suggests, but there is a way to achieve the functionality albeit with a bit of a performance consideration.
You could use the Worksheet_Change event to track for the presence of your UDF then process the hyperlink addition there.
You would need to set up an empty function to allow this to happen, otherwise Excel will throw an error whenever you entered =CustomHyperlink... in a cell.
The below should work, not really had time to test.
Private Sub worksheet_change(ByVal target As Range)
Dim SearchValue As String
If LCase(Left(target.Formula, 16)) = "=customhyperlink" Then
SearchValue = Mid(target.Formula, 19, Len(target.Formula) - 20)
target.Value = SearchValue
target.Hyperlinks.Add target, "http://www.google.com/search?q=" & SearchValue, , "Search Google for " & SearchValue, SearchValue
End If
End Sub
The performance consideration is of course the volatile Worksheet_Change event as this can really kill large, complex workbooks.

Resources