1

I have a list of issues in column B and their associated status in column C. I want to copy only the issues that have a status of "Ready for Testing", "Build in Prod", "In Progress" or "Awaiting CAB Approval" to column D and do not want blank cells in between.

I have slightly modified the code found in this topic but cannot get it working for the four different status types (I tried adding in ElseIf statements but that did not seem to work):

Copy all cells with certain value into another column skipping blanks

Sub RangeCopyPaste()
Dim cell As Range
Dim NewRange As Range
Dim MyCount As Long
MyCount = 1

'--> Loop through each cell in column C
'--> Add each cell in column B with value "Ready for Testing" in column B to 
NewRange
For Each cell In Worksheets("OverviewTest").Range("C6:C56")
    If cell.Value = "Ready for Testing" Then
        If MyCount = 1 Then Set NewRange = cell.Offset(0, -1)
        Set NewRange = Application.Union(NewRange, cell.Offset(0, -1))
        MyCount = MyCount + 1
    End If
Next cell

'--> Copy NewRange from inactive sheet into active sheet
NewRange.Copy Destination:=ActiveSheet.Range("D6")


End Sub

Thanks in advance for any assistance with this, I am very new to Excel VBA.

Update 02/06/2017

I have created a simplified version of my file for a demonstration of what I am trying to achieve. My original file has many tabs, with many more columns and hundreds of rows per tab. (Apologies, it will not allow me to add multiple images so I have had to upload one big image)

Sheet2 - Contains the all detail about the jobs

Sheet1 - I am looking for this to be the Overview tab only displaying active jobs. Column A contains hyperlinks to the changes in Sheet 2. Column F has conditional formatting that is removed if cells are copied so I have used a VLOOKUP instead

When I run the original script from Tom or Scott (with a separate loop for column D and E) the detail gets copied correctly, but the hyperlinks do not get copied. When I run the new script, column E gets copied correctly but column D and F do not for some reason. I think the original script would work for column E but for column D, is there a method to preserve the hyperlinks? https://i.stack.imgur.com/clR2b.jpg

Original script

Sub RangeCopyPaste()
Dim cell As Range
Dim NewChangeRange As Range
Dim NewDetailRange As Range


Set NewChangeRange = Range("D6") 'Set the first destination cell

For Each cell In Worksheets("Sheet1").Range("C6:C14") 'Loop through your Status column
    Select Case cell.Value 'Select Case is an alternative to writing multiple If, ElseIf statements, particularly if you want it to run the same code when it is true.
        Case "Ready for Testing", "Build in Prod", "In Progress", "Awaiting CAB Approval" 'Specify all the values which would consitute a "True" result
            NewChangeRange.Value = cell.Offset(0, -2).Value 'In the destination cell, take the cell value 1 column to the left of the cell which contained the required status
            Set NewChangeRange = NewChangeRange.Offset(1, 0) 'Setup the new destination cell ready for the next "True" result
    End Select
Next cell


Set NewDetailRange = Range("E6") 'Set the first destination cell

For Each cell In Worksheets("Sheet1").Range("C6:C14") 'Loop through your Status column
    Select Case cell.Value 'Select Case is an alternative to writing multiple If, ElseIf statements, particularly if you want it to run the same code when it is true.
        Case "Ready for Testing", "Build in Prod", "In Progress", "Awaiting CAB Approval" 'Specify all the values which would consitute a "True" result
            NewDetailRange.Value = cell.Offset(0, -1).Value 'In the destination cell, take the cell value 1 column to the left of the cell which contained the required status
            Set NewDetailRange = NewDetailRange.Offset(1, 0) 'Setup the new destination cell ready for the next "True" result
    End Select
Next cell

End Sub

New script

Sub RangeCopyPaste()
    Dim cell As Range
    Dim NewChangeRange As Range
    Dim NewDetailRange As Range


    Set NewChangeRange = Range("D6") 'Set the first destination cell

    For Each cell In Worksheets("Sheet1").Range("C6:C14") 'Loop through your Status column
        Select Case cell.Value 'Select Case is an alternative to writing multiple If, ElseIf statements, particularly if you want it to run the same code when it is true.
            Case "Ready for Testing", "Build in Prod", "In Progress", "Awaiting CAB Approval" 'Specify all the values which would consitute a "True" result
                Range(cell.Offset(0, -2), cell.Offset(0, -2)).Copy NewChangeRange
                Set NewChangeRange = NewChangeRange.Offset(1, 0) 'Setup the new destination cell ready for the next "True" result
        End Select
    Next cell


    Set NewDetailRange = Range("E6") 'Set the first destination cell

    For Each cell In Worksheets("Sheet1").Range("C6:C14") 'Loop through your Status column
        Select Case cell.Value 'Select Case is an alternative to writing multiple If, ElseIf statements, particularly if you want it to run the same code when it is true.
            Case "Ready for Testing", "Build in Prod", "In Progress", "Awaiting CAB Approval" 'Specify all the values which would consitute a "True" result
                NewDetailRange.Value = cell.Offset(0, -1).Value 'In the destination cell, take the cell value 1 column to the left of the cell which contained the required status
                Set NewDetailRange = NewDetailRange.Offset(1, 0) 'Setup the new destination cell ready for the next "True" result
        End Select
    Next cell

    End Sub
