using Lookup in VBA,Excel - vba

I have two Sheets , sheet1 and sheet2 .
Sheet1 has 27 columns, and sheet2 has 10 columns,
I am looking for the Id in sheet 1, column J and Need the corresponding date in sheet 2 , column g.
I Need this corresponding date to be printed in sheet 1 , column AA.
I am using the following belo VBA, it is printing the column D of sheet 2 insted of Column G.
This is the formula,
=IFERROR(VLOOKUP(j2;sheet2!$A:$L;7;0);"")
I dont want to use, record macro functionality. Kindly, help me to correct the code.
Sub lookup()
Dim totalrows As Long
Dim totalcolumn As Long
Dim rng As Range
Dim rng1 As Range
Dim i As Long
totalrows = ActiveSheet.UsedRange.Rows.Count
For i = 2 To totalrows
Sheets("Sheet1").Select
Set rng = Sheets("Sheet2").UsedRange.Find(Cells(i, 10).Value)
If Not rng Is Nothing Then
Cells(i, 27).Value = rng.Value
End If
Next i
End Sub

Instead of FOR loop you can use:
Sheets("Sheet1").Range("AA2:AA" & totalrows).Formula = Application.WorksheetFunction.IfError(Application.VLookup(Sheets("Sheet1").Range("J2:J15"), Sheets("Sheet2").Range("$A:$L"), 7, 0), "")
EDIT:_____________________________________________________________________________
Sub lookup()
Dim totalrows As Long, totalrowsSht2 As Long
totalrows = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
totalrowsSht2 = Sheets("Sheet2").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Sheet1").Range("AA2:AA" & totalrows).Formula = Application.WorksheetFunction.IfError(Application.VLookup(Sheets("Sheet1").Range("J2:J" & totalrowsSht2), Sheets("Sheet2").Range("$A:$L"), 7, 0), "")
End Sub

Related

VBA: How can i select the cell in a row which matches a variable's value?

I have 2 sheets. Sheet1 has 2 rows: column names and values.
Sheet 2 is a master sheet with all the possible column names in. I need to copy the values from sheet 1 into their appropriate column.
I think i can do this via a match function, and so far i have this:
Sub dynamic_paste()
Dim Columnname As String
Dim inputvalue As String
Dim starter As Integer
Dim i As Integer
starter = 0
For i = 1 To 4
'replace 4 with rangeused.rows.count?
Sheets("sheet1").Select
Range("a1").Select
ActiveCell.Offset(0, starter).Select
Columnname = ActiveCell
'sets columnname variable
ActiveCell.Offset(1, 0).Select
inputvalue = ActiveCell
'sets inputname variable
Sheets("sheet2").Select
'**Cells(0, WorksheetFunction.Match(Columnname, Rows(1), 0)).Select**
Range("a1").Offset(1, starter).Value = inputvalue
'inputs variable in the next cell along
starter = starter + 1
Next
End Sub
I need to find out how to use my columnname variable as the matching value, and then offset down to the first row that is empty - then change the value of that cell to the variable called inputvalue.
For extra points: I need to make sure the code doesnt break if they dont find a matching value, and if possible put any values that dont match into the end of the row?
What about this:
Dim LR As Long, X As Long, LC As Long, COL As Long
Dim RNG As Range, CL As Range
Option Explicit
Sub Test()
LR = Sheets(2).Cells.SpecialCells(xlCellTypeLastCell).Row 'Get last used row in your sheet
LC = Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column 'Get last used column in your sheet
Set RNG = Sheets(2).Range(Sheets(2).Cells(1, 1), Sheets(2).Cells(1, LC))
'Loop through all the columns on your sheet with values
For X = 1 To Sheets(1).Cells(1, Sheets(1).Columns.Count).End(xlToLeft).Column
Set CL = RNG.Find(Sheets(1).Cells(1, X).Value, lookat:=xlWhole)
If Not CL Is Nothing Then
COL = CL.Column
Sheets(2).Cells(LR + 1, COL).Value = Sheets(1).Cells(2, X).Value 'Get the value on LR offset by 1
Else
Sheets(2).Cells(1, Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column).Value = Sheets(1).Cells(1, X).Value
Sheets(2).Cells(LR + 1, Sheets(2).Cells(1, Sheets(2).Columns.Count).End(xlToLeft).Column).Value = Sheets(1).Cells(2, X).Value
End If
Next X
End Sub
This way you will avoid using select. Which is very recommandable!
This is Sheet1:
This is Sheet2:
This is the code:
Option Explicit
Sub DynamicPaste()
Dim col As Long
Dim wks1 As Worksheet: Set wks1 = Worksheets(1)
Dim wks2 As Worksheet: Set wks2 = Worksheets(2)
For col = 1 To 3
Dim currentRow As Long
currentRow = WorksheetFunction.Match(wks2.Cells(1, col), wks1.Columns(1))
wks2.Cells(2, col) = wks1.Cells(currentRow, 2)
Next col
End Sub
This is Sheet2 after the code:
This is a must-read - How to avoid using Select in Excel VBA

