Excel Forum Per condividere esperienze su Microsoft Excel

[RISOLTO] Velocizzare elaborazione VBA

  • Messaggi
  • OFFLINE
    Marius44
    Post: 1.228
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 03/03/2024 22:44
    Buona sera a tutti
    Ho continuato a fare prove di velocità e, ad un certo punto, mi sono ricordato di un lavoro di un amico ed ho provato ad adattarlo alle mie esigenze. Poichè il codice originale era per me abbastanza criptico ho chiesto umilmente aiuto all'amico (che tutti conoscete - Anthony47). Non si è tirato indietro ed alla mia richiesta ha risposta con qualcosa di sbalorditivo. Posto il codice ed allego il file con le "nostre" prove coi relativi tempi di esecuzione e col tempo segnato dalla macro dell'Amico che pubblicamente ringrazio per la condivisione.
    Sub ContaAmbi() 'byAnthony47 - pulsante 4
    Dim oArr(1 To 4005, 1 To 3), iArr(1 To 90, 1 To 90) As Integer, iInd As Integer
    Dim wArr, rArr, i As Long, j As Long, K As Long, a As Long
    Dim dSh As Worksheet, oSh As Worksheet, dePos As Range
    Dim iTime As Single
    '
    Set dSh = Sheets("Foglio2")
    Set oSh = Sheets("Foglio1")
    Set dePos = oSh.Range("P3")             '<<< La posizione di output
    '
    dePos.Resize(4005, 3).ClearContents
    iTime = Timer
    wArr = Range(dSh.Range("B2"), dSh.Range("B2").End(xlDown).Offset(0, 5)).Value
    'crea 4005 ambi canonici e pointer
    For i = 1 To 89
      For j = i + 1 To 90
        a = a + 1
        oArr(a, 1) = i: oArr(a, 2) = j
        iInd = iInd + 1
        iArr(i, j) = iInd
      Next j
    Next i
    'inizia ciclo ricerca-confronto ambi
    For i = 1 To UBound(wArr)
      For j = 1 To 5
        For K = j + 1 To 6
          oArr(iArr(wArr(i, j), wArr(i, K)), 3) = oArr(iArr(wArr(i, j), wArr(i, K)), 3) + 1
        Next K
      Next j
    Next i
    '
    dePos.Resize(4005, 3) = oArr
    dePos.Offset(-1, 3) = (Timer - iTime)
    Set dSh = Nothing
    Set oSh = Nothing
    Set dePos = Nothing
    End Sub
    

    Un grazie a tutti per la partecipazione e spero che il codice di Anthony sia gradito e possa agire da spunto per altre soluzioni.
    Ancora una buona serata,
    Mario
  • OFFLINE
    federico460
    Post: 3.276
    Registrato il: 10/10/2013
    Città: VICENZA
    Età: 69
    Utente Master
    365
    00 04/03/2024 00:09
    ciao
    Fulvio
    ho spiato e archiviato

    il file di MARIUS👋
    mai si sa.

    per la moda
    metti questa dove vuoi
    e tirala a destra di una cella ....e in basso
    =SE.ERRORE(INDICE(P$3:P$10000;AGGREGA(15;6;RIF.RIGA($1:$10000)/($R$3:$R$10000=MODA($R$3:$R$10000));RIF.RIGA(A1)));"")

    con il 365
    =FILTRO($P$3:$Q$10000;$R$3:$R$10000=MODA($R$3:$R$10000);"")
    

    magari falla con il vba
    verrebbe carino visto le righe che di solito usate per il lotto
    [Modificato da by sal 12/03/2024 15:44]
  • OFFLINE
    Marius44
    Post: 1.229
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 04/03/2024 09:35
    Ciao

    @federico460
    Non è che il precedente post andava in un'altra discussione?

    Aspetto sempre di sentire i pareri degli amici che hanno partecipato a questa discussione circa l'ultima macro.
    Ciao,
    Mario
  • OFFLINE
    federico460
    Post: 3.277
    Registrato il: 10/10/2013
    Città: VICENZA
    Età: 69
    Utente Master
    365
    00 04/03/2024 09:44
    ciao
    Marius scusami
    so che che è OT
    ma inerente ad una domanda fattami sulla MODA di ambi da Fulvio
    discutendo sul più e del meno.
    Il tuo file è capitato a fagiolo per un esempio.

    Io non ho file di lotto/enalotto salvati visto che il mio
    sistema è il classico.....c...lo...quelle rare volte
    che gioco al superenalotto
  • OFFLINE
    L2018
    Post: 1.192
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 09:51
    Ciao Mario
    ieri sera tardi ho visto il tuo post e subito salvato
    è davvero un lavoro pregevole e utile quello che hai fatto, ma la macro di Antony47 non la conoscevo, è veramente strabiliante.
    lanciata già diverse volte devo riuscire a capire dove prende la velocità, 4-5 centesimi di secondo sulla mia macchina.
    (Lo dico sempre, io, dentro di me, che le parole-chiave bisogna conoscerle, ma un ottimo algoritmo è fondamentale).
    Se ti è possibile, con calma, mi piacerebbe una semplice illustrazione passo-passo dell'algoritmo seguito.
    in parte lo seguo, in altri punti dovresti dirmi tu il trucco che realizza.
    Dico questo perchè io ogni tanto cito il PowerBasic, e sarei tentato di fare qualcosa di simile, sia per vedere cosa fa il Basic a parità di algoritmo, sia per vedere se concepisco io stesso qualcosa di furbesco.
    Nella tua macro i tasti P1 e P3 fanno i capricci, se li clicco preferiscono mostrare l'immagine del bottone piuttosto che lanciare le rispettive routines.
    Complimenti Mario !
    P.S.
    Uso spesso il tuo file che rileva i singoli, ambi e terni e relative vincite, e continuo a notare la sua semplicità e assoluta fluidità
    Grazie ancora
    [Modificato da L2018 04/03/2024 09:54]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.193
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 09:57
    Re:
    federico460, 04/03/2024 09:44:

    ciao
    Marius scusami
    so che che è OT
    ma inerente ad una domanda fattami sulla MODA di ambi da Fulvio
    discutendo sul più e del meno.
    Il tuo file è capitato a fagiolo per un esempio.



    Ciao Federico
    forse volevi dire
    una domanda sulla MODA di ambi fatta(ti) da LEO ?

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.230
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 04/03/2024 10:16
    Salve
    Nella foga dell'invio (hai ragione! la macro di Anthony47 è strabiliante) mi sono dimenticato di associare il codice ai rispettivi pulsanti. Comunque accanto al nome della macro vi è indicato il pulsante a cui associarla (per favore provvedete voi).

    Come detto la macro non è mia ed anch'io sono andato a tentativi per capire come funziona e mi sono convinto di una cosa: mentre noi andavamo a fare confronti per ogni singolo ambo Anthony47 fa un controllo con queste righe di codice:
    ....
    'inizia ciclo ricerca-confronto ambi
    For i = 1 To UBound(wArr)
      For j = 1 To 5
        For K = j + 1 To 6
          oArr(iArr(wArr(i, j), wArr(i, K)), 3) = oArr(iArr(wArr(i, j), wArr(i, K)), 3) + 1
        Next K
      Next j
    Next i
    ....
    

    Fa riferimento ad un array-indice (iArr). Credo proprio che il "trucco" stia li (ma sto ancora studiandola passo-passo)
    Ciao,
    Mario
  • OFFLINE
    federico460
    Post: 3.278
    Registrato il: 10/10/2013
    Città: VICENZA
    Età: 69
    Utente Master
    365
    00 04/03/2024 10:19
    ciao
    è inerente a

    Così come esiste la MODA di un singolo valore, si potrebbe congegnare, sempre con formula, la MODA di un ambo ?



    ma è quasi OT
  • OFFLINE
    L2018
    Post: 1.194
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 10:31
    Re:
    Mario, mi hai dato un'idea sulla possibile interpretazione della macro di Anthony
    Se il trucco sta nelle righe appena citate, la spiegazione sarebbe semplice
    l'algoritmo crea in memoria gli ambi e in memoria ci mette ANCHE le estrazioni, invece di andare a rilevarle una alla volta
    Se è così, ovviamente la velocità balza in su, ed è quello che da sempre faccio io in Basic
    Non leggo singoli dati, ma metto in memoria sia gli archivi che le tabelle di ogni cosa
    Anche per scrivere su file, prima creo velocemente una gigantesca stringa dei risultati, anche munita di separatori, poi la scrivo in un secondo su disco, anche per evitarne l'usura meccanica.
    Caspita
    P.S.
    Per fare un esempio lampante e che ho ben in mente mi rifaccio al Totocalcio di anni fa
    14 partite danno luogo a 4.782.969 stringhe colonnari ognuna della quali deve avere il ritorno carrello e il ritorno a capo
    per un totale di 76.527.504 bytes che io non mi sono mai sognato di far scrivere una alla volta, ANCHE per non usurare il disco.
    Quindi costruisco in RAM la stringa totale di 76 mega e alla fine la salvo su disco in un istante.
    tutta l'elaborazione in meno di un secondo, bello no ?
    ciao
    [Modificato da L2018 04/03/2024 11:14]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    by sal
    Post: 7.559
    Registrato il: 14/11/2004
    Utente Master
    Office 2019
    00 04/03/2024 15:53
    Ciao Conosco Antony e già mi ha dato qualche mano in altre situazioni, ho dato una scorsa veloce alla sua macro ma non so interpretare questa preparazione per il passaggio successivo

    'crea 4005 ambi canonici e pointer
    For i = 1 To 89
      For j = i + 1 To 90
        a = a + 1
        oArr(a, 1) = i: oArr(a, 2) = j
        iInd = iInd + 1
        iArr(i, j) = iInd
      Next j
    Next i


    l'elenco ambi già esiste perche ricrearlo ma poi in quel modo

    Ciao By Sal (8-D
    se ti piace la soluzione sostienici con una DONAZIONE a piacere. Grazie clicca qui
  • OFFLINE
    L2018
    Post: 1.197
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 16:33
    Re:
    by sal, 04/03/2024 15:53:



    'crea 4005 ambi canonici e pointer
    For i = 1 To 89
      For j = i + 1 To 90
        a = a + 1
        oArr(a, 1) = i: oArr(a, 2) = j
        iInd = iInd + 1
        iArr(i, j) = iInd
      Next j
    Next i


    l'elenco ambi già esiste perche ricrearlo ma poi in quel modo

    Ciao By Sal (8-D



    Sal, per me questo pezzo di codice non è difficile perchè in basic l'ho usato molte volte, nel senso che mi è venuto spontaneo crearlo.
    l'elenco degli ambi non esiste, non pre-esiste, lui lo crea come array (oarr(a,1))e (oarr(a,2)) (1°e 2° elemento dell'ambo)
    poi apre altro contatore iInd che avanza come il contatore A, e dice che l'indice di quell'ambo non è altro che il posto nello sviluppo.
    questo giochetto significa che io posso chiedere: qual'è l'ambo dell'indice 2345 ? e lui risponde per es. è il 3-24
    (ricordi quando io andavo cercando le combinazioni dalla posizione ? è la stessa cosa)
    ma guardando bene il codice si capisce che il contatore iInd è perfettamente inutile perchè uguale ad A, tanto che se lo togliamo la macro funziona benissimo (piccola sbavatura ridondante).

    Riepilogando:
    Una cosa è prendere gli ambi dal foglio (e non ci sono ancora)
    altra cosa è creare ambi, che ti si perdono mentre li maneggi
    altra cosa ancora è creare in memoria una tabella indicizzata, sempre disponibile ad ogni richiamo, in cui all'ambo corrisponde una posizione (A) e a una posizione (A) corrisponde un ambo.

    Adesso devo uscire un'oretta, ma al ritorno devo concentrarmi sul passaggio successivo, che è molto simile a certi ghirigori fatti da me in basic, ma siccome non li faccio da tempo, ne ho perso l'elasticità mnemonica.
    In pratica devo reinterpretare me stesso.
    Ottimo lavoro. Questo Anthony è davvero molto intelligente, non c'è dubbio.
    ciao
    [Modificato da L2018 12/03/2024 17:52]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.232
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 04/03/2024 17:59
    Buon pomeriggio a tutti
    Nell'attesa che Leo torni dalla sua passeggiata propongo il mio personale adattamento della macro di Anthony47 per i terni:
    Option Explicit
    
    'prova terni
    Sub ContaTerni() 'byAnthony47 revisione Marius44
    Dim oArr(1 To 117480, 1 To 4), iArr(1 To 90, 1 To 90, 1 To 90) As Long, iInd As Long
    Dim wArr, rArr, i As Long, j As Long, k As Long, a As Long, h As Long
    Dim dSh As Worksheet, oSh As Worksheet, dePos As Range
    Dim iTime As Single
    '
    Set dSh = Sheets("Foglio2")
    Set oSh = Sheets("Foglio1")
    Set dePos = oSh.Range("U3")             '<<< La posizione di output
    '
    dePos.Resize(117480, 4).ClearContents
    iTime = Timer
    wArr = Range(dSh.Range("B2"), dSh.Range("B2").End(xlDown).Offset(0, 5)).Value
    'crea 125580 ternii canonici e pointer
    For i = 1 To 88
      For j = i + 1 To 89
        For k = j + 1 To 90
          a = a + 1
          oArr(a, 1) = i: oArr(a, 2) = j: oArr(a, 3) = k
          iInd = iInd + 1
          iArr(i, j, k) = iInd
        Next k
      Next j
    Next i
    '
    'inizia ciclo ricerca-confronto terni
    For i = 1 To UBound(wArr)
      For j = 1 To 4
        For k = j + 1 To 5
          For h = k + 1 To 6
            oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) = oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) + 1
          Next h
        Next k
      Next j
    Next i
    '
    dePos.Resize(117480, 4) = oArr
    dePos.Offset(-1, 4) = (Timer - iTime)
    Set dSh = Nothing
    Set oSh = Nothing
    Set dePos = Nothing
    End Sub
    


    In meno di mezzo secondo si costruisce i 117mila e passa terni canonici, confronta le estrazioni e scrive quante volte è uscito un terno.
    Ragazzi, è fantastica.

    @bySal
    Come ha detto Leo, il mettere in memoria gli ambi o i terni fa guadagnare moltissimo nei tempi di confronto.

    Ciao a tutti,
    Mario

    PS - Potete inserirla nel precedente allegato e scriverà tutto dalla colonna U alla Y
  • OFFLINE
    L2018
    Post: 1.198
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 18:23
    ed eccomi al nocciolo della macro di Anthony, che è tutto nel 4° rigo

    Confronto
    'inizia ciclo ricerca-confronto ambi
    For i = 1 To UBound(wArr)
      For j = 1 To 5
        For K = j + 1 To 6
          oArr(iArr(wArr(i, j), wArr(i, K)), 3) = oArr(iArr(wArr(i, j), wArr(i, K)), 3) + 1
        Next K
      Next j
    Next i


    nella ricerca di J e K nell' archivio
    l'indice 3 (,3) dell'ambo oArr, dell' indice iArr dell'archivio wArr (se(i,j) = (i,K)) dev'essere aumentato di 1, che alla fine darà il numero delle uscite. tutto concentrato in un rigo concettoso. Ottimo
    -----------
    Grazie a Mario di cui ho intravisto l'adattamento ai terni, ma a cui chiederei se lo puo' adattare al lotto
    io ci ho provato eliminando il sesto estratto ma si è incagliato, dovrei riguardare meglio.

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.233
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 04/03/2024 18:55
    Ciao

    per @L2018 (Leo l'insaziabile 😁)
    Questa la macro dei terni "adattata" al gioco del lotto
    'prova terni per il Lotto
    
    'supponiamo che le estrazioni del lotto siano
    'le colonne dalla B alla F comprese di Foglio2
    
    Sub ContaTerniLotto()
    Dim oArr(1 To 117480, 1 To 4), iArr(1 To 90, 1 To 90, 1 To 90) As Long, iInd As Long
    Dim wArr, rArr, i As Long, j As Long, k As Long, a As Long, h As Long
    Dim dSh As Worksheet, oSh As Worksheet, dePos As Range
    Dim iTime As Single
    '
    Set dSh = Sheets("Foglio2")
    Set oSh = Sheets("Foglio1")
    Set dePos = oSh.Range("AA3")             '<<< La posizione di output
    '
    dePos.Resize(117480, 4).ClearContents
    iTime = Timer
    wArr = Range(dSh.Range("B2"), dSh.Range("B2").End(xlDown).Offset(0, 4)).Value
    'crea 117480 ternii canonici e pointer
    For i = 1 To 88
      For j = i + 1 To 89
        For k = j + 1 To 90
          a = a + 1
          oArr(a, 1) = i: oArr(a, 2) = j: oArr(a, 3) = k
          iInd = iInd + 1
          iArr(i, j, k) = iInd
        Next k
      Next j
    Next i
    '
    'inizia ciclo ricerca-confronto terni
    For i = 1 To UBound(wArr)
      For j = 1 To 3
        For k = j + 1 To 4
          For h = k + 1 To 5
            oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) = oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) + 1
          Next h
        Next k
      Next j
    Next i
    '
    dePos.Resize(117480, 4) = oArr
    dePos.Offset(-1, 4) = (Timer - iTime)
    Set dSh = Nothing
    Set oSh = Nothing
    Set dePos = Nothing
    End Sub
    

    Puoi provarla sullo stesso foglio perchè scriverà i risultati dalla col.AA in poi
    Ciao,
    Mario
  • OFFLINE
    L2018
    Post: 1.199
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 19:19
    Re:
    Marius44, 04/03/2024 18:55:

    Ciao

    per @L2018 (Leo l'insaziabile 😁)
    Questa la macro dei terni "adattata" al gioco del lotto
    Puoi provarla sullo stesso foglio perchè scriverà i risultati dalla col.AA in poi
    Ciao,Mario



    Hai detto bene, insaziabile
    Se ho 10 perchè non posso avere 15 ? ecc.
    poi vado a vedere il tuo lotto
    Intanto:
    i terni all'ena e lotto sono 117480
    nella macro la variabile iInd è inutile
    siccome difficilmente i terni sono usciti tutti, specialmente all' Enalotto, a che serve costruirli tutti ? e soprattutto a che serve elencarli tutti per poi dover scorrere e vedere tanti terni con frequenza 0 ?
    Ecco allora che alla "semplice" condizione di ordinare le estrazioni in modo crescente sulla riga si puo' evitare del tutto la costruzione dei terni, perchè ?
    Perchè la macro, quando va a leggere l'archivio, troverebbe gli estratti in modo crescente univoco, per cui basterebbe dire che una qualsiasi combinazione "A minore B minore C" dovrà incrementare per forza SOLO il 4° indice del terno A minore B minore C (l'indice delle frequenze), senza preoccuparsi di altro, anche se il terno non era stato costruito.
    Cioè la tabella dei terni viene costruita cammin facendo solo per i terni usciti
    Ne deriva che quelli NON usciti non li vogliamo neppure vedere.
    Basta dimensionare bene le variabili.
    E come saremmo messi a tempi di elaborazione?
    Semplice no ? la chiameremmo Revisione Leo
    purtroppo io ne so poco di VBA.
    Ciao
    [Modificato da L2018 04/03/2024 19:25]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.200
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 22:19
    Ciao Mario
    quando io dico lotto in realtà mi riferisco al Millionday, per cui ho adattato la tua macro all'uopo, tenendo conto di tutto quanto serve, compresi i terni che a questo gioco sono 26235.
    Poi, siccome non vedo affatto la necessità di 2 fogli per 4 dati pazzi, ho cercato di usare un solo foglio, ma mi dà un errore che non riesco a scovare.
    Ti mando il file, ti senti di dare uno sguardo ? dev'essere un'inezia che mi sfugge
    scusami
    grazie dall'insaziabile

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.234
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 04/03/2024 23:00
    Ciao
    Ho notato che nelle mie elaborazioni i numeri estratti vanno dal più piccolo al più grande da sinistra verso destra.
    Ho inserito questa formula ì: J1 =PICCOLO($A1:$E1;RIF.COLONNA(A1))
    che ho copiato a destra fino a N1 e poi tutto l'intervallo fino alla fine.
    Quindi ho modificato la tua macro così:
    Sub Leo_2()
    Dim oArr(1 To 26235, 1 To 4), iArr(1 To 55, 1 To 55, 1 To 55) As Long, iInd As Long
    Dim wArr, rArr, i As Long, j As Long, k As Long, a As Long, h As Long
    Dim dSh As Worksheet, oSh As Worksheet, dePos As Range
    Dim iTime As Single
    
    Set oSh = Sheets("Foglio1")
    Set dePos = oSh.Range("P1")             '<<< La posizione di output
    '
    dePos.Resize(26235, 4).ClearContents
    iTime = Timer
    wArr = Range(oSh.Range("J1"), oSh.Range("J1").End(xlDown).Offset(0, 5)).Value
    
    'crea 26235 terni canonici e pointer
    For i = 1 To 53
      For j = i + 1 To 54
        For k = j + 1 To 55
          a = a + 1
          oArr(a, 1) = i: oArr(a, 2) = j: oArr(a, 3) = k
          iInd = iInd + 1
          iArr(i, j, k) = iInd
        Next k
      Next j
    Next i
    'inizia ciclo ricerca-confronto terni
    For i = 1 To UBound(wArr)
      For j = 1 To 3
        For k = j + 1 To 4
          For h = k + 1 To 5
            oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) = oArr(iArr(wArr(i, j), wArr(i, k), wArr(i, h)), 4) + 1
          Next h
        Next k
      Next j
    Next i
    
    dePos.Resize(26235, 4) = oArr
    dePos.Offset(0, 5) = (Timer - iTime)
    Set oSh = Nothing
    Set dePos = Nothing
    End Sub
    
    

    Impiega (col mio PC) poco meno di 0.9 sec.
    Bada che scrive da P1 a destra per 4 colonne

    Buona notte,
    Mario
  • OFFLINE
    L2018
    Post: 1.201
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 04/03/2024 23:02
    eh grazie, ma se la mia già non andava....?

    Buonanotte....
    [Modificato da L2018 04/03/2024 23:41]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.207
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 06/03/2024 17:00
    Buon pomeriggio
    mi riferisco a Mario che ha aperto questa bella discussione, ma anche a chiunque sia interessato al problemino trattato.
    nell'ottica della velocizzazione dell'algoritmo di cui si parla vorrei chiedere Mario se per caso abbia approfondito ulteriormente.
    più precisamente mi riferisco al post #45, in cui ho accennato a qualcosa che ora credo di completare.
    mi riferisco anche all'ottima macro di Anthony per il Lotto, e nel mio caso per il Millionday
    Ho preso la macro riadattata da Mario, trasformato da lotto(90 numeri) a millionday (55 numeri), inserito l'archivio relativo, senza date perchè non capisco a cosa servano, ho radunato tutto in Foglio 1 perchè non capisco a cosa servano 2 fogli avendo 1 miliardo di colonne in Foglio1, ho tolto le intestazioni perchè sono ovvie, ho cambiato nome a 3 variabili, per non confondermi, e ho anche ordinato orizzontalmente le estrazioni, perchè diversamente davano errore.
    Insomma tutto chiaro e pulito.

    Il mio scopo in questi giorni era di verificare se fosse possibile velocizzare ulteriormente la macro.
    Non ci sono ancora riuscito per mancanza di calma e concentrazione ma soprattutto perchè non essendo pratico di VBA, ho incontrato 1 o 2 costrutti che non riesco ancora a fare miei.
    da una prova fatta spostando il timer ho visto che la costruzione dei terni richiede tempo trascurabile, il poco tempo necessario si riferisce al confronto dei terni con l'archivio.

    Ma qui faccio cascare l'asino:
    in questa routine il tempo si perde perché vengono scritti fisicamente tutti i 26235 terni, (117480 con 90 numeri) elencandoli tutti, compresi quelli mai usciti.
    Ma è ovvio che un archivio di 2219 estrazioni = 22190 terni non potrà mai contenere tutti i 26mila terni teorici, e questo a maggior ragione per lotto ed enalotto.
    io ne concludo che evidenziare terni non usciti faccia perdere tempo (se non ci fossero = non sono usciti)
    Poi....se io confronto i 26000 terni teorici con quelli usciti perdo altro tempo, e per predisporre questa cosa ne perdo ancora

    Allora dico:
    Senza costruire i terni teorici, non si potrebbe scorrere l'archivio prendendo atto di quelli usciti, giusto quelli, incrementando un contatore se se ne trovano 2 o più uguali ?
    su 22190 terni a tutt'oggi del Millionday e su 26235 terni teorici sono usciti esattamente 15005 di quelli teorici.
    quindi 15005 dei 26235 (57 %) e dei 22190 reali (67 %).
    questo conteggio basta o no per migliorare la macro di Anthony, cercando i toccare il minimo indispensabile ?
    qui ci sto provando ma qualche dettaglio mi sfugge del linguaggio VBA, e sono convinto che il risultato ci sarebbe.
    Qualcosa di equivalente io l'ho già fatta a suo tempo in Basic ma ora mi piace e apprezzo Excel che oltretutto mi tiene in contatto col Forum.

    Provo ad inviare il foglio, ben funzionante
    a sinistra archivio Million, poi la macro LEO1 (che parte con CTRL-M), e poi la macro LEO2 (che parte con CTRL N)
    Ragionateci sopra, anche io sto facendo qualcosa, VBA permettendomi.
    Grazie dell'attenzione, e scusate il comizio (qui siamo sotto elezioni).

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.235
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 06/03/2024 18:12
    Ciao
    Mi chiedo perchè imbarcarsi in qualcosa di assolutamente non facile per guadagnare qualche decimo di secondo!
    Seguendo il tuo "pippotto" (passami il termine 😁 ) bisognerebbe fare qualcosa del genere:
    1) ciclo che scansiona ogni riga
    2) crea i vari terni della riga (8, se non erro)
    3) confronta ogni terno coi precedenti
    4) se trova riscontro, incrementa l'indice di quel terno
    5) se non trova riscontro, crea l'indice e lo pone pari a 1
    ricomincia dal punto 2

    Premesso che non so se sia fattibile (in teoria si, ma in pratica ....) ho l'impressione che, pur eliminando la frazione per creare tutti i terni canonici, aumenterebbe il tempo invece di diminuirlo.

    Ciao,
    Mario
  • OFFLINE
    L2018
    Post: 1.208
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 06/03/2024 18:18
    Re:
    Marius44, 06/03/2024 18:12:

    Ciao
    Mi chiedo perchè imbarcarsi in qualcosa di assolutamente non facile per guadagnare qualche decimo di secondo!
    Seguendo il tuo "pippotto" (passami il termine 😁 ) bisognerebbe fare qualcosa del genere:
    1) ciclo che scansiona ogni riga
    2) crea i vari terni della riga (8, se non erro)
    3) confronta ogni terno coi precedenti
    4) se trova riscontro, incrementa l'indice di quel terno
    5) se non trova riscontro, crea l'indice e lo pone pari a 1
    ricomincia dal punto 2
    Premesso che non so se sia fattibile (in teoria si, ma in pratica ....) ho l'impressione che, pur eliminando la frazione per creare tutti i terni canonici, aumenterebbe il tempo invece di diminuirlo.
    Ciao,
    Mario



    se non sbaglio in molti sport si gioca proprio sui decimi di secondo
    Comunque io ci sto ancora riflettendo e onestamente penso che tu abbia ragione
    Ovviamente l'ipotesi si basava sulla speranza di guadagnare più di qualche decimo
    la creazione dei terni non occupa tempo, era il resto che io discutevo
    va be' mettiamoci l'animo in pace

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.209
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 08/03/2024 14:18
    Buongiorno
    in qualità di insaziabile proponente di "pippotti" ho il piacere di comunicare che sono riuscito a trasporre la famosa macro di Anthony47 in PowerBasic, dal momento che non mi era facile manomettere il suo VBA.
    E quindi a beneficio di chi fosse (ancora) interessato posso dire che tale macro VBA, sulla mia macchina I3, per esaminare 2221 estrazioni di Millionday per estrarne le frequenze dei terni, impiega circa 0,2 secondi in Excel.
    La stessa macro, trasposta in PowerBasic, appena appena ripulita di inezie, impiega dagli 1 a 2 millesimi di secondo, cioè circa 10 volte meno di Excel (ho messo i contatori solo a inizio e fine confronto per par condicio)
    il tempo si riferisce solo al confronto dei terni teorici con l'archivio.
    e questo la dice lunga sulla differenza tra Excel e PowerBasic.
    Inoltre avevo fatto un'obiezione per la quale mi chiedevo se fosse necessario evidenziare anche i terni NON usciti, ma questo "pippotto" non ancora ho la calma per farlo in Excel, mentre l'ho ampiamente realizzato in PowerBasic.
    Il fatto è che la costruzione dei terni teorici richiede tempo quasi 0, ma non avendo ancora potuto modificare la macro, non posso fare un paragone definitivamente preciso sull'ipotetico miglioramento che io possa aver apportato.
    Resta solo la differenza fondamentale fra Excel e altri linguaggi, ma lo sapevamo.
    Per non annoiarvi ancora pubblico solo l'immagine del mio risultato.

    Alla prossima
    [Modificato da L2018 08/03/2024 16:17]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.210
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    10 10/03/2024 10:14
    Buongiorno a tutti
    approfitto di questa giornata di poco traffico per riassumere quanto abbiamo già detto nei post precedenti
    sulla velocizzazione di un codice VBA

    la macro di Anthony47, postata e revisionata da Mario, è ottima, ed è fatta di tre parti:
    - creazione di Terni
    - confronto Terni-Archivio
    - elenco risultati
    il cronometro però è messo all'inizio e alla fine della macro, per cui rileva il tempo impiegato da tutta la procedura.

    costruire i Terni richiede un tempo trascurabile, qualche millisecondo
    Elencare i risultati richiede tempo variabile a seconda della quantità di dati
    Invece era utile conoscere il tempo impiegato dal solo confronto Terni-Archivio, per cui ho messo il cronometro
    appena all'inizio ed alla fine della routine.
    Il tempo per questa operazione è passato da circa un quarto di secondo a circa 20 millisecondi, oltre 10 volte di meno.

    Nella macro originale ho sostituito le variabili
    oArr( con Terno(
    iArr( con indice(
    wArr con archivio

    A questo punto mi sono dedicato alla routine di confronto, che sembrava inattaccabile, ho riflettuto a lungo sull'unica istruzione utile

    VB
    Terno(indice(archivio(i, j), archivio(i, k), archivio(i, h)), 4) = Terno(indice(archivio(i, j), archivio(i, k), archivio(i, h)), 4) + 1
    

    Per esperienza so che una uguaglianza costringe a rifare 2 volte lo stesso calcolo, anche se le 2 parti sono appunto uguali
    Quindi ho sostituito il rigo precedente con

    vb
    x = indice(archivio(i, j), archivio(i, k), archivio(i, h))
    Terno(x, 4) = Terno(x, 4) + 1
    

    ed ecco che finalmente il tempo del puro confronto è sceso da 20 millisecondi a 12-15 millisecondi, cioè il 20-30 % in meno, non è poco.
    e siccome nello stesso mio foglio excel, oltre all'archivio vedo entrambe le versioni della macro, ne deriva che non dico fesserie, anzi se si trattasse di grossi archivi le differenze sarebbero ben importanti.
    tutto quanto detto riguarda Excel, quindi fatte le debite proporzioni si ha che in Basic il tempo di esecuzione è mediamente di 1 millisecondo.
    Interessante no ?
    Più di così credo che non si possa fare.
    O meglio, avrei scovato ancora una cosa da verificare nell'operazione di confronto, ma per prudenza prima vedo se è vera, poi magari ne parliamo.
    ----------------------------------------
    Questa è tutta la macro per Millionday da me sistemata (facilmente adattabile a Lotto ed Enalotto):

    Macro
    Sub Leo_2()
    Dim Terno(1 To 26235, 1 To 4), indice(1 To 55, 1 To 55, 1 To 55) As Long
    Dim archivio, i As Long, j As Long, k As Long, a As Long, h As Long, x As Long
    Dim oSh As Worksheet, dePos As Range
    Dim iTime As Single, it As Single
    
    Set oSh = Sheets("Foglio1")
    Set dePos = oSh.Range("P1")             '<<< La posizione di output
    
    dePos.Resize(26235, 4).ClearContents
    archivio = Range(oSh.Range("A1"), oSh.Range("A1").End(xlDown).Offset(0, 5)).Value
    
    'crea 26235 terni canonici e pointer
    For i = 1 To 53
      For j = i + 1 To 54
        For k = j + 1 To 55
          a = a + 1
          Terno(a, 1) = i: Terno(a, 2) = j: Terno(a, 3) = k
          indice(i, j, k) = a
        Next k
      Next j
    Next i
    
    'ciclo ricerca-confronto terni
    iTime = Timer
    For i = 1 To UBound(archivio)
      For j = 1 To 3
        For k = j + 1 To 4
          For h = k + 1 To 5
          x = indice(archivio(i, j), archivio(i, k), archivio(i, h))
          Terno(x, 4) = Terno(x, 4) + 1
          Next h
        Next k
      Next j
    Next i
    
    it = Timer - iTime
    dePos.Resize(26235, 4) = Terno
    dePos.Offset(0, 5) = it
    Set oSh = Nothing
    Set dePos = Nothing
    End Sub
    
    -----------------
    qui sotto lo screenshot del risultato
    ---------------------------
    non riesco a capire per quale motivo da un po' di tempo gli screenshot, il codice VBA e alcune righe del post vanno fuori dei margini, cercheremo di provvedere
    [Modificato da L2018 10/03/2024 10:35]

    LEO
    https://t.me/LordBrum
  • OFFLINE
    L2018
    Post: 1.227
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 12/03/2024 20:26
    Ciao a tutti
    da giorni non vedo più reazioni o aggiornamenti in questa discussione.
    Forse è diminuito l'interesse, per cui mi limito a postare un piccolo omaggio, che consiste nell'aver raggruppato in un unico foglio 4 cose:
    un archivio di tipo Millionday di 2222 estrazioni, e 3 macro, con relativi pulsanti.
    la prima, di Anthony47, revisionata da Marius44, la seconda revisionata da me, che mi sono limitato a sostituire un rigo di codice con significativo risparmio di tempo, e la terza, in cui ho seguito un approccio diverso:
    non ho creato i cosiddetti terni canonici, ma ho semplicemente visitato l'archivio rilevando solo i terni presenti.
    Il tempo di confronto non è sostanzialmente diminuito rispetto alla seconda macro poichè non essendo pratico di VBA non ho potuto fare cambiamenti utili alla velocità.
    Per lo stesso motivo l'elenco dei terni conteggiati segue il metodo tradizionale banale, ma almeno mi consolo sapendo che non include i terni NON usciti.
    Qualche appassionato ci puo' mettere ancora le mani, sperando in un miglioramento ulteriore del tempo di elaborazione.
    Grazie ai partecipanti.


    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.236
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 20/03/2024 12:56
    Buon giorno a tutti.
    Qualche impegno mi ha tenuto lontano per qualche giorno. Contatti privati con L2018 han tenuto vivo il mio interesse per la questione velocità.
    Usufruendo della macro di Anthony47 (che non mi stancherò mai di ringraziare) e approfittando di un suggerimento di L2018 (un grazie di cuore anche a te) penso di aver ottenuto il massimo.
    Nell'allegato troverete un elenco di estrazioni (3734) di SuperEnalotto e la domanda era: quanti sono i terni che possono venir fuori da detto elenco, con quale frequenza sono stati estratti e, infine, quanti e quali sono quelli mai estratti.
    Cliccando sul pulsante "Mostra Terni" la macro impiega 0,796875 sec. per eseguire il lavoro. Meno di 8/10 di secondo! Stupefacente!
    I tempi parziali indicano qualcosa di insignificante per la creazione di tutti terni possibili coi 90 numeri (mi dà 0,000000 sec.), pochissimo per il confronto dei terni canonici con quelli rivenienti dall'elenco delle estrazioni (0,015625 sec.), stesso tempo per la suddivisione tra estratti e non estratti mentre la maggior parte (0,765625 sec.) la impiega per "scrivere" i dati sul foglio.
    Per coloro che volessero partecipare dico subito che la chicca sulla torta sarebbe un elenco discendente in base alla frequenza. Tale ordinamento impiega troppo tempo (col mio sistema) e, volutamente, l'ho tralasciato. Ma non è detto che non possa farsi.
    Questa la macro:
    Option Explicit
    
    Sub Unica()
    Dim Terno(1 To 117480, 1 To 4) As Long, indice(1 To 88, 1 To 89, 1 To 90) As Long
    Dim i As Long, j As Integer, k As Integer, h As Integer
    Dim a As Long, b As Long, x As Long
    Dim archivio, MAIUSCITI(1 To 117480, 1 To 3), ESTRATTI(1 To 117480, 1 To 4)
    Dim iT1 As Single, fT1 As Single
    
    Range("K2:R117481,I12:I15").ClearContents
    iT1 = Timer
    'crea 117480 terni canonici e pointer
    For i = 1 To 88
      For j = i + 1 To 89
        For k = j + 1 To 90
          a = a + 1
          Terno(a, 1) = i: Terno(a, 2) = j: Terno(a, 3) = k: Terno(a, 4) = 0
          indice(i, j, k) = a
        Next k
      Next j
    Next i
    fT1 = Timer
    Cells(12, 9) = fT1 - iT1
    iT1 = Timer
    archivio = Range(Range("A2"), Range("A2").End(xlDown).Offset(0, 5)).Value
    For i = 1 To UBound(archivio)
      For j = 1 To 4
        For k = j + 1 To 5
          For h = k + 1 To 6
            'velocizzazione by Leo
            x = indice(archivio(i, j), archivio(i, k), archivio(i, h))
            Terno(x, 4) = Terno(x, 4) + 1
          Next h
        Next k
      Next j
    Next i
    fT1 = Timer
    Cells(13, 9) = fT1 - iT1
    iT1 = Timer
    a = 0: b = 0
    For i = 1 To UBound(Terno)
      If Terno(i, 4) = 0 Then
        a = a + 1
        MAIUSCITI(a, 1) = Terno(i, 1)
        MAIUSCITI(a, 2) = Terno(i, 2)
        MAIUSCITI(a, 3) = Terno(i, 3)
      ElseIf Terno(i, 4) > 0 Then
        b = b + 1
        ESTRATTI(b, 1) = Terno(i, 1)
        ESTRATTI(b, 2) = Terno(i, 2)
        ESTRATTI(b, 3) = Terno(i, 3)
        ESTRATTI(b, 4) = Terno(i, 4)
      End If
    Next i
    fT1 = Timer
    Cells(14, 9) = fT1 - iT1
    iT1 = Timer
    Cells(2, 11).Resize(UBound(ESTRATTI), 4) = ESTRATTI
    Cells(2, 16).Resize(UBound(ESTRATTI), 3) = MAIUSCITI
    fT1 = Timer
    Cells(15, 9) = fT1 - iT1
    End Sub
    

    Ciao e mi aspetto i vostri interventi,
    Mario
  • OFFLINE
    L2018
    Post: 1.269
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 20/03/2024 14:25
    Re:
    Buongiorno
    Ehilà Mario, è un piacere rivederti qui in forma ufficiale col tuo prodotto che è innegabilmente ottimo da tutti i punti di vista, contenuto, prestazioni, impaginazione e precisione.
    Nella costruzione di programmi che usano i database io ritengo importantissima la velocità, perchè se tali programmi fossero destinati ad un uso intensivo e magari professionale, la differenza di pochi decimi di secondo su pochi dati diventerebbe insostenibile con grandi archivi.
    Ed è per questo che è molto apprezzabile che tu stesso abbia aperto questa discussione.
    Non mi soffermo sui dettagli, che abbiamo già discusso privatamente e sui quali vedremo cosa ci possa essere da completare.
    Solo una domanda: perchè hai eliminato la chicca delle frequenze discendenti ? mi pare che tu ce l'avessi o che io te l'avesi data, ma non fa niente, così ho il pretesto per postare anche la mia versione, che partendo anch' essa da Anthony47, e passando per te Mario, si completa con qualcosa di mio.
    Il file che mi accingo ad allegare è spartano e fa una sola operazione sugli stessi 3734 dati tuoi: mette tutti e solo i terni usciti dell'Enalotto in ordine di frequenza discendente.
    Oggettivamente è anche un po' più veloce, forse per certo tipo di mia cocciutaggine nel tentativo costante di migliorare gli algoritmi.

    Saluti

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.237
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 20/03/2024 15:05
    Ciao

    @L2018
    Leo, forse ti è sfuggito cosa ho scritto alla fine

    Per coloro che volessero partecipare dico subito che la chicca sulla torta sarebbe un elenco discendente in base alla frequenza. Tale ordinamento impiega troppo tempo (col mio sistema) e, volutamente, l'ho tralasciato. Ma non è detto che non possa farsi.



    Il tuo lavoro è velocissimo ma ... mostra solo la metà dei miei dati (😁). Dove sono i terni mai estratti?
    Ciao,
    Mario
  • OFFLINE
    L2018
    Post: 1.271
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 20/03/2024 15:12
    Re:
    Marius44, 20/03/2024 15:05:

    Ciao

    @L2018
    Leo, forse ti è sfuggito cosa ho scritto alla fine

    Per coloro che volessero partecipare dico subito che la chicca sulla torta sarebbe un elenco discendente in base alla frequenza. Tale ordinamento impiega troppo tempo (col mio sistema) e, volutamente, l'ho tralasciato. Ma non è detto che non possa farsi.



    Il tuo lavoro è velocissimo ma ... mostra solo la metà dei miei dati (😁). Dove sono i terni mai estratti?
    Ciao,
    Mario



    ahah, Mario, mi pareva di averlo già detto in altra occasione:
    mentre i terni usciti un VARIO NUMERO DI VOLTE necessitano di una differenziazione, quelli che non sono mai usciti...sono usciti SOLO 0 volte, e quindi dal mio punto di vista possono essere SOTTINTESI.
    Resta inteso che la mia velocità non LI riguarda, ma se li vuoi vedere cercherò di farli vedere, appena posso

    LEO
    https://t.me/LordBrum
  • OFFLINE
    Marius44
    Post: 1.238
    Registrato il: 24/06/2015
    Città: CATANIA
    Età: 80
    Utente Veteran
    Excel2019
    00 20/03/2024 17:26
    Ciao
    Come già detto, Leo è insaziabile
    La macro seguente mette in ordine discendente i terni (col tuo imprescindibile aiuto) in base alla frequenza.
    Ovviamente è leggermente più lenta della precedente (i tempi di esecuzione oscillano tra 0,70 e 1,2 sec. - e continuo a non capire il perchè di queste differenze) ma ritengo assolutamente accettabile vista la mole di lavoro che è costretta a fare.
    Option Explicit
    
    Sub Estratti_NonEstratti() 'commentata
    Dim indice(1 To 88, 1 To 89, 1 To 90, 99) As Long
    Dim archivio, i As Long, j As Long, k As Long, a As Long, h As Long
    Dim oSh As Worksheet, dePos As Range
    Dim iTime As Single, it As Single, ft As Single
    
    Set oSh = Sheets("Foglio2")             'Foglio in cui sono i dati d'archivio
    Set dePos = oSh.Range("K1")             'posizione di output
    
    'cancella precedenti
    Range("I12:I15,K:R").ClearContents
    
    Application.ScreenUpdating = False      'evita aggiornamento schermo
    iTime = Timer                           'start tempo
    'assegna a matrice i valori dell'archivio
    archivio = Range(oSh.Range("A2"), oSh.Range("A2").End(xlDown).Offset(0, 5)).Value
    'assegna alla matrice "indice" un determinato terno e la sua frequenza
    For i = 1 To UBound(archivio)
      For j = 1 To 4
        For k = j + 1 To 5
          For h = k + 1 To 6
            indice(archivio(i, j), archivio(i, k), archivio(i, h), 4) = indice(archivio(i, j), archivio(i, k), archivio(i, h), 4) + 1
          Next h
        Next k
      Next j
    Next i
    Cells(12, 9) = Timer - iTime               'tempo impiegato parte 1
    'visualizzazione provvisoria by Leo-Marius
    iTime = Timer
    Dim ur As Long, nt As Long
    nt = UBound(archivio) * 20
    ReDim scrivi(1 To nt, 1 To 4)
    a = 0
    For i = 99 To 1 Step -1
      For j = 1 To 88
        For k = j + 1 To 89
          For h = k + 1 To 90
            If indice(j, k, h, 4) = i Then
              a = a + 1
              scrivi(a, 1) = j: scrivi(a, 2) = k: scrivi(a, 3) = h: scrivi(a, 4) = i
            End If
          Next
        Next
      Next
    Next
    Cells(13, 9) = Timer - iTime
    iTime = Timer
    'elenco terni MAI usciti rispetto a quelli canonici(117480)
    Dim b As Long, dePos2 As Range
    Set dePos2 = oSh.Range("O1")
    ReDim NoTerno(1 To 117480 - a, 4)
      For j = 1 To 88
        For k = j + 1 To 89
          For h = k + 1 To 90
            If indice(j, k, h, 4) = 0 Then
              b = b + 1
              NoTerno(b, 1) = j: NoTerno(b, 2) = k: NoTerno(b, 3) = h: NoTerno(b, 4) = 0
            End If
          Next
        Next
      Next
    Cells(14, 9) = Timer - iTime
    Application.ScreenUpdating = True         'ripristina aggiornamento schermo
    iTime = Timer
    dePos.Resize(a, 4) = scrivi               'riporta i dati dalla matrice al foglio
    dePos2.Resize(b, 4) = NoTerno             'riporta i dati dalla matrice al foglio
    Cells(15, 9) = Timer - iTime
    Set oSh = Nothing
    Set dePos = Nothing
    Set dePos2 = Nothing
    End Sub
    


    Questo codice sostituisce il precedente.
    E con questo ritengo RISOLTO il problema.
    Ciao a tutti,
    Mario
  • OFFLINE
    L2018
    Post: 1.272
    Registrato il: 02/04/2018
    Città: PESCARA
    Età: 75
    Utente Veteran
    EXCEL 2016 - SPREAD32
    00 20/03/2024 17:52
    Re:
    Marius44, 20/03/2024 17:26:

    Ciao
    Come già detto, Leo è insaziabile...


    [SM=p4449751] non è che io sono insaziabile, nel post precedente TU auspicavi la frequenza discendente, ti ho solo chiesto perchè l'avessi tolta, io ce l'ho e me la tengo.
    E poi abbiamo detto che tutti vorremmo avere sempre di più di ciò che abbiamo.
    Inoltre appena poco fa sono riuscito a inserire 3 righe che nella mia macro evidenziano i terni NON usciti, l'evidenziazione comincia istantaneamente ma il cronometro è "leggermente" impietoso: 8,2 secondi, questo perchè la routine è grezza, se uso il ReDim migliora di poco. Approccio tardivo.
    Invece ho visto che tu quatto quatto hai rifatto gran parte del tutto predisponendo in anticipo la possibilità di conteggiare alternatamente usciti e non usciti, salvo esporli alla fine in un sol colpo. In questo senso sei stato davvero bravo.
    In teoria quindi per controrispondere alla tua mossa dovrei anche io rifare in modo significativo l'opera, ma mi accontento di quello che ho, a meno di prove fatte con calma.
    Certo, possiamo considerare risolto il problema e quindi la discussione, posso metterci il timbro, ma spero sempre in qualcosa di...non so come dire...
    Annaggia, fatte le debite proporzioni ho messo un archivio di equivalente difficoltà in PowerBasic: 2 MILLISECONDI !
    Ciao, ci si aggiorna, chiunque voglia.

    P.S.
    Dimenticavo
    il tempo di esecuzione di una macro è variabile anche a me, anche in PowerBasic, ed anche per molte persone, tanto che ci sono discussioni in rete, e la maggior parte di esse si consola facendo una media dei tempi.
    Tuttavia la differenza non cresce col tempo di elaborazione e quindi dopo 1 "miliardo" di operazioni di fatto non è più rilevante.
    La causa non la conosco.
    [Modificato da L2018 20/03/2024 18:08]

    LEO
    https://t.me/LordBrum
  • 15MediaObject4,17672 5
2