0

I have a reference sheet called Color Guide that is being used to keep track of paint colors and the links to those paint colors. It looks like this:

paint guide example

I have around 85 sheets, each one representing a building with each building having a set of allowable paint color choices for different rooms. It looks like this:

building sheet example

What I am looking to do is this: when I update my external hyperlink on the Color Guide sheet (first image), I need that same hyperlink to update on each building sheet. I have been trying to achieve this through VLOOKUP but the hyperlink doesn't pull over. I read online that I could chain the HYPERLINK formula together with the VLOOKUP formula. This is what that looks like, including the error I get when I click on the hyperlink from image 2:

formula plus error

What should I do? I've been working on this project for days and I can't get it to work. Other answers I've seen on here don't seem to resolve the issue.

LadyStensberg
  • 49
  • 1
  • 9

2 Answers2

1

Option 1: In sheet UDF

You could use the following code by Igor (modified slightly) in a standard module as a worksheet based way of updating Urls via a user defined function (UDF) GetUrl, wrapped inside a HYPERLINK function, to ensure you have a clickable link.

UDF code in standard module:

Option Explicit

 Function GetURL(cell As Range, Optional default_value As Variant) as hyperlink
 'Lists the Hyperlink Address for a Given Cell

 'If cell does not contain a hyperlink, return default_value
      If (cell.Hyperlinks.Count <> 1) Then
          GetURL = default_value
      Else
          GetURL = cell.Hyperlinks(1).Address
      End If
End Function

Where you deploy by having in a cell in sheet 2, for example, the following

=HYPERLINK(GetURL(Sheet1!A1))

And sheet one cell A1 has the hyperlink being updated.

You would need to tie a refresh of the UDF(calculation) to an event to ensure the hyperlink text visibly updates.

For example, in the sheet containing the UDF you could have the following by Greg Glynn to force a recalculation. Sure you can play around finding an efficient way to do this.

Private Sub Worksheet_Activate()

    Cells.Replace What:="=", Replacement:="=", LookAt:=xlPart, SearchOrder _
        :=xlByRows, MatchCase:=False, SearchFormat:=False, ReplaceFormat:=False

End Sub

As discussed for the above code:

Cell A1 has the hyperlink being updated

Cell A3 (which could be a cell in a different sheet) has the function GetURL ,wrapped inside the HYPERLINK function, which points at A1.

Using the UDF in the sheet

The function code would go in a standard module:

Press Alt + F11 to open the VBE and then in the project explorer window, right click Insert Module then enter the code into the module that appears e.g.

Entering code for User Defined Function into standard module

The trigger code (so the hyperlink text updates) would go in the worksheet code window for each sheet containing the function e.g. if sheet 4 had the GetUrl function in, you would enter in the sheet code window as follows:

Adding code into code window for a sheet

As i said in comments, this could be put into a function called when each sheet is activated.

Option 2: Button in worksheet associated with macro which prompts user to select a range containing the old urls and new urls

Or, the following, which is not optimised but i am happy to update as others chip in comments. This would simply be a procedure you place in a standard module you attach to a button (Google assign macro to button in Excel - you would also need to add the Developer tab to the Ribbon)

Option Explicit

Public Sub ReplaceLinks()

    Dim linksArr()

    Application.ScreenUpdating = False

    Dim myRange As Range

    Set myRange = Application.InputBox("Please select both columns containing range of hyperlinks to update", Type:=8)

    If Not myRange Is Nothing And myRange.Columns.Count = 2 Then

        linksArr = myRange.Value

    Else

        MsgBox "Please select a range of two columns"
        Exit Sub

    End If

    ReDim Preserve linksArr(1 To UBound(linksArr), 1 To 3)

    linksArr = ValidateUrls(linksArr)

    Dim currentLink As Long

    For currentLink = LBound(linksArr, 1) To UBound(linksArr, 1)

        If linksArr(currentLink, 3) Then

            UpdateMyHyperlink CStr(linksArr(currentLink, 1)), CStr(linksArr(currentLink, 2))

        End If

    Next currentLink

    WriteValidationResults linksArr, myRange