sum acorss sheets in vba

I have two Sheets , sheet1 called BW, and sheet 2 called reasons.
In sheet 1 I have columns AD till AW, which has to be added individually. i have table in sheet2, where I have listed the column names of AD till AW . in the second column of sheet 2 i Need the sum of column AD till AW. I tried a code like below
Sub sum()
Dim BWlRow As Long, CWlRow As Long, i As Long
Dim Sformula As String
Dim wsBW As Worksheet, wsCW As Worksheet
Set wsBW = Sheets("BW"): Set wsCW = Sheets("Reasons")
BWlRow = wsBW.Cells(wsBW.Rows.Count, "A").End(xlUp).Row
CWlRow = wsCW.Cells(wsCW.Rows.Count, "A").End(xlUp).Row
For i = 30 To 47 '
Sformula = "=SUM(AD2, BW)"
With wsBW
With .Range(.Cells(2, i), .Cells(BWlRow, i))
.Formula = Sformula
.Value = .Value
End With
End With
Next i
End Sub
I am not able to succeed with this.
Assumptions:
Sheets("BW") is the sheet why you have data from Column AD-AW
In Sheets("Reasons") Column A you have listed down the headers of Sheets("BW") Column AD-AW in same order, so there's no need to match for the headers
You want sum of corresponding Sheets("Reasons") Column A items in Sheets("Reasons") Column B
Last row of each sheet is on the basis of number of records in Column A of both sheets
Sub sum()
Dim BWlRow As Long, CWlRow As Long, i As Long
Dim Sformula As String
Dim wsBW As Worksheet, wsCW As Worksheet
Set wsBW = Sheets("BW"): Set wsCW = Sheets("Reasons")
BWlRow = wsBW.Cells(wsBW.Rows.Count, "A").End(xlUp).Row
CWlRow = wsCW.Cells(wsCW.Rows.Count, "A").End(xlUp).Row
Sformula = "=SUM(INDIRECT(""BW!"" & CELL(""address"",OFFSET(AD$2,0,ROW()-2)) & "":"" & CELL(""address"",OFFSET(AD$10,0,ROW()-2))))"
With wsCW
With .Range(.Cells(2, 2), .Cells(CWlRow, 2))
.Formula = Sformula
.Value = .Value
End With
End With
End Sub

Excel vba copying and pasting based on cell value code not working

So im pretty new to VBA coding, and I'm trying to setup a commandbutton that when activated copys everything from sheet "Opties" to the sheet "BOM" from the column D and F that has a 1 in column with the titel "Totaal" and remove blanks.
So far this is my code
Sub Copy()
Dim c As Integer
Dim x As Integer
Dim y As Integer
Dim ws1 As Worksheet: Set ws1 = Sheets("Optie")
Dim ws2 As Worksheet: Set ws2 = Sheets("BOM")
Dim colNum As Integer
colNum = Worksheetfuntion.Match("Totaal", ws1.Range("A1:ZZ1"), 0)
c = 1
x = -4 + colNum
y = -6 + colNum
Set rng1 = ws1.Column(colNum)
Set rng2 = ws2.Range("C5:C25000")
For Each c In ws1.rng1
rng1.Offset(0, x).Copy
rng2.Offset(0, 1).PasteSpecial xlPasteValues
rng1.Offset(0, y).Copy
rng2.Offset(0, 2).PasteSpecial xlPasteValues
Next c
End Sub
I think the following code should work:
'Try to avoid using names that Excel uses - you will sometimes "block" the
'native function, so call the subroutine "myCopy" or something else, but
'preferably not "Copy"
Sub myCopy()
Dim r1 As Long ' Use Long rather than Integer, because Excel
Dim r2 As Long ' now allows for more than 65536 rows
'Use Worksheets collection for worksheets, and only use the Sheets
' collection if you need to process Charts as well as Worksheets
Dim ws1 As Worksheet: Set ws1 = Worksheets("Optie") 'Should this be "Opties"?
Dim ws2 As Worksheet: Set ws2 = Worksheets("BOM")
Dim colNum As Long
colNum = WorksheetFunction.Match("Totaal", ws1.Range("A1:ZZ1"), 0)
r2 = 5 ' I guessed that 5 is the first row you want to write to
'Loop through every row until the last non-empty row in Totaal column
For r1 = 1 To ws1.Cells(ws1.Rows.Count, colNum).End(xlUp).Row
'See if value in Totaal column is 1
If ws1.Cells(r1, colNum).Value = 1 Then
'I have guessed that your destination columns are D & E based on
'your Offset(0, 1) and Offset(0, 2) from column C
'I have guessed that your source columns are F & D based on the
'question mentioning those columns, and the offsets of -4 and -6
'in your current code - I assume based on "Totaal" being column J
'Change my guesses as necessary
'Copy values to destination from source
ws2.Cells(r2, "D").Value = ws1.Cells(r1, "F").Value
ws2.Cells(r2, "E").Value = ws1.Cells(r1, "D").Value
'Increment row counter for destination sheet
r2 = r2 + 1
End If
Next
End Sub

