2

I want to loop a certain macro in excel VBA. However, I don't know how to do this (I tried and failed multiple times). The annotations in the code below are given to show what I want to do. The code as it is works perfectly, I just want it to loop for every chunck of data until all data has been transposed into the second worksheet (the first worksheet contains about 5000 rows of data, and every 18 rows has to be transposed into 1 row in the second worksheet):

    Sub test()

' test Macro

Range("G2").Select
ActiveCell.FormulaR1C1 = "=RC[-2]/RC[-1]*100"
Range("G2").Select
Selection.AutoFill Destination:=Range("G2:G19"), Type:=xlFillDefault
Range("G2:G19").Select
Range("A2:C2").Select
Selection.Copy
Sheets("Sheet2_Transposed data").Select
Range("A2").Select
ActiveSheet.Paste
    'I want to loop this for every next row until all data has been pasted (so A3, A4, etc.)
Sheets("Sheet1_session_data").Select
Range("G2:G19").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet2_Transposed_data").Select
Range("D2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
    :=False, Transpose:=True
Range("D2:U2").Select
Application.CutCopyMode = False
    'Here I also want to loop for every next row until all data has been transposed and pasted (e.g. D3:U3, D4:U4 etc.)
Selection.NumberFormat = "0"
Sheets("Sheet1_session_data").Select
Rows("2:19").Select
Selection.Delete Shift:=xlUp
    ' Here I delete the entire data chunck that has been transposed, so the next chunck of data is the same selection. 

End Sub

Hope this question was understandable, and I hope someone can help. Thanks.

  • what do you mean you want to loop? there are other data in `Sheet1_session_data`? Cause in your code, you already deleted the entire `Row("2:19")`. or does that mean after you have looped through all the columns? Can you somehow show sample data, and expected result? We can help post screen shots, just provide the link. – L42 Feb 10 '14 at 08:31
  • Edited post, I need to tranpose 5000 (or more) rows of data, and every 18 rows is data from 1 user that has to be transposed into 1 row on the second worksheet. – Arco Jansen Feb 10 '14 at 08:35
  • ah i get it. But, i leave it to @Siddharth Rout. :D – L42 Feb 10 '14 at 08:47
  • Can you give me a sample data so that I can give you an exact code with explanation? – Siddharth Rout Feb 10 '14 at 08:52
  • See comment under your answer. Thanks a lot for helping! – Arco Jansen Feb 10 '14 at 09:14

1 Answers1

5

You can actually reduce your code.

First Tip:

Please avoid the use of .Select/.Activate INTERESTING READ

Second Tip:

Instead of doing an Autofill, you can enter the formula in the relevant cells in one go. For example. this

Range("G2").Select
ActiveCell.FormulaR1C1 = "=RC[-2]/RC[-1]*100"
Range("G2").Select
Selection.AutoFill Destination:=Range("G2:G19"), Type:=xlFillDefault

can be written as

Range("G2:G19").FormulaR1C1 = "=RC[-2]/RC[-1]*100"

Third Tip:

You don't need to do a copy and paste in separate lines. You can do it in one line. For example

Range("A2:C2").Select
Selection.Copy
Sheets("Sheet2_Transposed data").Select
Range("A2").Select
ActiveSheet.Paste

can be written as

Range("A2:C2").Copy Sheets("Sheet2_Transposed data").Range("A2")

Same thing when you are doing a PasteSpecial. But you use .Value = .Value soo this

Range("G2:G19").Select
Application.CutCopyMode = False
Selection.Copy
Sheets("Sheet1_Transposed_data").Select
Range("D2").Select
Selection.PasteSpecial Paste:=xlPasteValues, Operation:=xlNone, SkipBlanks _
:=False, Transpose:=True

can be written as

Sheets("Sheet1_Transposed_data").Range("D2:D19").Value = _
Sheets("Sheet1").Range("G2:G19").Value

Missed the Transpose part. (Thanks Simoco). In this case, you can write the code as

Range("A2:C2").Copy 
Sheets("Sheet2_Transposed data").Range("D2").PasteSpecial Paste:=xlPasteValues, _
Operation:=xlNone, SkipBlanks:=False, Transpose:=True

Fourth Tip:

To loop through cells, you can use a For Loop. Say you want to loop though cells A2 to A20 then you can do like this

For i = 2 To 20
    With Range("A" & i)
        '
        '~~> Do Something
        '
    End With
Next i

EDIT:

Your before and after Screenshots (From Comments):

enter image description here

and

enter image description here

After seeing your screenshots, I guess this is what you are trying? This is untested as I just quickly wrote it. Let me know if you get any errors :)

Sub test()
    Dim wsInPut As Worksheet, wsOutput As Worksheet
    Dim lRow As Long, NewRw As Long, i As Long

    '~~> Set your sheets here
    Set wsInPut = ThisWorkbook.Sheets("Sheet1_session_data")
    Set wsOutput = ThisWorkbook.Sheets("Sheet2_Transposed data")

    '~~> Start row in "Sheet2_Transposed data"
    NewRw = 2

    With wsInPut
        '~~> Find Last Row
        lRow = .Range("A" & .Rows.Count).End(xlUp).Row

        '~~> Calculate the average in one go
        .Range("G2:G" & lRow).FormulaR1C1 = "=RC[-2]/RC[-1]*100"

        '~~> Loop through the rows
        For i = 2 To lRow Step 18
            wsOutput.Range("A" & NewRw).Value = .Range("A" & i).Value
            wsOutput.Range("B" & NewRw).Value = .Range("B" & i).Value
            wsOutput.Range("C" & NewRw).Value = .Range("C" & i).Value

            .Range("G" & i & ":G" & (i + 17)).Copy

            wsOutput.Range("D" & NewRw).PasteSpecial Paste:=xlPasteValues, _
            Operation:=xlNone, SkipBlanks:=False, Transpose:=True

            NewRw = NewRw + 1
        Next i

        wsOutput.Range("D2:U" & (NewRw - 1)).NumberFormat = "0"
    End With
