4
votes

I am trying to copy a entire row on a sheet named "All groups" (A to AF) if column AG contained a certain value and paste it into a sheet named "Green" (if AG =1, blue if AG=2 and Red if AG=3 ).

However, i get a type mismatch error.

I have looked on the forum and the internet of posts of similar errors but i wasn't able to find an answer that would help me. I am using Excel 2016 and Here is my code:

     Sub sort()
    Dim LSearchRow As Integer
    Dim LCopyToRow As Integer

Worksheets("All groups").Select
'Start search in row 3
    LSearchRow = 3
'Start copying data to row 3 in Destination Sheet (row counter variable)
    LCopyToRow = 3
    While Len(Range("A" & CStr(LSearchRow)).Value) > 0
'If value in column AG = "1", copy and paste entire row to Green. Then go back and continue searching
        If Range("AG" & CStr(LSearchRow)).Value = "1" Then
            Rows(CStr(LSearchRow) & "A:AF" & CStr(LSearchRow)).Select
            Selection.Copy
            Worksheets("Green").Select
            Rows(CStr(LCopyToRow) & "A:AF" & CStr(LCopyToRow)).Select
            ActiveSheet.Paste
            LCopyToRow = LCopyToRow + 1
            Worksheets("All groups").Select

'If value in column AG = "2", copy and paste entire row to Blue. Then go back and continue searching
        ElseIf Range("AG" & CStr(LSearchRow)).Value = "2" Then
            Rows(CStr(LSearchRow) & "A:AF" & CStr(LSearchRow)).Select
            Selection.Copy
            Worksheets("Blue").Select
            Rows(CStr(LCopyToRow) & "A:AF" & CStr(LCopyToRow)).Select
            ActiveSheet.Paste
            LCopyToRow = LCopyToRow + 1
            Worksheets("All groups").Select

'If value in column AG = "3", copy and paste entire row to Red. Then go back and continue searching
        Else
            Rows(CStr(LSearchRow) & "A:AF" & CStr(LSearchRow)).Select
            Selection.Copy
            Worksheets("Red").Select
            Rows(CStr(LCopyToRow) & "A:AF" & CStr(LCopyToRow)).Select
            ActiveSheet.Paste
            LCopyToRow = LCopyToRow + 1
            Worksheets("All groups").Select
            End If

        Wend

        End Sub
2
On which line do you get the error? Btw, Rows(CStr(LSearchRow) & "A:AF" & CStr(LSearchRow)) shpuld be Rows(CStr(LSearchRow) & ":" & CStr(LSearchRow)) - R3uK
All I got was: Run Time Error 13 Type Mismatch. It didn't display the line number nor highlighted it. btw when i tried Rows(CStr(LSearchRow) & ":" & CStr(LSearchRow)) i get an application-defined or object-defined error - Dr. Steinberg
Strange for the Rows(... statement... Anyway, as you don't get an highlighted row, I suggest that you place breakpoints on almost every line to narrow down the culprit line. Are you used to debug like this? If not I'll propose a curated solution for what you are trying to do! ;) - R3uK
i am fairly new to vba so i have never debugged like this before :) usually vba excel highlights the line that the error occurs on. However on this particular error it didn't highlight the line that was causing the error. - Dr. Steinberg
Might be a silly question, but how big is your data set? How many lines do you have? - R3uK

2 Answers

0
votes

You've gotten a little over-exuberant with the CStr number-to-text-that-looks-like-a-number conversions. Numbers should be treated as numbers and text as text. Cross-matching may or may not produce the desired results.

I couldn't find where you were incrementing the LSearchRow var so I've added that.

Sub all_group_sort()
    Dim LSearchRow As Long
    Dim LCopyToRow As Long

    With Worksheets("All groups")
        'Start search in row 3
        LSearchRow = 3

        'Start copying data to row 3 in Destination Sheet (row counter variable)
        LCopyToRow = 3  '= LSearchRow
        While CBool(Len(Range("A" & LSearchRow).Value2))
            'If value in column AG = "1", copy and paste entire row to Green. Then go back and continue searching
            Select Case CStr(.Range("AG" & LSearchRow).Value2)
                Case "1"
                    .Cells(LSearchRow, "A").Resize(1, 32).Copy _
                        Destination:=Worksheets("Green").Cells(LCopyToRow, "A")
                    LCopyToRow = LCopyToRow + 1
                Case "2"
                    .Cells(LSearchRow, "A").Resize(1, 32).Copy _
                        Destination:=Worksheets("Blue").Cells(LCopyToRow, "A")
                    LCopyToRow = LCopyToRow + 1
                Case "3"
                    .Cells(LSearchRow, "A").Resize(1, 32).Copy _
                        Destination:=Worksheets("Red").Cells(LCopyToRow, "A")
                    LCopyToRow = LCopyToRow + 1
                Case Else
                    'do nothing
                    Debug.Print "Not 1,2 or 3 - " & .Range("AG" & LSearchRow).Value2
            End Select
            LSearchRow = LSearchRow + 1
        Wend
    End With
End Sub

This sort of criteria check is handled very well by a Select Case statement. The actual copying only needs a destination of a single cell; the rest of the paste just follows it.

0
votes

You don't need to use CStr everywhere, VBA will implicitly convert the whole characters chain to a String as it is a concatenation (string addition) and that he expect to have a String argument.

Further more, the .Select is a really heavy method that is for the extreme majority of the cases absolutely useless, so I got rid of them!

I added Worksheet variable (notice the Set keyword to assign value to an object), changed the Ifs to a Select Case and go everything that wasn't necessary inside of the If.

Finally, I changed the calculation of the Paste row to be the first empty row in each sheet for each paste!

This is your code a bit transformed but it decompose every step of the process, let me know if that work fine :

Sub sort()
Dim wS As Worksheet, _
    wsDest As Worksheet, _
    LSearchRow As Integer, _
    LCopyToRow As Integer

Set wS = Sheets("All groups")
LSearchRow = 3      'Start search in row 3
LCopyToRow = 3      'Start copying data to row 3 in Destination Sheet (row counter variable)

With wS
    While Len(CStr(.Range("A" & LSearchRow).Value)) > 0
        'Copy the row
        .Rows(LSearchRow & "A:AF" & LSearchRow).Copy
        'Select the sheet to paste on
        Select Case .Range("AG" & LSearchRow).Value
            Case Is = 1
                Set wsDest = Sheets("Green")
            Case Is = 2
                Set wsDest = Sheets("Blue")
            Case Is = 3
                Set wsDest = Sheets("Red")
            Case Else
                'Cover unknown cases
                MsgBox "Case not cover by code, press Ctrl+Break to stop code and debug", vbCritical + vbOKOnly
        End Select
        'Calculate first empty row on destination sheet
        LCopyToRow = wsDest.Range("A" & wsDest.Rows.Count).End(xlUp).Row + 1
        'Paste the copied row
        wsDest.Rows(LCopyToRow & "A:AF" & LCopyToRow).Paste
        'Continue to next line
        LSearchRow = LSearchRow + 1
    Wend
End With

End Sub