How do I add a Hyperlink to each item in a column? - excel

Column B is Employee name and is also an individual Worksheet name.
Anticipated Outcome: A hyperlink to the individual Worksheet on each item in column B.
Issue: The code starts and stops at the top of the list and puts in a hyperlink to the last employee on the list.
Sub HyperlinkAdd()
ts= "Employee List"
lx = sheets(ts).Range("L1").value
Sheets(ts).Range("L1").Formula= "=Subtotal(3,B4:B1000)+3"
For x = 3 to lx
If Range("B" & x).value <> "" And Range("B" & x).value <> "Employees" Then
Sheets(ts).Hyperlinks.Add Anchor:Selection, Address:="", _
Subaddress:="'" & Range("B" & x) & "'!A1"
Else
End if
Next X
End Sub

Try this:
Sub add_hyperlink()
Dim target_range As Range
Dim cell As Range
Set target_range = ThisWorkbook.Sheets("Sheet1").Range("B1", Range("B1").End(xlDown))
For Each cell In target_range
ThisWorkbook.Sheets("Sheet1").Hyperlinks.Add Anchor:=cell, Address:="https://www.google.com/", SubAddress:= _
"Sheet1!A1", TextToDisplay:=cell.Value
Next cell
End Sub

How about the following, simply amend the range you want to work with, I've set it up so it works from B1 to the last populated cell on Column B:
Sub HyperlinkAdd()
Dim ws As Worksheet: Set ws = Sheets("Sheet1")
'declare and set your working worksheet, amend as required
Dim LastRow As Long
Dim rng As Range, cell As Range
LastRow = ws.Cells(ws.Rows.Count, "B").End(xlUp).Row
'get the last row with data on Column b
Set rng = ws.Range(ws.Range("B1"), ws.Range("B" & LastRow))
'set the range to work with
For Each cell In rng
If cell.Value <> "" And cell.Value <> "Employees" Then
ws.Hyperlinks.Add Anchor:=cell, Address:="", SubAddress:=cell.Value & "!A1", TextToDisplay:=cell.Value
End If
Next
End Sub

I take a different tack and make a table of contents with each sheet (with exceptions) added to the list, and hyperlinks forward and back. You'll want to change the location of the "return" link on the employee sheet to somewhere suitable.
Private Sub Make_TOC()
'TOC Table of contents Hyperlink
Dim bkEmployees As Workbook
Set bkEmployees = ActiveWorkbook
Dim shContents As Worksheet, shDetail As Worksheet
If Not WorksheetExists("Contents") Then
Set shContents = bkEmployees.Sheets.Add(before:=ActiveWorkbook.Sheets(1))
shContents.Name = "Contents"
Else
Set shContents = bkEmployees.Sheets("Contents")
shContents.Move before:=bkEmployees.Sheets(1)
End If
shContents.Activate
shContents.Range("A1").Select
shContents.Columns("A:B").NumberFormat = "#"
For locX = 2 To bkEmployees.Sheets.Count
Select Case bkEmployees.Sheets(locX).Name
'add any sheets you don't want messed with
Case "Sheet1", "Sheet2", "Contents"
'don't include the sheets above in the TOC
Case Else
shContents.Cells(locX, 1) = bkEmployees.Sheets(locX).Name
shContents.Cells(locX, 1).Select
strSubAddress = "'" & shContents.Cells(locX, 1).Value & "'!A1"
shContents.Hyperlinks.Add Anchor:=shContents.Cells(locX, 1), _
Address:="", SubAddress:="'" & bkEmployees.Sheets(locX).Name & "'" & "!A1", _
TextToDisplay:=bkEmployees.Sheets(locX).Name, ScreenTip:="Go to Detail Sheet"
'change this code to put the anchor for the return link somewhere suitable.
bkEmployees.Sheets(locX).Hyperlinks.Add Anchor:=bkEmployees.Sheets(locX).Cells(1, 1), _
Address:="", SubAddress:="'" & shContents.Name & "'" & "!A" & locX, _
TextToDisplay:="Return to TOC", ScreenTip:="Return to Table of Contents"
End Select
Next locX
shContents.Range("A1").Value = "Table Of Contents"
shContents.Range("A1").Select
shContents.Columns("A").AutoFit
End Sub

