Multiple Vlookups using VBA in one sub - vba

I am trying to fill multiple columns in a sheet with vlookups from another sheet named "Go Live Data" in the same workbook, to the end of the range.
So, based off of the value starting in A6 in my sheet, I want to lookup to range A:K in sheet "Go Live Data" for cells starting in U6 to the end of the data filled in the tab (this will change dynamically). I want to repeat this for cells starting with V6 and W6.
This is the code that I have now, but it does not populate.
Sub VlookupGoLiveandBOP()
Dim Rng As Range, Dn As Range
Set Rng = Range(Range("A6"), Range("A" & Rows.Count).End(xlUp))
With Range("U6")
.Formula = "=IF(ISNA(VLOOKUP(A6,Go Live
Data!$A:$K,2,FALSE)),"""",VLOOKUP(A6,Go Live Data!$A:$K,2,FALSE))"
.AutoFill Destination:=Rng.Offset(, 66)
With Range("v6")
.Formula = "=IF(ISNA(VLOOKUP(A6,Go Live
Data!$A:$K,3,FALSE)),"""",VLOOKUP(A6,Go Live Data!$A:$K,3,FALSE))"
.AutoFill Destination:=Rng.Offset(, 66)
With Range("w6")
.Formula = "=IF(ISNA(VLOOKUP(A6,Go Live
Data!$A:$K,4,FALSE)),"""",VLOOKUP(A6,Go Live Data!$A:$K,4,FALSE))"
.AutoFill Destination:=Rng.Offset(, 66)
End With
Rng.Offset(, 66).Value = Rng.Offset(, 66).Value
End Sub
Am I on the wrong track? Thank you for your help.

Try the code below, it will help you assign the VLookup range correctly.
When using LKUpRng.Address(True, True, xlA1, xlExternal) the 4th parameter xlExternal adds also the sheet's name (and workbook if needed) with all the ' and ! needed.
Code
Option Explicit
Sub VlookupGoLiveandBOP()
Dim Rng As Range, Dn As Range
Dim LKUpRng As Range
Dim LkUpStr As String
Set LKUpRng = Sheets("Go Live Data").Range("A:K")
LkUpStr = LKUpRng.Address(True, True, xlA1, xlExternal) '<-- get the Range as a String, including the sheet's name
Set Rng = Range(Range("A6"), Range("A" & Rows.Count).End(xlUp))
Range("U6").Formula = "=IF(ISNA(VLOOKUP(A6," & LkUpStr & ",2,FALSE)),"""",VLOOKUP(A6," & LkUpStr & ",2,FALSE))"
End Sub

Related

Error by copy pasting ranged due to merged cells

