View Full Version : [SOLVED:] Conditional Search Copy Entire Row to next row on match
equalizer
05-14-2015, 01:39 PM
First time VBA user using Excel 2010 part of Office Pro 2010.
I need to search for data in col 2 and if it matches then copy that row to row below.
Search terms are "A" OR "D"
Before
Num
Reg
Com 1
Com 2
2
A 
yes
no
3
B 
no
no
4
D
yes
yes
5
C
no
no
After
Num
Reg
Com 1
Com 2
2
A
yes
no
2
A
yes
no
3
B
no
no
4
D
yes
yes
4
D
yes
yes
5
C
no
no
Used code from other questions and mashed this up.  
Problem is with this code I need to new macro for each search term
because there is no OR statement allowed in Cell.Find( What ..) ?
Must be better way using some functions that I'm not familiar with.
[CODE][Sub Search_Value_Copy_Row_()
OR_Count = Application.WorksheetFunction.CountIf(Range("A1:Z100"), "A")
Do Until OR_Count = 0
    Cells.Find(What:="A", After:=ActiveCell, LookIn:=xlFormulas, LookAt _
           :=xlPart, SearchOrder:=xlByRows, SearchDirection:=xlNext, MatchCase:= _
           False, SearchFormat:=False).Activate
   
    ActiveCell.EntireRow.Copy
    ActiveCell.EntireRow.Insert
    
    ActiveCell.Offset(1, 0).Select
        
    OR_Count = OR_Count - 1
Loop
End Sub
/CODE]
mperrah
05-15-2015, 08:18 AM
try this
Sub vbax52593()
' ask for letter match then duplicate row and shift down
Dim x, lr
Dim fStrng
lr = Cells(Rows.Count, 1).End(xlUp).Row
fStrng = InputBox("What do you want to search for and copy down?")
    For x = 2 To lr
        If Cells(x, 2).Value = fStrng Then
            'MsgBox "we found a match!", vbOKOnly
            Range("A" & x & ":D" & x).Copy
            Range("A" & x & ":D" & x).Offset(1).Insert shift:=xlDown
            Application.CutCopyMode = False
            x = x + 1
            lr = lr + 1
        Else
            'MsgBox ("No match at " & x)
        End If
    Next x
End Sub
-mark
equalizer
05-15-2015, 08:59 AM
Thank you so much Mark, I will give it a try.  
Can you explain statement  lr= Cells(Rows.Count, 1).End(xlUp).Row ?
Most examples I have seen start counting from bottom so they don't mess up the row count as I have done below.
I like how you came up with adding both counters to counter this problem.
I came up with this last night.  I think I will end up merging the two versions.
Sub COPY_CURRENT_ROW_CASE()
    Application.ScreenUpdating = False
    For MY_ROWS = (ActiveSheet.UsedRange.Rows.Count + 1) To 1 Step -1
        x = Range("C" & MY_ROWS).Value
       
       Select Case x
          Case "A", "D" 
            Rows(MY_ROWS).Copy
            Rows(MY_ROWS + 1).Insert
            
          Case Else
       End Select
     
    Next MY_ROWS
    Application.CutCopyMode = False
    Application.ScreenUpdating = True