Related

Matching data in excel from one worksheet to another

Currently I have a macro function using vba in excel that takes a row of data when you input it with a specific number. For example, I search 0.55 it will then search through "sheet 2" and paste the entire row that has 0.55 in "sheet 1".
What I would like is for it not to search an individual number, but a set of numbers found in sheet and then paste the corresponding data (full row) from sheet 2 next the data is sheet one.
Visual:
Sheet 1 sheet 1
Highlighted numbers are the ones I want found from sheet 2 (and only those)
The result would look like this:
Desired result
Where the data on the right is from sheet 2.
Current code:
Sub myFind()
'Standard module code, like: Module1.
'Find my data and list found rows in report!
Dim rngData As Object
Dim strDataShtNm$, strReportShtNm$, strMySearch$, strMyCell$
Dim lngLstDatCol&, lngLstDatRow&, lngReportLstRow&, lngMyFoundCnt&
On Error GoTo myEnd
'*******************************************************************************
strDataShtNm = "Sheet2" 'This is the name of the sheet that has the data!
strReportShtNm = "Sheet1" 'This is the name of the report to sheet!
'*******************************************************************************
Sheets(strReportShtNm).Select
Application.ScreenUpdating = False
'Define data sheet's data range!
Sheets(strDataShtNm).Select
With ActiveSheet.UsedRange
lngLstDatRow = .Rows.Count + .Row - 1
lngLstDatCol = .Columns.Count + .Column - 1
End With
Set rngData = ActiveSheet.Range(Cells(1, 1), Cells(lngLstDatRow, lngLstDatCol))
'Get the string to search for!
strMySearch = InputBox("Enter what to search for, below:" & vbLf & vbLf & _
"Note: The search is case sensitive!", _
Space(3) & "Find All", _
"")
'Do the search!
For Each Cell In rngData
strMyCell = Cell.Value
'If found then list entire row!
If strMyCell = strMySearch Then
lngMyFoundCnt = lngMyFoundCnt + 1
ActiveSheet.Rows(Cell.Row & ":" & Cell.Row).Copy
With Sheets(strReportShtNm)
'Paste found data's row!
lngReportLstRow = .UsedRange.Rows.Count + .UsedRange.Row
ActiveSheet.Paste Destination:=.Range("A" & lngReportLstRow).EntireRow
End With
End If
Next Cell
myEnd:
'Do clean-up!
Application.ScreenUpdating = True
Application.CutCopyMode = False
Sheets(strReportShtNm).Select
'If not found then notify!
If lngMyFoundCnt = 0 Then
MsgBox """" & strMySearch & """" & Space(3) & "Was not found!", _
vbCritical + vbOKOnly, _
Space(3) & "Not Found!"
End If
End Sub
Thank you so much in advance

VBA - Group with subgroup extract using keyword

