Results 1 to 12 of 12

Thread: [RESOLVED] Excel VBA - alternatives for loops?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Resolved [RESOLVED] Excel VBA - alternatives for loops?

    Hi guys

    I just found out that one of my old macro's didn't do its job well enough. So I rewrote it - unfortunately I'm not that gifted at VBA, so now I need to charge the computer with a supernova if it should be able to process it!

    I found I need a total of 5 nested for...next statements with the following counters:
    VB Code:
    1. For i = 5 To 250
    2.     For j = i To i + 15
    3.         For k = i To i + 15
    4.             For l = 5 To 250
    5.                 For m = l To l + 15
    6.                     If gSheet.Cells(i, 1).Value = "BFORR" Then
    7.                         If gSheet.Cells(j, 2).Value = "Kundegrupper" Then
    8.                             gSheet.Activate
    9.                             gSheet.Rows(j).EntireRow.Copy
    10.                             tSheet.Activate
    11.                             tSheet.Rows(j).PasteSpecial

    The code goes on like this, eventually to include k,l and m as well.

    As I said - it takes literally ages (Don't know how long to be precise, but so far +3hours - I can do it manually in 1!)

    Is there an alternative to for...next or can I make it leaner in a way??

    /Nick
    Last edited by direktoren; May 17th, 2006 at 09:28 AM. Reason: RESOLVED

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Excel VBA - alternatives for loops?

    It all depends on what you are trying to do..


    Why do you need nested loop's? (I cant see any reason for it in your code)

    Is there a need for PasteSpecial (as opposed to just a paste)? If not, we can speed that up a lot.

    How are your variables declared?



    It's probably best to explain what you want the code to do, and show us the code you have.

  3. #3
    Fanatic Member Comintern's Avatar
    Join Date
    Nov 2004
    Location
    Lincoln, NE
    Posts
    826

    Re: Excel VBA - alternatives for loops?

    .Activate, .Copy, and .Paste are horribly slow. One thing to try would be to do direct value assignments for the ranges. Can you post the full sub (or at least the nested loops)?

  4. #4

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Excel VBA - alternatives for loops?

    Thanx for all the replies

    I am aware that .activate, and copy paste takes up tons of time - but without activating the sheet I often occur errors!

    'Code removed and put in next reply

    Description of what I want to do:

    gSheet - contains a report gotten from OLAP (so it is hierachicly structured)
    tSheet - empty sheet, where I need a corrected copy of gSheet.

    Contains:
    gSheet;
    column A - Contains a mainregistration number, for instance BFORR.
    This coulmn is the "head" of the hierachy. lets Call them a,
    b, c and d (in reality there are about 25)
    Column B - contains the different groupings, which exist under the
    given registration number, lets call them v,w,x,y and z.
    Column C - Contains the actual data (numbers).

    Problems;

    - Not all of the variables (a-d and v-z) is included every time, so they should only be copied if they exist (logically)

    - Some of the subgroupings (they are also listed in column B) are "misplaced", so they need to be subtracted from one group and then added to another, e.g. a minus c and b plus c. (but of course, only if there are existing!)

    - some of the registration numbers should, if they exist, be added to other registration numbers, e.g. c plus d.

    I hope this helps a bit! I know it would be easier if I could just upload the sheet, but its confidential - and I can't upload or download anything!

    /Nick
    P.s. The code which (almost) used to work for me is listed at another thread http://vbforums.com/showthread.php?p...47#post2472747

  5. #5

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Excel VBA - alternatives for loops?

    VB Code:
    1. Sub KngrOvfData()
    2. Dim i As Integer
    3. Dim j As Integer
    4. Dim k As Integer
    5. Dim l As Integer
    6. Dim m As Integer
    7. Dim gSheet As Worksheet
    8. Dim tSheet As Worksheet
    9. Dim eSheet As Worksheet
    10.  
    11.     Set gSheet = ActiveWorkbook.Worksheets("Grund")
    12.     Set tSheet = ActiveWorkbook.Worksheets("Tilrettet")
    13.     Set eSheet = ActiveWorkbook.Worksheets("Ekskl.ny-øgede og tlf")
    14.  
    15. Application.ScreenUpdating = False
    16.  
    17. For i = 5 To 250
    18.     For j = i To i + 15
    19.         For k = i To i + 15
    20.             For l = 5 To 250
    21.                 For m = l To l + 15
    22.                     If gSheet.Cells(i, 1).Value = "BFORR" Then
    23.                         If gSheet.Cells(j, 2).Value = "Kundegrupper" Then
    24.                             gSheet.Activate
    25.                             gSheet.Rows(j).EntireRow.Copy
    26.                             tSheet.Activate
    27.                             tSheet.Rows(j).PasteSpecial
    28.                             Application.CutCopyMode = False
    29.                         End If
    30.                         If gSheet.Cells(j, 2).Value = "Mindre Erhverv" Then
    31.                             gSheet.Activate
    32.                             gSheet.Rows(j).EntireRow.Copy
    33.                             tSheet.Activate
    34.                             tSheet.Rows(j).PasteSpecial
    35.                             Application.CutCopyMode = False
    36.                             If gSheet.Cells(k, 2).Value = "04 Fonde/investeringsselskaber" Then
    37.                                 gSheet.Activate
    38.                                 gSheet.Range(Cells(k, 3), Cells(k, 3).End(xlToRight)).Copy
    39.                                 tSheet.Activate
    40.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    41.                                 Application.CutCopyMode = False
    42.                             End If
    43.                             If gSheet.Cells(k, 2).Value = "Ukendt" Then
    44.                                 gSheet.Activate
    45.                                 gSheet.Range(Cells(k, 3), Cells(k, 3).End(xlToRight)).Copy
    46.                                 tSheet.Activate
    47.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    48.                                 Application.CutCopyMode = False
    49.                             End If
    50.                         End If
    51.                         '....top code repeats a couple of times, and then gets to the "bit more advanced part".
    52.                     If gSheet.Cells(i, 1).Value = "Z3684 BANKAKT BG BANK" Then
    53.                         If gSheet.Cells(j, 2).Value = "Kundegrupper" Then
    54.                             gSheet.Activate
    55.                             gSheet.Rows(j).EntireRow.Copy
    56.                             tSheet.Activate
    57.                             tSheet.Rows(j).PasteSpecial
    58.                             Application.CutCopyMode = False
    59.                             If gSheet.Cells(l, 1).Value = "N3394 CENTRAL INKASSO BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(j, 2).Value Then
    60.                                 gSheet.Activate
    61.                                 gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    62.                                 tSheet.Activate
    63.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    64.                                 Application.CutCopyMode = False
    65.                             End If
    66.                             If gSheet.Cells(l, 1).Value = "3472 Hensættelser BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(j, 2).Value Then
    67.                                 gSheet.Activate
    68.                                 gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    69.                                 tSheet.Activate
    70.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    71.                                 Application.CutCopyMode = False
    72.                             End If
    73.                         End If
    74.                         If gSheet.Cells(j, 2).Value = "Mindre Erhverv" Then
    75.                             gSheet.Activate
    76.                             gSheet.Rows(j).EntireRow.Copy
    77.                             tSheet.Activate
    78.                             tSheet.Rows(j).PasteSpecial
    79.                             Application.CutCopyMode = False
    80.                             If gSheet.Cells(l, 1).Value = "N3394 CENTRAL INKASSO BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(j, 2).Value Then
    81.                                 gSheet.Activate
    82.                                 gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    83.                                 tSheet.Activate
    84.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    85.                                 Application.CutCopyMode = False
    86.                             End If
    87.                             If gSheet.Cells(l, 1).Value = "3472 Hensættelser BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(j, 2).Value Then
    88.                                 gSheet.Activate
    89.                                 gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    90.                                 tSheet.Activate
    91.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    92.                                 Application.CutCopyMode = False
    93.                             End If
    94.                             If gSheet.Cells(k, 2).Value = "04 Fonde/investeringsselskaber" Then
    95.                                 gSheet.Activate
    96.                                 gSheet.Range(Cells(k, 3), Cells(k, 3).End(xlToRight)).Copy
    97.                                 tSheet.Activate
    98.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    99.                                 Application.CutCopyMode = False
    100.                                 If gSheet.Cells(l, 1).Value = "N3394 CENTRAL INKASSO BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(k, 2).Value Then
    101.                                     gSheet.Activate
    102.                                     gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    103.                                     tSheet.Activate
    104.                                     tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    105.                                     Application.CutCopyMode = False
    106.                                 End If
    107.                                 If gSheet.Cells(l, 1).Value = "3472 Hensættelser BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(k, 2).Value Then
    108.                                     gSheet.Activate
    109.                                     gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    110.                                     tSheet.Activate
    111.                                     tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    112.                                     Application.CutCopyMode = False
    113.                                 End If
    114.                             End If
    115.                             If gSheet.Cells(k, 2).Value = "Ukendt" Then
    116.                                 gSheet.Activate
    117.                                 gSheet.Range(Cells(k, 3), Cells(k, 3).End(xlToRight)).Copy
    118.                                 tSheet.Activate
    119.                                 tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    120.                                 Application.CutCopyMode = False
    121.                                 If gSheet.Cells(l, 1).Value = "N3394 CENTRAL INKASSO BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(k, 2).Value Then
    122.                                     gSheet.Activate
    123.                                     gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    124.                                     tSheet.Activate
    125.                                     tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    126.                                     Application.CutCopyMode = False
    127.                                 End If
    128.                                 If gSheet.Cells(l, 1).Value = "3472 Hensættelser BG" And gSheet.Cells(m, 2).Value = gSheet.Cells(k, 2).Value Then
    129.                                     gSheet.Activate
    130.                                     gSheet.Range(Cells(m, 3), Cells(m, 3).End(xlToRight)).Copy
    131.                                     tSheet.Activate
    132.                                     tSheet.Range(Cells(j, 3), Cells(j, 3).End(xlToRight)).PasteSpecial Paste:=xlValues, operation:=xlAdd
    133.                                     Application.CutCopyMode = False
    134.                                 End If
    135.                             End If
    136.                         End If
    137.                     End If
    138.                 Next m
    139.             Next l
    140.         Next k
    141.     Next j
    142. Next i
    143.  
    144. 'The code has been sharply reduced to meet the 10000 character limit - but it should contain a little bit of everything like this.
    145.  
    146. End Sub
    Last edited by direktoren; May 17th, 2006 at 02:09 AM. Reason: oops

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: Excel VBA - alternatives for loops?

    A few things I can say for a rapid speed-up:
    1. Is there always a need for PasteSpecial (as opposed to just a paste)? If not, we can speed that up a lot. eg:
      VB Code:
      1. gSheet.Activate
      2.                             gSheet.Rows(j).EntireRow.Copy
      3.                             tSheet.Activate
      4.                             tSheet.Rows(j).PasteSpecial
      5.                             Application.CutCopyMode = False
      can become:
      VB Code:
      1. gSheet.Rows(j).EntireRow.Copy tSheet.Rows(j)
    2. Change your variables from Integer to Long. Long is a 32-bit integer, (rather than 16 bit) which is faster, as that is what the processor uses.
    3. When you are testing the same cell for multiple values, use a select case - as that only reads the cells (which is slow) once. It is also much easier to read. For example, this:
      VB Code:
      1. If gSheet.Cells(k, 2).Value = "04 Fonde/investeringsselskaber" Then
      2. ...
      3.                             End If
      4.                             If gSheet.Cells(k, 2).Value = "Ukendt" Then
      5. ..
      6.                             End If
      would become this:
      VB Code:
      1. Select Case gSheet.Cells(k, 2).Value
      2.                             Case "04 Fonde/investeringsselskaber"
      3. ...
      4.                             Case "Ukendt"
      5. ..
      6.                             End Select
    4. The big one... You should not run a loop unless it is needed. Obvious ones are the "m" and "l" loops - they are only used (in what you posted) if the first column contains "Z3684 BANKAKT BG BANK", so they should only be inside that (I also dont understand these loops to be honest, it's hard to read the code at the moment!).

      If the row doesn't contain "Z3684 BANKAKT BG BANK", your code will be almost 4000 times faster.



    If you expand on these points enough, you should end up with code more like this:
    VB Code:
    1. For i = 5 To 250
    2.   Select Case gSheet.Cells(i, 1).Value
    3.   Case "BFORR"
    4.     For j = i To i + 15
    5.       Select Case gSheet.Cells(j, 2).Value
    6.       Case "Kundegrupper"
    7.           '<copy>
    8.       Case "Mindre Erhverv"
    9.           '<copy>
    10.           For k = i To i + 15
    11.             Select Case gSheet.Cells(k, 2).Value
    12.             Case "04 Fonde/investeringsselskaber"
    13.                 '<copy>
    14.             Case "Ukendt"
    15.                 '<copy>
    16.             End Select
    17.           Next k
    18.       End Select
    19.     Next j
    20.   Case "Z3684 BANKAKT BG BANK"
    21.     For j = i To i + 15
    22.       Select Case gSheet.Cells(j, 2).Value
    23.       Case "Kundegrupper"

    Depending on the data, this should take the time from 3+ hours to less than a couple of minutes.

  7. #7

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Excel VBA - alternatives for loops?

    Thanx Si

    Wow - I'm really learning something here...The copy line - never seen it before! excellent...

    I had heard about the cases, but didn't really know the difference between them and if statements, so I'll be working with them a lot more now!

    Another question though.

    I found that the following limitation for j;
    VB Code:
    1. For j = i To i + 15
    isn't useful after all. I need it to be a bit more flexible.

    is it possible to do something like this;

    -first add a blank row before every cell in column B with the value "Kundegrupper", since this is always present as the first grouping of the registration number (this i actually know hw to do! )

    - then define j something like:
    VB Code:
    1. For j = i To gSheet.Cells(i, 2).End(xlDown)
    This doesn't work - but something like it? so I will be able to vary the length of the search loop...

    Thanx
    Nick

  8. #8
    Fanatic Member Comintern's Avatar
    Join Date
    Nov 2004
    Location
    Lincoln, NE
    Posts
    826

    Re: Excel VBA - alternatives for loops?

    This code returns a Range:
    VB Code:
    1. gSheet.Cells(i, 2).End(xlDown)
    To make it work, you need to just get the row number from the returned range:
    VB Code:
    1. For j = i To gSheet.Cells(i, 2).End(xlDown).Row

  9. #9

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Excel VBA - alternatives for loops?

    Excellent

    Works like a peach - although i can't help slamming my head to the table - tried the range, the range value, rows.count.

    Anyways thanks a lot, now I can get back to work!

    Nick

  10. #10
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: [RESOLVED] Excel VBA - alternatives for loops?

    Good stuff.

    Is it now taking a decent amount of time, or would you like it to be even faster? (I've got a few more speed improvements if you want them!).

  11. #11

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: [RESOLVED] Excel VBA - alternatives for loops?

    thanks, but no...

    that won't be necessary - with end formatting and everything it only takes 4,6 seconds to run - so its 782 times faster than me doing it manually...

    One thing I would like some help with though! On my raw data sheet (taken from OLAP) I've got a lot of red and blue arrows. Can I remove them via code or do I have to do it manually? I don't know how to tackle it since the arrows are "on top" of the cells...

  12. #12
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,974

    Re: [RESOLVED] Excel VBA - alternatives for loops?

    Excellent news on the timing.

    It's definitely possible to remove the arrows, as you can do almost anything with code that you can do manually. To find out how to do this, I just created a macro (of me deleting an arrow manually), which gave me this code:
    VB Code:
    1. ActiveSheet.Shapes("Line 1").Select
    2.     Selection.Delete
    ..which is actually the same as this (by removing the Select/Selection):
    VB Code:
    1. ActiveSheet.Shapes("Line 1").Delete
    ..with a minor bit of fiddling this can be turned into a loop to remove all shapes that have a name starting with "Line " (note that you can remove the If/End If to delete all drawing objects):
    VB Code:
    1. Dim objShape As Shape
    2.  
    3.   For Each objShape In ActiveSheet.Shapes
    4.     If Left(objShape.Name, 5) = "Line " Then
    5.      objShape.Delete
    6.     End If
    7.   Next objShape

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width