Copy-paste specific columns from rows if an If condition is satisfied - excel

I am trying to build a macro to copy paste specific columns from rows, when an If condition is satisfied. The part of the If condition is tested and working, as I have used it in another macro. The problem in my case is that I dont know how to select specific columns of a row inside a loop. I only know how to select the entire row (in this case it would have been rows(i).EntireRow.Copy if I am not mistaken). I am providing my code below. The part that needs editing is the
.Rows(i).Columns(1, 4, 6, 8).Copy
Sheets("WFRandVFR_REPORT").range("W2").Paste
The entire code is this one
(UPDATED VERSION)
I am providing the screenshots too
Dim lr As Long
Dim rng As range
Dim mDiff1 As Double
mDiff1 = 0.01
With Worksheets("WFRandVFR_REPORT")
lr = range("L" & Rows.Count).End(xlUp).Row
For i = 2 To lr
If Cells(i, "U").Value - Cells(i, "V").Value > mDiff1 Then
If rng Is Nothing Then
Set rng = .range("L" & i & ":V" & i)
Else
Set rng = Union(rng, .range("L" & i & ":V" & i))
End If
End If
Next i
rng.Copy
Sheets("WFRandVFR_REPORT").range("AI2").PasteSpecial
End With

To copy you may use
Range("A" & i & ", D" & i & ", F" & i & ", H" & i & "").Copy '(as mentioned in comment)
or
Union(.Range("A" & i), .Range("D" & i), .Range("F" & i), .Range("H" & i)).Copy
Thus, try
Union(.Range("A" & i), .Range("D" & i), .Range("F" & i), .Range("H" & i)).Copy
Sheets("WFRandVFR_REPORT").range("W2").PasteSpecial xlPasteValues
or just
Union(.Range("A" & i), .Range("D" & i), .Range("F" & i), .Range("H" & i)).Copy
Sheets("WFRandVFR_REPORT").range("W2").PasteSpecial
or
Union(.Range("A" & i), .Range("D" & i), .Range("F" & i), .Range("H" & i)).Copy Sheets("WFRandVFR_REPORT").range("W2")
EDIT :
Is there any specific reason why you are looping from bottom to up, if not change FOR loop as
For i = 2 To lastrow
Your code will be
Dim mDiff As Integer
Dim rng As Range
mDiff = 0.03
With Worksheets("WFRandVFR_REPORT")
lastrow = Range("L" & Rows.Count).End(xlUp).Row
For i = 2 To lastrow
If Cells(i, "U").Value - Cells(i, "V").Value > mDiff Then
If rng Is Nothing Then
Set rng = .Range("L" & i & ":V" & i)
Else
Set rng = Union(rng, .Range("L" & i & ":V" & i))
End If
End If
Next i
rng.Copy
Sheets("WFRandVFR_REPORT").Range("AI2").PasteSpecial
End With

Related

How to convert several non-adjacent columns to lowercase

