VBA , Using offset - vba

I am having 4 sht, sht1, sht2, sht3 and sht4.
I am copying the columns E and F from sht 1 to sht3. and then i look into the corresponding values in sht 2, and paste them in sht3.
I then lookinto in my sht3, if the column "G" has "NO"; then i copy the corresponding rows to sht4.
till, this i have completed coding.
I wanted to look into the column E in sht4, and paste the corresponding ID from sht1. Could someone tell, how i could do it ?
EDIT.
In sht3, i have the rows filled only when there is Id in column F.
In few cases, i dont have column F,means there is no ID.
so, i copy them to sht4. Now i have in sht4, column E Filled. I want to look into the relevant Information of those ID in sht1. I want the Information from each and every column in sht1, except E .
I know we can use Offset, but how do I use it in this case,
I have tried the following code
Sub nlookup()
Dim i As Long
Dim totalrows As Long
Dim rng As Range
Sheets("sht1").Select
totalrows = ActiveSheet.UsedRange.Rows.Count
Sheets("sht4").Select
For i = 5 To totalrows
Set rng = Sheets("sht2").UsedRange.Find(Cells(i, 5).Value)
'If it is found put its value on the destination sheet
If Not rng Is Nothing Then
Cells(i, 6).Value = rng.Value
Cells(i, 1).Value = rng.Offset(0, 0).Value
Cells(i, 2).Value = rng.Offset(0, 14).Value
Cells(i, 3).Value = rng.Offset(0, 1).Value
Cells(i, 4).Value = rng.Offset(0, 2).Value
Cells(i, 12).Value = rng.Offset(0, 8).Value
Cells(i, 13).Value = rng.Offset(0, 9).Value
End If
Next
End Sub
Set rng = Sheets("sht2").UsedRange.Find(Cells(i, 5).Value), there is no Need of looking into this line, i beleive.

The code will consider the following as discussed in chat:
Data should be copied from sht1 to sht4 on Id's in both sheets
Id's are in Column L and Column E for sht1 and sht4 respectively
Columns to be copy from sht1 to sht4 as A->A, B->C,C->D,I->L,J->M,O->B
Data in sht1 and sht4 starts from Row 5 and Row 2 respectively
Sub Demo()
Dim srcLastRow As Long, destLastRow As Long
Dim srcWS As Worksheet, destWS As Worksheet
Dim i As Long, j As Long
Application.ScreenUpdating = False
Set srcWS = ThisWorkbook.Sheets("Sht1")
Set destWS = ThisWorkbook.Sheets("Sht4")
srcLastRow = srcWS.Cells(srcWS.Rows.Count, "L").End(xlUp).Row
destLastRow = destWS.Cells(destWS.Rows.Count, "E").End(xlUp).Row
For i = 2 To destLastRow
For j = 5 To srcLastRow
If destWS.Cells(i, "E").Value = srcWS.Cells(j, "L").Value Then
destWS.Cells(i, "A") = srcWS.Cells(j, "A")
destWS.Cells(i, "B") = srcWS.Cells(j, "O")
destWS.Cells(i, "C") = srcWS.Cells(j, "B")
destWS.Cells(i, "D") = srcWS.Cells(j, "C")
destWS.Cells(i, "L") = srcWS.Cells(j, "I")
destWS.Cells(i, "M") = srcWS.Cells(j, "J")
End If
Next j
Next i
Application.ScreenUpdating = True
End Sub

Why not just use Cells(i, 4).Value = rng.Cells(i, 6).Value ?
Also get rid of the.Select
Sub nlookup()
dim sht as Worksheet
Dim i As Long
Dim totalrows As Long
Dim rng As Range
totalrows = Sheets("sht1").UsedRange.Rows.Count
Set sht = Worksheets("sht4")
For i = 5 To totalrows
Set rng = Sheets("sht2").UsedRange.Find(sht.Cells(i, 5).Value)
'If it is found put its value on the destination sheet
If Not rng Is Nothing Then
sht.Cells(i, 6).Value = rng.Value
sht.Cells(i, 1).Value = rng.Cells(i, 1).Value
sht.Cells(i, 2).Value = rng.Cells(i, 16).Value
sht.Cells(i, 3).Value = rng.Cells(i, 4).Value
sht.Cells(i, 4).Value = rng.Cells(i, 6).Value
sht.Cells(i, 12).Value = rng.Cells(i, 20).Value
sht.Cells(i, 13).Value = rng.Cells(i, 22).Value
End If
Next
End Sub