End Sub
Community
  • 1
  • 1
Siddharth Rout
  • 147,039
  • 17
  • 206
  • 250
  • I understand my code can be shorter, thanks for that. But I do need to loop (see edit question) – Arco Jansen Feb 10 '14 at 08:36
  • That I also understand, thank you. But I don't want a set selection range. I want to be able to loop until all data from the first worksheet has been transposed into the second. (Because the amount of data will differ from time to time, sometimes 5000 rows of data, sometimes 15000 rows of data). – Arco Jansen Feb 10 '14 at 08:39
  • @ArcoJansen: Have you seen [THIS](http://stackoverflow.com/questions/11169445/error-finding-last-used-cell-in-vba)? simply replace `20` with `LastRow` – Siddharth Rout Feb 10 '14 at 08:40
  • @ArcoJansen: I still think, you may not need a loop. See the `EDIT` in my updated answer. Let me know if that is what you are trying to do? – Siddharth Rout Feb 10 '14 at 08:47
  • Hi, @SiddharthRout:) Good explanation:) but as I see OP wants to transpose data: `Selection.PasteSpecial ... Transpose:=True`. Maybe you need to change last code in third tip?) Or I've missed something? – Dmitry Pavliv Feb 10 '14 at 08:48
  • @SiddharthRout i think `A2:C2` gives identity to the user. `G2:G19` is percentage of that particular user. So every `18-row` is another user which needs to be transpose and consolidated to the other worksheet. i'm sloppy in imagination as well, but that's how i read the OP's code. Since you're at it, i leave it you :p hahaha – L42 Feb 10 '14 at 08:51
  • @simoco: incorporated. thanks. Dunno how I missed that. – Siddharth Rout Feb 10 '14 at 08:53
  • @L42: Asked for sample data. See last line of the answer. Lets see what happens now. – Siddharth Rout Feb 10 '14 at 08:54
  • I think you should also change the same thing in "Edit" part:) – Dmitry Pavliv Feb 10 '14 at 08:54
  • 1
    @simoco: Yeah I thought about that but then decided to wait for the sample data because I have a feeling that I will have to change that part after I see the data :) – Siddharth Rout Feb 10 '14 at 08:55
  • Alright, here is the link to sample data (First and second worksheet). Links: 1. http://imageshack.com/a/img834/6505/i5nu.jpg 2. http://imageshack.com/a/img811/2600/y232.jpg – Arco Jansen Feb 10 '14 at 09:09
  • @ArcoJansen: I understood sheet1 but not sheet2. What are those values? scrore or max score? – Siddharth Rout Feb 10 '14 at 09:15
  • Ah I am sorry. That's what I also do in my code, I make an extra column containing the percentage of the score (so: score/maxscore*100). What's in the second sheet under the "variables" are the percentage scores (which I make as an extra column in the first sheet). – Arco Jansen Feb 10 '14 at 09:16
  • @ArcoJansen: So shouldn't the values in Col M to U be below D to L? – Siddharth Rout Feb 10 '14 at 09:18
  • @ArcoJansen: Can you shown me an exact output of sheet 1 in sheet2? – Siddharth Rout Feb 10 '14 at 09:20
  • @SiddharthRout: I don't think I understand what you are asking me. – Arco Jansen Feb 10 '14 at 09:20
  • @ArcoJansen: See my last comment. simply create two rows with the exact output in sheet2 and provide me the link and I will take it form there. – Siddharth Rout Feb 10 '14 at 09:23
  • @SiddharthRout: I will show the output after I run the current code once: 1. http://imageshack.com/a/img713/861/zafh.jpg 2 .http://imageshack.com/a/img856/7456/ltjo.jpg – Arco Jansen Feb 10 '14 at 09:29
  • @ArcoJansen: Ok I got it :) – Siddharth Rout Feb 10 '14 at 09:37
  • @ArcoJansen: I still think one of the image is wrong because 2/21 is not 33 it is 9.22. :) unless it is 7/21 – Siddharth Rout Feb 10 '14 at 09:38
  • @ArcoJansen: One last question. Is the data always sorted and there are 18 entries per user? – Siddharth Rout Feb 10 '14 at 09:40
  • @SiddharthRout Yes, you are correct haha, that should be 7/21 ;). Yes, there are always 18 entries per user and it is always sorted the exact same way. – Arco Jansen Feb 10 '14 at 09:46
  • @ArcoJansen: See my updated post (EDIT Section) You may have to refresh the page. – Siddharth Rout Feb 10 '14 at 09:59
  • @SiddharthRout: It works like a charm, exactly what I wanted! Thanks a lot, you really helped me out! I understand what you did, and will apply it to future macro's. Amazing :). – Arco Jansen Feb 10 '14 at 10:05
  • @ArcoJansen Glad it all worked out in the end... And yes... Don't forget the tips :p – Siddharth Rout Feb 10 '14 at 10:06