vba macro to use vlookup - vba

I am trying to fetch the value using a vba macro and vlookup in excel. Expected value is the value from "hiveCatalog" sheet but actual result is "N/A"
When i try normal vlookup in excel, i do get the expected value.
Below is the code - written to update a specific column in the first sheet using the value from another sheet.
Sub **addVlookUpColumn**()
Dim Row As Long
Dim Clm As Long
Dim Sheet1 As Worksheet, Sheet2 As Worksheet
Set Sheet1 = ThisWorkbook.Worksheets("Attributesstagingdirectload")
Set Sheet2 = ThisWorkbook.Worksheets("hiveCatalog")
Table1 = Sheet1.Range("A2:A11000")
Table2 = Sheet2.Range("A3:A11000")
Row = Sheet1.Range("D2").Row
Clm = Sheet2.Range("D2").Column
For Each cl In Table1
Sheet1.Cells(Row, Clm) = Application.VLookup(c1, Table2, 1, False)
Row = Row + 1
Next cl
End Sub
Do let me know where i am going wrong
Below image contains the column header of both the sheets and sheet names

Maybe you need to set where table2 is
You can give this a try if hiveCatalog is where the table is located.
Sheet1.Cells(Row, Clm) = Application.VLookup(Sheet1.Cells(Row, Clm) = WorksheetFunction.VLookup(c1, Worksheets("hiveCatalog").Table2, 1, False))

Related

Excel Vba: Need help to drag formula