Related

Select Specific Column VBA COPY

I am trying to copy a few colums of data that meet a certain criteria and then paste the first column of the copied data into a specific column on a second spreadsheet by nation. I am stuck selecting data from the copied cells- the second if statement.
New Working Code
Sub SortData()
'Clear Data from Practices Sheet
Sheet2.Range("B6:F1000").Clear
a = Worksheets("Home").Cells(Rows.Count, 3).End(xlUp).Row
For i = 3 To a
If Worksheets("Home").Cells(i, 4).Value = "Active" And Worksheets("Home").Cells(i, 3).Value = "Denmark" Then
C = Worksheets("Home").Cells(i, 2).Copy
Worksheets("Practices").Activate
b = Worksheets("Practices").Cells(Rows.Count, 2).End(xlUp).Row
Worksheets("Practices").Cells(b + 1, 2).Select 'column To paste data into
ActiveSheet.Paste
Worksheets("Home").Activate
ElseIf Worksheets("Home").Cells(i, 4).Value = "Active" And Worksheets("Home").Cells(i, 3).Value = "Netherlands" Then
C = Worksheets("Home").Cells(i, 2).Copy
Worksheets("Practices").Activate
b1 = Worksheets("Practices").Cells(Rows.Count, 4).End(xlUp).Row
Worksheets("Practices").Cells(b1 + 1, 4).Select
ActiveSheet.Paste
Worksheets("Home").Activate
ElseIf Worksheets("Home").Cells(i, 4).Value = "Active" And Worksheets("Home").Cells(i, 3).Value = "UK" Then
C = Worksheets("Home").Cells(i, 2).Copy
Worksheets("Practices").Activate
b = Worksheets("Practices").Cells(Rows.Count, 6).End(xlUp).Row
Worksheets("Practices").Cells(b + 1, 6).Select
ActiveSheet.Paste
Worksheets("Home").Activate
End If
Next
End Sub
How to make this more concise?
I recommend to reduce redundant code like this:
Don't use .Select and .Activate as I told in my first comment.
How to avoid using Select in Excel VBA
Use Option Explicit to make sure all variables are declared.
Don't use the same code lines over and over. Instead make a function/procedure or reduce redundancy like I did below.
Always use descriptive variable names instead of one letter names. Otherwise your code is very hard to read/understand by humans.
Option Explicit
Public Sub SortData()
'Clear Data from Practices Sheet
Worksheets("Practices").Range("B6:F1000").Clear
Dim LastUsedRow As Long
LastUsedRow = Worksheets("Home").Cells(Rows.Count, 3).End(xlUp).Row
Dim i As Long
For i = 3 To LastUsedRow
If Worksheets("Home").Cells(i, 4).Value = "Active" Then
Dim PasteColumn As Long
Select Case Worksheets("Home").Cells(i, 3).Value
Case "Denmark": PasteColumn = 2
Case "Netherlands": PasteColumn = 4
Case "UK": PasteColumn = 6
Case Else: PasteColumn = 0 'we need this to cancel copy
End Select
If PasteColumn > 0 Then
Dim PasteLastRow As Long
PasteLastRow = Worksheets("Practices").Cells(Rows.Count, PasteColumn).End(xlUp).Row
Worksheets("Home").Cells(i, 2).Copy
Worksheets("Practices").Cells(PasteLastRow + 1, PasteColumn).Paste
End If
End If
Next i
End Sub
I have had a go at what i think you mean. But there are many errors and inconsistencies throughout as noted in the comments.
Sub SortData()
Dim a As Long, c As Range, sh As Worksheet, ws As Worksheet, b As Long
Set sh = ThisWorkbook.Sheets("Home")
Set ws = ThisWorkbook.Sheets("Practices")
a = sh.Cells(Rows.Count, 3).End(xlUp).Row
For i = 3 To a
If sh.Cells(i, 4).Value = "Active" Then
Set c = sh.Range(Cells(i, "A"), Cells(i, "D"))
End If
If c.Columns(3) = "Denmark" Then
b = ws.Cells(Rows.Count, 5).End(xlUp).Row
c.Copy
ws.Cells(i, 2).PasteSpecial
ElseIf c.Cells(i, 3) = "Netherlands" Then
b = ws.Cells(Rows.Count, 5).End(xlUp).Row
c.Copy
ws.Cells(i, 2).PasteSpecial
ElseIf C.Cells(i, 3) = "UK" Then
b = ws.Cells(Rows.Count, 5).End(xlUp).Row
c.Copy
ws.Cells(b + 1, 6).PasteSpecial
End If
Next
End Sub

