Need Faster VBA, For Lottery Checker

motilulla

Well-known Member
Joined
Feb 13, 2008
Messages
2,362
Office Version
  1. 2010
Using Excel 2010
Hello,

Here is example with 95 rows in the range B6:F53135 I have a set of 5 numbers combinations and in the range K6:O1332 I have a sets of results. (I want to check all the result against all combinations)

For that I am have formula in cell H3 below which have converted into VBA. The below VBA give me the results in cell H6 to down.

The problem when there is combination with 53130 rows and results with 1332 rows it is taking too much time (approximately 00:02:30 Minutes) to populate the results in the column H.

Please I need a help is there any fast VBA version to solve the time issue.

Here is below the example sheet with formula and VBA which I am using are attached.

Excel Questions.xlsm
ABCDEFGHIJKLMNOP
1
2
35
4531305313053130531305313013321332133213321332
5Combin1n2n3n4n5Match ResultsResultn1n2n3n4n5
61123455112345
72123464212678
8312347431291011
94123484412121314
105123494512151617
1161234104612181920
1271234114712212223
13812341248136912
149123413491371013
15101234144101381114
161112341541113151821
171212341641213161922
181312341741313172023
19141234184141461014
2015123419415147915
21161234204161481216
221712342141714111317
231812342241814182224
241912342341914192125
25201234244201561115
26211234254211571217
272212356422158913
28231235742315101618
29241235842415141923
30251235942515202124
312612351042616131620
322712351142716171825
332812351242817111621
342912351342917142022
353012351443017232425
363112351543118101519
373212351643219141624
3833123517433110122025
3934123518434111121823
4035123519435113152225
41361235204362361015
4237123521437237914
43381235224382381217
443912352343923111316
454012352444023182225
464112352544123192124
474212367442246913
4843123684432471012
4944123694442481115
504512361044524141618
514612361134624171922
524712361244724202324
53481236133482561216
54491236143492571118
55501236154502581014
56511236163512591519
575212361735225131720
585312361835326111417
595412361935426192325
605512362035527131521
615612362135627162025
62571236223572891621
635812362335828131823
645912362435929121824
6560123625360210132224
666112378461210171821
676212379462211122021
6863123710463214152425
6964123711364346711
7065123712365348910
716612371346634121315
726712371446734141721
736812371536834162325
7469123716369356818
75701237173703571516
76711237183713591117
777212371937235101219
787312372037335131422
797412372137436131719
807512372237536142024
81761237233763781920
827712372437737122122
837812372537837171824
84791238937938132125
858012381038038152223
868112381148139131820
8782123812482310112022
8883123813383310141823
8984123814484311122425
90851238153854561723
9186123816386457821
92871238174874591214
938812381838845101124
948912381938945131619
959012382039045151820
96911238213914681924
979212382239246121821
989312382339346151622
999412382439447131423
1009512382539548132022
Sheet Lottery
Cell Formulas
RangeFormula
H3H3=MAX(MMULT(COUNTIF(B6:F6,K$6:O$53135),{1;1;1;1;1}))
K4:O4,B4:F4B4=COUNTA(B6:B53135)
A7:A100A7=A6+1
Press CTRL+SHIFT+ENTER to enter array formulas.


VBA Code:
Option Explicit
Sub VBA_MultiLotteryChecker()
    
    Range("H6:H53135").ClearContents
    
    Dim startTime As Double
    Dim MinutesElapsed As String
    startTime = Timer
    
Dim a, b, c
Dim i As Long, j As Long, k As Long, n As Long, Lr As Long, l As Long
Dim xmax As Long

Application.ScreenUpdating = False

Lr = Cells(Rows.Count, "B").End(xlUp).row
a = Range("B6:H" & Lr)
ReDim c(1 To Lr)
Lr = Cells(Rows.Count, "K").End(xlUp).row
b = Range("K2:O" & Lr)