SOLVED, SEE CODE BELOW
I'm working on a code for filtering data and pasting the filtered data to the "destination" sheet.
In the "review" sheet there is a long list with data that can be subdivided in certain categories. In cell F9 off the coversheet I can select a category.
After pressing a button the data in the "review" sheet needs to be filtered and the data that is left after filtering should be pasted in the "destination" sheet. the "destination" sheet is a blank new sheet.
The filtering part works, however the copy paste part is giving some errors. Because the "review" sheet has some merged cells in it. I am able to paste the formatting and the columnwidths, but the values give an error due to merged cells. Is there some way to work around this??
In addition to this, when pasting the formatting, this is pasted to the same number of rows as in the "review" sheet before filtering. I want the formatting to be applicable on only the numer of rows left after filtering.
I hope someone can help me out.
See my source code below:
Dim wksCVP As Worksheet
Dim wksReview As Worksheet
Dim wksNew As Worksheet
Set wksReview = Worksheets("REVIEW")
Set wksCVP = Worksheets("COVER PAGE")
Set wksNew = ThisWorkbook.Worksheets.Add
wksReview.Cells.Copy wksNew.Cells
wksNew.Cells.UnMerge
Dim LastRow As Long
With wksNew
LastRow = .Cells(.Rows.Count, "A").End(xlUp).Row
End With
Select Case wksCVP.Range("F9").Value
Case "Instrumentation"
kolom = "J"
Case "Equipment"
kolom = "K"
Case "Design / Fabrication"
kolom = "L"
Case "Inspection & Testing"
kolom = "M"
Case "General / Other"
kolom = "N"
End Select
If wksCVP.Range("F9").Value <> "" Then
For i = 5 To LastRow
If wksNew.Range(kolom & i).Value <> "X" Then
wksNew.Rows(i).EntireRow.Hidden = True
End If
Next i
End If
wksNew.Activate
ActiveSheet.Range("A5", "Z" & LastRow + 1).SpecialCells(xlCellTypeVisible).Copy
With Sheets("DESTINATION").Range("A1")
.PasteSpecial Paste:=xlPasteAll
End With
wksNew.delete
For the Formats and the ColumnWidths being in a merged cell, which is only partially copied, the easiest way is to add a new worksheet, to copy the initial values there and to unmerge it. Then do something like this:
Option Explicit
Sub TestMe()
Dim wksTheNew As Worksheet
Dim wksReview As Worksheet
Dim wksDestination As Worksheet
Set wksReview = Worksheets("Review")
Set wksDestination = Worksheets("Destination")
Set wksTheNew = ThisWorkbook.Worksheets.Add
wksReview.Cells.Copy wksTheNew.Cells
wksTheNew.Cells.UnMerge
'now copy the formats and the values from wksTheNew
'it will not give an error, because it is unmerged
Application.DisplayAlerts = False
wksTheNew.Delete
Application.DisplayAlerts = True
End Sub
Once you are ready with your actions, you may simply delete the new worksheet.
Just change your sequence:
With Sheets("DESTINATION").Range("A1")
.PasteSpecial Paste:=xlPasteValues
.PasteSpecial Paste:=xlPasteFormats
.PasteSpecial Paste:=xlPasteColumnWidths
End With
Pasting values first shouldn't trigger an error.

Conditionally updating a formula using VBA

I want to use a VBA Function to insert a formulas into cells based on two conditions.
The conditions are (1) there has to be something in the Description (Column D on my spreadsheet) and (2) the cell I'm pasting the code into has to be blank.
The best way I can see of doing this is with a loop, but I can't figure out how to update the references in my formulas to take account of the new position.
The code below works, but it does not check to see if the cells are empty first.
Range("B8").Formula = "=IF(D8="""","""",IF(ISERROR(VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,2,FALSE)),"""",VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,2,FALSE)))"
Range("B8").Select
Selection.AutoFill Destination:=Range("B8:B" & Total), Type:=x1filldefault
'Adds the above formula into the range B8 to B(the last cell in use)
Range("C8").Formula = "=IF(D8="""","""",IF(ISERROR(VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,3,FALSE)),"""",VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,3,FALSE)))"
Range("C8").Select
Selection.AutoFill Destination:=Range("C8:C" & Total), Type:=x1filldefault
'Adds the above formula into the range C8 to C(the last cell in use)
Range("E8").Formula = "=IF(D8="""","""",IF(ISERROR(VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,4,FALSE)),"""",VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,4,FALSE)))"
Range("E8").Select
Selection.AutoFill Destination:=Range("E8:E" & Total), Type:=x1filldefault
'Adds the above formula into the range E8 to E(the last cell in use)
Range("J8").Formula = "=IF(D8="""","""",IF(ISERROR(VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,9,FALSE)),"""",VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,9,FALSE)))"
Range("J8").Select
Selection.AutoFill Destination:=Range("J8:J" & Total), Type:=x1filldefault
'Adds the above formula into the range J8 to J(the last cell in use)
Range("A8").Formula = "=If(B8="""","""",Row(A8))"
Range("A8").Select
Untested, but this should do what you want.
In a loop:
For i = 8 to Total
If cells(i, 4) <> "" Then
AddFormulaIfNotBlank cells(i, 2), _
"=IF(D<r>="""","""",IF(ISERROR(VLOOKUP(Trim(D<r>),Sheet3!$B$8:$M$7500,2,FALSE))" _
& ","""",VLOOKUP(Trim(D<r>),Sheet3!$B$8:$M$7500,2,FALSE)))"
'add rest of formulas here....
Next i
Next i
Helper Sub: populate only empty cells, and adjust the formula for the current row
Sub AddFormulaIfNotBlank(c As Range, f As String)
If Len(c.value)=0 Then
c.formula = Replace(f, "<r>", c.Row)
End If
End sub
I've tested this briefly. it assumes that the currently selected cell is at the top of the column you want to work down through before you start the procedure. Also there isn't any error handling
Sub CopyFormulas()
Dim xlRange As Range
Dim xlCell As Range
Dim xlAddress As String
xlAddress = ActiveCell.Address & ":$" & Mid(ActiveCell.Address, 2, InStr(1, ActiveCell.Address, "$")) & Mid(Cells.SpecialCells(xlCellTypeLastCell).Address, InStrRev(Cells.SpecialCells(xlCellTypeLastCell).Address, "$"), Len(Cells.SpecialCells(xlCellTypeLastCell).Address))
Set xlRange = Range(ActiveCell, xlAddress)
For Each xlCell In xlRange
xlAddress = "D" & Mid(xlCell.Address, InStrRev(xlCell.Address, "$"), Len(xlCell.Address))
If xlCell.Value = "" And Range(xlAddress).Value <> "" Then
xlCell.Value = "=IF(D8="""","""",IF(ISERROR(VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,2,FALSE)),"""",VLOOKUP(Trim(D8),Sheet3!$B$8:$M$7500,2,FALSE)))"
End If
Next xlCell
End Sub