Loop and IF statement takes too much time

The code bellow is suppose to do a vlookup in a different worksheet based on some criteria. I declared all the variables and it does its job, but it takes too much time to wait. I believe that this is because of the loop and the two if statements I have, but I cannot see another way of writing two criteria (IF statements). Any other approach will be must appreciated. Thanks!
Please find attached the code below:
Private Sub CommandButton3_Click()
Dim vlookup As Variant
Dim lastRow As Long, lastRow1 As Long
Dim ws As Worksheet, ws1 As Worksheet
Dim j As Long
Set ws = Sheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Set ws1 = Sheets("Sheet2")
lastRow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
Application.ScreenUpdating = False
For j = 2 To lastRow
If Cells(j, "a") > 1000 And Cells(j, "b") <> "" Then
With ws.Range("f2:f" & lastRow)
.Formula = "=iferror(vlookup(e2, " & ws1.Range("a2:c" & lastRow1).Address(1, 1, external:=True) & ", 3, false), text(,))"
.value = .value
End With
ElseIf Cells(j, "a") > 1000 Then
With ws.Range("f2:f" & lastRow)
.Formula = "=iferror(vlookup(d2, " & ws1.Range("a2:c" & lastRow1).Address(1, 1, external:=True) & ", 3, false), text(,))"
.value = .value
End With
Else
Cells(j, "f") = "No"
End If
Next
End Sub
You are writing and rewriting the same formula(s) into the same cells over and over.
Private Sub CommandButton3_Click()
Dim r As Variant
Dim lastRow As Long, lastRow1 As Long, j As Long
Dim ws As Worksheet, ws1 As Worksheet, rng As Range
Set ws = Worksheets("Sheet1")
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row
Set ws1 = Worksheets("Sheet2")
lastRow1 = ws1.Cells(ws1.Rows.Count, "A").End(xlUp).Row
Set rng = ws1.Columns(1)
With ws
For j = 2 To lastRow
If .Cells(j, "a") > 1000 And .Cells(j, "b") <> "" Then
r = Application.Match(.Cells(j, "e").Value2, rng, 0)
If Not IsError(r) Then
.Cells(j, "f") = ws1.Cells(r, "c").Value
else
.Cells(j, "f") = vbnullstring
End If
ElseIf .Cells(j, "a") > 1000 Then
r = Application.Match(.Cells(j, "d").Value2, rng, 0)
If Not IsError(r) Then
.Cells(j, "f") = ws1.Cells(r, "c").Value
else
.Cells(j, "f") = vbnullstring
End If
Else
.Cells(j, "f") = "No"
End If
Next j
End With
End Sub

Using rangefind