Excel VBA Runtime Error '424' Object Required when deleting rows

I'm trying to compare cell values between 2 Sheets (Sheet1 & Sheet2) to see if they match, and if they match move the matching values in Sheet1 to a pre-existing list (Sheet3) and delete the values in Sheet1 afterwards.
I'm using the reverse For Loop in Excel VBA, but everything works until the part where I start deleting the row using newrange1.EntireRow.Delete.
This throws a '424' Object Required Error in VBA and I've spent hours trying to solve this, I'm not sure why this is appearing. Am I selecting the row incorrectly? The object?
Would appreciate if anyone can point me to the correct direction.
Here's my code:
Sub Step2()
Sheets("Sheet1").Activate
Dim counter As Long, unsubListCount As Long, z As Long, x As Long, startRow As Long
counter = 0
startRow = 2
z = 0
x = 0
' Count Sheet3 Entries
unsubListCount = Worksheets("Sheet3").UsedRange.Rows.Count
Dim rng1 As Range, rng2 As Range, cell1 As Range, cell2 As Range, newrange1 As Range
' Select all emails in Sheet1 and Sheet2 (exclude first row)
Set rng1 = Worksheets("Sheet1").Range("D1:D" & Worksheets("Sheet1").UsedRange.Rows.Count)
Set rng2 = Worksheets("Sheet2").Range("D1:D" & Worksheets("Sheet2").UsedRange.Rows.Count)
' Brute Loop through each Sheet1 row to check with Sheet2
For z = rng1.Count To startRow Step -1
'Cells(z, 4)
Set cell1 = Worksheets("Sheet1").Cells(z, "D")
For x = rng2.Count To startRow Step -1
Set cell2 = Worksheets("Sheet2").Cells(x, "D")
If cell1.Value = cell2.Value Then ' If rng1 and rng2 emails match
counter = counter + 1
Set newrange1 = Worksheets("Sheet1").Rows(cell1.Row)
newrange1.Copy Destination:=Worksheets("Sheet3").Range("A" & unsubListCount + counter)
newrange1.EntireRow.Delete
End If
Next
Next
End Sub
Here's the error I'm getting:
Your inner loop produces a lot of step-by-step work that is better accomplished with Application.Match. Your use of .UsedRange to retrieve the extents of the values in the D columns is better by looking for the last value from the bottom up.
Option Explicit
Sub Step2()
Dim z As Long, startRow As Long
Dim rng2 As Range, wk3 As Worksheet, chk As Variant
startRow = 2
z = 0
Set wk3 = Worksheets("Sheet3")
' Select all emails in Sheet1 and Sheet2 (exclude first row)
With Worksheets("Sheet2")
Set rng2 = .Range(.Cells(2, "D"), .Cells(.Rows.Count, "D").End(xlUp))
End With
With Worksheets("Sheet1")
For z = .Cells(.Rows.Count, "D").End(xlUp).Row To startRow Step -1
chk = Application.Match(.Cells(z, "D").Value2, rng2, 0)
If Not IsError(chk) Then
.Cells(z, "A").EntireRow.Copy _
Destination:=wk3.Cells(Rows.Count, "A").End(xlUp).Offset(1, 0)
.Cells(z, "A").EntireRow.Delete
End If
Next
End With
End Sub
As noted by Ryan Wildry, your original problem was continuing the loop and comparing after deleting the row. This can be avoided by adding Exit For after newrange1.EntireRow.Delete to jump out of the inner loop once a match was found. I don't think you should 'reset cell1' as this may foul up the loop iteration.
I think what's happening is when you are deleting the row, you are losing the reference to the range Cell1. So I reset this after the deletion is done, and removed the reference to newRange1. Give this a shot, I have it working on my end. I also formatted the code slightly too.
Option Explicit
Sub Testing()
Dim counter As Long: counter = 0
Dim z As Long: z = 0
Dim x As Long: x = 0
Dim startRow As Long: startRow = 2
Dim Sheet1 As Worksheet: Set Sheet1 = ThisWorkbook.Sheets("Sheet1")
Dim Sheet2 As Worksheet: Set Sheet2 = ThisWorkbook.Sheets("Sheet2")
Dim Sheet3 As Worksheet: Set Sheet3 = ThisWorkbook.Sheets("Sheet3")
Dim rng1 As Range: Set rng1 = Sheet1.Range("D1:D" & Sheet1.UsedRange.Rows.Count)
Dim rng2 As Range: Set rng2 = Sheet2.Range("D1:D" & Sheet2.UsedRange.Rows.Count)
Dim unsubListCount As Long: unsubListCount = Sheet3.UsedRange.Rows.Count
Dim cell1 As Range
Dim cell2 As Range
Dim newrange1 As Range
' Brute Loop through each Sheet1 row to check with Sheet2
For z = rng1.Count To startRow Step -1
Set cell1 = Sheet1.Cells(z, 4)
For x = rng2.Count To startRow Step -1
Set cell2 = Sheet2.Cells(x, 4)
If cell1 = cell2 Then
counter = counter + 1
Set newrange1 = Sheet1.Rows(cell1.Row)
newrange1.Copy Destination:=Sheet3.Range("A" & unsubListCount + counter)
newrange1.EntireRow.Delete
Set newrange1 = Nothing
Set cell1 = Sheet1.Cells(z, 4)
End If
Next
Next
End Sub

