Loop and IF statement takes too much time - vba

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

Related

Excel VBA Remove Triple Duplicate in One Row Loop

I want to delete entire row when all 3 numeric values in cells in columns G,H,I are equal. I wrote a vba code and it does not delete nothing. can Someone advise?
Sub remove_dup()
Dim rng As Range
Dim NumRows As Long
Dim i As Long
Set rng = Range("G2", Range("G2").End(xlDown))
NumRows = Range("G2", Range("G2").End(xlDown)).Rows.Count
For i = 2 To NumRows
Cells(i, 7).Select
If Cells(i, 7).Value = Cells(i, 8).Value = Cells(i, 9).Value Then
EntireRow.Delete
Else
Selection.Offset(1, 0).Select
End If
Next i
End Sub
Try this code. When deleting rows, always start from last row and work towards first one. That way you are sure you wont skip any row.
Sub remove_dup()
Dim rng As Range
Dim NumRows As Long
Dim i As Long
NumRows = Range("G2", Range("G2").End(xlDown)).Rows.Count
For i = NumRows + 1 To 2 Step -1
If Cells(i, 7).Value = Cells(i, 8).Value And Cells(i, 7).Value = Cells(i, 9).Value Then
Cells(i, 7).EntireRow.Delete
Else
End If
Next i
End Sub
Remember when you delete rows, all you need to loop in reverse order.
Please give this a try...
Sub remove_dup()
Dim NumRows As Long
Dim i As Long
NumRows = Cells(Rows.Count, "G").End(xlUp).Row
For i = NumRows To 2 Step -1
If Application.CountIf(Range(Cells(i, 7), Cells(i, 9)), Cells(i, 7)) = 3 Then
Rows(i).Delete
End If
Next i
End Sub
You can delete all rows together using UNION. Try this
Sub remove_dup()
Dim ws As Worksheet
Dim lastRow As Long, i As Long
Dim cel As Range, rng As Range
Set ws = ThisWorkbook.Sheets("Sheet4") 'change Sheet3 to your data range
With ws
lastRow = .Cells(.Rows.Count, "G").End(xlUp).Row 'last row with data in Column G
For i = lastRow To 2 Step -1 'loop from bottom to top
If .Range("G" & i).Value = .Range("H" & i).Value And .Range("G" & i).Value = .Range("I" & i).Value Then
If rng Is Nothing Then 'put cell in a range
Set rng = .Range("G" & i)
Else
Set rng = Union(rng, .Range("G" & i))
End If
End If
Next i
End With
rng.EntireRow.Delete 'delete all rows together
End Sub

Conditional copy Excel File-2 data to excel file-1?

I am using Excel 2007. I try to copy Unit-price from the Excel file-2 data to the Excel file-1 when certain columns data matching from file-1 with file-2.
Thanks for the helps & guidance.
My VBA Code:
Sub mySales()
Dim LastRow As Integer, i As Integer, erow As Integer, Pipe_Class As String, Pipe_Description As String, End_Type As String, Pipe_Size As String
Dim wbk As Workbook
strPriceFile = "C:\Temp\File-2.xlsx"
LastRow = ActiveSheet.Range(“A” & Rows.Count).End(xlUp).Row
For i = 2 To LastRow
Pipe_Class = ""
Pipe_Description = ""
End_Type = ""
Pipe_Size = ""
Pipe_Class = ActiveSheet.Cells(i, 1).Value
Pipe_Description = ActiveSheet.Cells(i, 2).Value
End_Type = ActiveSheet.Cells(i, 3).Value
Pipe_Size = ActiveSheet.Cells(i, 4).Value
Set wbk = Workbooks.Open(strPriceFile)
Worksheets("SOR2").Select
If Cells(i, 1) = Pipe_Class And Cells(i, 2) = Pipe_Description And Cells(i, 3) = End_Type And Cells(i, 4) = Pipe_Size Then
Range(Cells(i, 12), Cells(i, 12)).Select
Selection.Copy
??? After Here how select my current file & paste ????????
Worksheets("SOR1").Select
erow = ActiveSheet.Cells(Rows.Count, 1).End(xlUp).Offset(1, 0).Row
ActiveSheet.Cells(erow, 12).Select
ActiveSheet.Paste
ActiveWorkbook.Save
End If
Next i
ActiveWorkbook.Close
Application.CutCopyMode = False
End Sub
I haven't checked all your code, but I have refactored what you have in your question in an attempt to open the Workbook once and to assign proper objects so that you can keep track of what action is being applied to which worksheet.
Sub mySales()
Dim LastRow As Integer, i As Integer, erow As Integer
Dim wbSrc As Workbook
Dim wsSrc As Worksheet
Dim wbDst As Workbook
Dim wsDst As Worksheet
Dim strPriceFile As String
Set wbDst = ActiveWorkbook
Set wsDst = ActiveSheet
strPriceFile = "C:\Temp\File-2.xlsx"
Set wbSrc = Workbooks.Open(strPriceFile)
Set wsSrc = wbSrc.Worksheets("SOR2")
LastRow = wsDst.Range("A" & wsDst.Rows.Count).End(xlUp).Row
erow = LastRow + 1
For i = 2 To LastRow
If wsSrc.Cells(i, 1).Value = wsDst.Cells(i, 1).Value And _
wsSrc.Cells(i, 2).Value = wsDst.Cells(i, 2).Value And _
wsSrc.Cells(i, 3).Value = wsDst.Cells(i, 3).Value And _
wsSrc.Cells(i, 4).Value = wsDst.Cells(i, 4).Value Then
wsSrc.Cells(i, 12).Copy wsDst.Cells(erow, 12)
erow = erow + 1 ' your current code would always copies to the same row,
' but I **think** you probably want to copy to the
' next row each time
End If
Next i
wbSrc.Close
If erow > LastRow + 1 Then
wbDst.Save
End If
wbDst.Close
End Sub
The code is completely untested but, even if it doesn't work, at least it should give you an idea of how you should be processing multiple workbooks and multiple worksheets.

