Editing code to copy the whole row - vba

I found some code that does most of what I need it to do but I need to copy the whole row where it finds the occurrence of the variable, not just the cell in which it finds the occurrence. Any thoughts on how to edit it to copy the cell in which it found the variable to the last cell in the row containing data?
Sub Copy_To_Another_Sheet_1()
Dim FirstAddress As String
Dim MyArr As Variant
Dim Rng As Range
Dim Rcount As Long
Dim I As Long
Dim NewSh As Worksheet
Dim Initiatives As Worksheet
Set Initiatives = ThisWorkbook.Worksheets("Initiatives")
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
MyArr = Array("Components")
Set NewSh = Worksheets.Add
With Initiatives.Range("B3:B500")
Rcount = 0
For I = LBound(MyArr) To UBound(MyArr)
Set Rng = .Find(What:=MyArr(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rcount = Rcount + 1
Rng.Copy NewSh.Range("A" & Rcount)
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub

Change this line:
Rng.Copy NewSh.Range("A" & Rcount)
Into this:
Rng.EntireRow.Copy NewSh.Rows(Rcount)
This will copy the whole row of Rng into the whole row of index Rcount, as opposed to just doing a single cell of each.

Related

VBA - Search value in a column and reorder them in a new column

in a column I have multiple values (Vat numbers) but not in consecutive rows, for example in A1, A5, A8,...
I need to copy each value from column A and paste them in a new column but reordered in consecutive rows, for example B1,B2,B3,...
The following macro does this job but only if in the value it is included the symbol "#" because it uses the function "Array" (if I replace # with numbers as 1,2,3,4,5,6,7,8,9, I get the same VAT number multiple times and I do not require it).
Sub Copy_To_Another_Sheet_1()
Dim FirstAddress As String
Dim MyArr As Variant
Dim Rng As Range
Dim Rcount As Long
Dim I As Long
Dim NewSh As Worksheet
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
MyArr = Array("#")
Set NewSh = Sheets("Sheet2")
With Sheets("Sheet2").Range("A1:A100")
Rcount = 0
For I = LBound(MyArr) To UBound(MyArr)
'If you use LookIn:=xlValues it will also work with a
'formula cell that evaluates to "#"
'Note : I use xlPart in this example and not xlWhole 'MyArr(I)
Set Rng = .Find(What:=MyArr(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rcount = Rcount + 1
NewSh.Range("A" & Rcount).Value = Rng.Value
' Use this if you only want to copy the value
' NewSh.Range("A" & Rcount).Value = Rng.Value
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
Thanks
Marco

Inserting Range into Array in VBA for iteration

I am facing some issues with VBA. Let me explain what I am trying to achieve. I have 2 sheets in 1 workbook. They are labelled "Sheet1" and "Sheet2."
In "Sheet1," there are 100 rows and 100 columns. In column A, it is filled with eg: SUBJ001 all the way to SUBJ100. In "Sheet2," there is only 1 Column A, with a range of rows. Eg: "SUBJ003, SUBJ033, SUBJ45." What I am trying to achieve is to use my mouse, highlight the column A in "Sheet2," and compare each individual cell with the cells in column A. Should there be a match, it will copy the entire row and paste them in a new sheet that the macro creates in the same workbook. However, i am experiencing an out of range error at Set Rng =.Find(What:=Arr(I), ... Thanks!
Sub Copy_To_Another_Sheet_1()
Dim FirstAddress As String
Dim MyArr As Variant
Dim Rng As Range
Dim Rcount As Long
Dim I As Long
Dim NewSh As Worksheet
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
Set Rng = Application.InputBox("Select target range with the mouse", Type:=8)
MyArr = Rng
Set NewSh = Worksheets.Add
With Sheets("Sheet1").Range("A:A")
Rcount = 0
For I = LBound(MyArr) To UBound(MyArr)
Set Rng = .Find(What:=MyArr(I), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
FirstAddress = Rng.Address
Do
Rcount = Rcount + 1
Rng.EntireRow.Copy NewSh.Range("A" & Rcount)
' Use this if you only want to copy the value
' NewSh.Range("A" & Rcount).Value = Rng.Value
Set Rng = .FindNext(Rng)
Loop While Not Rng Is Nothing And Rng.Address <> FirstAddress
End If
Next I
End With
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
MyArr = Rng is setting MyArr to be a two-dimensional array where the first rank corresponds to the rows in Rng and the second rank corresponds to the columns in Rng.
Assuming you only have one column in Rng, then your Find statement should refer to the values in that first column using MyArr(I, 1), i.e.
Set Rng = .Find(What:=MyArr(I, 1), _
After:=.Cells(.Cells.Count), _
LookIn:=xlFormulas, _
LookAt:=xlPart, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)

Modify macro for column search

I have a macro that until now was used just to search one cell from column F but now I must search for all the cell in column F. If value from F is found in range N:AN, offset(f,0,1) must have the cell value (found row , column AI).
Sub find()
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Sheet1").Range("f48").Value
If Trim(FindString) <> "" Then
With Sheets("Sheet1").Range("n:an")
Set Rng = .find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
Sheets("Sheet1").Range("f48").Offset(0, 1).Value = Rng.Offset(0, 21).Value
Else
Sheets("Sheet1").Range("f48").Offset(0, 1).Value = "Nothing found"
End If
End With
End If
End Sub
Perhaps this, if I understand correctly (it does assume the value in F will only be found once at most).
Sub find()
Dim Rng As Range
Dim r As Range
With Sheets("Sheet1")
For Each r In .Range("F1", .Range("F" & .Rows.Count).End(xlUp))
If Trim(r) <> vbNullString Then
With .Range("n:an")
Set Rng = .find(What:=r.Value, _
LookAt:=xlWhole, _
MatchCase:=False)
If Not Rng Is Nothing Then
r.Offset(0, 1).Value = .Cells(Rng.Row, "AI").Value
'Else
' Sheets("Sheet1").Range("f48").Offset(0, 1).Value = "Nothing found"
End If
End With
End If
Next r
End With
End Sub
See if this is helpful. Its a bit of a change but I think it may be cleaner :)
Of course you need to adjust it for your offset criteria once you "find" a match in the N:NA range
Sub Dougsloop()
Dim rCell As Range
Dim rRng As Range
Dim wsO As Worksheet
Dim aRR As Variant
Set wsO = ThisWorkbook.Sheets("Sheet1")
aRR = wsO.UsedRange.Columns("N:NA")
Set rRng = ThisWorkbook.Sheets("Sheet1").Range("F1:F500")
For Each rCell In rRng.Cells
If Trim(rCell.Value) <> vbNullString Then
thisValue = rCell.Value
If IsError(Application.Match(aRR, thisValue, 0)) = True Then
'Generic Eror Handling
ElseIf IsError(Application.Match(aRR, thisValue, 0)) = False Then
'Stuff you do when you find the match
rCell.Offset(0, 1).Value = "found it"
End If
End If
Next rCell
End Sub

Delete rows with based on cell value

I'm trying to search Column A in Sheet2 for the value of A1 in Sheet1.
If it exists, I'd like to delete the whole row in Sheet2.
If it doesn't exist, I'd like the message box to open.
Here's what I have, but I'm struggling with actually deleting the row:
Sub Delete_Rows()
Dim FindString As String
Dim Rng As Range
FindString = Sheets("Sheet1").Range("A1")
If Trim(FindString) <> "" Then
With Sheets("Sheet2").Range("A:A")
Set Rng = .Find(What:=FindString, _
After:=.Cells(.Cells.Count), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False)
If Not Rng Is Nothing Then
'I can't figure out how to delete the row
Else
MsgBox "Not Found"
End If
End With
End If
End Sub
Here is an example based on THIS
You don't need to loop. You can use .Autofilter which is faster than looping.
Sub Sample()
Dim ws1 As Worksheet, ws2 As Worksheet
Dim delRange As Range
Dim lRow As Long
Dim strSearch As String
Set ws1 = Sheet1: Set ws2 = Sheet2
strSearch = ws1.Range("A1").Value
With ws2
'~~> Remove any filters
.AutoFilterMode = False
lRow = .Range("A" & .Rows.Count).End(xlUp).Row
With .Range("A1:A" & lRow)
.AutoFilter Field:=1, Criteria1:="=" & strSearch
Set delRange = .Offset(1, 0).SpecialCells(xlCellTypeVisible).EntireRow
End With
'~~> Remove any filters
.AutoFilterMode = False
End With
If delRange Is Nothing Then
MsgBox "Not Found"
Else
delRange.Delete
End If
End Sub
Here is the code to :
loop through all the values in Column A of Sheet1,
look for all matches (with FindNext method) in Column A of Sheet 2
and delete the rows that matches
Give it a try :
Sub test_user5472539()
Dim Ws1 As Worksheet, _
Ws2 As Worksheet, _
LastRow As Long, _
FindString As String, _
FirstAddress As String, _
cF As Range
Set Ws1 = ActiveWorkbook.Sheets("Sheet1")
Set Ws2 = ActiveWorkbook.Sheets("Sheet2")
LastRow = Ws1.Range("A" & Ws1.Rows.Count).End(xlUp).Row
For i = 1 To LastRow
FindString = Ws1.Range("A" & i)
If Trim(FindString) <> "" Then
Ws2.Range("A1").Activate
With Ws2.Range("A:A")
'First, define properly the Find method
Set cF = .Find(What:=FindString, _
After:=.Cells(1, 1), _
LookIn:=xlValues, _
LookAt:=xlWhole, _
SearchOrder:=xlByRows, _
SearchDirection:=xlNext, _
MatchCase:=False, _
SearchFormat:=False)
'If there is a result, keep looking with FindNext method
If Not cF Is Nothing Then
FirstAddress = cF.Address
Do
cF.EntireRow.Delete
Set cF = .FindNext(cF)
'Look until you find again the first result
Loop While Not cF Is Nothing And cF.Address <> FirstAddress
Else
MsgBox "Not Found"
End If
End With
Else
End If
Next i
End Sub

Macro to copy rows where cells interior color is orange, then paste data to new worksheet

I have for the most part it working. I can't seem to get through the CopyRng block to set it for each sheet and gather the entire row where the cells are color filled. Set CopyRng = sh.Cells().Interior.Color = vbOrange sh.Cells().EntireRowCan anyone help?
Module1:
Function LastRow(sh As Worksheet)
On Error Resume Next
LastRow = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByRows, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Row
On Error GoTo 0
End Function
Function LastCol(sh As Worksheet)
On Error Resume Next
LastCol = sh.Cells.Find(What:="*", _
After:=sh.Range("A1"), _
Lookat:=xlPart, _
LookIn:=xlFormulas, _
SearchOrder:=xlByColumns, _
SearchDirection:=xlPrevious, _
MatchCase:=False).Column
On Error GoTo 0
End Function
Module2:
Option Explicit
Sub CopyRangeFromMultiWorksheets()
Dim sh As Worksheet
Dim DestSh As Worksheet
Dim Last As Long
Dim CopyRng As Range
Dim tbl As ListObject
Dim Cell As Range
Dim clrOrange As Long
With Application
.ScreenUpdating = False
.EnableEvents = False
End With
' Delete the summary sheet if it exists.
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.Worksheets("SummarySheet").Delete
On Error GoTo 0
Application.DisplayAlerts = True
' Add a new summary worksheet.
Set DestSh = ThisWorkbook.Worksheets.Add
DestSh.Name = "SummarySheet"
Range("A1").FormulaR1C1 = "=TODAY()"
Range("A3:G3").Font.Bold = True
Range("A3") = "Vendor"
Range("B3") = "Account#"
Range("C3") = "Job/Dept"
Range("D3") = "Cost Code/Account"
Range("E3") = "PO"
Range("F3") = "Bill Date"
Range("G3") = "Bill Date2"
clrOrange = RGB(255, 192, 0)
' Loop through all worksheets and copy the data to the
' summary worksheet.
For Each sh In ThisWorkbook.Worksheets
For Each tbl In sh.ListObjects
For Each Cell In tbl.DataBodyRange
If sh.Name <> DestSh.Name Then
' Find the last row with data on the summary worksheet.
Last = LastRow(DestSh)
' Specify the range to place the data. Select entire row where cells are orange.
If Cell.Interior.Color = clrOrange Then
If CopyRng Is Nothing Then
Set CopyRng = Cell
Else
Set CopyRng = Union(CopyRng, Cell)
End If
End If
' This statement copies values and formats from each
' worksheet.
Cell.EntireRow.Copy
With DestSh.Cells(Last + 1, "A")
.PasteSpecial xlPasteValues
Application.CutCopyMode = False
End With
End If
Next
Next
Next
ExitTheSub:
Application.GoTo DestSh.Cells(1)
' AutoFit the column width in the summary sheet.
DestSh.Columns.AutoFit
With Application
.ScreenUpdating = True
.EnableEvents = True
End With
End Sub
You need to loop through the cells and check each to see if they are orange, then add them to CopyRng one by one:
Dim Cell as Range
For Each Cell in sh.Range("A1:A50") 'Or whatever the range is where orange cells can be
If Cell.Interior.Color = vbOrange Then
If CopyRng is Nothing then
Set CopyRng = Cell
Else
Set CopyRng = Union(CopyRng, Cell)
End If
EndIf
Next
CopyRng.Copy
etc.