End Sub
mperrah
05-15-2015, 09:43 AM
Sure, by the way welcome to the Forum :)
lr = Cells(Rows.Count, 1).End(xlUp).Row 
I use lr as a variable to hold the value for the last row
Cells is in a (row, column) format
Rows,count is a property of the Cells object, so is columns.count 
.end is equivalent to holding Ctrl+Down, it can have an issue if there are blank spaces
I see some people use a cell address to start counting up from like 1048576 which currently the last row of newer versions of excel
older versions had 65536. a good practice to plan for bad data
mperrah
05-15-2015, 09:55 AM
Also it is very important to count from bottom up or right to left if you plan to delete rows
as you count down from 1 to 10 if you delete row 4, 5 becomes 4 and the iteration is thrown off.
I guess from bottom up all the time would be ok, 
but if you have a range that only deals with a few rows with no insert or delete
counting all the extra rows is an unnecessary memory expense
mperrah
05-15-2015, 10:46 AM
altered to only check for A or D, removed input option...
noticed it fails to copy D if you run it several times, curious.
first time is no problem though
Sub vbax52593B()
' duplicate A and D row and shift down
Dim x, lr
lr = Cells(Rows.Count, 1).End(xlUp).Row
    For x = 2 To lr
        If Cells(x, 2).Value = "A" Or _
            Cells(x, 2).Value = "D" Then
            Range("A" & x & ":D" & x).Copy
            Range("A" & x & ":D" & x).Offset(1).Insert shift:=xlDown
            Application.CutCopyMode = False
            x = x + 1
            lr = lr + 1
        Else
            'MsgBox ("No match at " & x)
        End If
    Next x
End Sub
mperrah
05-15-2015, 11:00 AM
fixed it by starting from bottom,
you can run it multiple times successfully, yeah
Sub vbax52593B()
' duplicate A and D row and shift down
Dim x, lr
lr = Cells(Rows.Count, 1).End(xlUp).Row
    For x = lr To 2 Step -1
        If Cells(x, 2).Value = "A" Or _
            Cells(x, 2).Value = "D" Then
            Range("A" & x & ":D" & x).Copy
            Range("A" & x & ":D" & x).Offset(1).Insert shift:=xlDown
            Application.CutCopyMode = False
        Else
            'MsgBox ("No match at " & x)
        End If
    Next x
End Sub
equalizer
05-15-2015, 11:21 AM
Thanks for testing.  I was confused by the Range A & D with my dataset A and D, but I figured out that Range() takes starting ending arguments.
 Just happens to my match my dataset.  Now I know to make sample dataset unique, Tom1, Tom2, etc.
mperrah
05-18-2015, 02:59 PM
Glad to help
Be sure to mark your thread as "solved" using the Thread Tools link if your question has been sufficiently answered.
-mark
mperrah
05-18-2015, 03:03 PM
Tried your offering for rows(x), me like :thumb
Sub vbax52593C()
' duplicate A and D row and shift down
Dim x, lr
lr = Cells(Rows.Count, 1).End(xlUp).Row
    For x = lr To 2 Step -1
        If Cells(x, 2).Value = "A" Or _
            Cells(x, 2).Value = "D" Then
            Rows(x).Copy
            Rows(x).Offset(1).Insert shift:=xlDown
            Application.CutCopyMode = False
        Else
            'MsgBox ("No match at " & x)
        End If
    Next x
End Sub
equalizer
05-18-2015, 03:50 PM
Glad you liked it!   So many different ways to do simple things, its confusing for beginners. 
Can you explain syntax 
Range("A" & x & ":D" & x).
and
shift:=xlDown
Once I get that down, I can close as solved.
mperrah
05-19-2015, 11:36 AM
Sure thing,
Range("A" & x & ":D" & x)
I'm looping up through the rows with variable "x"
and when we find a match I want the 4 columns at the intersecting row to copy
so I need the range in the format 
range("A2:D2")
excel looks at stuff in quotes as literal and stuff out of the quotes as a variable
and to get the variable in there I put the first literal in quotes "A" then the variable out of quotes "x" 
note that these need to be combined with an "&" sign (like concatenating a string)
I always need to be sure to carefully in-quote and out-quote in pairs.
The 
 shift:=down  is telling excel what to do with the displaced cells after it inserts the copied cells,
so it inserts our match then scoots the previous cell data down (instead of over-writing it)
another option is 
shift:=right
hope this illuminates
-mark
mperrah
05-19-2015, 11:41 AM
note: I found your use of 
 rows(x) 
in post #3 accomplished the same task as my concatenated mess,
Range("A" & x & ":D" & x) 
Hence my revised post #10
cheers
-mark
Powered by vBulletin® Version 4.2.5 Copyright © 2025 vBulletin Solutions Inc. All rights reserved.