For i = 1 To UBound(a, 1)
    xmax = 0
    For j = 1 To UBound(b, 1)
        n = 0
        For k = 1 To 5
            For l = 1 To 5
                If a(i, k) = b(j, l) Then
                    n = n + 1
                    Exit For
                End If
            Next l
        Next k
          
           If n > xmax Then
                xmax = n
            End If

        Next j
    
    c(i) = xmax
Next i

[H6].Resize(UBound(c, 1), 1) = Application.Transpose(c)

Application.ScreenUpdating = True

   MinutesElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
   MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation

End Sub

Regards,
Moti
 

Excel Facts

Do you hate GETPIVOTDATA?
Prevent GETPIVOTDATA. Select inside a PivotTable. In the Analyze tab of the ribbon, open the dropown next to Options and turn it off
Any reason you didn't use the code I gave you the last time ?
Also some of your results in your sample data look wrong to me based on the sample data, perhaps you ran it on the full data set.

Here is the code I gave you previously modified for only 5 combinations instead of the previous 14

VBA Code:
Sub VBA_MultiLotteryChecker()
    Dim startTime As Double
    startTime = Timer
   
    Dim a, b, c
    Dim i As Long, j As Long, k As Long, n As Long, m As Long
    Dim Lr As Long, xmax As Long
    Dim iPossible As Long, iMiss As Long, xMiss As Long
   
    Lr = Cells(Rows.Count, "H").End(xlUp).Row
    Range("H6:H" & Lr).ClearContents
   
    Application.ScreenUpdating = False
   
    Lr = Cells(Rows.Count, "B").End(xlUp).Row
    a = Range("B6:F" & Lr)
    ReDim c(1 To Lr, 1 To 1)
    Lr = Cells(Rows.Count, "K").End(xlUp).Row
    b = Range("K6:O" & Lr)
   
    iPossible = UBound(b, 2)
   
    For i = 1 To UBound(a, 1)
        xmax = 0
        xMiss = iPossible
       
        For j = 1 To UBound(b, 1)
            n = 0
            iMiss = 0
            For k = 1 To 5
                If a(i, k) = b(j, k) Then
                    n = n + 1
                Else
                    ' if more misses than the best so far no point in looking further
                    iMiss = iMiss + 1
                    If iMiss > xMiss Then Exit For
                End If
            Next k
           
            If n > xmax Then
                xmax = n
                xMiss = iPossible - xmax
            End If
            ' if iPossible is reached no point looking further
            If xmax = iPossible Then Exit For
        Next j
      
        c(i, 1) = xmax
    Next i
    
    Range("H6").Resize(UBound(c, 1), 1) = c
   
    Application.ScreenUpdating = True
   
    Debug.Print Timer - startTime
     
End Sub
 
Upvote 0
Any reason you didn't use the code I gave you the last time ?
Alex Blakenburg, Please not at all that is working like magic. As you will see that VBA was converted from the following formula
VBA Code:
=MAX(MMULT(--($U$6:$AH$20000=B6:O6),TRANSPOSE(COLUMN($U$6:$AH$6))^0))

Also some of your results in your sample data look wrong to me based on the sample data, perhaps you ran it on the full data set.
You have reason that is not correct. I ran it on full data.

Here is the code I gave you previously modified for only 5 combinations instead of the previous 14
This is another issue Post#1 VBA is converted from the following formula.
Code:
=MAX(MMULT(COUNTIF(B6:F6,K$6:O$53135),{1;1;1;1;1}))
May be it needs another look at it?


I tried your code and change the lines to get results in Column I...Instead of H
Code:
Lr = Cells(Rows.Count, "I").End(xlUp).row
    Range("I6:I" & Lr).ClearContents

Range("I6").Resize(UBound(c, 1), 1) = c

Here are exact results from both macros
Post#1 (VBA_MultiLotteryChecker_1)
And you’re from Post#2 (VBA_MultiLotteryChecker_2)

The post#1code result is correct in the column H, on actual data. Matches results are shown in the Q6:Q11

