Vlookup with Hyperlink - VBA - vba

I'm currently seaching to find a way to copy and paste hyperlink link from another sheet.
The way the program supposed to be working is that you choose from a list a item category and then all the following columns are automatically filled with Vlookup check-up on the ''Category'' Sheet
The problem :
Need to keep the hyperlink when copy and past the information, I'm still new in the code and currently have no idea how to make it worked.
I really want to keep the VBA, because the code is hide and people won't be able to mess with it and can write on top off the cell for special case.
Sub Update()
Dim calData As String
Dim add As String
Dim i, LastRow
LastRow = Range("G" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If Cells(i, "G").Value <> "" Then
Range("Q" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 4, False)
Range("R" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 6, False)
'Set calData = Worksheets("Calendar").Range("R" & i)
'add = "G:\Engineering\Engineering trainees (HUG)\Etalonnage\Procédures calibration\" & Data
'With Worksheets("Calendar")
'.Hyperlinks.add Anchor:=.Range("R" & i), _
'Address:=add, _
'TextToDisplay:=Data
'End With
Range("S" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 7, False)
Range("T" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 8, False)
End If
End Sub

I think you are close. Try below code.
Note as a practice, try not to use "add" as a variable name. It messes the IntelliSense, i changed to addr.
Wouldn't the Q,R,S,T columns better off with Formula instead of fixed value? Unless you have an Event code to call this Sub when cells in column G are changed.
Sub Update()
Dim calData As String
Dim addr As String
Dim i As Long, LastRow As Long
LastRow = Range("G" & Rows.Count).End(xlUp).Row
For i = 3 To LastRow
If Cells(i, "G").Value <> "" Then
Range("Q" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 4, False)
Range("R" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 6, False)
calData = Worksheets("Calendar").Range("R" & i).Value ' Or .Text, depends on data
addr = "G:\Engineering\Engineering trainees (HUG)\Etalonnage\Procédures calibration\" & calData
With Worksheets("Calendar")
.Hyperlinks.Add Anchor:=.Range("R" & i), Address:=addr, TextToDisplay:=calData
End With
Range("S" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 7, False)
Range("T" & i).Value = Application.VLookup(Cells(i, "G"), Sheets("Category").Range("A2:H60"), 8, False)
End If
Next
End Sub

Related

isNumeric returning wrong state in Excel VBA

In the code below, I was attempting to do a calculation if the number in the specific cell was numeric, else return number from other cell. I think that my implementation is incorrect as I only get the else state populating if the first cell is not numeric and vise versa. Can you tell me how to fix this?
This is an example of the data:
The 6th entry should return 27 in the Meas-LO column.
Thanks
Here is the code
Sub ReturnMarginal()
'UpdatebySUPERtoolsforExcel2016
Dim xOut As Worksheet
Dim xWb As Workbook
Dim xWks As Worksheet
Dim InterSectRange As Range
Dim lowLimCol As Integer
Dim hiLimCol As Integer
Dim measCol As Integer
Application.ScreenUpdating = False
Set xWb = ActiveWorkbook
For Each xWks In xWb.Sheets
xRow = 1
With xWks
FindString = "LowLimit"
If Not xWks.Rows(1).Find(FindString) Is Nothing Then
.Cells(xRow, 16) = "Meas-LO"
.Cells(xRow, 17) = "Meas-Hi"
.Cells(xRow, 18) = "Min Value"
.Cells(xRow, 19) = "Marginal"
LastRow = .UsedRange.Rows.Count
lowLimCol = Application.WorksheetFunction.Match("LowLimit", xWks.Range("1:1"), 0)
hiLimCol = Application.WorksheetFunction.Match("HighLimit", xWks.Range("1:1"), 0)
measLimCol = Application.WorksheetFunction.Match("MeasValue", xWks.Range("1:1"), 0)
If IsNumeric(Cells(2, lowLimCol).Address(False, False)) Then
.Range("P2:P" & LastRow).Formula = "=" & Cells(2, measLimCol).Address(False, False) & "-" & Cells(2, lowLimCol).Address(False, False)
Else
.Range("P2:P" & LastRow).Formula = "=" & Cells(2, measLimCol).Address(False, False)
End If
.Range("Q2:Q" & LastRow).Formula = "=" & Cells(2, hiLimCol).Address(False, False) & "-" & Cells(2, measLimCol).Address(False, False)
.Range("R2").Formula = "=min(P2,Q2)"
.Range("R2").AutoFill Destination:=.Range("R2:R" & LastRow)
.Range("S2").Formula = "=IF(AND(R2>=-3, R2<=3), ""Marginal"", R2)"
.Range("S2").AutoFill Destination:=.Range("S2:S" & LastRow)
End If
End With
Application.ScreenUpdating = True 'turn it back on
Next xWks
End Sub
Cells(2, lowLimCol).Address(False, False) Returns a string address not the value. So it will never be numeric.
Change to:
.Cells(2, lowLimCol).Value2
After understanding what you meant for the second part of your problem, I think the quickest fix for how your formula is set up is to fill the whole column with a formula.
This will be quicker than looping through each cell in code to check if it is a number. You can fill the whole range with a formula that does the check on the spreadsheet itself: e.g. =IF(ISNUMBER(C1),C1-D1,C1)
To get that in your code, I would replace the whole if isNumeric then...
Replace this section:
If IsNumeric(Cells(2, lowLimCol).Address(False, False)) Then
.Range("P2:P" & LastRow).Formula = "=" & Cells(2, measLimCol).Address(False, False) & "-" & Cells(2, lowLimCol).Address(False, False)
Else
.Range("P2:P" & LastRow).Formula = "=" & Cells(2, measLimCol).Address(False, False)
End If
With this line:
.Range("P2:P" & lastRow).Formula = "=IF(ISNUMBER(" & .Cells(2, measLimCol).Value2 & ")," & Cells(2, measLimCol).Address(False, False) & "-" & Cells(2, lowLimCol).Address(False, False) & "," & Cells(2, measLimCol).Address(False, False) & ")"

Excel VBA To Add New Row If Condition Is Met

I am attempting to write some VBA that will accomplish
if row O is not null then copy all data to new row, then in current row clear columns I, J, K, L, M, N
in the newly inserted row clear columns O
The caveat I am not sure to account for is - throws a
Type mismatch error
Here is the syntax that I am trying to work with
Sub BlueBell()
Application.ScreenUpdating = False
Dim i As Long, y
ReDim y(2 To Range("A" & Rows.Count).End(3).Row)
For i = UBound(y) To LBound(y) Step -1
If Cells(i, "O") Then
If Cells(i, "I") = "" And Cells(i, "K") = "" And Cells(i, "M") = "" Then
GoTo DoNothing
Else
Rows(i).Copy
Cells(i, "A").Insert
Range("I" & i & ":J" & i & ":K" & i & ":L" & i & ":M" & i & ":N" & i & ":O" & i + 1).ClearContents
GoTo DoNothing
End If
End If
DoNothing:
Next i
End Sub
Apart from your error with using a string as a boolean expression, there are several things that can be changed in your code:
Sub BlueBell()
Application.ScreenUpdating = False
Dim i As Long ', y() As Variant
'ReDim y(2 To Range("A" & Rows.Count).End(3).Row) 'Why use an array?
For i = Range("A" & Rows.Count).End(3).Row To 2 Step -1
If Not IsEmpty(Cells(i, "O").Value) Then
'Avoid the use of GoTo
If Cells(i, "I").Value <> "" Or _
Cells(i, "K").Value <> "" Or _
Cells(i, "M").Value <> "" Then
Rows(i).Copy
Cells(i, "A").Insert
'Don't use a "Ix:Jx:Kx:Lx:Mx:Nx:Ox+1" range - it will lead to problems
'because even really experienced users don't understand what it does
Range("I" & i & ":N" & i).ClearContents
Range("O" & i + 1).ClearContents
End If
End If
Next i
'It's a good habit to reset anything that you disabled at the start of your code
Application.ScreenUpdating = True
End Sub

VBA in Excel returning Type mismatch

I'm trying to create a Macro that will modify contents in columns S, W and AH based on the content in AB
e.g. if AB1 = No, then S1=C-MEM, AH = N/A and W is cleared.
For some reason, I get a 'Type mismatch' error on the first line of my if statement and can't figure out why or how to fix it - even after reading other posts about similar issue.
Sub test()
Dim lastrow As Long
Dim i As Long
lastrow = Range("AB" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
**-> If Range("AB" & i).Value = "No" Then
Range("S" & i).Value = "C-MEM"
Range("W" & i).Value = ""
Range("AH" & i).Value = "N/A"
End If
Next i
End Sub
Thanks
You are trying to test if an error is = No.
Test for the error and skip the logic in that loop:
Sub test()
Dim lastrow As Long
Dim i As Long
lastrow = Range("AB" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Not IsError(Range("AB" & i).Value) Then
If Range("AB" & i).Value = "No" Then
Range("S" & i).Value = "C-MEM"
Range("W" & i).Value = ""
Range("AH" & i).Value = "N/A"
End If
End If
Next i
End Sub

Correcting formula in vba excel

I want to create a macro that check all the cells of a column and if the first two characters of a cell is "BB" then i want the macro to extract three characters from the cell and paste it to the next column but a the corresponding row.
But my formula after the if clause is not working.
this is what i have done since:
Sub test()
Dim lmid As String
Dim srange, SelData, ExtBbFor As String
Dim lastrow As Long
Dim i, icount As Integer
lastrow = ActiveSheet.Range("B30000").End(xlUp).Row
srange = "G1:G" & lastrow
SelData = "A1:G" & lastrow
Range(srange).Formula = "=mid(E1,1,3)"
For i = 1 To lastrow
If InStr(1, LCase(Range("E" & i)), "bb") <> 0 Then
Range("G" & i).Formula = "=mid("E & i", 4, 3)"
End If
Next i
End Sub
thanks in advance
Try with below. It will work
Range("G" & i).Value = Mid(Range("E" & i), 4, 3)
If the cell is not limited to 7 then you need as below
Range("G" & i).Value = "=Mid(E" & i & ", 3, " & Len(E & "& i & ") & ")"
It will extract from the 3rd character up to the last character in a cell.
Your syntax is wrong where you're trying to concatenate strings, I think you mean to use:
Range("G" & i).Formula = "=MID(E" & i & ",4,3)"
Based on your code I think this will do the exact same thing without having to loop or declare any variables:
Sub test()
With Range("G1:G" & Cells(Rows.Count, 2).End(xlUp).Row)
.FormulaR1C1 = "=IF(UPPER(LEFT(RC[-2],2))=""BB"",MID(RC[-2],4,3),"""")"
.Value = .Value
End With
End Sub

Application defined or object defined error - depending on which Worksheet is opened

I'm having an issue that I am struggling to solve as it's a bit specific. I have code that does copy and paste from one sheet to others. Each part of the code basically copies part from the master sheet "current" to the specified sheet.
When I run my code I receive an error "Application defined or object defined error" and the code stops at the work sheet "Dividend yield" after the following line
Worksheets("div. yield").Range("B7").Select
However if I open the sheet "Dividend yield" and run my code from there it will work fine until the last sheet "Reverse PE" where it will again throw and error "Application defined or object defined error" after the line
Worksheets("Reverse_PE").Range("B9").Select
I guess the error is related to the next coming rows with Autofill method but I have not found any useful solutions to this problem. Could somebody please advise me how to solve this error?
Full macros code is below.
Function getYield() As Double
Dim appIE As Object
Set appIE = CreateObject("internetexplorer.application")
With appIE
.Navigate "http://uk.investing.com/rates-bonds/world-government-bonds"
.Visible = False
End With
Do While appIE.Busy
DoEvents
Loop
Set allRowOfData = appIE.document.getElementById("pair_23705")
Dim myValue As Double: myValue = allRowOfData.Cells(2).innerHTML
appIE.Quit
Set appIE = Nothing
Worksheets("Reverse_PE").Range("B7").Value = myValue
Worksheets("Reverse_PE").Range("B7").Value = Worksheets("Reverse_PE").Range("B7").Value / 100
End Function
Sub adjust()
Dim copyAdress As Range
Dim copyRange As Range
Dim lastRow As Long
Dim Median As Range
'''PE'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("PE_RATIO", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 1, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE").Range("B7", "B" & lastRow)
Worksheets("PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE").Range("B5").Font.Bold = True
Worksheets("PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B4),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE").Range("A7", "A" & lastRow + 2)
''Dividend yield'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("div. yield").Range("A7", "A" & lastRow + 2)
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
Worksheets("div. yield").Range("B7").Select
Selection.AutoFill Destination:=Sheets("div. yield").Range("B7:B" & lastRow + 2), Type:=xlFillDefault
'''PE Forward'''
Set copyAdress = Worksheets("current").Range("A1:CJ10000").Find("P/E-Ratio 03E", lookat:=xlPart)
lastRow = Cells(65536, copyAdress.Column).End(xlUp).Row
Set copyRange = Worksheets("current").Range(Cells(copyAdress.Row + 3, copyAdress.Column), Cells(lastRow, copyAdress.Column))
Worksheets("PE_forward").Range("B1").EntireColumn.Insert
copyRange.Copy Destination:=Sheets("PE_forward").Range("B7", "B" & lastRow + 2)
Worksheets("PE_forward").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("PE_forward").Range("B3").FormulaArray = "=MEDIAN(B7:B" & lastRow + 2 & ")"
Worksheets("PE_forward").Range("B5").Font.Bold = True
Worksheets("PE_forward").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$7:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
Worksheets("PE_forward").Columns("B").Replace What:="#VALUE!", Replacement:=""
Worksheets("PE_forward").Range("B3").NumberFormat = ""
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("PE_forward").Range("A7", "A" & lastRow + 2)
'''Reverse PE'''
Set copyRange = Worksheets("current").Range("A5", "A" & lastRow)
copyRange.Copy Destination:=Sheets("Reverse_PE").Range("A9", "A" & lastRow + 4)
Worksheets("Reverse_PE").Range("B1").EntireColumn.Insert
Worksheets("Reverse_PE").Range("B2").Value = Worksheets("current").Range("A1").Value
Worksheets("Reverse_PE").Range("B5").FormulaArray = "=IF(ISNUMBER(VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)),VLOOKUP($A$5,$A$9:$HI$1750,COLUMN(B751),FALSE)," & Chr(34) & NA & Chr(34) & ")"
getYield
Worksheets("Reverse_PE").Range("B3").FormulaArray = "=MEDIAN(B9:B" & lastRow + 4 & ")"
Worksheets("Reverse_PE").Range("B9").FormulaArray = "=IF(ISNUMBER(PE!B7),1/PE!B7," & Chr(34) & Chr(34) & ")"
Worksheets("Reverse_PE").Range("B9").Select
Selection.AutoFill Destination:=Sheets("Reverse_PE").Range("B9:B" & lastRow + 4), Type:=xlFillDefault
Worksheets("Reverse_PE").Range("B3:B" & lastRow + 4).Select
Selection.Style = "Percent"
Selection.NumberFormat = "0.00%"
You can't use the select method unless the sheet is first active, so add this line:
Worksheets("div. yield").Activate
Worksheets("div. yield").Range("B7").FormulaArray = "=IF(ISNUMBER(current!X5),current!X5," & Chr(34) & Chr(34) & ")"
and later at:
Worksheets("Reverse_PE").Activate
Worksheets("Reverse_PE").Range("B9").Select
There are much faster and more maintainable ways of doing what you're trying to do, but the above sheet activation will solve your immediate problem.
Don't forget to activate each sheet before you try to select one of the cells on it.