I have three sheets, sheet S, Sheet P and Sheet Data.
I first copy the column of Sheet S to Sheet Data. Then in column E of sheet Data, I look for the ID. The ID In column E of data sheet, matches with the column A of P sheet, then I copy the corresponding ID.
The problem here is the Sheet data contains 214 rows, while sheet P contains 1110.
while comparing the ID, there are two different ID from row 870 and 871, which are not copied, even though they are same.
Could someone guide what could be the reason ?
Sub lookup()
Dim lLastrow, totalrows As Long
Dim rng As Range
Dim i As Long
'Copy lookup values from S to Data
With Sheets("S")
lLastrow = .Cells(.Rows.count, 1).End(xlUp).Row
.Range("P5:P" & lLastrow).Copy Destination:=Sheets("Data").Range("E5")
.Range("G5:G" & lLastrow).Copy Destination:=Sheets("Data").Range("H5")
End With
totalrows = Sheets("P").Cells(Sheets("P").Rows.count, "A").End(xlUp).Row
For i = 5 To lLastrow
'Search for the value on P_APQP
With Sheets("P")
Set rng = .Columns(1).Find(Sheets("Data").Cells(i, 5).Value & "*", lookat:=xlWhole)
End With
'If it is found put its value on the destination sheet
If Not rng Is Nothing Then
With Sheets("Data")
.Cells(i, 6).Value = rng.Value
.Cells(i, 1).Value = rng.Offset(0, 1).Value
.Cells(i, 2).Value = rng.Offset(0, 2).Value
.Cells(i, 3).Value = rng.Offset(0, 3).Value
.Cells(i, 4).Value = rng.Offset(0, 9).Value
.Cells(i, 9).Value = rng.Offset(0, 10).Value
.Cells(i, 13).Value = rng.Offset(0, 6).Value
.Cells(i, 14).Value = rng.Offset(0, 5).Value
.Cells(i, 15).Value = rng.Offset(0, 4).Value
.Cells(i, 16).Value = rng.Offset(0, 8).Value
End With
End If
Next i
End Sub
I'll post the whole code. I also made an adjustment to your first line of declarations - as you had it, only totalrows was being declared as Long. You have to spell each one out I'm afraid.
Sub lookup()
Dim lLastrow As Long, totalrows As Long
Dim rng As Range
Dim i As Long
With Sheets("S")
lLastrow = .Cells(.Rows.Count, 1).End(xlUp).Row
.Range("P5:P" & lLastrow).Copy Destination:=Sheets("Data").Range("E5")
.Range("G5:G" & lLastrow).Copy Destination:=Sheets("Data").Range("H5")
End With
totalrows = Sheets("P").Cells(Sheets("P").Rows.Count, "A").End(xlUp).Row
For i = 5 To lLastrow
'Search for the value on P_APQP
With Sheets("P")
'amended below
Set rng = .Columns(1).Find(Trim(Sheets("Data").Cells(i, 5).Value) & "*", lookat:=xlWhole)
End With
'If it is found put its value on the destination sheet
If Not rng Is Nothing Then
With Sheets("Data")
.Cells(i, 6).Value = rng.Value
.Cells(i, 1).Resize(, 3).Value = rng.Offset(0, 1).Value
.Cells(i, 2).Value = rng.Offset(0, 2).Value
.Cells(i, 3).Value = rng.Offset(0, 3).Value
.Cells(i, 4).Value = rng.Offset(0, 9).Value
.Cells(i, 9).Value = rng.Offset(0, 10).Value
.Cells(i, 13).Value = rng.Offset(0, 6).Value
.Cells(i, 14).Value = rng.Offset(0, 5).Value
.Cells(i, 15).Value = rng.Offset(0, 4).Value
.Cells(i, 16).Value = rng.Offset(0, 8).Value
End With
End If
Next i
End Sub

Comparing source sheet and Dest sheet , and copying the unmatched data in the source sheet