The post#2code result is in column I, on actual data. Which does not match with column H, Matches results are shown in the Q16:Q21? I guess because both formulas are different…for more conformation you can run the Formula if require.

Here below is sheet attached with all actual layout results. Reduced the data 95 to 92, Xl2bb does not copy.

Excel VBA Questions.xlsm
ABCDEFGHIJKLMNOPQ
1
2
35MatchResult
49292929292Macro_1Macro_29292929292MatchMacro_1
5Combin1n2n3n4n5Match ResultsMatch ResultsResultn1n2n3n4n5Match92
61123455511234551
721234644212678455
83123474431291011336
94123484441212131420
105123494451215161710
1161234104461218192000
12712341144712212223
138123412448136912MatchResult
1491234134491371013MatchMacro_2
151012341444101381114Match92
161112341544111315182151
1712123416441213161922421
1813123417441313172023370
19141234184414146101420
2015123419441514791510
21161234204416148121600
2217123421441714111317
2318123422441814182224
2419123423441914192125
252012342444201561115
262112342544211571217
2722123564322158913
282312357432315101618
292412358432415141923
302512359432515202124
3126123510432616131620
3227123511432716171825
3328123512432817111621
3429123513432917142022
3530123514433017232425
3631123515433118101519
3732123516433219141624
38331235174333110122025
39341235184334111121823
40351235194335113152225
413612352043362361015
42371235214337237914
433812352243382381217
4439123523433923111316
4540123524434023182225
4641123525434123192124
4742123674342246913
48431236843432471012
49441236943442481115
5045123610434524141618
5146123611334624171922
5247123612434724202324
534812361333482561216
544912361433492571118
555012361543502581014
565112361633512591519
5752123617335225131720
5853123618335326111417
5954123619335426192325
6055123620335527131521
6156123621335627162025
625712362233572891621
6358123623335828131823
6459123624335929121824
65601236253360210132224
6661123784461210171821
6762123794362211122021
68631237104363214152425
69641237113364346711
70651237123365348910
7166123713436634121315
7267123714436734141721
7368123715336834162325
74691237163369356818
757012371733703571516
767112371833713591117
7772123719337235101219
7873123720337335131422
7974123721337436131719
8075123722337536142024
817612372333763781920
8277123724337737122122
8378123725337837171824
847912389337938132125
8580123810338038152223
8681123811438139131820
87821238124382310112022
88831238133383310141823
89841238144384311122425
908512381533854561723
91861238163386457821
928712381743874591214
9388123818338845101124
9489123819338945131619
9590123820339045151820
969112382133914681924
9792123822339246121821
Sheet Lottery-Test
Cell Formulas
RangeFormula
H3H3=MAX(MMULT(COUNTIF(B6:F6,K$6:O$97),{1;1;1;1;1}))
K4:O4,B4:F4B4=COUNTA(B6:B97)
Q5,Q15Q5=SUM(Q6:Q11)
Q6:Q11Q6=COUNTIF(H$6:H$97,P6)
Q16:Q21Q16=COUNTIF(I$6:I$97,P16)
Press CTRL+SHIFT+ENTER to enter array formulas.


Regards,
Moti
 
Last edited:
Upvote 0
I assume the logic is exactly the same as for the 14 columns right ?
Can you post the whole sheet using Dropbox, Google drive, OneDrive ... and make sure anyone with the link can access it.
.
For item 22 on the left you are saying you get 4 while my macro is returning 3 but I can find nothing in the right hand side that would give you 4

PS: I am signing off for the night

1708174216433.png
 
Upvote 0
Try this code.
I avoided unnecessary Trail of matchings. It is assumed as given in file that in both tables in each row numbe.rs are in ascending order.
VBA Code:
Sub VBA_MultiLotteryChecker()
    
    Range("H6:H53135").ClearContents
    
    Dim startTime As Double
    Dim MinutesElapsed As String
    startTime = Timer
    