Excel: How to copy a row if it contains certain text to another worksheet (VBA)

I'm looking to use a marco that would be able to search a column in said sheet and if certain text is found - in my case the word "FAIL" - copy that entire rows data/formatting and paste it into another sheet - sheet 4 in my case - along with any other rows that contained that specific text.
i have been using this code but it only copy pastes one row then stops rather than going through and copying any rows with "FAIL"
Sub Test()
For Each Cell In Sheets(1).Range("H:H")
If Cell.Value = "FAIL" Then
matchRow = Cell.Row
Rows(matchRow & ":" & matchRow).Select
Rows(matchRow & ":" & matchRow).Select
Selection.Copy
Sheets(4).Select
ActiveSheet.Rows(matchRow).Select
ActiveSheet.Paste
Sheets(4).Select
End If
Next
End Sub
First post and brand new to VBA so apologies if too vague.
Try the code below (explanation inside the code as comments):
Option Explicit
Sub Test()
Dim Cell As Range
With Sheets(1)
' loop column H untill last cell with value (not entire column)
For Each Cell In .Range("H1:H" & .Cells(.Rows.Count, "H").End(xlUp).Row)
If Cell.Value = "FAIL" Then
' Copy>>Paste in 1-line (no need to use Select)
.Rows(Cell.Row).Copy Destination:=Sheets(4).Rows(Cell.Row)
End If
Next Cell
End With
End Sub
Try like this:
Option Explicit
Sub TestMe()
Dim Cell As Range
Dim matchRow As Long
With Worksheets(1)
For Each Cell In .Range("H:H")
If Cell.Value = "FAIL" Then
matchRow = .Cell.Row
.Rows(matchRow & ":" & matchRow).Select
.Rows(matchRow & ":" & matchRow).Select
Selection.Copy
Worksheets(4).Select
Worksheets(4).Rows(matchRow).Select
Worksheets(4).Paste
.Select
End If
Next
End With
End Sub
The problem in your code is that you do not reference the worksheets all the time correctly. Thus it does not work correctly.
As a 2. step, you can try to avoid all the selections in your code, it is a best practice to avoid using either Select or Activate in Excel VBA.

VBA Worksheet Sub Create Named Range in Another Worksheet