Have data on columnA and trying to filter data using keywords. member of groups is in the down adjacent cells. starting with +.
Sub Mymacro()
Range("B2:B2000").Clear
For Each Cell In Sheets(1).Range("A1:A2000")
matchrow = Cell.Row
Find = "*" + Worksheets("Sheet1").Range("B1") + "*"
If Cell.Value Like Find Then
Cell.Offset(0, 1).Value = Cell.Offset(0, 0).Value
End If
Next
End Sub
Private Sub Worksheet_Change(ByVal Target As Range)
If Target.Address = "$B$1" Then
Call Mymacro
End If
End Sub
The above code is extracting text correctly with the green text but the expecting item is still missing which is just highlighted using the red text. tried a couple of options but no luck.
Referencing a worksheet with its index number as Sheets(1) is not advisable. It refers to the first sheet in the workbook including a chart sheet. If the sheet referred is moved from its first position in the workbook then the macro will run in the new worksheet at the first position. If the first sheet is a chart sheet, the macro will cause error. Hence, please replace below Sheets(1) reference with Sheet name like Sheets("Sheet1") or VBA Project worksheet name as Sheet1
Option Explicit
Sub Mymacro()
Dim fltArea As Range, fltAreas As Range, fltAreasGroup As Range
Dim lastRow As Long
lastRow = Sheets(1).Range("A1048576").End(xlUp).Row
Sheets(1).Range("B2:B" & lastRow).Clear
Sheets(1).Range("$A$1:$A$" & lastRow).AutoFilter Field:=1, Criteria1:="=+*", _
Operator:=xlAnd
Set fltAreasGroup = Sheets(1).Range("$A$2:$A$" & lastRow).SpecialCells(xlCellTypeVisible)
Sheets(1).AutoFilterMode = False
For Each fltAreas In fltAreasGroup.Areas
Set fltArea = fltAreas.Offset(-1).Resize(fltAreas.Rows.Count + 1, 1)
If InStr(1, Join(Application.Transpose(Application.Index(fltArea.Value, 0, 1)), ","), _
Sheets(1).Range("B1").Value, vbTextCompare) > 0 Then
fltArea.Offset(, 1).Value = fltArea.Value
End If
Next
Sheets(1).Range("$A$1:$B$" & lastRow).AutoFilter Field:=1, Criteria1:="=*" & Sheets(1).Range("B1").Value & "*", _
Operator:=xlAnd
Sheets(1).Range("$A$1:$B$" & lastRow).AutoFilter Field:=2, Criteria1:="="
Set fltAreas = Sheets(1).Range("$A$2:$A$" & lastRow).SpecialCells(xlCellTypeVisible)
Sheets(1).AutoFilterMode = False
For Each fltArea In fltAreas
fltArea.Offset(, 1).Value = fltArea.Value
Next
End Sub

Number each Row when printing VBA