Color non-adjacent cells that match criteria

I use the below code to color the cells in column K and Z that match the criteria; but it colors all cells between K and Z. To fix, I use the last line of code to remove the color in columns L thru Y. Is there a way to modify the line of code that starts with "Range" to only color cells K and Z that match the criteria?
Sub ColrCls()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("K" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
If .Cells(i, 11).Value = "Non Sen" And .Cells(i, 26).Value = "N/A" Then
Range(.Cells(i, 11), .Cells(i, 26)).Interior.ColorIndex = 6
End If
Next i
Columns("L:Y").Interior.ColorIndex = xlNone
End With
End Sub
You are specifying the Range.Parent property in your With ... End With statement but ignoring it when it is most important¹.
Sub ColrCls()
Dim ws As Worksheet
Dim lRow As Long, i As Long
Set ws = ThisWorkbook.Sheets("Sheet1")
With ws
lRow = .Range("K" & .Rows.Count).End(xlUp).Row
For i = 2 To lRow
If .Cells(i, 11).Value = "Non Sen" And .Cells(i, 26).Value = "N/A" Then
.Range("K" & i & ", Z" & i).Interior.ColorIndex = 6
Else
.Range("K" & i & ", Z" & i).Interior.Pattern = xlNone
End If
Next i
End With
End Sub
A Range object to Union discontiguous cells could be one of the following.
.Range("K5, Z5")
Union(.Cells(5, "K"), .Cells(5, "Z"))
In the example above, I've concatenated together a string like the first of these two examples.
¹ See Is the . in .Range necessary when defined by .Cells? for an earnest discussion on this subject.
You could replace
Range(.Cells(i, 11), .Cells(i, 26)).Interior.ColorIndex = 6
with
.Cells(i, 11).Interior.ColorIndex = 6
.Cells(i, 26).Interior.ColorIndex = 6

VBA Dynamic Filtering and Copy Paste into new worksheet

I am trying to write a vba script that will filter on two columns, column A and column D. Preferably, I want to create a button that will execute once I have chosen the filter criteria. Sample of input data below.
Sub Compiler()
Dim i
Dim LastRow As Integer
LastRow = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Sheet4").Range("A2:J6768").ClearContents
For i = 2 To LastRow
If Sheets("Sheet1").Cells(i, "A").Values = Sheets("Sheet3").Cells(3, "B").Values And Sheets("Sheet1").Cells(i, "D").Values = Sheets("Sheet3").Cells(3, "D").Values Then
Sheets("Sheet1").Cells(i, "A" & "D").EntireRow.Copy Destination:=Sheets("Sheet4").Range("A" + Rows.Count).End(xlUp)
End If
Next i
End Sub
Sample Data to run vba script
I have included my previous answer's changes into the full code block that is now provided below.
Sub Compiler()
Dim i
Dim LastRow, Pasterow As Integer
Dim sht As Worksheet
Set sht = ThisWorkbook.Sheets("Sheet4")
LastRow = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
Sheets("Sheet4").Range("A2:J6768").ClearContents
For i = 2 To LastRow
If Sheets("Sheet1").Range("A" & i).Value = Sheets("Sheet3").Range("B3").Value And Sheets("Sheet1").Range("D" & i).Value = Sheets("Sheet3").Range("D3").Value Then
Pasterow = sht.Cells(sht.Rows.Count, "A").End(xlUp).Row + 1
Sheets("Sheet1").Rows(i).EntireRow.Copy Destination:=Sheets("Sheet4").Range("A" & Pasterow)
End If
Next i
Sheets("sheet4").Rows(1).Delete
End Sub
Sheets("Sheet1").Cells(i, "A").Values
Sheets("Sheet3").Cells(3, "B").Values
etc
You keep using values. Don't you mean value?
This answered the question I was asking, I tried to work with Dan's answer but didn't get very far.
Private Sub CommandButton1_Click()
FinalRow = Sheets("Sheet1").Cells(rows.Count, 1).End(xlUp).Row
Sheets("Sheet4").Range(Sheets("Sheet4").Cells(1, "A"), Sheets("Sheet4").Cells(FinalRow, "K")).ClearContents
If Sheets("Sheet4").Cells(1, "A").Value = "" Then
Sheets("Sheet1").Range("A1:K1").Copy
Sheets("Sheet4").Range(Sheets("Sheet4").Cells(1, "A"), Sheets("Sheet4").Cells(1, "K")).PasteSpecial (xlPasteValues)
End If
For x = 2 To FinalRow
ThisValue = Sheets("Sheet1").Cells(x, "A").Value
ThatValue = Sheets("Sheet1").Cells(x, "D").Value
If ThisValue = Sheets("Sheet3").Cells(3, "B").Value And ThatValue = Sheets("Sheet3").Cells(3, "D").Value Then
Sheets("Sheet1").Range(Sheets("Sheet1").Cells(x, 1), Sheets("Sheet1").Cells(x, 11)).Copy
Sheets("Sheet4").Select
NextRow = Sheets("Sheet4").Cells(rows.Count, 1).End(xlUp).Row + 1
With Sheets("Sheet4").Range(Sheets("Sheet4").Cells(NextRow, 1), Sheets("Sheet4").Cells(NextRow, 11))
.PasteSpecial (xlPasteFormats)
.PasteSpecial (xlPasteValues)
End With
End If
Next x
Worksheets("Sheet4").Cells.EntireColumn.AutoFit
End Sub

Compare column A with column C, Move matching Cell from location to column B on corresponding row

Sub Match()
Dim var As Variant, iSheet As Integer, iRow As Long, iRowL As Long, bln As Boolean, rng1 As Range, rng2 As Range, i As Long, j As Long
If Not IsEmpty(rng1) Then
For i = 1 To Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = Sheets("Sheet1").Range("A" & i)
For j = 1 To Sheets("Sheet1").Range("C" & Rows.Count).End(xlUp).Row
Set rng2 = Sheets("Sheet1").Range("C" & j)
bln = False
var = Application.Match(rng1.Value, rng2, 0)
If Not IsError(var) Then
bln = True
Exit For
Exit For
End If
Set rng2 = Nothing
Next j
Set rng1 = Nothing
Next i
For i = 1 To Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
Set rng1 = Sheets("Sheet1").Range("A" & i)
If bln = False Then
Cells(rng1).Font.Bold = False
Else
Cells(rng1).Font.Bold = True
End If
Next i
End If
Application.ScreenUpdating = True
End Sub
Sub CompareAndHighlight()
Dim rng1 As Range, rng2 As Range, i As Long, j As Long
For i = 1 To Sheets("sheet1").Range("C" & Rows.Count).End(xlUp).Row
Set rng1 = Sheets("sheet1").Range("C" & i)
For j = 1 To Sheets("sheet2").Range("C" & Rows.Count).End(xlUp).Row
Set rng2 = Sheets("sheet2").Range("C" & j)
If StrComp(Trim(rng1.Text), Trim(rng2.Text), vbTextCompare) = 0 Then
rng1.Interior.Color = RGB(255, 255, 0)
End If
Set rng2 = Nothing
Next j
Set rng1 = Nothing
Next i
End Sub
I am trying to compare the data column A with the data in column C
However the challenge is , If there is a match I will then need to move the cell from column C to column B on the corresponding row.
Unfortunately I can not post pictures yet, I hope this is clear enough for someone to support me with?
I have improvised to use the "code snippet to display how the data should look assuming they are arranged in Columns A B and C
Before
A12334 A12352
A12335 A12353
A12336 A12339
A12337 A12340
A12338 A12341
A12339 A12354
A12340 A12355
A12341 A12356
A12342 A22354
A12343 A22356
A12344 A22358
A12345 A22360
A12346 A22362
A12347 A22364
A12348 A22366
A12349 A22368
A12350 A22370
A12351 A22372
A12352 A12357
A12353 A12358
A12354 A12334
A12355 A12335
A12356 A12336
A12357 A12337
A12358 A12338
A12359 A22370
A12360 A22372
A12361 A12361
After:
A12334 A12334
A12335 A12335
A12336 A12336
A12337 A12337
A12338 A12338
A12339 A12339
A12340 A12340
A12341 A12341
A12342 A22354
A12343 A22356
A12344 A22358
A12345 A22360
A12346 A22362
A12347 A22364
A12348 A22366
A12349 A22368
A12350 A22370
A12351 A22372
A12352 A12352
A12353 A12353
A12354 A12354
A12355 A12355
A12356 A12356
A12357 A12357
A12358 A12358
A12359 A22370
A12360 A22372
A12361 A12361
Try this to get to your original need: (Not sure what your sheet names are so you might need to edit to reflect correct sheet.)
Sub CompareAndMove()
Dim rng1 As Range, rng2 As Range, i As Long, iL As Long, var As Range, j As Long, ws1 As Worksheet, Chk As Range, LastDest As Long
Set ws1 = Sheets("Sheet1")
iL = ws1.Range("A" & Rows.Count).End(xlUp).Row
For j = 3 To 5
Set rng2 = ws1.Range(ws1.Cells(2, j), ws1.Cells(ws1.Cells(Rows.Count, j).End(xlUp).Row, j))
For i = 2 To iL
Set rng1 = ws1.Range("A" & i)
Set var = rng2.Find(rng1.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not var Is Nothing Then
rng1.Interior.Color = RGB(255, 255, 0)
rng1.Copy
rng1.Offset(0, 1).PasteSpecial
End If
Next i
ws1.Range("B2:B" & ws1.Range("B" & Rows.Count).End(xlUp).Row).Copy
LastDest = Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row + 1
Sheets("Sheet2").Cells(LastDest, 1).PasteSpecial xlPasteValues
LastDest = Sheets("Sheet2").Range("A" & Rows.Count).End(xlUp).Row
Set rng3 = Sheets("Sheet2").Range("A2:A" & LastDest)
For each Chk in rng3
If Len(Chk.Value) = 0 Then
Chk.EntireRow.Delete xlShiftUp
End If
Next Chk
ws1.Range("B:B").Clear
Next j
End Sub
Sub CompareAndMove()
Dim rng1 As Range, rng2 As Range, i As Long, iL As Long, var As Variant
iL = Sheets("Sheet1").Range("A" & Rows.Count).End(xlUp).Row
For i = 2 To iL
Set rng1 = Sheets("Sheet1").Range("A" & i)
Set rng2 = Sheets("Sheet1").Range("C:C")
var = Application.Match(rng1.Value, rng2, 1)
If Not IsError(Application.Match(rng1.Value, rng2, 0)) Then
bln = True
If bln = True Then
rng1.Interior.Color = RGB(255, 255, 0)
rng1.Copy
rng1.Offset(0, 1).PasteSpecial
End If
Set rng1 = Nothing
Set rng2 = Nothing
End If
Next i
End Sub
Sub CompareAndMove()
Dim rng1 As Range, rng2 As Range, i As Long, iL As Long, var As Range, j As Long, ws1 As Worksheet, rng3 As Range, rng4 As Range, lRows As Long, lRows2 As Long, jL
Set ws1 = Sheets("Comparison Sheet")
Set ws2 = Sheets("Comparison Sheet Final")
iL = ws1.Range("A" & Rows.Count).End(xlUp).Row
jL = ws1.Cells(2, Columns.Count).End(xlToLeft).Column
For j = 3 To jL
Set rng2 = ws1.Range(ws1.Cells(2, j), ws1.Cells(ws1.Cells(Rows.Count, j).End(xlUp).Row, j))
For i = 2 To iL
Set rng1 = ws1.Range("A" & i)
Set var = rng2.Find(rng1.Value, LookIn:=xlValues, LookAt:=xlWhole)
If Not var Is Nothing Then
rng1.Interior.Color = RGB(255, 255, 0)
rng1.Offset(0, 1).Font.Name = "Wingdings"
rng1.Offset(0, 1).Value = ChrW(&HFC)
End If
Next i
ws1.Cells(2, 2) = ws1.Cells(2, j)
lRows = ws1.Cells(Rows.Count, "A").End(xlUp).Row
Set rng3 = ws1.Range(ws1.Cells(2, 2), ws1.Cells(lRows, 2))
lRows2 = ws2.Cells(Rows.Count, "A").End(xlUp).Row
lCols = j - 1
Set rng4 = ws2.Range(ws2.Cells(2, lCols), ws2.Cells(lRows, lCols))
rng4.Font.Name = "Wingdings"
rng4.Value = rng3.Value
rng3.ClearContents
ws2.Rows(2).Font.Name = "Calibri"
Next j
End Sub
How it currently looks with your code with slight edits