Dim a, b, c
Dim i As Long, j As Long, k As Long, n As Long, Lr As Long, l As Long
Dim xmax As Long, Z As Long

Application.ScreenUpdating = False

Lr = Cells(Rows.Count, "B").End(xlUp).Row
a = Range("B6:H" & Lr)
ReDim c(1 To Lr)
Lr = Cells(Rows.Count, "K").End(xlUp).Row
b = Range("K6:O" & Lr)

For i = 1 To UBound(a, 1)
    xmax = 0
    For j = 1 To UBound(b, 1)
        n = 0: Z = 1
        For k = 1 To 5
            For l = Z To 5
                If a(i, k) = b(j, l) Then
                    n = n + 1: Z = l
                    Exit For
                ElseIf a(i, k) < b(j, l) Then
                    Z = l: Exit For
                End If
            Next l
        Next k
          
           If n > xmax Then
                xmax = n
            End If

        Next j
    
    c(i) = xmax
Next i

[H6].Resize(UBound(c, 1), 1) = Application.Transpose(c)

Application.ScreenUpdating = True

   MinutesElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
   MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation

End Sub
 
Upvote 1
Try this code.
I avoided unnecessary Trail of matchings. It is assumed as given in file that in both tables in each row numbe.rs are in ascending order.
Hello kvsrinivasamurthy, respect to code post#1, your code finishes 25 second early, within 00:02:05 minutes. It is better, but I wonder could it be faster?

Thank you for your help.

Kind Regards,
Moti
 
Upvote 0
I assume the logic is exactly the same as for the 14 columns right ?
Can you post the whole sheet using Dropbox, Google drive, OneDrive ... and make sure anyone with the link can access it.
.
For item 22 on the left you are saying you get 4 while my macro is returning 3 but I can find nothing in the right hand side that would give you 4

PS: I am signing off for the night

View attachment 107016
Hello Alex Blakenburg, i have uploaded whole file using Dropbox here is the link below hope you can down load it. Column G has the result by Formula and column H result by VBA which take 00:02:30 Minutes

VBA Multi Lottery Checker.xlsm

I am not expert but I guess previous VBA check 14 columns against 14 columns but in serial for example 1-X-2 if in other side is 1-2-X this is one match only 1 to 1, X to 2 not match, 2 To X also does not match.

But this may is different also noticed this check only numbers, other has text and numbers. may i am wrong.

Have a good weekend

Regards,
Moti
 
Upvote 0
On my machine with your sample workbook the time reduced from 2:53 using the code in the workbook to 0:16 using the code below.
That is a significant reduction however I am not sure that your sample workbook is indicative of actual data since the 'Results' section appears to be multiple copies of the same set of 148 results. Therefore I don't expect my code to be as much faster on real data, though there are a few minor speed enhancements in it. Anyway, you can give it a try.

VBA Code:
Sub VBA_MultiLotteryChecker_v2()
  Dim startTime As Double
  Dim MinutesElapsed As String
  startTime = Timer
      
  Dim d As Object
  Dim s As String
  Dim a, b, c
  Dim i As Long, j As Long, k As Long, n As Long, Lr As Long, x As Long
  Dim xmax As Long, startcol As Long
  
  Set d = CreateObject("Scripting.Dictionary")
  Application.ScreenUpdating = False
  Range("H6:H53135").ClearContents
  Lr = Cells(Rows.Count, "B").End(xlUp).row
  a = Range("B6:F" & Lr)
  
  Lr = Cells(Rows.Count, "K").End(xlUp).row
  b = Range("K6:O" & Lr)

  For i = 1 To UBound(b)
    s = Join(Application.Index(b, i, 0), "|")
    If Not d.exists(s) Then d(s) = i
  Next i
  b = Application.Index(b, Application.Transpose(d.Items), Array(1, 2, 3, 4, 5))
  ReDim c(1 To UBound(a), 1 To 1)
  For i = 1 To UBound(a, 1)
    xmax = 0
    For j = 1 To UBound(b, 1)
      n = 0
      startcol = 1
      For k = 1 To 5
        For x = startcol To 5
          If a(i, k) = b(j, x) Then
            n = n + 1
            startcol = x + 1
            Exit For
          End If
        Next x
      Next k
      If n > xmax Then xmax = n
    Next j
    c(i, 1) = xmax
  Next i
  Range("H6").Resize(UBound(c), 1).Value = c
  Application.ScreenUpdating = True

  MinutesElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
  MsgBox "This code ran successfully in " & MinutesElapsed & " minutes", vbInformation