BrianK
  • 55
  • 6

2 Answers2

0

Take advantage of Case statement here. See below.

Sub RangeCopyPaste()

Dim cell As Range
Dim NewRange As Range
Dim MyCount As Long
MyCount = 1

'--> Loop through each cell in column C
'--> Add each cell in column B with value "Ready for Testing" in column B to 

For Each cell In Worksheets("OverviewTest").Range("C6:C56")

    Select Case cell.Value 

        Case is = "Ready for Testing", "Build in Prod", "In Progress", "Awaiting CAB Approval"

            If MyCount = 1 Then 
                Set NewRange = cell.Offset(0, -1)
            Else
               Set NewRange = Application.Union(NewRange, cell.Offset(0, -1))
            End If

            MyCount = MyCount + 1

    End Select

Next cell

'--> Copy NewRange from inactive sheet into active sheet
NewRange.Copy Destination:=ActiveSheet.Range("D6")


End Sub
Scott Holtzman
  • 27,099
  • 5
  • 37
  • 72
0

Try the code below to resolve your issue;

Sub RangeCopyPaste()
Dim cell As Range
Dim NewRange As Range

Set NewRange = Range("D1") 'Set the first destination cell

For Each cell In Worksheets("Sheet1").Range("C1:C16") 'Loop through your Status column
    Select Case cell.Value 'Select Case is an alternative to writing multiple If, ElseIf statements, particularly if you want it to run the same code when it is true.
        Case "Ready for testing", "Build in Prod", "In Progress", "Awaiting CAB Approval" 'Specify all the values which would consitute a "True" result
            NewRange.Formula = Range(cell.Offset(0, -2), cell.Offset(0, -2)).Formula 'Copies the formula from Column A
            NewRange.Offset(0, 1).Value = Range(cell.Offset(0, -1), cell.Offset(0, -1)).Value ' Copies the value from Column B
            NewRange.Offset(0, 2).Value = Range(cell).Formula ' Copies the formula from Column C
            Set NewRange = NewRange.Offset(1, 0) 'Setup the new destination cell ready for the next "True" result
    End Select
Next cell

End Sub
TomW
  • 68
  • 7
  • Thanks for the alternative and the helpful explanation. Would it be possible to modify the above code to copy out A1, B1, C1 to D1, E1, F1 where a True result exists in C1? – BrianK Jun 02 '17 at 09:01
  • Sure it would. Replace the "NewRange.Value = cell.Offset(0,-1).Value" with Range(cell.Offset(0,-2),cell.Offset(0,3)).Copy NewRange Also change the NewRange setting as it will currently overwrite data. – TomW Jun 02 '17 at 10:20
  • Hi Tom, thanks for the new info but it hasn't exactly worked with what I am trying to do. I have updated my original question with screenshots as I can't add them here. – BrianK Jun 02 '17 at 13:28
  • Hi Brian, your problem appears to be that the hyperlink reference changes as the formula moves to Column D. Instead of having; Row()-4 try doing a MATCH formula; MATCH(B6,Sheet2!$B$2:$B$10,0) This should mean that the hyperlink still refers to the correct row on Sheet2. As for Column F, if you already have a formula set up to perform the VLOOKUP, do you need to copy the value from Column C? – TomW Jun 02 '17 at 14:17
  • Hi Tom, the only way I could get the HYPERLINK functionality to work with MATCH is using the following: `=HYPERLINK("#"&CELL("address",INDEX(Sheet2!B2:B9,MATCH(B6,Sheet2!B2:B9,0))),Sheet2!$A2)` But this still caused A6-A11 to be copied to D6-D11 instead of the cells in column A that have the desired status in column C (I hadn't figured out how to correctly set the Range.Copy earlier but I have this updated now in the code so VLOOKUP is still being used for Column C) Thanks @TomW – BrianK Jun 02 '17 at 15:17
  • Found a way to copy the HYPERLINK with the MATCH formula using the following code (From Jacobs comment here:
    [link]https://shortest.link/2F):
    `Sub COPYPASTE() Set Inputtable = Application.InputBox(prompt:=”Input”, Type:=8) Set Outputtable = Application.InputBox(prompt:=”Output”, Type:=8) Number_of_rows = Inputtable.Rows.Count Number_of_col = Inputtable.Columns.Count For j = 1 To Number_of_rows For i = 1 To Number_of_col Outputtable(j, i).Formula = Inputtable(j, i).Formula Next Next End Sub`
    Any idea how to incorporate the .Formula action into your script?
    – BrianK Jun 02 '17 at 19:15
  • Hi Brian, Have a look at the edit above. I have added some lines within the Case statement which will mean it copies the formulas from Columns A and C, but the value of Column B. – TomW Jun 05 '17 at 14:00
  • Hi Tom, Thanks very much for all your help. I now have this working in my document. – BrianK Jun 06 '17 at 09:36