Reputation: 13
Background
Goal I would only like to paste values from Sheet A into Sheet B only when cells in Sheet A, Column P contain the value "Yes!". Not sure how to incorporate that condition into my current macro:
Current Work
The macro below pastes all values to/from specified sheets/cells regardless of values in Sheet A,Column P. I cannot condition this on respective rows in Sheet A,Column P containing the value "Yes!". Basically Sheet A,Column P describes the data in Sheet A,Columns Q-AA, and therefore only data that meet that criteria needs to be copied and pasted to Sheet B.
Sub copy_sheetA_to_sheetB()
Dim OneRng As Range
Set OneRng = Sheets("Sheet A").Range("Q2:AA" & Cells(Rows.Count, "A").End(xlUp).Row)
OneRng.copy
Sheets("Sheet B").Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial Paste:=xlPasteValues
Application.CutCopyMode = False
End Sub
Upvotes: 1
Views: 222
Reputation: 54948
Sub CopyAtoB()
' Define constants.
Const SRC_SHEET As String = "Sheet A"
Const SRC_FIRST_LOOKUP_CELL As String = "P2"
Const SRC_COPY_COLUMNS As String = "Q:AA"
Const DST_SHEET As String = "Sheet B"
Const DST_FIRST_CELL As String = "A2"
Const CRITERIA_STRING As String = "Yes!" ' case-insensitive
' Reference the workbook.
Dim wb As Workbook: Set wb = ThisWorkbook ' workbook containing this code
' Reference the source range.
Dim sws As Worksheet: Set sws = wb.Sheets(SRC_SHEET)
If sws.FilterMode Then sws.ShowAllData
Dim slrg As Range, srCount As Long
With sws.Range(SRC_FIRST_LOOKUP_CELL)
Dim slCell As Range: Set slCell = .Resize(sws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If Not slCell Is Nothing Then
srCount = slCell.Row - .Row + 1
Set slrg = .Resize(srCount)
End If
End With
If srCount = 0 Then
MsgBox "No data found.", vbExclamation
Exit Sub
End If
Dim scrg As Range: Set scrg = slrg.EntireRow.Columns(SRC_COPY_COLUMNS)
Dim cCount As Long: cCount = scrg.Columns.Count
' Write the values from the source range to the Data array.
Dim Data(): Data = scrg.Value
' Return the matches in a 2D one-based single-column array
' of the same size as the size of the source lookup range.
' Matches will return 1 while non-matches will return an error value.
Dim srMatches():
srMatches = Application.Match(slrg, Array(CRITERIA_STRING), 0)
If Application.Count(srMatches) = 0 Then
MsgBox "No criteria matches found.", vbCritical
Exit Sub
End If
' Write the matching rows to the top of the Data array.
Dim sr As Long, c As Long, dr As Long
For sr = 1 To srCount
If IsNumeric(srMatches(sr, 1)) Then
dr = dr + 1
For c = 1 To cCount
Data(dr, c) = Data(sr, c)
Next c
End If
Next sr
' Reference the destination range.
Dim dws As Worksheet: Set dws = wb.Sheets(DST_SHEET)
If dws.FilterMode Then dws.ShowAllData
Dim dfCell As Range
With dws.Range(DST_FIRST_CELL)
Set dfCell = .Resize(dws.Rows.Count - .Row + 1) _
.Find("*", , xlFormulas, , , xlPrevious)
If dfCell Is Nothing Then
Set dfCell = .Cells
Else
Set dfCell = dfCell.Offset(1)
End If
End With
Dim drg As Range: Set drg = dfCell.Resize(dr, cCount)
' Write the values from the top of the Data array to the destination range.
drg.Value = Data
' Inform.
MsgBox "Values copied.", vbInformation
End Sub
Upvotes: 0
Reputation: 46
I advise adding a for-loop and a condition:
Please validate and let me know if this solution is applicable. Below is an updated code snippet:
Sub copy_sheetA_to_sheetB()
Dim OneRng As Range
Set OneRng = Sheets("Sheet A").Range("P2:AA" & Cells(Rows.Count, "A").End(xlUp).Row) 'include column P as a flag
For c = 1 To OneRng.Rows.Count
If OneRng.Cells(c,1).Value = "Yes!" Then
OneRng.Offset(0,1).Resize(OneRng.Rows.Count, OneRng.Columns.Count-1).copy
Sheets("Sheet B").Range("A" & Rows.Count).End(xlUp)(2).PasteSpecial Paste:=xlPasteValues
End If
Application.CutCopyMode = False
End Sub
Upvotes: 1