This is looping through a worksheet that is about 10k rows and it is taking a considerable amount of time. Is there a way to do this faster aside from an array? thank you
For i = 2 To spberowcnt
With spbe30
.Range("b" & i).Value = LCase(.Range("b" & i).Value)
.Range("d" & i).Value = LCase(.Range("d" & i).Value)
.Range("i" & i).Value = LCase(.Range("i" & i).Value)
.Range("j" & i).Value = LCase(.Range("j" & i).Value)
.Range("l" & i).Value = LCase(.Range("l" & i).Value)
.Range("m" & i).Value = LCase(.Range("m" & i).Value)
.Range("n" & i).Value = LCase(.Range("n" & i).Value)
.Range("p" & i).Value = LCase(.Range("p" & i).Value)
.Range("q" & i).Value = LCase(.Range("q" & i).Value)
.Range("r" & i).Value = LCase(.Range("r" & i).Value)
.Range("z" & i).Value = LCase(.Range("z" & i).Value)
.Range("aa" & i).Value = LCase(.Range("aa" & i).Value)
End With
Next i
For i = 2 To spberowcnt
With spbe60
.Range("b" & i).Value = LCase(.Range("b" & i).Value)
.Range("d" & i).Value = LCase(.Range("d" & i).Value)
.Range("i" & i).Value = LCase(.Range("i" & i).Value)
.Range("j" & i).Value = LCase(.Range("j" & i).Value)
.Range("l" & i).Value = LCase(.Range("l" & i).Value)
.Range("m" & i).Value = LCase(.Range("m" & i).Value)
.Range("n" & i).Value = LCase(.Range("n" & i).Value)
.Range("p" & i).Value = LCase(.Range("p" & i).Value)
.Range("q" & i).Value = LCase(.Range("q" & i).Value)
.Range("r" & i).Value = LCase(.Range("r" & i).Value)
.Range("z" & i).Value = LCase(.Range("z" & i).Value)
.Range("aa" & i).Value = LCase(.Range("aa" & i).Value)
End With
Next i
This is the array solution
Sub test()
Application.ScreenUpdating = False
Dim arrWorksheets(1) As Variant, ws As Worksheet
Set arrWorksheets(0) = spbe30
Set arrWorksheets(1) = spbe60
Dim arrColumns As Variant
arrColumns = Array("B", "D", "AA") 'adjust to your needs
Dim arrValues As Variant
Dim iWs As Long, iC As Long, i As Long
For iWs = 0 To UBound(arrWorksheets)
Set ws = arrWorksheets(iWs)
For iC = 0 To UBound(arrColumns)
arrValues = ws.Range(arrColumns(iC) & "2").Resize(spberowcnt).Value
For i = 1 To UBound(arrValues, 1)
arrValues(i, 1) = LCase(arrValues(i, 1))
Next
ws.Range(arrColumns(iC) & "2").Resize(spberowcnt).Value = arrValues
Next
Next
Application.ScreenUpdating = True
End Sub
Alternative: helper columns ...
You could try something like the following, looping over the columns instead of the individual cells and using Evaluate and Lower on the entire column. You could also process adjacent columns together.
cols = Array("B", "D", "I:J", "L:N", "P:R", "Z:AA")
For i = LBound(cols) to Ubound(cols)
Dim col As String
col = cols(i)
With spbe30
Dim rng As Range
Set rng = .Rows("2:" & spberowcnt).Columns(col)
rng.Value = .Evaluate("LOWER(" & rng.Address & ")")
End With
Next
But as mentioned in comments, an array is probably the way to go.

is my nested for is not working? value won't be copied (VBA, Looping, Using a nested for to copy data)

