lundi 19 septembre 2022

VBA - Generate random number only to 3 digits with Norm_inv OR ptimize the function

I wrote a macro for generate random number from sample. The RNG core is:

For i = 6 To LR

Set row = RANGE(Cells(i, 8), Cells(i, LC))

prumer = Application.Average(row)
smodch = Application.stdev(row)

    
    For A = B To LCNEW
       Cells(i, A).Value = Application.Norm_Inv(Rnd(), prumer, smodch)
       Cells(i, A).Value = Application.ROUND(Cells(i, A).Value, 3)
       Cells(i, A).NumberFormat = "0.000"
    Next A
    
Next i
 

It takes a row, calculate average and stdev and then do the stuff.

But on my computer it runs very quick (like 5-10 sec for 80 rows with 10 numbers and calculating 100 more randomized) - and on older computer it runs like 5 minutes! Can I somehow calculete norm inv only to 3 digits? Or optimalize it more?

The whole code is:

Sub RNGTOX()

   Dim lastcell As RANGE
   Dim row As RANGE
   Dim i As Long
   Dim A As Long
   Dim B As Long
   Dim prumer As Variant
   Dim smodch As Variant
   Dim LR As Long
   Dim LC As Long
   Dim ocislovani As RANGE
   Dim sSIDE As Worksheet
        
 If RANGE("H6").Value = vbNullString Then
 MsgBox "Chybí data."
 Exit Sub
 End If
            
Application.ScreenUpdating = False
     
Set sSIDE = ActiveSheet
Set lastcell = ActiveSheet.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious)

LR = Cells(Rows.count, 1).End(xlUp).row
LC = Cells(6, Columns.count).End(xlToLeft).Column
B = LC + 1
LCNEW = RANGE("B2").Value + 7

If LCNEW <= LC Then
MsgBox "Počet už je dosažený. Není třeba dopočítávat."
Exit Sub
Else
End If

'ocislovani souboru
Set ocislovani = sSIDE.RANGE(sSIDE.Cells(5, 8), sSIDE.Cells(5, LCNEW))

counter_cisla = 1
For Each cell_a In ocislovani
cell_a.Value = counter_cisla
counter_cisla = counter_cisla + 1
Next cell_a


'i radek, A sloupec
For i = 6 To LR

Set row = RANGE(Cells(i, 8), Cells(i, LC))

prumer = Application.Average(row)
smodch = Application.stdev(row)

    
    For A = B To LCNEW
       Cells(i, A).Value = Application.Norm_Inv(Rnd(), prumer, smodch)
       Cells(i, A).Value = Application.ROUND(Cells(i, A).Value, 3)
       Cells(i, A).NumberFormat = "0.000"
    Next A
    
Next i


RANGE("H6").Select
       
Application.ScreenUpdating = True


End Sub




Aucun commentaire:

Enregistrer un commentaire