I have two Sheets Sht1 and Sht2.
I am comparing the column A of sheet1 with column A of sheet2. The column A of both the Sheets, contains ID.
If there is a non matching ID in sheet2, then I want to copy the unmatched row in sheet1.
I tried a code below, and the problem is, it is just copying the unmatched last row of sheet2 multiple times and keeps running without Exit.
Could anyone help me how i could correct it.
Sub trialtest()
Dim srcLastRow As Long, destLastRow As Long
Dim srcWS As Worksheet, destWS As Worksheet
Dim i As Long, j As Long
Application.ScreenUpdating = False
Set srcWS = ThisWorkbook.Sheets("S2")
Set destWS = ThisWorkbook.Sheets("S1")
srcLastRow = srcWS.Cells(srcWS.Rows.Count, "A").End(xlUp).Row
destLastRow = destWS.Cells(destWS.Rows.Count, "A").End(xlUp).Row
For i = 5 To destLastRow
For j = 5 To srcLastRow
If destWS.Cells(i, "A").Value <> srcWS.Cells(j, "A").Value Then
destWS.Cells(i, "A") = srcWS.Cells(j, "A")
destWS.Cells(i, "B") = srcWS.Cells(j, "B")
destWS.Cells(i, "C") = srcWS.Cells(j, "C")
destWS.Cells(i, "D") = srcWS.Cells(j, "D")
destWS.Cells(i, "E") = srcWS.Cells(j, "E")
destWS.Cells(i, "F") = srcWS.Cells(j, "F")
destWS.Cells(i, "G") = srcWS.Cells(j, "G")
destWS.Cells(i, "H") = srcWS.Cells(j, "H")
destWS.Cells(i, "I") = srcWS.Cells(j, "I")
destWS.Cells(i, "J") = srcWS.Cells(j, "J")
destWS.Cells(i, "K") = srcWS.Cells(j, "K")
destWS.Cells(i, "L") = srcWS.Cells(j, "L")
destWS.Cells(i, "M") = srcWS.Cells(j, "M")
destWS.Cells(i, "N") = srcWS.Cells(j, "N")
destWS.Cells(i, "O") = srcWS.Cells(j, "O")
destWS.Cells(i, "P") = srcWS.Cells(j, "P")
destWS.Cells(i, "Q") = srcWS.Cells(j, "Q")
destWS.Cells(i, "R") = srcWS.Cells(j, "R")
destWS.Cells(i, "S") = srcWS.Cells(j, "S")
End If
Next j
Next i
Application.ScreenUpdating = True
End Sub
I know you have accepted an answer however, i just want to share this approach with you:
If i understood your question correctly, if an ID in sheet 1 is not equal to an ID in sheet 2, then replace that sheet 1 ID with the ID from sheet 2?
Option Explicit
Dim i, n As Long
Sub IDReplace()
n = Sheets("Sheet1").Cells(Rows.Count, 1).End(xlUp).Row
With Sheets("Sheet1")
For i = 2 To n
If .Cells(i, 1).Value <> .Parent.Sheets("Sheet2").Cells(i, 1).Value Then
.Cells(i, 1).Value = .Parent.Sheets("Sheet2").Cells(i, 1).Value
End If
Next i
End With
End Sub
Based on the fact that Sheet 1 is the main sheet you are focusing on, you need only count the rows of Sheet 1 and not Sheet2
Happy to Help :)
Try this code
Sub trialtest()
Dim srcLastRow As Long, destLastRow As Long, rowIndex As Long
Dim srcWS As Worksheet, destWS As Worksheet
Dim i As Long, j As Long
Dim found As Boolean
Application.ScreenUpdating = False
Set srcWS = ThisWorkbook.Sheets("S2")
Set destWS = ThisWorkbook.Sheets("S1")
srcLastRow = srcWS.Cells(srcWS.Rows.Count, "A").End(xlUp).Row
destLastRow = destWS.Cells(destWS.Rows.Count, "A").End(xlUp).Row
rowIndex = destLastRow
found = False
For i = 5 To srcLastRow
For j = 5 To destLastRow
'Debug.Print srcWS.Cells(i, "A").Value & " : " & destWS.Cells(j, "A").Value
If srcWS.Cells(i, "A").Value = destWS.Cells(j, "A").Value Then
found = True
'rowIndex = rowIndex + 1
'destWS.Cells(rowIndex, "A") = srcWS.Cells(j, "A")
Exit For
End If
Next j
If found = False Then
rowIndex = rowIndex + 1
'destWS.Cells(rowIndex, "A") = srcWS.Cells(i, "A")
destWS.Range("A" & rowIndex & ":S" & rowIndex).Value = srcWS.Range("A" & i & ":S" & i).Value
End If
found = False
Next i
Application.ScreenUpdating = True
End Sub
Let me know if anything is not clear.
I would work here with the find method. with the find method you can look if the ID from Sheet S2 is in Sheet S1.
if it finds the ID in Sheet S1 the Variable c has the ID Value. If it don't find the ID in Sheet S1, the value of c is Nothing.
Then the code will copy the Row at the End your List of ID's from Sheet S1.
Sub trialtest()
Dim srcLastRow As Long, destLastRow As Long
Dim srcWS As Worksheet, destWS As Worksheet
Dim i As Long, j As Long
Application.ScreenUpdating = False
Set srcWS = ThisWorkbook.Sheets("S2")
Set destWS = ThisWorkbook.Sheets("S1")
srcLastRow = srcWS.Cells(srcWS.Rows.Count, "A").End(xlUp).Row
destLastRow = destWS.Cells(destWS.Rows.Count, "A").End(xlUp).Row
With destWS.Range(Cells(5, 1), Cells(destLastRow, 1))
For j = 5 To srcLastRow
Set c = .Find(srcWS.Cells(j, "A").Value, LookIn:=xlValues)
' if value not in destWS copy it form srcWS
If c Is Nothing Then
srcWS.Range("A" & j & ":S" & j).Copy _
Destination:=destWS.Cells(destLastRow + 1, 1)
destLastRow = destLastRow + 1
End If
Next j
End With
Application.ScreenUpdating = True
End Sub

