0

I am a newbie to the VBA world and need your help.

I want to copy data from columns A, B and C in Sheet2 and Sheet3 and paste it in Columns A, B and C of Sheet1 but stacked. Meaning, data from Sheet2 should be pasted in "A1:A4", then data from Sheet3 should be pasted in "A5:A9".

I am using the following code and getting an error:

j = 1
For i = 1 to 2
    For k = 1 to 3  

    Sheets(i+1).range(cells(1,k),cells(4,k).copy
    Sheet(1).range(cells(j,k),cells(j+3,k).PasteSpecial xlPasteValues
    
    Next k
j = j + 4

next i

If there is a better way to do it, it would be helpful too. Please help!

  • Is this just something that paste transpose will sort out? Or does it need to be VBA? https://support.microsoft.com/en-us/office/transpose-data-from-rows-to-columns-or-vice-versa-in-excel-for-mac-9c16dd55-ed1a-4aa2-8b74-b1b9211e2ede – Nick.Mc Apr 11 '21 at 05:48
  • 2
    Please never post things like "getting an error" without..... _actually posting the error message_ – Nick.Mc Apr 11 '21 at 05:49

1 Answers1

-1

The difference between your code and the one submitted below is in the effort expanded on preparation. Preparation led to recognition of problems where lack of preparation led to confusion and, ultimately, this question. What I'm saying is that I don't think you would have needed to ask had you known to prepare adequately.

Private Sub Snippet()
    ' 218

    Dim Ws(1 To 2)  As Worksheet    ' "Source 1" and "Source 2"
    Dim i           As Integer      ' loop counter: Ws index
    Dim Rs          As Long         ' loop counter: rows (source)
    Dim WsOut       As Worksheet    ' "Output"
    Dim Rt          As Long         ' target row

    With ThisWorkbook
        Set WsOut = .Worksheets("Output")
        Set Ws(1) = .Worksheets("Source 1")
        Set Ws(2) = .Worksheets("Source 2")
    End With
    
    With WsOut                      ' = last used row in WsOut
        Rt = .Cells(.Rows.Count, "A").End(xlUp).Row
    End With

    Application.ScreenUpdating = False
    For i = 1 To 2                  ' loop through Ws(1 to 2)
        With Ws(i)                  ' find last used row in Ws(1)
            ' start copying from row 2 because row 1 probably holds captions
            ' end with last used row in column A
            For Rs = 2 To .Cells(.Rows.Count, "A").End(xlUp).Row
                Rt = Rt + 1
                .Range(.Cells(Rs, 1), .Cells(Rs, 3)).Copy
                WsOut.Cells(Rt, 1).PasteSpecial xlPasteValues
            Next Rs
        End With
    Next i
    
    With Application
        .CutCopyMode = False
        .ScreenUpdating = True
    End With
End Sub

The procedure starts off by naming all variables. The first result was to replace references like "Sheet(1)" even at this early stage because "Sheet(1)" is the first sheet from the left in the tab bar. If you add a sheet unwittingly your code won't work anymore or, rather, it will destroy your workbook. Your variables "k" and "j" were replaced with "Rs" and "Rt" marking them as row numbers (source and target).

Next, the code makes sure that the worksheets are properly defined as being within ThisWorkbook. They are also properly linked to their real life names, executing a decision made at the beginning. Actually, the variable declarations are modified many times while the rest of the code is developed. It isn't hewn in stone at the beginning but everything is built on it nevertheless.

Then the Target Row is set, and a system for it's maintenance designed. The system is to find the last used row first and then increment that number every time before a new row is written.

The decision is made to turn off ScreenUpdating while the code runs. It will run faster that way but you must make provision to turn the feature back on at the end. That part of the code is written at this time.

And only now I arrive at the point which you had started out with. My code is remarkably like yours. Note that Copy/PasteSpecial allows you to choose what to paste, in this case "Values". You might use Copy with Destination instead which would also include formats. Or you might specify to copy formulas instead of values. To copy values you could simply use syntax like WsOut.Cells(Rt, 1).Value = .Cells(Rs, 1).Value` in a little loop. Because of the solid fundament on which this code is built it's very easy to modify these two lines using the established components.

The code ends on setting Application.CutCopyMode = False and presenting the result of the action in the display by restoring ScreenUpdating.

Variatus
  • 14,293
  • 2
  • 14
  • 30