I'm finding the matches in two columns (myrange1 & myrange2), filling them in a third column ("R") of sheet2. I have my Range from column "R" printing out to a PDF just fine, but I want each one to be numbered sequentially on the PDF i.e. 1,2,3,4 etc. Help much appreciated. Pretty new to VBA as well.
Sub matchcopy()
Dim myrange1 As Range, myrange2 As Range, cell As Range
With Sheets("Sheet1")
Set myrange1 = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
End With
With Sheets("Sheet2")
Set myrange2 = .Range("A1", .Range("A" & Rows.Count).End(xlUp))
End With
For Each cell In myrange1
If Not IsError(Application.Match(cell.Value, myrange2, 0)) Then
'cell.Value, myrange2, 0
cell.Copy
Sheet2.Range("R5000").End(xlUp).Offset(1, 0).PasteSpecial xlPasteFormulasAndNumberFormats
Else
'MsgBox "no match is found in range"
End If
Next cell
Columns("R:R").EntireColumn.AutoFit
Call Set_PrintRnag
End Sub
Sub Set_PrintRnag()
Dim LstRw As Long
Dim Rng As Range
LstRw = Cells(Rows.Count, "R").End(xlUp).Row
Set Rng = Range("R1:R" & LstRw)
With ActiveSheet.PageSetup
.LeftHeader = "&C &B &20 Cohort List Report : " & Format(Date,
"mm/dd/yyyy")
End With
Rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:=ThisWorkbook.Path & _
"\CohortList " & " " & Format(Date, "mm-dd-yyyy") & ".pdf", _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
End Sub
As close as possible to your code, though looping through a range is always time consuming and you would be faster working with arrays of the columns to be compared:
Option Explicit
Sub matchcopy()
Dim i&
Dim myrange1 As Range, myrange2 As Range, cell As Range
' You can use the Codenames instead of Worksheet("Sheet1") etc.
Set myrange1 = Sheet1.Range("A1", Sheet1.Range("A" & Rows.Count).End(xlUp))
Set myrange2 = Sheet2.Range("A1", Sheet2.Range("A" & Rows.Count).End(xlUp))
Sheet2.Range("R:S") = "" ' <~~ clear result columns
For Each cell In myrange1 ' presumably unique items
If Not IsError(Application.Match(cell.Value, myrange2, 0)) Then
cell.Copy
With Sheet2.Range("R5000").End(xlUp)
i = i + 1 ' <~~ counter
.Offset(1, 0) = i ' counter i equals .Row - 1
.Offset(1, 1).PasteSpecial xlPasteFormulasAndNumberFormats
End With
Else
'MsgBox "no match is found in range"
End If
Next cell
Sheet2.Columns("R:S").EntireColumn.AutoFit
Call Set_PrintRnag ' called procedure see OP
End Sub
Sub Set_PrintRnag()
Dim LstRw As Long
Dim Rng As Range
LstRw = Sheet2.Cells(Rows.Count, "R").End(xlUp).Row
Set Rng = Sheet2.Range("R1:S" & LstRw)
With Sheet2.PageSetup
.LeftHeader = "&C &B &20 Cohort List Report : " & Format(Date, "mm/dd/yyyy")
End With
Rng.ExportAsFixedFormat Type:=xlTypePDF, Filename:=ThisWorkbook.Path & _
"\CohortList " & " " & Format(Date, "mm-dd-yyyy") & ".pdf", _
Quality:=xlQualityStandard, IncludeDocProperties:=True, _
IgnorePrintAreas:=False, OpenAfterPublish:=True
End Sub
Additional hint
To get some ideas how to use a datafield array, see e.g. SO answer to Loop with multiple ranges
Do you need a VBA script to accomplish your desired goal? If you are just trying to compare two values and output the result in your Column R, you should be able to do it with an IF function: https://support.office.com/en-us/article/if-function-69aed7c9-4e8a-4755-a9bc-aa8bbff73be2
If you want sequential numbering for results, I'd suggest having the number in an adjacent column and exploring the COUNTA function: https://support.office.com/en-us/article/counta-function-7dc98875-d5c1-46f1-9a82-53f3219e2509
And if you do require this in VBA scripting format, you can do it with an Excel function first and record a macro afterwards. Makes creating the actual VBA syntax a little easier! https://support.office.com/en-us/article/automate-tasks-with-the-macro-recorder-974ef220-f716-4e01-b015-3ea70e64937b

Create hyperlink when new sheet is created

I have VBA code found on the internet. It creates sheets using my template based on a list in my summary sheet.
I want it to make a hyperlink to the sheet in my list.
Mal=Template
Sammendrag=Summary
Here it is:
Sub CreateSheetsFromAList() ' Example Add Worksheets with Unique Names
Dim MyRange As Range, i As Long
Dim ShtName As String
Application.ScreenUpdating = 0
With Sheets("Sammendrag")
Set MyRange = .Range("B10:B69" & .Range("a" & .Rows.Count).End(xlUp).Row)
End With
Sheets("Mal").Visible = True
With MyRange
For i = 1 To .Rows.Count
ShtName = Trim(.Cells(i, 1).Value)
If Len(ShtName) Then
If Not WorksheetExists(ShtName) Then
Sheets("Mal").Copy After:=Sheets(Sheets.Count)
ActiveSheet.name = ShtName
End If
End If
Next
End With
Sheets("Mal").Visible = False
Application.ScreenUpdating = 1
End Sub
With this code you can add a hyperlink:
.Cells(i, 1).Hyperlinks.Add Anchor:=.Cells(i, 1), Address:="", SubAddress:="'" & Worksheets(SHtName).Name & "'!A1", TextToDisplay:=Worksheets(SHtName).Name
On click you will jump to Cell A1 of the Sheet.