Auto fill down cell in Excel VBA Macro

Sub AutoFill()
Dim x As Long
Dim y As Long
Dim lastrow As Long
Dim lastcolumn As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
lastcolumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
lastrow = ActiveSheet.UsedRange.Row - 1 + ActiveSheet.UsedRange.Rows.Count
For x = 2 To lastrow
If Cells(x, 2).Value = "" Then
Cells(x, 2).Value = Cells(x - 1, 2).Value
Cells(x, 3).Value = Cells(x - 1, 3).Value
Cells(x, 5).Value = Cells(x - 1, 5).Value
End If
Next x
Application.ScreenUpdating = True
End Sub
With the above code My cells are being filled up, but the last row fills till the end of excel sheet. In the Excel sheet column D is already filled in Column B C & E should be auto fill to down. What should be the changes in the code?
Excel VBA Last Row: The Complete Tutorial To Finding The Last Row In Excel With VBA (And Code Examples) recommends using LookIn:=xlFormulas when determining the last with using Cells.Find.
lastrow = Find(What:=” * ”, LookIn:=xlFormulas, SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
Because you stated that column D is already filled in I use:
lastrow = Range("D" & Rows.Count).End(xlUp).Row
If column E isn't filled in then Cells(x, 2).Value must be <> "".
Sub AutoFill()
Dim x As Long
Dim y As Long
Dim lastrow As Long
Dim lastcolumn As Long
Application.ScreenUpdating = False
Application.DisplayAlerts = False
lastcolumn = ActiveSheet.UsedRange.Column - 1 + ActiveSheet.UsedRange.Columns.Count
lastrow = Range("D" & Rows.Count).End(xlUp).Row
For x = 2 To lastrow
If Cells(x, 2).Value = "" Then Cells(x, 2).Value = Cells(x - 1, 2).Value
If Cells(x, 3).Value = "" Then Cells(x, 3).Value = Cells(x - 1, 3).Value
If Cells(x, 5).Value = "" Then Cells(x, 5).Value = Cells(x - 1, 4).Value
Next x
Application.ScreenUpdating = True
End Sub