hi can you help me solve my problem? my problem is I want to copy some data from another worksheet with some condition, i'm using the nested for to do the looping if the condition is met.
but the problem is the value that I want to copy is not copied to the destination cell, its blank.
but the rest of the code is working and the data is successfully copied.
do you know how to solve this? did i miss some syntax ? thank you so much!
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "B").End(xlUp).Row
'b value is more than 30.000 data
b = wsDestI.Cells(wsDestI.Rows.Count, "G").End(xlUp).Row
For i = 1 To lCopyLastRow
If IsEmpty(wsCopy.Range("E" & 9 + i).Value) = True Then
'this nested for is not working, it wont copy the data
For s = 4 To b
If (wsCopy.Range("B" & 9 + i).Value = wsDestI.Range("G" & s).Value) Then
wsDestI.Range("C" & s).copy wsDest.Range("M" & Rows.Count).End(xlUp).Offset(1, 0)
wsDestI.Range("G" & s).copy wsDest.Range("S" & Rows.Count).End(xlUp).Offset(1, 0)
wsDestI.Range("M" & s).copy wsDest.Range("P" & Rows.Count).End(xlUp).Offset(1, 0)
End If
Next s
ElseIf IsEmpty(wsCopy.Range("B" & 9 + i).Value) = True Then
wsCopy.Range("E" & i + 9).copy wsDest.Range("M" & Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("K" & 9 + i).copy wsDest.Range("P" & Rows.Count).End(xlUp).Offset(1, 0)
wsDest.Range("S" & Rows.Count).End(xlUp).Offset(1, 0) = "0"
Else:
wsCopy.Activate
wsDest.Activate
wsCopy.Range("E" & 9 + i).copy wsDest.Range("M" & Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("B" & 9 + i).copy wsDest.Range("S" & Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("K" & 9 + i).copy wsDest.Range("P" & Rows.Count).End(xlUp).Offset(1, 0)
End If
Next i
Give this a try - I've cleaned up some of your syntax and I fully qualified all of the Rows.Counts. I also did some additional things like removed those Activate lines (unnecessary), changed your i loop to start at 10 (since you just add 9 to it everywhere anyways), and added all the declarations/sets that you weren't displaying in your post.
Option Explicit
Sub Test()
Dim lCopyLastRow As Long, b As Long, i As Long, s As Long
Dim wsCopy As Worksheet, wsDestI As Worksheet, wsDest As Worksheet
Set wsCopy = ThisWorkbook.Worksheets("wsCopy")
Set wsDestI = ThisWorkbook.Worksheets("wsDestI")
Set wsDest = ThisWorkbook.Worksheets("wsDest")
lCopyLastRow = wsCopy.Cells(wsCopy.Rows.Count, "B").End(xlUp).Row
b = wsDestI.Cells(wsDestI.Rows.Count, "G").End(xlUp).Row
For i = 10 To lCopyLastRow
If IsEmpty(wsCopy.Range("E" & i).Value) = True Then
For s = 4 To b
If (wsCopy.Range("B" & i).Value = wsDestI.Range("G" & s).Value) Then
wsDestI.Range("C" & s).Copy wsDest.Range("M" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsDestI.Range("G" & s).Copy wsDest.Range("S" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsDestI.Range("M" & s).Copy wsDest.Range("P" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
End If
Next s
ElseIf IsEmpty(wsCopy.Range("B" & i).Value) = True Then
wsCopy.Range("E" & 9 + i).Copy wsDest.Range("M" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("K" & 9 + i).Copy wsDest.Range("P" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsDest.Range("S" & wsDest.Rows.Count).End(xlUp).Offset(1, 0) = 0
Else
wsCopy.Range("E" & i).Copy wsDest.Range("M" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("B" & i).Copy wsDest.Range("S" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
wsCopy.Range("K" & i).Copy wsDest.Range("P" & wsDest.Rows.Count).End(xlUp).Offset(1, 0)
End If
Next i
End Sub

How to read all the data cells and only highlight the cells which have a more than 10 characters

I need to read all the data cell which have the entries but I only need to highlight the cells which have a character more than 10 in that data cell.
For example:
In the A column I need to read all the data but my condition is that I need to highlight the cell which contains more than 10 char.
Likewise In the B column I need to do the same thing but here I need to highlight the cell which contains more than 12 char.
Likewise I want to implement one solution for all the columns which contains the data.
Please help me to resolve it.
The code I tried:
Sub Dendrinos2()
Dim i As Long
Dim lr As Long
lr = Cells(Rows.Count, 5).End(xlUp).Row
For i = lr To 2 Step -1
If Range("C" & i).Value > 6 Then Range("C" & i).Interior.ColorIndex = 3
If Range("G" & i).Value > 3 Then Range("G" & i).Interior.ColorIndex = 3
If Range("I" & i).Value > 3 Then Range("I" & i).Interior.ColorIndex = 3
If Range("C" & i).Value < -3 Then Range("C" & i).Interior.ColorIndex = 3
If Range("G" & i).Value < -3 Then Range("G" & i).Interior.ColorIndex = 3
If Range("I" & i).Value < -3 Then Range("I" & i).Interior.ColorIndex = 3
If Range("E" & i).Value = "--" Then Range("E" & i).Interior.ColorIndex = Range("A" & i).Interior.ColorIndex
If Range("G" & i).Value = "--" Then Range("G" & i).Interior.ColorIndex = Range("A" & i).Interior.ColorIndex
If Range("I" & i).Value = "--" Then Range("I" & i).Interior.ColorIndex = Range("A" & i).Interior.ColorIndex
Next i
End Sub
Use conditional formatting with a simple formula that covers columns A and B.
Sub highlightLength()
With Worksheets("sheet3")
With .Range("A:B")
.FormatConditions.Delete
.FormatConditions.Add Type:=xlExpression, Formula1:="=len(a1)>(column(a1)+4)*2"
With .FormatConditions(.FormatConditions.Count)
.Interior.Color = vbYellow
End With
End With
End With
End Sub
I would do something like this:
Sub Dendrinos2()
Dim i As Long
Dim lr As Long
Dim sht As Worksheet
Set sht = ActiveSheet
lr = sht.Cells(sht.Rows.Count, 5).End(xlUp).Row
For i = lr To 2 Step -1
Checklength sht.Range("A" & i), 10
Checklength sht.Range("B" & i), 12
CheckLimits sht.Range("C" & i), -3, 6
CheckLimits sht.Range("G" & i), -3, 3
CheckLimits sht.Range("I" & i), -3, 3
CheckDashes sht.Range("E" & i), sht.Range("A" & i)
CheckDashes sht.Range("G" & i), sht.Range("A" & i)
CheckDashes sht.Range("I" & i), sht.Range("A" & i)
Next i
End Sub
Sub CheckLimits(c As Range, ll, ul)
With c
If .Value < ll Or .Value > ul Then .Interior.ColorIndex = 3
End With
End Sub
Sub CheckDashes(c As Range, cA As Range)
With c
If .Value = "--" Then
.Interior.ColorIndex = cA.Interior.ColorIndex
End If
End With
End Sub
Sub Checklength(c As Range, l As Long)
With c
If Len(.Value) > l Then .Interior.ColorIndex = 3
End With
End Sub

VBA excel - range.formula issue

There is a particular part of my code which I cannot make work,
I'm trying to do the following command on VBA =RIGHT(LEFT(X1;Z1-2);LEN(LEFT(X1;Z1-2))-FIND(":";X1))
On cell X1, there is a text: RESULTS:NG & MODEL:IJ
My VBA code is:
LR = Cells(Rows.Count, "A").End(xlUp).Row
For i = 1 To LR
cel = "A" & i
cel2 = "Y" & i
cel3 = "Z" & i
cel4 = "X" & i
Range("M" & i).Formula = "=RIGHT(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "),LEN(LEFT(" & cel4 & "," & cel3 & "-" & 2 & "))-FIND(:" & cel4 & "))"
Next i
I'm open for a better approach for this issue as well
Thanks in advance
Try writing all the formulas at once and reduce using quotes within the formula as much as possible.
Range(Cells(1, "M"), cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
All range and cells reference within a sub procedure are better with a properly defined parent worksheet reference.
dim lr as long
with worksheets("sheet1")
LR = .Cells(.Rows.Count, "A").End(xlUp).Row
.Range(.Cells(1, "M"), .cells(lr, "M")).Formula = _
"=RIGHT(LEFT(X1, Z1-2), LEN(LEFT(X1, Z1-2))-FIND(char(58), X1))"
end with

ClearContents and Shift Data Below up without deleting rows/cells

I automating a spreadsheet cleaning tools that removes data from the spreadsheet if certain values are in a particular column. Originally, it deleted entire rows of data if the specific value is found. However, this is causing numerous reference errors by deleting the rows. Sample of the original code below.
Set rData = .Range("L5:L" & last & ",AX5:AX" & last)
For i = rData.Row To rData.Row + rData.Rows.Count - 1
If .Range("AX" & i) = "DONE" Or .Range("AX" & i) = "CANCEL" Then
.Range("A" & i, "AX" & i).Copy
bottom = activewkb.Worksheets("OrderStatus").Range("I" & Rows.Count).End(xlUp).Row + 1
activewkb.Worksheets("OrderStatus").Range("A" & bottom).PasteSpecial Paste:=xlPasteValues
If i > 0 Then
.Range("D" & i & ":CA" & i).ClearContents
End If
End If
Next i
The easiest way to get rid of the reference errors is to clear the contents from column D through DD if the requirements are satisfied then shift all of the data below it up for column D to DD up one row. The new code is below. I am getting an error on the .Range("D" & i).Offset(1,0).Value line.
Set rData = .Range("L5:L" & last & ",AX5:AX" & last)
For i = rData.Row To rData.Row + rData.Rows.Count - 1
If .Range("AX" & i) = "DONE" Or .Range("AX" & i) = "CANCEL" Then
.Range("A" & i, "AX" & i).Copy
bottom = activewkb.Worksheets("OrderStatus").Range("I" & Rows.Count).End(xlUp).Row + 1
activewkb.Worksheets("OrderStatus").Range("A" & bottom).PasteSpecial Paste:=xlPasteValues
If i > 0 Then
.Range("D" & i & ":CA" & i).ClearContents
.Range("D" & i).Offset(1, 0).Value
.Offset(1, 0).Select
End If
End If
Next i
Any suggestions are appreciated! Thanks in advance.

Resources