Converting a macro to UDF

excelNewbie22

Well-known Member
Joined
Aug 4, 2021
Messages
528
Office Version
  1. 365
Platform
  1. Windows
HI!
can anyone help with adding/'converting' the following macro into UDF?
sample:
Excel Formula:
=GenComb(a1:z1,6)
and if possible adding these functions:
a-ignoring blank cells in the range
b-setting the range as vertical or horizontal
c-counta the all column in the header/title
d-increase the range over 32 numbers by allowing the results to split into 2 columns

VBA Code:
Option Explicit
'by JohnnyL from mrexcel.com
' Inspired by some previous code from pgc01 https://www.mrexcel.com/board/threads/combination-help.277924/post-1379220

Sub AllCombinationsV2()
'
    Dim StartTime                   As Double
    StartTime = Timer                                                                                               ' Start the stop watch
'
    Dim ArrayRow                    As Long
    Dim DrawAmount                  As Long, TotalCombinations      As Long
    Dim OutputRow                   As Long
    Dim PoolSize                    As Long
    Dim NumbersPoolRange            As Range
    Dim OutputColumn                As String
    Dim OutputHeader                As String
    Dim NumbersDrawnArray           As Variant, NumbersPoolArray    As Variant, OutputArray     As Variant
'
    Set NumbersPoolRange = Range("cn1:dl1")             ' <--- Set this to the range of the pool #s to use
    DrawAmount = "6"                                  ' <--- set the amount of #s to pick in this cell
    OutputColumn = "bd"                               ' <--- Set this to the column letter that you want to display results to
    OutputRow = 2                                     ' <--- Set this to the row # to start displaying the combinations
   
    ' ----- Modification
    Dim NumbersPoolArrayTemp As Variant
    Dim iPoolArray As Long
    NumbersPoolArrayTemp = NumbersPoolRange
    ReDim NumbersPoolArray(1 To 1, 1 To UBound(NumbersPoolArrayTemp, 2))
    For iPoolArray = 1 To UBound(NumbersPoolArrayTemp, 2)
        If NumbersPoolArrayTemp(1, iPoolArray) <> "" Then
            PoolSize = PoolSize + 1
            NumbersPoolArray(1, PoolSize) = NumbersPoolArrayTemp(1, iPoolArray)
        End If
    Next iPoolArray
'    PoolSize = NumbersPoolRange.Columns.Count         ' Get the amount of numbers in the pool - replaced by counter
    OutputHeader = DrawAmount & " of " & PoolSize                                                                ' <--- Set this to the header for the output column
'
    Application.ScreenUpdating = False                                                                             ' Turn screen updationg off
'
    TotalCombinations = Application.WorksheetFunction.Combin(PoolSize, DrawAmount)                    ' Get total # of combinations that will be produced
'
    ReDim Preserve NumbersPoolArray(1 To 1, 1 To PoolSize)
' ----- End of modification
    'Range("A3").Value = "Total # of combinations"                                                                   ' Display header of 'Total # of combinations'
    'Range("aa1").Value = TotalCombinations                                                                           ' Display # of combinations that will be generated
'
    ReDim NumbersDrawnArray(1 To DrawAmount)                                                                       ' Establish size of 1D one based NumbersDrawnArray
    ReDim OutputArray(1 To TotalCombinations, 1 To DrawAmount)                                                      ' Establish size of 2D one based OutputArray
'
    Call GetAllCombinations(NumbersPoolArray, DrawAmount, NumbersDrawnArray, ArrayRow, OutputArray, 1, 1)           ' Calculate the Combinations
'
    Range(OutputColumn & OutputRow - 1).Value = OutputHeader                                                        ' Display output header
    Range(OutputColumn & OutputRow).Resize(TotalCombinations, 1).Value = OutputArray                                ' Display results to sheet
'
    ActiveSheet.UsedRange.EntireColumn.AutoFit                                                                     ' Autofit all column widths on the sheett
'
    Application.ScreenUpdating = True                                                                               ' Turn screen updationg back on
'
    'Debug.Print TotalCombinations & " combinations completed in " & Timer - StartTime & " seconds."                 ' Display the completion time in the 'Immediate' window ... CTRL+G in the VBE window
    'MsgBox TotalCombinations & " combinations completed in " & Timer - StartTime & " seconds."                      ' Display the combination count & time to complete to the user
End Sub

Sub GetAllCombinations(ByVal NumbersPoolArray As Variant, ByVal DrawAmount As Long, ByVal NumbersDrawnArray As Variant, _
        ByRef ArrayRow As Long, ByRef OutputArray As Variant, ByVal NumbersPoolColumn As Long, ByVal DrawNumber As Long)
'
    Dim ArrayColumn         As Long
'
    For NumbersPoolColumn = NumbersPoolColumn To UBound(NumbersPoolArray, 2)                                        ' Loop through the NumbersPoolArray columns
        NumbersDrawnArray(DrawNumber) = NumbersPoolArray(1, NumbersPoolColumn)                                      '   Save NumbersPoolArray(1, NumbersPoolColumn) value to NumbersDrawnArray(DrawNumber)
'
        If DrawNumber = DrawAmount Then                                                                             '   If last DrawNumber of DrawAmount has been reached then ...
            ArrayRow = ArrayRow + 1                                                                                 '       Increment ArrayRow
'
            For ArrayColumn = 1 To DrawAmount                                                                       '       Loop through NumbersDrawnArray columns
                OutputArray(ArrayRow, 1) = OutputArray(ArrayRow, 1) & NumbersDrawnArray(ArrayColumn) & "-"          '           Save NumbersDrawnArray column value & delimiter to OutputArray
            Next                                                                                                   '       Loop back
'
            OutputArray(ArrayRow, 1) = Left$(OutputArray(ArrayRow, 1), Len(OutputArray(ArrayRow, 1)) - 1)           '       Remove the last delimiter '-' from the OutputArray string
        Else                                                                                                        '   Else ...
            Call GetAllCombinations(NumbersPoolArray, DrawAmount, NumbersDrawnArray, ArrayRow, _
                    OutputArray, NumbersPoolColumn + 1, DrawNumber + 1)                                             '       Recursive loop to get next value of NumbersDrawnArray
        End If
    Next                                                                                                            ' Loop back
End Sub
 

Excel Facts

How to find 2nd largest value in a column?
MAX finds the largest value. =LARGE(A:A,2) will find the second largest. =SMALL(A:A,3) will find the third smallest

Forum statistics

Threads
1,223,227
Messages
6,170,848
Members
452,361
Latest member
d3ad3y3

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