Multiple Rows and Columns to Single Column Excel

I have different data on multiple rows and columns in Excel and I want all the data to be on a single Column. I tried the Transpose Function but it's not helping me to get what I want.
This is what I have right now:
And this is what I want to get:
Can anyone kindly tell me how I can achieve that? Any built in function or Macro will be helpful. Thanks.
Try this code:
Sub RangetoColumn()
Dim LastRow As Long, LastColumn As Long
Dim CurrentSheet As Worksheet, TargetSheet As Worksheet
Dim i As Long, j As Long, Count As Long
Set CurrentSheet = ThisWorkbook.Worksheets("Sheet1")'-->change Sheet1 to your source sheet
Set TargetSheet = ThisWorkbook.Worksheets("Sheet2")'-->change Sheet2 to your target sheet
LastRow = CurrentSheet.Cells(Rows.Count, "A").End(xlUp).Row
Count = 1
For i = 1 To LastRow
LastColumn = CurrentSheet.Cells(i, Columns.Count).End(xlToLeft).Column
For j = 1 To LastColumn
TargetSheet.Range("A" & Count).Value = CurrentSheet.Cells(i, j).Value
Count = Count + 1
Next j
Next i
End Sub
Code will read Range from Sheet1 and will create a Column in Sheet2.
I think this tutorial should help you : tutorial
you can try that solution for your needs.
Try using & in both cells. Try like this A1&B1 to combine the data in cell A1 and cell B1; copy and paste, then enjoy.
this will have all current sheet cells listed down its column A and cleared all other adjacent columns
Option Explicit
Sub RangeToOneColumn()
Dim lastRow As Long, i As Long, j As Long
Dim rng As Range
Dim myArr As Variant
With ThisWorkbook.Worksheets("Sheet1") '<== change it to your needs
lastRow = .Cells(.rows.Count, "A").End(xlUp).Row
ReDim myArr(0 To lastRow - 1)
For i = 1 To lastRow
Set rng = .Range(.Cells(i, 1), .Cells(i, .Columns.Count).End(xlToLeft))
myArr(i - 1) = Application.Transpose(Application.Transpose(rng))
Next i
.Cells(1, 1).CurrentRegion.ClearContents
j = 1
For i = LBound(myArr) To UBound(myArr)
.Cells(j, 1).Resize(UBound(myArr(i))) = Application.Transpose(myArr(i))
j = j + UBound(myArr(i))
Next i
End With
End Sub
since it uses array, it runs faster than iterating a coping&pasting through cells