End Sub
 
Upvote 1
In the sample data the numbers in the rows are sorted in ascending order, if this can be relied on then the below modification of Peter's code might take a little bit more off the time.

VBA Code:
Sub VBA_MultiLotteryChecker_v2_PeterMod()
  Dim startTime As Double
  Dim MinutesElapsed As String
  startTime = Timer
      
  Dim d As Object
  Dim s As String
  Dim a, b, c
  Dim i As Long, j As Long, k As Long, n As Long, Lr As Long, x As Long
  Dim xmax As Long, startcol As Long
  Dim m As Long
  
  Set d = CreateObject("Scripting.Dictionary")
  Application.ScreenUpdating = False
  Lr = Cells(Rows.Count, "H").End(xlUp).Row
  Range("H6:H" & Lr).ClearContents
  Lr = Cells(Rows.Count, "B").End(xlUp).Row
  a = Range("B6:F" & Lr)
  Dim maxcols As Long
  maxcols = UBound(a, 2)
  
  Lr = Cells(Rows.Count, "K").End(xlUp).Row
  b = Range("K6:O" & Lr)

  For i = 1 To UBound(b)
    s = ""
    For m = 1 To maxcols
        s = s & "|" & b(i, m)
    Next m
    s = Right(s, Len(s) - 1)    
    If Not d.exists(s) Then d(s) = i
  Next i
  b = Application.Index(b, Application.Transpose(d.Items), Array(1, 2, 3, 4, 5))
  ReDim c(1 To UBound(a), 1 To 1)
  For i = 1 To UBound(a, 1)
    xmax = 0
    ' Check if exact result exists - assumes both rows are sorted in ascending order
    s = ""
    For m = 1 To maxcols
        s = s & "|" & a(i, m)
    Next m
    s = Right(s, Len(s) - 1)
    If d.exists(s) Then
        xmax = maxcols
    Else
        
        For j = 1 To UBound(b, 1)
          n = 0
          startcol = 1
          For k = 1 To 5
            For x = startcol To 5
              If a(i, k) = b(j, x) Then
                n = n + 1
                startcol = x + 1
                Exit For
              End If
            Next x
          Next k
          If n > xmax Then xmax = n
          ' Since we have checked for a 5 max then next possible is 4
          If xmax = 4 Then Exit For
        Next j
    End If
    c(i, 1) = xmax
  Next i
  Range("H6").Resize(UBound(c), 1).Value = c
  Application.ScreenUpdating = True

  MinutesElapsed = Format((Timer - startTime) / 86400, "hh:mm:ss")
  MsgBox "AB This code ran successfully in " & MinutesElapsed & " minutes", vbInformation
End Sub
 
Upvote 1
In the sample data the numbers in the rows are sorted in ascending order, if this can be relied on then the below modification of Peter's code might take a little bit more off the time.
Hi Alex, Yes that could be marginally faster, depending on the results section contents.
BTW,
  • My code was already dependant on both sets of data having each row in ascending order
  • The difference would be minimal but I don't think there is any need to strip the first "|" off s is there?
    If there is, then simpler than s = Right(s, Len(s) - 1) would be s = Mid(s, 2)
 
Upvote 0

Forum statistics

Threads
1,215,128
Messages
6,123,206
Members
449,090
Latest member
bes000

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top