random e timer a scadenza



  • random e timer a scadenza
    di nichicanta data: 16/05/2013 20:38:21

    Amici del forum, ho bisogno di inserire in un programmino di quiz di cultura generale un timer (con impostazione del tempo tramite inputbox: tipo 30';60';120' ecc..) azionato da un pulsante di comando situato sulla userform, magari da attivare o disattivare all'occorrenza.
    Inoltre chiedo di poter randomizzare i dati su piu' colonne ( al riguardo preciso che nel forum ho trovato il codice che lo fa solo su una colonna, i vorrei su piu' colonne) scegliendo man mano io il numero di domande alle quali rispondere sempre tramite input box (nel quale inserire volta per volta, alla pressione di un altro pulsante di comando, il numero delle domande alle quali rispondere)
    A tal proposito allego un file di esempio su come ho impostato la userform e i pulsanti di comando con l'indicazione ( nelle caption dei pulsanti delle funzioni da svolgere).
    Grazie come sempre per la generosità e la disponibilità che mettete a disposizione degli altri.
    P.S. allego i codici che ho trovato nel forum, al fine di perfezionarlo insiemo a Voi e adattarlo alla mia esigenza.

     
    sub mischia ()
    Dim c As Range
        Dim i As Integer
        Dim j As Integer
        Dim kk As Integer
        Dim Swap As String
        Dim NRighe As Integer
        Dim NColonne As Integer
        
        Set c = Selection
        NColonne = c.Columns(c.Columns.Count).Column - c.Column + 1
        NRighe = c.Rows(c.Rows.Count).Row - c.Row + 1
        If NColonne = 1 Then
        Randomize
        For kk = 1 To NRighe * 5
            i = Int((NRighe * Rnd) + 1)
            j = Int((NRighe * Rnd) + 1)
            Swap = c.Cells(i, 1).Value
            c.Cells(i, 1).Value = c.Cells(j, 1).Value
            c.Cells(j, 1).Value = Swap
        Next
        End If
    end sub
    
    
    
    Private Sub CmdAvanti_Click()
    Dim NumeroCasuale As Integer
    Dim StrTemp As String * 1
    
    If OptSequenziale.Value = True Then
    If RigaDomanda < DomandeTotali Then
    RigaDomanda = RigaDomanda + 1
    Call LeggiDomanda(RigaDomanda)
    Call AzzeraOpzioni
    End If
    ElseIf OptCasuale.Value = True Then
    Me.MousePointer = 13
    
    Do
    Randomize Timer
    NumeroCasuale = Int((DomandeTotali * Rnd) + 1)
    
    StrTemp = Foglio1.Cells(NumeroCasuale, 8)
    Loop While (LCase(StrTemp) = "x")
    
    RigaDomanda = NumeroCasuale
    Call LeggiDomanda(RigaDomanda)
    Call AzzeraOpzioni
    
    Me.MousePointer = 0
    End If
    
    Call AggiornaCombo
    DomandaDaVerificare = 0
    CmdVerificaRisposta.SetFocus
    End Sub 



  • di nichicanta data: 16/05/2013 20:48:34

    Scusatemi, Premete ALT+F11 per visualizzare la userfom che ho creato.



  • di Vecchio Frac data: 17/05/2013 12:03:45

    Up.
    Per non dimenticarmelo ^_^
    Proprio ieri ho postato un suggerimento sull'utilizzo di un timer.
    Appena ho tempo guardo meglio l'intera domanda.





  • di nichicanta (utente non iscritto) data: 17/05/2013 14:58:11

    Amici tutti del forum perche(finalmente ho trovato il codice che fa per me) con questo codice il pulsante di comando dopo aver impostato la sua Caption a Stop Timer non arresta il tempo.
    Grazie, vi saluto.
    Ho provato piu' volte, sempre in base alla mia scolastica conoscenza di vb e vba ma senza riuscirci.
    Grazie e buon lavoro a tutti.


     
    Option Explicit
    
          Declare Function SetTimer Lib "user32" _
                (ByVal hwnd As Long, _
                ByVal nIDEvent As Long, _
                ByVal uElapse As Long, _
                ByVal lpTimerFunc As Long) As Long
    
          Declare Function KillTimer Lib "user32" _
                (ByVal hwnd As Long, _
                ByVal nIDEvent As Long) As Long
    
          Global iCounter As Integer
    
          Sub TimerProc(ByVal hwnd As Long, _
                         ByVal uMsg As Long, _
                         ByVal idEvent As Long, _
                         ByVal dwTime As Long)
    
              iCounter = iCounter + 1
              Form1.Text1.Text = CStr(iCounter)
          End Sub
    
    					5.Copiare il codice seguente nella finestra del codice di Form1:
          Option Explicit
          Dim lngTimerID As Long
          Dim BlnTimer As Boolean
    
          Private Sub Form_Load()
             BlnTimer = False
             Command1.Caption = "Start Timer"
          End Sub
    
          Private Sub Command1_Click()
          'Starts and stops the timer.
    
             If BlnTimer = False Then
                lngTimerID = SetTimer(0, 0, 200, AddressOf TimerProc)
                If lngTimerID = 0 Then
                  MsgBox "Timer not created. Ending Program"
                  Exit Sub
                End If
                BlnTimer = True
                Command1.Caption = "Stop Timer"
             Else
                lngTimerID = KillTimer(0, lngTimerID)
                If lngTimerID = 0 Then
                   MsgBox "couldn't kill the timer"
                End If
                BlnTimer = False
                Command1.Caption = "Start Timer"
              End If
    
          End Sub
    
    



  • di Vecchio Frac data: 17/05/2013 15:30:24

    Conosco questo codice ^_^
    Funziona usando le API. Sicuramente un metodo più robusto di OnTime, però bisogna starci attenti per non incastrare il sistema :)
    Ti faccio i complimenti per aver cercato una soluzione da solo e per essere finito sulla strada giusta :)
    Come premio ti allego un file funzionante che mostra l'uso dei Timer sia con il metodo OnTime che con le API Set/KillTimer. Questo file permette l'utilizzo simultaneo e asincrono di più di un timer. Giusto per la cronaca :)

    Nel merito del codice che hai postato, hai seguito le istruzioni?
    il primo pezzo di codice in un modulo, il secondo nella zona codice del foglio1.

    Perchè funzioni poi devi impostare correttamente le firme delle sub a seconda di come si chiamano i tuoi oggetti For e CommandButton.

     
    Private Sub Form_Load()
    deve diventare
    Private Sub UserForm_Initialize()
    
    e
    
    Private Sub Command1_Click()
    deve diventare
    Private Sub CommandButton1_Click()






  • di nichicanta (utente non iscritto) data: 18/05/2013 20:41:11

    Grazie come sempre Vecchio Frac, cmq avevo più volte già fatto come tu mi hai giustamente consigliato, sia per il commandbutton1 che per la userform, provvedo a sistemare il codice e ti faccio sapere.
    Chiedo a te, ma la rchiesta di aiuto è estesa a tutti coloro che vorranno aiutarmi, ""come impostare la funzione random dati su più colonne (poichè il codice da me precedentemente postato lo fa su una colonna), in modo da completare (con il tuo codice precedente) il programmino dei quiz"".
    A presto e di nuovo grazie.



  • di nichicanta data: 23/05/2013 15:57:15

    Caro Vecchio Frac ho sistemato il codice del timer, grazie ancora per la tua collaborazione, cmq ti chiedo di aiutarmi nel creare il codice random per dati presenti in più colonne e non solo su una colonna come quello che ho postato giorni fa.
    Saluti



  • di nichicanta (utente non iscritto) data: 31/05/2013 17:02:03

    Amici del forum, sono a chiedervi aiuto su come creare una funzione che mi mischi i dati su piu' colonne (mantenendo inalterate le colonne adiacenti alla A, parlo di domande con relative risposte dislocate sulle altre 4 colonne, es. come si fa con ordina crescente o viceversa su piu' colonne), in rete ho trovato questo codice ma lo fa solo su selezione e quello precedentemente postato solo su una colonna.
    Grazie ancora a tutti voi.
     
    Sub mischia()
    
        Dim c As Range
        Dim i As Integer
        Dim j As Integer
        Dim kk As Integer
        Dim Swap As String
        Dim NRighe As Integer
        Dim NColonne As Integer
        
        Set c = ActiveSheet.Range("A2:A20") 'Selection
        NColonne = c.Columns(c.Columns.Count).Column - c.Column + 1
        NRighe = c.Rows(c.Rows.Count).Row - c.Row + 1
        If NColonne = 1 Then
        Randomize
        For kk = 1 To NRighe * 5
            i = Int((NRighe * Rnd) + 1)
            j = Int((NRighe * Rnd) + 1)
            Swap = c.Cells(i, 1).Value
            c.Cells(i, 1).Value = c.Cells(j, 1).Value
            c.Cells(j, 1).Value = Swap
        Next
        End If
    End Sub



  • di Vecchio Frac data: 31/05/2013 23:32:58

    Crei una colonna di appoggio, ma adiacente alla tabella dati (esempio inserisci una colonna prima di A), la riempi con dei numeri casuali, effettui l'ordinamento della tabella sulla base di tale colonna, infine elimini la colonna A perchè non ti serve più, e hai risolto.
    Tempo fa avevo fatto una cosa simile per qualcun altro.
    Sei in grado di buttare giù un po' di codice?





  • di nichicanta (utente non iscritto) data: 12/06/2013 16:17:15

    Caro Vecchio Frac ( continuo con te ma senza esclusione per gli altri amici che vorranno intervenire nella presente discussione) ti allego il file che ho creato seguendo il tuo consiglio, ma mi sono accorto che quando ordino i dati scegliendo la colonna a ( in ordine dal piu' piccolo al piu' grande) mi crea celle vuote e duplicate, cioè 2 volte gli stessi numeri casuali).
    dove sbaglio?
    Poi, nel momento in cui voglio optare (cioè con un optionbutton, chiamato "casuale", su userform quando clicco sopra per il random della stessa colonna devo creare un macro che mi inserisca la colonna A e proseguo con questo codice appena postato( dopo aver risolto la problematica segnalata)?
    Grazie in anticipo, come sempre.



  • di nichicanta (utente non iscritto) data: 12/06/2013 16:28:56

    Carissimi amici, sempre rimanendo nell'argomento (random dati), dato che per altro utente, sempre per la realizzazione di un programma per quiz ministeriali avete creato questo codice, non sarebbe opportuno (proprio perche il file excel allegato è impostato sempre in quel modo, come nr. di colonne, formattazione e altro, non può variare)adatatrlo alla mia esigenza senza creare una colonna di appoggio bensi partire prorpio da quei dati e colonne?
    Ringrazio tutti come sempre.
     
    Private Sub CmdAvanti_Click()
    Dim NumeroCasuale As Integer
    Dim StrTemp As String * 1
    
    If OptSequenziale.Value = True Then
    If RigaDomanda < DomandeTotali Then
    RigaDomanda = RigaDomanda + 1
    Call LeggiDomanda(RigaDomanda)
    Call AzzeraOpzioni
    End If
    ElseIf OptCasuale.Value = True Then
    Me.MousePointer = 13
    
    Do
    Randomize Timer
    NumeroCasuale = Int((DomandeTotali * Rnd) + 1)
    
    StrTemp = Foglio1.Cells(NumeroCasuale, 8)
    Loop While (LCase(StrTemp) = "x")
    
    RigaDomanda = NumeroCasuale
    Call LeggiDomanda(RigaDomanda)
    Call AzzeraOpzioni
    
    Me.MousePointer = 0
    End If
    
    Call AggiornaCombo
    DomandaDaVerificare = 0
    CmdVerificaRisposta.SetFocus
    End Sub  
    



  • di nichicanta (utente non iscritto) data: 15/06/2013 18:44:08

    Carissimi Amici del forum, per chi avesse la mia necessità, allego il codice che fa questo.
    Rinnovo il mio grazie a tutti (esperti e non ) che mi aiutano nel risolvere le mie problematiche.
    A presto.




     
    Sub Mischia() 'mischia tutte le righe del foglio
    'richiede come parametro la stringa del nome del foglio
    Dim i As Long, riga As Long, ultima As Long, rr As Long, temp As Long, Sh As Worksheet
        Set Sh = ThisWorkbook.Sheets(1)
        With Sh
            ultima = Range("A1").End(xlDown).Row 'Ultima riga occupata del foglio
            temp = ultima + 1 'riga di "appoggio" che uso per mischiare
            For riga = 2 To ultima - 1 'dalla prima alla penultima riga
                Do
                    rr = Int((ultima * Rnd) + 1) 'scelgo una riga a caso
                Loop Until rr > riga 'se è una riga gia mischiata ripeto il passo precedente
                Cells(riga, 1).EntireRow.Copy Destination:=Cells(temp, 1) 'copio la riga da mischiare nella riga di appoggio
                Cells(rr, 1).EntireRow.Copy Destination:=Cells(riga, 1) 'copio la riga scelta a caso sulla riga da mischiare
                Cells(temp, 1).EntireRow.Copy Destination:=Cells(rr, 1) 'copio la riga di appoggio sulla riga scelta a caso
            Next riga 'passa alla successiva riga da mischiare
            Cells(temp, 1).EntireRow.ClearContents 'cancello la riga di appoggio
        End With 'Sh
        Set Sh = Nothing
    End Sub
     
    



  • di Vecchio Frac data: 15/06/2013 20:13:51

    Ho capito il meccanismo.
    Terribilmente lento ^_^ ma funziona.





  • di Vecchio Frac data: 15/06/2013 20:32:41

    cit. " mi crea celle vuote e duplicate, cioè 2 volte gli stessi numeri casuali"
    ---> è perchè nel file originale (perlomeno, in quello che hai postato e che ho visto io) ci sono effettivamente "NR" duplicati e righe vuote a partire da una certa riga in giù.
    Prova il codice allegato che fa esattamente quello che volevi (mescolare la tabella con una colonna d'appoggio riempita di numeri casuali... quello che ho descritto sopra insomma). Certamente un codice più semplice ma ugualmente efficace.
    Per evitare la situazione che descrivi (numeri duplicati e righe vuote) queste righe vuote in fondo alla tabella devono essere ovviamente tutte eliminate (tanto, non contengono dati).
     
    Option Explicit
    
    Sub shuffle()
    'Creo una colonna di appoggio, ma adiacente alla tabella dati (inserisco una colonna prima di A),
    'la riempio con dei numeri casuali, effettuo l'ordinamento della tabella sulla base di tale colonna,
    'infine elimino la colonna A perchè non serve più.
    Dim tot As Long
    
        tot = [COUNTA(A:A)]
        [A1].EntireColumn.Insert
        [A1] = "TEMP"
        
        Randomize Timer
        With Range(Cells(2, "A"), Cells(tot - 1, "A"))
            .Formula = "=RAND()"
            .Value = .Value
        End With
        
        [A1].CurrentRegion.Sort key1:=[A1], header:=xlYes
        [A:A].EntireColumn.Delete
    
    End Sub






  • di nichicanta (utente non iscritto) data: 17/06/2013 10:26:59

    Grazie V.F. ho utilizzato il tuo codice, funziona benissimo, anche perchè il mio lo hai considerato molto lento.
    Un sincero ringraziamento a te e atutti Voi del forum.



  • di Vecchio Frac data: 17/06/2013 10:39:45

    cit. "ho utilizzato il tuo codice, funziona benissimo, anche perchè il mio lo hai considerato molto lento"
    ---> Le due considerazioni non devono essere accoppiate... anche il tuo codice funziona benissimo, e lo puoi utilizzare tranquillamente; *tuttavia* io lo trovo lento rispetto ad altra soluzione. E non è che quello che dico io debba essere considerato a priori come l'ultima parola... anzi spesso e volentieri faccio degli errori banali di cui spesso mi vergogno (e via a revisionare il codice anche per giorni ^_^)





  • di nichicanta (utente non iscritto) data: 17/06/2013 10:56:40

    Carissimo V.Frac, sono daccordo con te su quello che dici, ma cerco di ascoltare sempre chi (ormai da anni, per esperienza, consiglia cose più funzionali) e cmq io decido di adottare il codice migliore dopo aver fatto tante prove e averlo testato con migliaia di dati.
    Ti saluto.