Results 1 to 22 of 22

Thread: [Resolved]Speeding it up?!?

  1. #1

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Resolved [Resolved]Speeding it up?!?

    Hi all you wiz'es

    I'm done with a macro at work, but need to test it completely with different values and options in the sheet - however this takes a LONG time since my macro is running on brute force!

    VB Code:
    1. Sub Start()
    2. Dim iSheet As Worksheet
    3. Dim kSheet As Worksheet
    4. Dim n As Long
    5. Dim j As Long
    6.    
    7. Application.ScreenUpdating = False
    8.    
    9.     Set iSheet = ActiveWorkbook.Sheets("Input")
    10.     Set kSheet = ActiveWorkbook.Sheets("Konstante")
    11.    
    12.     For n = 1 To 15000
    13.         For j = 1 To 300
    14.             If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "M").Value Then
    15.                 iSheet.Cells(n, "N").Value = kSheet.Cells(j, "B").Value
    16.             End If
    17.             If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "N").Value Then
    18.                 iSheet.Cells(n, "O").Value = kSheet.Cells(j, "B").Value
    19.             End If
    20.             If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "F").Value Then
    21.                 iSheet.Cells(n, "P").Value = kSheet.Cells(j, "B").Value
    22.             End If
    23.             If kSheet.Cells(j, "C").Value = iSheet.Cells(n, "F").Value Then
    24.                 iSheet.Cells(n, "AF").Value = kSheet.Cells(j, "D").Value
    25.             End If
    26.             iSheet.Cells(n, "AG").Value = iSheet.Cells(n, "AE").Value & iSheet.Cells(n, "AF").Value
    27.             If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "AG").Value Then
    28.                 kSheet.Activate
    29.                 kSheet.Range(Cells(j, "B"), Cells(j, "O")).Copy
    30.                 iSheet.Activate
    31.                 iSheet.Range(Cells(n, "Q"), Cells(n, "AD")).PasteSpecial Paste:=xlValues
    32.                 Application.CutCopyMode = False
    33.             End If
    34.         Next j
    35.     Next n
    36.        
    37.     Set iSheet = Nothing
    38.     Set kSheet = Nothing
    39.  
    40. Application.ScreenUpdating = True
    41. End Sub

    The final macro is made up with 12 of these subcommands and a complete test takes 6500 secs! (that's 1h 48m 20s!!) - since I need to test it with a lot of different combinations I would like to speed up the process!

    Is this possible??

    thanx
    /nick
    Last edited by direktoren; Mar 13th, 2006 at 03:37 AM. Reason: question solved

  2. #2
    Frenzied Member DKenny's Avatar
    Join Date
    Sep 2005
    Location
    on the good ship oblivion..
    Posts
    1,171

    Re: Speeding it up?!?

    Nick
    Let's start by changing this section of code.
    VB Code:
    1. If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "AG").Value Then
    2.     kSheet.Activate
    3.     kSheet.Range(Cells(j, "B"), Cells(j, "O")).Copy
    4.     iSheet.Activate
    5.     iSheet.Range(Cells(n, "Q"), Cells(n, "AD")).PasteSpecial Paste:=xlValues
    6.     Application.CutCopyMode = False
    7. End If
    Activating sheets and copying data in this way is going to be really slow. You can achieve the same result without having to switch between sheets, using the following code.
    VB Code:
    1. If kSheet.Cells(j, "A").Value = iSheet.Cells(n, "AG").Value Then
    2.     iSheet.Range(Cells(n, "Q"), Cells(n, "AD")).Value = kSheet.Range(Cells(j, "B"), Cells(j, "O")).Value
    3. End If
    This may be enough to get the performance to where you want it, so lets try that. Time it, and if you still need more we can try some other optimizations.
    Declan

    Don't forget to mark your Thread as resolved.
    Take a moment to rate posts that you think are helpful

  3. #3

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    Hi Kenny

    Thanx, didn't even look at that one - it helped a bit...However the of my subcommands looks like the one posted except, with those the copying formats are a bit different (some are value, som are transpose, som have skipblanks etc. most are a mix), so I don't think i can equal those ones...

    Anything else up your sleeve?

  4. #4
    Frenzied Member DKenny's Avatar
    Join Date
    Sep 2005
    Location
    on the good ship oblivion..
    Posts
    1,171

    Re: Speeding it up?!?

    Can you upload a copy of the workbook?
    We should be able to get rid of one of the loops (either j or n) which should speed the process up significantly. I would like to see the structure to determine which loop tp remove.
    Declan

    Don't forget to mark your Thread as resolved.
    Take a moment to rate posts that you think are helpful

  5. #5
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: Speeding it up?!?

    Nick ...

    You are probably doing a LOT of extra tests.

    Will more than ONE constant be matched for Input Columns "M", "N", or "F"? If only one constant will be matched, you should use an "ElseIf" construct to bypass the unneeded comparison tests.

    If you have long strings that can be absolutely identified from the first few characters, only use as few of the first characters as are needed to make the identification.

    How many rows from the Konstante Sheet will be used for any SINGLE row of the Eingang sheet? If there is only ONE Konstante row that matches any Input row then you can abort the "j" loop once the correct Konstante row has been found. I usually use a Boolean to do this:
    Code:
    Dim found As Boolean
    
    'Initialize FOUND flag to NOT FOUND
    found = False
    For j = 1 To 300
        If mytest Then
            'Everywhere the test passes, do this:
            found = True
            'If only one test can ever pass, also do this immediately
            Exit For
        End If
        
        'If the results of more than one test must be processed, at the END of the "j" loop do this:
        If found Then Exit For
    Next j
    
    If found Then
        'Process "Test Passed' Here
    Else
        'Process "Test Failed' Here
    End If
    
    '  ... continue processing "n" loop
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  6. #6
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: Speeding it up?!?

    Nick ...

    Also, I have a hunch that if you use a Dictionary lookup for your Konstants it will be faster (???) than scanning the kSheet for each row in the iSheet. Do any of the Konstants in Column C ALSO appear in Column A? That makes a big difference in how I would approach the code.

    You can build the Dictionary Keys automatically from the kSheet, but writing the code to initialize 300 or 600 constants will be a royal pain. But then you only have to do it once!

    If you answer this question as well as the ones from my previous post regarding "how many tested constants can be mapped from rows M, N, and F on the iSheet?", we may be able to get this thing to run a lot faster.
    Last edited by Webtest; Mar 6th, 2006 at 02:03 PM.
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  7. #7
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: Speeding it up?!?

    For what you are doing it seems to me you could read the ranges into arrays, do all of the processing on the arrays, then write the arrays back to the spreadsheet when you are done. Arrays are very fast. Also, you should use integers instead of longs for the index.

    VB Code:
    1. Dim n As Integer, j As Integer
    2.     Dim iArray As Variant, kArray As Variant
    3.    
    4.     With ActiveWorkbook
    5.         iArray = .Sheets("Input").Range("A1:M15000")
    6.         kArray = .Sheets("Konstante").Range("A1:M15000")
    7.     End With
    8.    
    9.      For n = 1 To 15000
    10.         For j = 1 To 300
    11.             If kArray(j, 1) = iArray(n, 13) Then iArray(n,12) = kArray(j, 2)
    12.             'other stuff
    13.         Next j
    14.     Next n
    15.    
    16.     With ActiveWorkbook
    17.         .Sheets("Input").Range("A1:M15000") = iArray
    18.         .Sheets("Konstante").Range("A1:M15000") = kArray
    19.     End With
    Last edited by VBAhack; Mar 6th, 2006 at 04:17 PM.

  8. #8
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: Speeding it up?!?

    VBAhack ...

    That was going to be a part of my suggestion ... the Dictionary Key/Value pair could consist of the Constants as Keys, and the Value could consist of the index into a pair of arrays ... one for which column to store the Constant "B" cell, and the the second with the *>edit B actual values. There is a built-in function to determine if a Key exists that could simplify the string testing.

    Using Integers for Row numbers is not guaranteed (I know in this case we have been told there are only 15000 rows) since the number of rows possible is 65536 ... this overflows an Integer. I've also seen reports that it actually can take longer to access 16 bit integers since native memory accesses are 32 bits (I can't swear to this).
    Last edited by Webtest; Mar 6th, 2006 at 04:38 PM. Reason: See *>edit in first paragraph
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  9. #9
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: Speeding it up?!?

    Quote Originally Posted by Webtest
    I've also seen reports that it actually can take longer to access 16 bit integers since native memory accesses are 32 bits
    Yeah, I remember seeing something similar. Easy way to find out - try both and time it.

  10. #10

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    Thanx for all the good advice

    Now for the questions regarding them...

    DKenny --> I had to go back to the copy paste instead of equalling the cells, because even though I'm using .value it is copying the formula in the cell, instead of the value - therefore back to pastespecial with xlvalue. I'm btw not able to upload the workbook, first off, the figures in it are confidential so i would have to make up a lot of fake figures, and second it's huge - the workbook is 24,7 MB...

    VBAHack --> Tried using your idea with the arrays, it was so much faster, BUT for some odd reason it's not working - u see, it's not copying the cells, so I can't use it for that much (Is there something I have missed?)

    Webtest --> Not more than one constant from the kSheet will be matched by M, N and F (meaning there is a separate constant for each of them). And yes the Konstants in column C matches some of those from column A, but they yield different outputs (this is why I moved them to "C" - to avoid finding the wrong constant).

    Hope this explains it a bit - especially hoping to hear from you hack, since it did go a lot faster that way (it went from 17 minutes, to 11 sek!)

    Regards
    Nick

  11. #11
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: Speeding it up?!?

    Nick ... I'm still not sure I understand.

    If you find a match for "M" are you done with testing for that row or do you STILL have to check "N" and "F"?

    If you do NOT find a match for "M" but you DO find a match for "N" are you done with testing for that row or do you STILL need to check for "F"?
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  12. #12

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    Well it's a bit tricky to explain, but let me try in simple terms;

    for the sake of ease, k=ksheet and i=isheet.

    if iM=kA then iN=kB --> if iN=kA then iO=kB (so these 2 processes are linked, because N is blank until the macro has been runned)

    unaffected by this I've got

    if iF=kA then iP=kB

    Later on I then have

    if iF=kC then iAF=kD (this constant is situated in kC because the same values are figurating in kA --> thus to get the right result I've moved it...

    So answering your question in short; Yes, When I find a match for M I still need to find a match for both N and F.

    /Nick

  13. #13
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: Speeding it up?!?

    Quote Originally Posted by direktoren
    VBAHack --> Tried using your idea with the arrays, it was so much faster, BUT for some odd reason it's not working - u see, it's not copying the cells, so I can't use it for that much (Is there something I have missed?)
    Very strange. I just did a test where I opened a brand new workbook, pasted the following into a new code module, and executed it. Result was cells on sheets 1 and 2 where modified. Total execution time was about 2 sec.

    VB Code:
    1. Sub GoodTest()
    2.     Dim n As Integer, j As Integer
    3.     Dim iArray As Variant, kArray As Variant
    4.    
    5.     With ActiveWorkbook            'read ranges into arrays
    6.         iArray = .Sheets("Sheet1").Range("A1:M15000")
    7.         kArray = .Sheets("Sheet2").Range("A1:M15000")
    8.     End With
    9.    
    10.      For n = 1 To 15000    'modify array values
    11.         For j = 1 To 300
    12.             kArray(j, 1) = n + j
    13.             iArray(n, 5) = n - j
    14.         Next j
    15.     Next n
    16.    
    17.     With ActiveWorkbook             'write arrays back out to cells
    18.         .Sheets("Sheet1").Range("A1:M15000") = iArray
    19.         .Sheets("Sheet2").Range("A1:M15000") = kArray
    20.     End With
    21. End Sub
    Last edited by VBAhack; Mar 8th, 2006 at 04:24 PM.

  14. #14

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Unhappy Re: Speeding it up?!?

    I don't get it either...

    My code looks like this:

    VB Code:
    1. Sub Star()
    2. Dim iArray As Variant
    3. Dim kArray As Variant
    4. Dim n As Long
    5. Dim j As Long
    6.  
    7. With ActiveWorkbook
    8.     iArray = .Sheets("Input").Range("A1:AM15000")
    9.     kArray = .Sheets("Konstante").Range("A1:T15000")
    10. End With
    11.    
    12.     For n = 1 To 15000
    13.         For j = 1 To 300
    14.             If kArray(j, 1) = iArray(n, 13) Then
    15.                 iArray(n, 14) = kArray(j, 2)
    16.             End If
    17.             If kArray(j, 1) = iArray(n, 14) Then
    18.                 iArray(n, 15) = kArray(j, 2)
    19.             End If
    20.             If kArray(j, 1) = iArray(n, 6) Then
    21.                 iArray(n, 16) = kArray(j, 2)
    22.             End If
    23.             If kArray(j, 3) = iArray(n, 6) Then
    24.                 iArray(n, 32) = kArray(j, 4)
    25.             End If
    26.         Next j
    27.     Next n
    28.        
    29. With ActiveWorkbook
    30.     .Sheets("Input").Range("A1:M15000") = iArray
    31.     .Sheets("Konstante").Range("A1:M15000") = kArray
    32. End With
    33.  
    34. End Sub

    I was thrilled when I ran it - timed it at 10,4 sec, but then I wanted to start testing and found out that it didn't copy anything between the arrays, thus making its speed rather useless!

  15. #15
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709

    Re: Speeding it up?!?

    Turn screenupdating off before its executed and back on when its do. This should help since it wont have to update the screen display for every cell change.
    VB Code:
    1. Application.ScreenUpdating = False
    2. 'Do stuff
    3. Application.ScreenUpdating = True
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  16. #16

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    Thanx Rob - but as you can see at my initial post, I already have turned it off. But now I'm trying to follow VBAHacks advise (using arrays instead of ranges), but I can't get it to work properly...

  17. #17
    Ex-Super Mod RobDog888's Avatar
    Join Date
    Apr 2001
    Location
    LA, Calif. Raiders #1 AKA:Gangsta Yoda™
    Posts
    60,709

    Re: Speeding it up?!?

    Sorry I missed it but I did read all the posts, probably just forgot after 14 posts lol.

    Post your new issue.
    VB/Office Guru™ (AKA: Gangsta Yoda®)
    I dont answer coding questions via PM. Please post a thread in the appropriate forum.

    Microsoft MVP 2006-2011
    Office Development FAQ (C#, VB.NET, VB 6, VBA)
    Senior Jedi Software Engineer MCP (VB 6 & .NET), BSEE, CET
    If a post has helped you then Please Rate it!
    Reps & Rating PostsVS.NET on Vista Multiple .NET Framework Versions Office Primary Interop AssembliesVB/Office Guru™ Word SpellChecker™.NETVB/Office Guru™ Word SpellChecker™ VB6VB.NET Attributes Ex.Outlook Global Address ListAPI Viewer utility.NET API Viewer Utility
    System: Intel i7 6850K, Geforce GTX1060, Samsung M.2 1 TB & SATA 500 GB, 32 GBs DDR4 3300 Quad Channel RAM, 2 Viewsonic 24" LCDs, Windows 10, Office 2016, VS 2019, VB6 SP6

  18. #18

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    Well my new issue is post #14...I tried using VBAHacks advise, array instead of ranges, but although it is superfast, I can't get it to copy anything! which is kind of what I need it to do, so right now I'm still using the code I posted in #1 - but what I would like is to get the Arrays working...

  19. #19
    Frenzied Member
    Join Date
    May 2004
    Location
    Carlisle, PA
    Posts
    1,045

    Re: Speeding it up?!?

    Nick ...
    Do a "sanity" check like this ... open the View > Immediate window ... and manually compare the 100 lines that you get. If the comparisons don't fly, you won't get any of your target cells loaded!
    Code:
        For n = 1 To 10
            For j = 1 To 10
    
                'TEST TEST TEST TEST
                Debug.Print kArray(j,1), iArray(n,13), iArray(n,14), iArray(n,6), kArray(j,3)
                'END TEST
    
                If kArray(j, 1) = iArray(n, 13) Then
                    iArray(n, 14) = kArray(j, 2)
                End If
                If kArray(j, 1) = iArray(n, 14) Then
                    iArray(n, 15) = kArray(j, 2)
                End If
                If kArray(j, 1) = iArray(n, 6) Then
                    iArray(n, 16) = kArray(j, 2)
                End If
                If kArray(j, 3) = iArray(n, 6) Then
                    iArray(n, 32) = kArray(j, 4)
                End If
            Next j
        Next n
    Blessings in abundance,
    All the Best,
    & ENJOY!

    Art . . . . Carlisle, PA . . USA

  20. #20
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: Speeding it up?!?

    I noticed that you are writing to different ranges than you are reading into the arrays. They need to match:

    VB Code:
    1. With ActiveWorkbook
    2.     iArray = .Sheets("Input").Range("A1:AM15000")
    3.     kArray = .Sheets("Konstante").Range("A1:T15000")
    4. End With
    5.        
    6. With ActiveWorkbook
    7.     .Sheets("Input").Range("A1:M15000") = iArray      ' should be A1:AM15000
    8.     .Sheets("Konstante").Range("A1:M15000") = kArray  'should be A1:T15000
    9. End With

    This might be your problem.

  21. #21

    Thread Starter
    Lively Member
    Join Date
    Feb 2006
    Posts
    96

    Re: Speeding it up?!?

    OMG - That was it!

    Thanx Hack, Guess I will be remembering to double check my script from now on....

    /Nick

  22. #22
    Fanatic Member VBAhack's Avatar
    Join Date
    Dec 2004
    Location
    Sector 000
    Posts
    617

    Re: [Resolved]Speeding it up?!?

    Glad to hear you got it working. If you wanted to expend more energy, you might be able to get some incremental improvements by, for example, using Integer instead of Long for the index (keeping in mind the comments by Webtest), and/or implementing speed tips such as ones found:

    http://www.vbforums.com/showthread.php?t=264351
    http://www.aivosto.com/vbtips/stringopt.html
    http://www.planet-source-code.com/vb...34787&lngWId=1
    http://www.persistentrealities.com/v...egory=1&item=0
    Last edited by VBAhack; Mar 15th, 2006 at 04:10 PM.

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