End Sub

Private Function ValidateUrls(ByVal linksArr As Variant) As Variant

    Dim currentLink As Long

    For currentLink = LBound(linksArr, 1) To UBound(linksArr, 1)

        linksArr(currentLink, 3) = IsURLGood(CStr(linksArr(currentLink, 1)))

    Next currentLink

    ValidateUrls = linksArr

End Function

Public Function IsURLGood(ByVal url As String) As Boolean

    'https://www.experts-exchange.com/questions/27240517/vba-check-URL-if-it-is-active-or-not.html by m4trix

    Dim request As WinHttpRequest

    Set request = New WinHttpRequest

    On Error GoTo IsURLGoodError
    request.Open "HEAD", url
    request.Send

    IsURLGood = request.Status = 200

    Exit Function

IsURLGoodError:
    IsURLGood = False
End Function

Private Sub UpdateMyHyperlink(ByVal oldUrl As String, ByVal newUrl As String)

    Dim ws As Variant
    Dim hyperlink As Variant

    For Each ws In ThisWorkbook.Worksheets

        For Each hyperlink In ws.Hyperlinks

            If hyperlink.Address = oldUrl & "/" Then
                hyperlink.Address = Application.WorksheetFunction.Substitute(hyperlink.Address, oldUrl, newUrl)
                hyperlink.TextToDisplay = newUrl
            End If

        Next
    Next

End Sub

Private Sub WriteValidationResults(ByVal linksArr As Variant, ByRef myRange As Range)

    Dim isUrlValidOutput As Range

    Set isUrlValidOutput = myRange.Offset(, 2).Resize(myRange.Rows.Count, 1)

    isUrlValidOutput = Application.Index(linksArr, , 3)

    isUrlValidOutput.Offset(-1, 0).Resize(1) = "Valid URL"

End Sub

And you would set your data up as follows (column D is added via the code):

Data for url updates

Adding a forms control button:

Inserting a form control button

Automatically it will pop up a window where you can then assign the update links procedure:

Assign macro to button

QHarr
  • 83,427
  • 12
  • 54
  • 101
  • Does it matter which sheet I add the code to? I don't know VBA. I was hoping to do this with a simple formula. Also, does the above work with the VLOOKUP I mentioned? – LadyStensberg Dec 14 '17 at 22:56
  • The top code goes in a standard module. The bottom code, which was an example event triggered update, because it is a worksheet event would go in the specific worksheet (code window) containing the urls to update. – QHarr Dec 14 '17 at 23:24
  • There maybe other ways to force recalculation, this was simply a way that you could manually update in the master sheet and when you navigated to a specific worksheet it triggers the activate event shown which then causes a recalculation. You would repeat this code in each worksheet containing urls to update (or have it as a function which is called... i will edit an example in tomorrow). I THINK (not sure) the problem with the VLOOKUP approach is that you don't end up with a clickable hyperlink. I will add pictures to the edit if that helps? – QHarr Dec 14 '17 at 23:24
  • the other idea i toyed with coding earlier was where you have an update sheet. In it you have two columns "old url" and "new url", here you enter the amendments to apply to the workbook (on a row by row basis) and then push an update urls button that triggers a macro which loops all the existing hyperlinks updating their addresses as appropriate (i also messed around with verifying that the website of the new url responded i.e. was valid). – QHarr Dec 14 '17 at 23:33
1

My solution:

The issue was that HYPERLINK wasn't able to build a correct hyperlink in addition to using VLOOKUP.

I solved this by creating 2 columns on the Color Guide. The first stored the name of the color. The second stored the hyperlink. On the second sheet, where I wanted to pull the name and hyperlink into, I used the following formula:

=HYPERLINK(VLOOKUP(C3, 'Color Guide'!$A:$D, 4), VLOOKUP(C3, 'Color Guide'!$A:$D, 3))

The first VLOOKUP pulled the link location, the second VLOOKUP pulled the 'friendly name'. This works great and auto-updates the link when it is changed on the Color Guide!

LadyStensberg
  • 49
  • 1
  • 9