I need help placing a formula in row 51 from column A to AE on sheet "COPY". The formula is "Trim(A1)" and needs to be dragged until "Trim(AE1)" while still being in row 51 (A51:AE51)
This is what I have so far, but its pulling up an error on "lascolumn = range..."
Sub INSERT_TRIM_COPY()
Sheets("COPY").Select
Dim Lastcolumn As Long
Lastcolumn = Range("A:AE" & Columns.Count).End(xlToRight).Column
Range("A51:AE51" & Lastcolumn).FORMULA = "=TRIM(A1)"
End Sub
You need to use: Range(Cells(51,1), Cells(51,Lastcolumn).Formula = "=Trim(A1) Because your lastcolumn is variable is numeric you need to use the cells function in the range. The first number is for row number and the second is for the column.
I believe the following will do what you expect it to, the code you used to get the Last Column wasn't right:
Sub foo()
Dim ws As Worksheet: Set ws = Sheets("COPY")
LastCol = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
'get the last Column on Row 1 with data
ws.Range(ws.Cells(51, 1), ws.Cells(51, LastCol)).Formula = "=Trim(A1)"
'add formula from column A to the last Column
End Sub

Vlookup in 2 workbooks

I need to run Vlookups for data in 2 workbooks. I will open both of my workbooks when running the VBA codes, and I saved both workbooks as .xlsm so they are both macro enabled.
I have no problem using the Vlookup Excel function but I want to run it automatically using VBA code.
Here is the information,
I have 2 workbooks, Book3.xlsm and Book32.xlsm. Book3 is where I want my result to be, as shown in the second picture. The data range varies each month, so I need to loop through the end of the last row.
I have 3 columns in Book3 ID and Type and Result and 2 columns in Book32, ID and Result, and I want to do Vlookup using the ID column in Book3 and get the values in Result columns in Book32. The data are both in Sheet1.
Now my code will run but please look for the first picture where it is not showing the desired result. I can leave the value as #N/A if can't be found but in this case, all the values should be found using Vlookup.
Here is my code,
Sub test()
On Error Resume Next
Dim Res_Row As Integer
Dim Res_Clm As Integer
Dim Table1 As Range
Dim Table2 As Range
Dim cl As Range
Set Table1 = Workbooks("Book3.xlsm").Sheets("Sheet1").Columns("A:C")
Set Table2 = Workbooks("Book32.xlsm").Sheets("Sheet1").Columns("A:B")
Res_Row = Sheet1.Range("C2").Row
Res_Clm = Sheet1.Range("C2").Column
For Each cl In Table1
Sheet1.Cells(Res_Row, Res_Clm) = Application.WorksheetFunction.VLookup(cl, Table2, 2, False)
Res_Row = Res_Row + 1
Next cl
MsgBox "Done"
End Sub
How about this code, which avoids the loop and is easier to read \ maintain.
With Workbooks("Book3.xlsm").Sheets("Sheet1")
Dim lRow as Long
lRow = .Range("A" & .Rows.Count).End(xlup).Row
With .Range("C2:C" & lRow)
.FormulaR1C1 = "=Vlookup(RC[-2],[Book32.xlsm]Sheet1!C1:C2,2,0)"
.Value = .Value
End With
End With
Here it is :
Sub test()
On Error Resume Next
Dim Res_Row As Integer
Dim Res_Clm As Integer
Dim Table1 As Range
Dim Table2 As Range
Set Table1 = Workbooks("Book3.xlsm").Sheets("Sheet1").Columns("A:C")
Set Table2 = Workbooks("Book32.xlsm").Sheets("Sheet1").Columns("A:B")
Res_Clm = 3
The loop will be on each rows of the table1.
For Each i In Table1.Rows
If Sheet1.Cells(i.row, 1) = "" Then Exit For
If there is no data ("") in the cell, the program exit the loop
Sheet1.Cells(i.row, Res_Clm) = Application.WorksheetFunction.VLookup(Sheet1.Cells(i.row, 1), Table2, 2, False)
Next i
Next i increment the i of the for each loop.. It is like i = i+1
MsgBox "Done"
End Sub
You use the wrong argument for the first argument of the vlookup.
Also your loop on "cl" would only work on three rows, so I use row argument.
In general, I would adwise to code your vlookup fonction instead of using Application.WorksheetFunction.VLookup. I'm quite sure it is longer.

Excel VBA: How to find first empty row within a Table for a Loop routine?

I reformatted a range of Sheets("Records") in a workbook as a Table (named "RecordsTable") to make it easier to do INDEX(MATCH,MATCH) functions for generating reports.... but now I screwed up my looping routine for filling that range from the input on Sheets("FORM").
It used to be:
Set r = Sheets("Records").Range(A & Rows.Count).End(x1Up).Offset(1, 0)
i = 0
For Each c In Range("dataRange")
'dataRange is a list of cells to reference from the FORM input sheet
r.Offset(0, i).Value = Worksheets("FORM").Range(c)
i = i + 1
Next
However this code is now selecting the first row at the END of "RecordsTable" (row 501, as I defined 500 rows in my table) and inserting the data there.
I tried to change it to this:
Set r = Sheets("Records").ListObjects("RecordsTable").DataBodyRange("A" & Rows.Count).End(x1Up).Offset(1, 0)
i = 0
For Each c In Range("dataRange")
r.Offset(0, i).Value = Worksheets("FORM").Range(c)
i = i + 1
Next
But this code is still selecting row 501 and making that row part of "RecordsTable".
How can I properly Set "r" to = the first empty row in "RecordsTable"?
For reference, Column "A" in "RecordsTable" has the header [INV #]. Also, when I step into the "Set r = ..." line, Rows.Count is returning a value of 1million+ (ie, total rows on the sheet) - if I understand this correctly, I want it to return a value of 500 (ie, total rows in table) - is that correct?
EDIT
"dataRange" is a single column list of cell references (I do have them labeled in column B, as #chrisneilsen suggest:
A
J6
Y6
J8
J10
Y8
etc.
They are the cells on Sheets("FORM") that I need to pull data from and populate into my table, in the order indicated in "dataRange".
Assuming you really have a Table, adding data to a Table (ListObject) using it's properties and methods:
Sub Demo()
Dim lo As ListObject
Dim c As Range
Set lo = Worksheets("Records").ListObjects("RecordsTable")
For Each c In Sheets("V").Range("dataRange")
If Not lo.InsertRowRange Is Nothing Then
lo.InsertRowRange.Cells(1, 1) = Sheets("FORM").Range(c)
Else
lo.ListRows.Add.Range.Cells(1, 1) = Sheets("FORM").Range(c)
End If
Next
End Sub
Note: looping a range on sheet V and using that as a pointer to data on sheet FORM, copied from your answer - I'm assuming you know what you are doing here
Based on OP comment, adding data a single new row
Sub Demo()
Dim lo As ListObject
Dim c As Range, TableRange As Range
Dim i As Long
Set lo = Worksheetsheets("Records").ListObjects("RecordsTable")
If Not lo.InsertRowRange Is Nothing Then
Set TableRange = lo.InsertRowRange
Else
Set TableRange = lo.ListRows.Add.Range
End If
i = 1
For Each c In Sheets("V").Range("dataRange")
TableRange.Cells(1, i) = Sheets("FORM").Range(c)
i = i + 1
Next
End Sub
Note, this assumes that the order of the table columns is the same as the order of dataRange. It may be better to include table field names in dataRange to avoid any mismatch issues
As mentioned in updated OP, if column labels are in the next column, replace the For loop with this (and add Dim r as Range, col as long to declarations)
For Each c In Sheets("V").Range("dataRange")
If Not c = vbNullString Then
Set r = Worksheets("FORM").Range(c.Value)
col = lo.ListColumns(c.Offset(, 1).Value).Index
TableRange.Cells(1, col) = r.Value
End If
Next

Auto-filtering Excel Range based on input range

In an excel spreadsheet I have 3 columns of data. Column A+B have text inputted and column C is numerical (1-5). I will be creating an input box. depending on the input it will filter the results for column C.
For example :
if I inputted G this conditions will filter the results for column C having 1,2 & 4
if i inputted A this conditions will filter the results for column C having 1 & 3
is this possible to do? my thought was these macros to filter the results and then export it to a new spreadsheet. Is there any other way of doing this ? Sorry for the award explanation :S
This uses the Range.AdvancedFilter method further described here to filter your data, based on user input, and copies the filtered data to a second worksheet in the same workbook.
Because AdvancedFilter requires some 'setting-up' the following assumptions have been made in my example. You may need to change these for your requirements.
There are two worksheets, one (called Data) containing your data; and the second (called Results) containing the AdvancedFilter criteria and the copied results. This second sheet is assumed to be a blank sheet. The criteria are programmatically applied to this sheet.
Your Data must have data headings. If you change the heading called 'Criteria' in my example then you will need to also change this in the code.
You can add additional filter criteria within the code should you wish.
If no, or an unknown filter ID is entered into the inputbox, then all the data is copied to the Results sheet. The results sheet is automatically cleared if the Sub is re-run. An example of applying filter value G is shown below:
Option Explicit
Sub advFiltVals()
Dim wsData As Worksheet, wsResult As Worksheet
Dim frstRow As Long, lstRow As Long, stcol As Long, endcol As Long
Dim critStRow As Long, critStCol As Long
Dim copyStRow As Long, copyStCol As Long
Dim filtVal As String
Dim critRng As Range, copyToRng As Range
Set wsData = Sheets("Data")
Set wsResult = Sheets("Results")
'data
frstRow = 1
stcol = 1
endcol = 3
'result
critStRow = 1 'header row
critStCol = 1
copyStRow = 2
copyStCol = 3
With wsResult
.UsedRange.Clear
Set copyToRng = .Cells(copyStRow, copyStCol)
.Cells(critStRow, critStCol).Value = "Criteria"
filtVal = InputBox("Enter filter value.")
Select Case UCase(filtVal)
Case Is = "A"
.Cells(critStRow, critStCol).Offset(1, 0) = 1
.Cells(critStRow, critStCol).Offset(2, 0) = 3
Set critRng = .Range(.Cells(critStRow, critStCol), .Cells(critStRow, critStCol).Offset(2, 0))
Case Is = "G"
.Cells(critStRow, critStCol).Offset(1, 0) = 1
.Cells(critStRow, critStCol).Offset(2, 0) = 2
.Cells(critStRow, critStCol).Offset(3, 0) = 4
Set critRng = .Range(.Cells(critStRow, critStCol), .Cells(critStRow, critStCol).Offset(3, 0))
Case Else
Set critRng = .Cells(critStRow, critStCol)
End Select
End With
With wsData
If .FilterMode = True Then
.ShowAllData
End If
lstRow = .Cells(Rows.Count, endcol).End(xlUp).Row
With .Range(.Cells(frstRow, stcol), .Cells(lstRow, endcol))
.AdvancedFilter Action:=xlFilterCopy, CriteriaRange:=critRng, CopyToRange:=copyToRng, Unique:=False
End With
End With
End Sub

VBA Excel Macro Copying One Column into Another Workbook

I have 2 workbooks and am trying to find a way to copy a column from wb1 into wb2. I am aware I could just copy/paste, but the idea is to make something so my boss can click the macro and everything populates.
I have been trying a code I came across in another question:
Sub Import()
Dim sourceColumn As Range
Dim destColumn As Range
Set sourceColumn = Workbooks("C:\Documents and Settings\********\My Documents\*********.xlsm").Worksheets(2).Columns("BL")
Set destColumn = Workbooks("C:\Documents and Settings\********\My Documents\*********.xlsm").Worksheets(2).Columns("A")
sourceColumn.Copy Destination = destColumn
End Sub
When I run this, I get a "Subscript Out Of Range" Error.
The source column contains a formula relying on other columns and the destination column is empty, but even when I ran this on dummy workbooks with small digits I got the same error.
Is there something super basic I am missing here?
EDIT : Just realized what's probably missing from that piece of code you have. Add a ":" in there! Change to destination:=Workbooks(".... and it should work fine.
Extra details : When working with function parameters, you have to add the ":" in order to specify to the computer you're not evaluating an equality, but doing a parameter assignment.
(Old, flashy answer)
As I assume this is what you're trying to do; this script will probably do what you want. The style will NOT be preserved however.
Sub yourSub()
Application.ScreenUpdating = False 'Disables "Screen flashing" between 2 workbooks
Dim colA As Integer, colB As Integer
Dim rowA As Integer, rowB As Integer
Dim wbA As Workbook, wbB As Workbook
Set wbA = ThisWorkbook
Set wbB = Workbooks.Open("C:/YourFilePath/YourFile.xls")
colA = 1 'Replace "1" with the number of the column FROM which you're copying
colB = 1 'Replace "1" with the number of the column TO which you're copying
rowA = 1 'Replace "1" with the number of the starting row of the column FROM which you're copying
rowB = 1 'Replace "1" with the number of the row of the column TO which you're copying
wbA.Activate
lastA = Cells(Rows.Count, colA).End(xlUp).Row 'This finds the last row of the data of the column FROM which you're copying
For x = rowA To lastA 'Loops through all the rows of A
wbA.Activate
yourData = Cells(x, colA)
wbB.Activate
Cells(rowB, colB) = yourData
rowB = rowB + 1 'Increments the current line of destination workbook
Next x 'Skips to next row
Application.ScreenUpdating = True 'Re-enables Screen Updating
End Sub
I didn't have time to test this yet. Will do as soon as possible.