I have a private sub that needs to create named ranges within another worksheet. It needs to stay a worksheet function, as it is a Worksheet_Change sub. I have successfully been able to set a range variable equal to a range on another sheet with this line:
Set rng2 = Sheets("Lists").Range(Sheets("Lists").Cells(2, Col), Sheets("Lists").Cells(Unique, Col))
However, when I put rng2 into the other portion of my code, it simply refers to the correct range within the Active Sheet.
Here is what I have tried:
ActiveWorkbook.Names.Add Name:="Level" & Col, RefersTo:= _
"= " & Sheets("Lists").Range(Sheets("Lists").Cells(2, Col), Sheets("Lists").Cells(Unique, Col)).Address & ""
and:
ActiveWorkbook.Names.Add Name:="Level" & Col, RefersTo:= _
"=" & rng2.Address & ""
The bottom function works when it is within a module stored inside the workbook as a whole, but again, does not work within a worksheet sub.
I have also tried Sheets("Lists").rng2.Address in the bottom attempt.
To have the address include the sheet's name, you have to set the external parameter:
rng2.address(external:=True)
Your RefersTo string needs to be something like "=Lists!A1". So all it's missing is the reference to the lists worksheet.
Try something like this:
Dim wsLists As Worksheet
Set wsLists = ThisWorkbook.Worksheets("Lists")
With wsLists
Set rng2 = .Range(.Cells(2, Col), .Cells(Unique, Col))
ThisWorkbook.Names.Add Name:="Level" & Col, RefersTo:="=" & rng2.Address(external:=True)
End With

VBA Look through List

I've got the following code which gets the word dividend from a column and then takes the whole row and copy pastes it to a new sheet.
Sub SortActions()
Dim i&, k&, s$, v, r As Range, ws As Worksheet
Set r = [index(a:a,match("###start",a:a,),):index(a:a,match("###end",a:a,),)].Offset(, 6)
k = r.Row - 1
v = r
For i = 1 To UBound(v)
If LCase$(v(i, 1)) = "dividend" Then
s = s & ", " & i + k & ":" & i + k
End If
Next
s = Mid$(s, 3)
If Len(s) Then
Set ws = ActiveSheet
With Sheets.Add(, ws)
ws.Range(s).Copy .[a1]
Rows("1:1").Select
Selection.Insert Shift:=xlDown, CopyOrigin:=xlFormatFromLeftOrAbove
Sheets("20140701_corporate_action_servi").Select
Rows("2:2").Select
Selection.Copy2
Range("C32").Select
Sheets("Sheet11").Select
ActiveSheet.Paste
End With
End If
End Sub
Is there a way to make this dynamic. So if I want to search for more than word. For example if I have several rows with dividends and special dividends -> it would take all rows of dividends and all rows of special dividends and put them in separate sheets. I have tried ti with recording a macro it doesn't work as the words can differ. Maybe getting the content into a list would work. Please assist . Thanks
As suggested by #Macro Man , I am submitting images of an example sheet and sheet after filter with a simple macro for filtering one field. Please all credit to #Macro Man, it is for illustration in a simple way.
Simple code as follows.
Sub Filter1Field()
With Sheet1
.AutoFilterMode = False
With .Range("A1:H13")
.AutoFilter
.AutoFilter Field:=5, Criteria1:="Dividend"
End With
End With
End Sub
*****UPDATE*******
If your other criteria such as "Sp. Dividend" is other field but on the same row as shown in the image appended and you wish to copy to other sheet you can use the code given below. Another image shows results obtained on sheet2. You can adopt the code to your requrements.
You can use this code:
Sub Test2()
Dim LastRow As Long
Sheets("Sheet2").UsedRange.Offset(0).ClearContents
With Worksheets("Sheet1")
.Range("A1:H13").AutoFilter
.Range("A1:H13").AutoFilter field:=5, Criteria1:="Dividend"
.Range("A1:H13").AutoFilter field:=6, Criteria1:="=Sp. Dividend"
LastRow = .Range("A" & .Rows.Count).End(xlUp).Row
.Range("A1:A" & LastRow).SpecialCells(xlCellTypeVisible).EntireRow.Copy _
Destination:=Sheets("Sheet2").Range("A1")
End With
End Sub