Extract matched data from a table to another worksheet in Excel VBA

I've got a sample table in Sheet1 as below:
Location Model Part #
BF03 200W 40536573
BF04 200W 40536573
CV01 120W 40536585
CV02 135W 20085112
CV03 900W 20349280
CV04 135W 20085112
As a reference data of BF03 is in cell B6.
What I need it to do is:
A) When user typed part number (ex: 40536573) in Sheet3 say cell A1, only the matched location will be picked up
B) The picked up "location" value will be tabulated in Sheet2 starting from cell A6.
The output will look something like this:
Location Model Part #
BF03 200W 40536573
BF04 200W 40536573
To make matter more complicated, I would then need to have the "Location" data to be concatenated into a string and store it in Sheet 2 Cell A2.
I'm guessing we need to do a For Loop count rows but I couldn't get any reference on how to write it properly.
Below are what my error "OVERFLOW" code looks like
Private Sub Worksheet_SelectionChange(ByVal Target As Range)
Dim FindMatch As String
Dim Rng As Range
Dim counter As Integer
counter = ActiveWorkbook.Worksheets("Sheet2").Range("A6", Worksheets("Sheet2").Range("A6").End(xlDown)).Rows.Count
For i = 6 To counter
'Get the value from other sheet set as FindMatch
FindMatch = Sheets("Sheet3").Cell("A1").Value
'Find each row if matches the desired FindMatch
If Trim(FindMatch) <> "" Then
With Sheets("Sheet2").Range("D" & i).Rows.Count
Set Rng = .Find(What:=FindMatch, _
after:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
'copy the values required to the cell
Cells(i, 2) = Sheets("Sheet2").Cells(Rng.Row, 2)
Else
MsgBox "Nothing found"
End If
End With
End If
Next i
End Sub
Instead of using the .find method, I managed to use a simple for loop. Sometimes you need to think simple i guess :) I have also added a small function to clear previously used fields. If you check and give feedback if you face any problem, we can try to fix it.
Dim ws1 As Worksheet
Dim ws2 As Worksheet
Dim ws3 As Worksheet
Dim S_Var As String
Dim copyRange As Range
Dim ws1_lastrow As Long
Dim ws2_lastrow As Long
Dim searchresult As Range
Set ws1 = Sheets("Sheet1")
Set ws2 = Sheets("Sheet2")
Set ws3 = Sheets("Sheet3")
S_Var = ws3.Range("A1").Value
ws1_lastrow = ws1.Range("A" & ws1.Rows.Count).End(xlUp).Row
Set copyRange = ws1.Range("A1:C" & ws1_lastrow)
'Clear Data
ws2.Range("A2").Value = ""
If Range("A7").Value <> "" Then
ws2.Range("A7:C" & ws2.Range("A" & ws1.Rows.Count).End(xlUp).Row).Value = ""
End If
'Searchin through the sheet1 column1
For i = 2 To ws1_lastrow
If ws1.Range("C" & i) = S_Var Then
ws2_lastrow = ws2.Range("A" & ws2.Rows.Count).End(xlUp).Row
ws1.Range("A" & i & ":C" & i).Copy Destination:=ws2.Range("A" & ws2_lastrow + 1)
End If
Next
'Adding location to sheet2 A2 as string
ws2_lastrow = ws2.Range("A" & ws1.Rows.Count).End(xlUp).Row
For i = 7 To ws2_lastrow 'starting from 7, where location starts
If ws2.Range("A2").Value = "" Then
ws2.Range("A2").Value = ws2.Range("A" & i).Value
Else
ws2.Range("A2").Value = ws2.Range("A2").Value & "," & ws2.Range("A" & i).Value
End If
Next

Resources