¿Cómo copyr datos de una fila si hay un cierto valor presente en la columna, usando VBA?

He estado trabajando en una spreadsheet para ayudar con los informes y estoy perplejo sobre el elemento final. Esencialmente, si la columna G de una hoja de trabajo contiene una cierta cadena de text, quiero copyr la fila apropiada a otra spreadsheet debajo de los datos existentes en esa hoja.

Después de dos horas de búsqueda en Google, he probado varias soluciones pero no he podido configurar una para hacer lo que quiero. Actualmente estoy trabajando con lo siguiente:

Dim x As Integer Dim Thisvalue As String Dim NextRow As Range Sheets("Week 4").Select ' Find the last row of data FinalRow = Cells(Rows.Count, 1).End(xlUp).Row ' Loop through each row For x = 2 To FinalRow ' Decide if to copy based on column D Thisvalue = Cells(x, 7).Value If Thisvalue = "Customer placed on hold" Then Cells(x, 1).Resize(1, 33).Copy Sheets("Retained data").Select NextRow = Cells(Rows.Count, 1).End(xlUp).Row + 1 Cells(NextRow, 1).Select ActiveSheet.Paste Sheets("Week 4").Select End If Next x End Sub 

Sin embargo, creo que estoy en el path equivocado y honestamente, he olvidado tanto acerca de VBA que, esencialmente, estoy comenzando de cero nuevamente, según mi conocimiento. ¡Cualquier ayuda sería muy apreciada!

El siguiente código recorrerá todas las celdas de la Columna G (hasta FinalRow ) y verificará el valor "Cliente retenido". Cuando lo encuentra, copy la fila completa en la siguiente fila de disponibilidad en la hoja de trabajo "Datos retenidos".

Nota: es mejor evitar el uso de Select y ActiveSheet ya que pueden cambiar de acuerdo con su ActiveSheet actual. En su lugar, es mejor utilizar objects de hoja referencedos, .Cells y ranges.

Código

 Option Explicit Sub CopyRow() Dim x As Long Dim Thisvalue As String Dim NextRow As Long Dim FinalRow As Long With Sheets("Week 4") ' Find the last row of data in Column A FinalRow = .Cells(.Rows.Count, 1).End(xlUp).Row ' Loop through each row For x = 2 To FinalRow ' Decide if to copy based on column G If .Cells(x, 7).Value = "Customer placed on hold" Then ' Find the last row of data NextRow = Sheets("Retained data").Cells(Sheets("Retained data").Rows.Count, 1).End(xlUp).Row ' copy > paste in 1 line .Cells(x, 7).EntireRow.Copy Sheets("Retained data").Range("A" & NextRow + 1) End If Next x End With End Sub 

Prueba este:

 Sub Makro2() Dim x As Integer Dim Thisvalue As String Sheets("Week 4").Select ' Find the last row of data FinalRow = Cells(Rows.Count, 1).End(xlUp).Row ' Loop through each row For x = 2 To FinalRow ' Decide if to copy based on column D Thisvalue = Cells(x, 7).Value If Thisvalue = "Customer placed on hold" Then Range(Cells(x, 1), Cells(x, 33)).Copy With Sheets("Retained data") .Cells(.Cells(Rows.Count, 1).End(xlUp).Row + 1, 1).PasteSpecial xlPasteAll End With End If Next x End Sub 

dado que desea verificar los valores de la columna "G" contra una cadena ( "Customer placed on hold" ), entonces desea evitar el bucle a través de las celdas de la columna "A" y recorrer solo las celdas de "cadena" de las columnas "G"

a continuación, puede evitar el bucle a través de todas las celdas y simplemente Find() las deseadas:

 Sub CopyRow() Dim firstAddress As String Dim f As Range With Worksheets("Week 4") '<--| reference your relevant worksheet With .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through its column G "string" values only Set f = .Find(what:="Customer placed on hold", lookat:=xlWhole, LookIn:=xlValues, after:=.Areas(.Areas.COUNT).Cells(.Areas(.Areas.COUNT).COUNT)) '<--| search for wanted string in referenced range, starting from the cell after its last cell (ie: the first cell) If Not f Is Nothing Then '<--| if found firstAddress = f.Address '<--| store its address to stop 'Find()' loop at its wrapping back to the first found cell Do With Worksheets("Retained data") '<--| reference target sheet f.EntireRow.Copy .Cells(.Rows.COUNT, 1).End(xlUp).Offset(1) '<--| copy found cell entire row into last referenced worksheet first not empty cell End With Set f = .FindNext(f) '<--| find next cell matching wanted value Loop While f.Address <> firstAddress '<--| exit loop when it wraps back to first found cell End If End With End With End Sub 

si los datos de su columna "G" se extienden más allá del range real de los datos de la columna "A", y usted está interesado en limitar el range a este último, entonces solo tiene que cambiar:

 With .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues) '<--| loop through its column G "string" values only 

a

 With Intersect(.Range("A2", .Cells(.Rows.COUNT, "A").End(xlUp)).EntireRow, .Range("G2", .Cells(.Rows.COUNT, "G").End(xlUp)).SpecialCells(xlCellTypeConstants, xlTextValues)) '<--| loop through its column G "string" values only down to its column "A" last not empty row