Codice VBA con With



  • Codice VBA con With
    di alessia (utente non iscritto) data: 28/11/2013 10:15:21

    Buongiorno a tutti....
    Mi ritrovo qui nel chiedervi un aiuto. Ho bisogno di ripulire delle ulteriori Txtbox. Ma non ci riesco. Ho allegato il codice VBA che funziona solo per le Txtbox all'interno del Frame chiamato frInserimentoDati.
    Poichè ho altri Frame, vorrei che si pulisse anche le altre txtbox contenuti all'interno di frame con nomi diversi. Non so se sono stata chiara. Il codice allegato dovrebbe chiarire.
    Grazie a tutti
     
    '============================
    '===== Routine UserForm =====
    '============================
    
    Private Sub mPulisciTextBox()
    
        Dim ctrl As Control
        
        With Me.frInserimentoDati
         'With Me.frRagioneSociale  'Mi da errore. Avrei bisogno di pulire anche queste TXTbox.Come posso correggerlo?
                                      ' cosa devo aggiungere?
         'With Me.frReferente
         
            For Each ctrl In .Controls
                If TypeOf ctrl Is _
                    MSForms.TextBox Then
                        ctrl.Text = ""
                End If
            Next
        End With
        
        Set ctrl = Nothing
    
    End Sub



  • di patel data: 28/11/2013 10:35:10

    se alleghi il file forse troviamo l'errore





  • di Grograman (utente non iscritto) data: 28/11/2013 10:37:02

    Non ho capito il problema, ma prova così:
     
      Dim ctrl As Control
      
      With Me
        For Each ctrl In .Controls
          If TypeOf ctrl Is MSForms.TextBox Then
            ctrl.Text = "A"
          End If
        Next
      End With



  • di alessia (utente non iscritto) data: 28/11/2013 11:02:54

    Ragazzi ho inserito il file..... Come potete notare il problema si riscontra quando pigio il tasto Nuovo.
    Grazie per la Vostra disponibilità



  • di valerio612 data: 28/11/2013 11:45:27

    Ciao,

    prova questo codice

     
    Dim oCtrl As Control
            For Each oCtrl In Me.Controls
                If TypeName(oCtrl) = "TextBox" Then
                    oCtrl.Text = ""
                End If
            Next



  • di Grograman (utente non iscritto) data: 28/11/2013 11:53:33

    Ciao!

    Sì è come dicevamo prima. Hai messo la paternità solo del frame.
    Quindi lasciando semplicemente "with me" azzeri tutte le textbox.

    Già che ci siamo, visto che ripeti più volte la medesima operazione, sia con il pulsante "avanti", "primo", "ultimo" e "indietro" ti ho condensato l'alimentazione sfruttando una routine dedicata a cui passare il numero della riga da riportare.
    E' un pò più facile sia da leggere che da manutenere ;)

    Allego esempio.
     
    '==================================
    '===== Pulsanti frame Ricerca =====
    '==================================
    Private Sub cmdPrimo_Click()
    Call Alimenta_Form(2)
      lRigaAttiva = 2
      Me.cmdInserisci.Enabled = False
    End Sub
    
    
    Private Sub cmdAvanti_Click()
      If Not lRigaAttiva >= lUltRiga Then
        lRigaAttiva = lRigaAttiva + 1
        Call Alimenta_Form(lRigaAttiva)
      End If
      Me.cmdInserisci.Enabled = False
    End Sub
    
    Private Sub cmdIndietro_Click()
      If Not lRigaAttiva <= 2 Then
        lRigaAttiva = lRigaAttiva - 1
        Call Alimenta_Form(lRigaAttiva)
      End If
      Me.cmdInserisci.Enabled = False
    End Sub
    
    Private Sub cmdUltimo_Click()
      Call Alimenta_Form(lUltRiga)
      lRigaAttiva = lUltRiga
      Me.cmdInserisci.Enabled = False
    End Sub
    Private Sub Alimenta_Form(ByVal Riga As Long)
      With Me
        .txtID.Text = sh.Range("A" & Riga).Value
        .txtNome.Text = sh.Range("B" & Riga).Value
        .txtIndirizzo.Text = sh.Range("C" & Riga).Value
        .txtCivico.Text = sh.Range("D" & Riga).Value
        .txtComune.Text = sh.Range("E" & Riga).Value
        .txtProvincia.Text = sh.Range("F" & Riga).Value
        .txtTelefono.Text = sh.Range("G" & Riga).Value
        .txtCellulare.Text = sh.Range("H" & Riga).Value
        .txtEmail.Text = sh.Range("I" & Riga).Value
        .txtSito_Internet.Text = sh.Range("J" & Riga).Value
        .txtRuolo.Text = sh.Range("K" & Riga).Value
        .txtC_F.Text = sh.Range("L" & Riga).Value
        .txtReferente_1.Text = sh.Range("M" & Riga).Value
        .txtRecapito_1.Text = sh.Range("N" & Riga).Value
        .txtReferente_2.Text = sh.Range("O" & Riga).Value
        .txtRecapito_2.Text = sh.Range("P" & Riga).Value
        .txtReferente_3.Text = sh.Range("Q" & Riga).Value
        .txtRecapito_3.Text = sh.Range("R" & Riga).Value
        .txtRagione_Sociale.Text = sh.Range("S" & Riga).Value
        .txtIndirizzo_2.Text = sh.Range("T" & Riga).Value
      End With
    End Sub



  • di alessia (utente non iscritto) data: 28/11/2013 12:00:32

    Grograman dove devo inserire questo codice che mi hai scritto?
    Grazie



  • di alessia (utente non iscritto) data: 28/11/2013 12:03:41

    Grazie Valerio...



  • di alessia (utente non iscritto) data: 28/11/2013 12:05:52

    X Grograman.
    Infatti, la paternità è solo ad un Frame. Vorrei estenderlo a più frame come nell'esempio che ho citato prima.
    Grazie



  • di Grograman (utente non iscritto) data: 28/11/2013 12:11:54

    Mi autocito:

    "Allego esempio."



  • di alessia (utente non iscritto) data: 28/11/2013 12:23:23

    Grazie... stavo impazzendo. Ma come hai fatto?



  • di alessia (utente non iscritto) data: 28/11/2013 12:36:46

    Ops.. avevo dimenticato di mettere la spunta.
    Grazie Grograman



  • di Grograman data: 28/11/2013 12:40:06

    Ma io non ho fatto niente, e anche Valerio ti aveva dato la soluzione ;)

    Tu facevi un ciclo solo nei controlli dello specifico frame.
    Bastava togliere una paternità, in modo che il cilco agisse su "userformxx.controls" e non su userformxx.frameyy.controls"


     
    DA COSI':
    With Me.frInserimentoDati
      For Each ctrl In .Controls
      next ctrl
    end with
    
    
    A COSI':
    With Me
      For Each ctrl In .Controls
      next ctrl
    end with
    
    
      



  • di alessia (utente non iscritto) data: 28/11/2013 12:48:39

    Grazie ragazzi, mi ero persa. Io non ho la conoscenza del VBA. Sto imparando qual cosa adesso. Non me ne Vogliate. Forse per Voi no, ma mi avete risolto un grande problema di cui sola non nè sarei uscita. Adesso grazie a Voi posso continuare con il progetto.
    Che dirVi di più... Grazie ed un'abbraccio ad entrambi...
    By Alessia



  • di Vecchio Frac data: 28/11/2013 12:53:15

    cit. "E' un pò più facile sia da leggere che da manutenere"
    @Sfida per Grò (e per chiunque altro)
    Riesci a compattare almeno la sub Alimenta_Form? ^_^





  • di alessia (utente non iscritto) data: 28/11/2013 13:02:46

    Ciao Frac.... Cosa significa che non va bene la soluzione di Grograman?
    Non capisco.



  • di Grograman (utente non iscritto) data: 28/11/2013 13:09:19

    Significa che il tuo codice è troppo prolisso

    @VF: Se potessi rinominare "nature" le textbox le alimenterei con un ciclo for, essendo le colonne da alimentare consecutive



  • di alessia (utente non iscritto) data: 28/11/2013 13:18:03

    Non ci ho capito molto... Per me credo che vada bene così. L'importante che funziona, anche perchè non saprei da dove cominciare.
    Ci possono essere problemi in questo modo Grograman?



  • di Vecchio Frac data: 28/11/2013 13:32:00

    Non ho detto che non va bene... ho lanciato un sassolino a Grò perchè cerchi di ottimizzare :)
    E ha già trovato una possibile strada da imboccare :)






  • di scossa data: 28/11/2013 14:00:40

    Attenzione, non sempre rendere più breve o compatto il codice equivale ad "ottimizzarlo", perlomeno ai fini dell'efficienza.
    Prendiamo in considerazione le due sub sottoriportate (non ha importanza se la seconda agisce sempre su un'unica textbox; la seconda abbinatela ad esempio al command "Ultimo").
    Fare un ciclo For ... Next rende il secondo codice (Alimenta_Form2) più breve e veloce da scrivere ma allunga i tempi di esecuzione: 3,7 secondi la prima contro 4,2 secondi di quella col ciclo; una differenza minima, ma dimostra che usare un ciclo non comporta una "ottimizzazione" delle performance.
    Visto che la fatica di scrivere le 20 righe di assegnazione l'ha già fatta ....
     
    Private Sub Alimenta_Form(ByVal Riga As Long)
      Dim nStart As Single
      Dim j As Long
      Dim k As Long
      nStart = Timer
      For j = 1 To 10000
        With Me
          .txtID.Text = sh.Range("A" & Riga).Value
          .txtNome.Text = sh.Range("B" & Riga).Value
          .txtIndirizzo.Text = sh.Range("C" & Riga).Value
          .txtCivico.Text = sh.Range("D" & Riga).Value
          .txtComune.Text = sh.Range("E" & Riga).Value
          .txtProvincia.Text = sh.Range("F" & Riga).Value
          .txtTelefono.Text = sh.Range("G" & Riga).Value
          .txtCellulare.Text = sh.Range("H" & Riga).Value
          .txtEmail.Text = sh.Range("I" & Riga).Value
          .txtSito_Internet.Text = sh.Range("J" & Riga).Value
          .txtRuolo.Text = sh.Range("K" & Riga).Value
          .txtC_F.Text = sh.Range("L" & Riga).Value
          .txtReferente_1.Text = sh.Range("M" & Riga).Value
          .txtRecapito_1.Text = sh.Range("N" & Riga).Value
          .txtReferente_2.Text = sh.Range("O" & Riga).Value
          .txtRecapito_2.Text = sh.Range("P" & Riga).Value
          .txtReferente_3.Text = sh.Range("Q" & Riga).Value
          .txtRecapito_3.Text = sh.Range("R" & Riga).Value
          .txtRagione_Sociale.Text = sh.Range("S" & Riga).Value
          .txtIndirizzo_2.Text = sh.Range("T" & Riga).Value
        End With
      Next j
      MsgBox Timer - nStart
    End Sub
    
    Private Sub Alimenta_Form2(ByVal Riga As Long)
      Dim nStart As Single
      Dim j As Long
      Dim k As Long
      nStart = Timer
      For j = 1 To 10000
        With Me
          For k = 1 To 20 'tante sono le textbox riempite sopra
            .txtID.Text = sh.Range("A" & Riga).Value
          Next k
        End With
      Next j
      MsgBox Timer - nStart
    End Sub



  • di alessia (utente non iscritto) data: 28/11/2013 14:26:07

    X Scossa... Cosa devo fare? Devo inserire il tuo codice? Se si,dove?
    Grazie



  • di scossa data: 28/11/2013 14:27:35

    @alessia: no, usa tranquillamente quello di Grograman.



  • di alessia (utente non iscritto) data: 28/11/2013 14:28:18

    Ps. Io sto aggiungendo altre txtbox e vedo che va bene. E' il caso di cambiare?



  • di alessia (utente non iscritto) data: 28/11/2013 14:30:30

    x Scossa.... Ok. che sollievo.... continuo il mio lavoro.
    Grazie ragazzi.



  • di Vecchio Frac data: 28/11/2013 21:35:20

    cit. "Attenzione, non sempre rendere più breve o compatto il codice equivale ad "ottimizzarlo", perlomeno ai fini dell'efficienza."
    ---> Mah, non sarei così categorico. Solitamente compattare si identifica con ottimizzare, certo bisogna saperlo fare con gli strumenti a disposizione. L'efficienza non si misura sempre solo in millisecondi, ma anche in leggibilità e manutenzione. Io per esempio avevo in testa un array di textbox da alimentare all'interno del ciclo. E forse si può anche fare a meno del ciclo ^_^ Se ho tempo domani metto giù qualcosa.
    Questo mio intervento non è utile ai fini della problematica di Alessia, lo so.
    Ho divagato un po' nell'interesse di chi ha anche curiosità scientifica.
    Io intendevo stimolare Grograman che so essere sempre attento a questi profili ^_^





  • di scossa data: 28/11/2013 22:07:31

    cit. Vecchio Frac: "---> Mah, non sarei così categorico."

    cit. scossa: "Attenzione, **non sempre** rendere più breve o compatto il codice equivale ad "ottimizzarlo", perlomeno ai fini dell'efficienza."

    Proprio con quel **non sempre** intendevo NON essere categorico.
    Il punto, secondo me, è che efficienza, compattezza e pulizia in un codice si ottengono (forse) se lo si scrive (o riscrive) "in proprio" fin dall'inizio ed avendo ben chiaro il risultato da raggiungere; ma se si deve intervenire su un codice "incerto" altrui, per correggerlo, è inevitabile "scendere a compromessi" per non stravolgere il codice originale.



  • di Vecchio Frac data: 29/11/2013 10:34:58

    @Grograman
    Io pensavo a una cosa come questa per riscrivere "Alimenta_Form".
    Come vedi non ho rinominato le textbox, non serve e comunque si possono inserire tutte quelle che servono. L'unica accortezza da adottare è che l'ordine di inserimento deve essere quello del foglio altrimenti naturalmente vengono assegnato valori sbagliati ai campi.
    E anche i tempi di esecuzione, non sono poi così terribili ^_^
     
    Private Sub Alimenta_Form(ByVal Riga As Long)
    Dim col As Integer, v As Variant
    
        col = 0
        For Each v In Array(txtID, txtNome, txtIndirizzo, txtCivico, txtComune, txtProvincia, _
            txtTelefono, txtCellulare, txtEmail, txtSito_Internet, txtRuolo, txtC_F, txtReferente_1, _
            txtRecapito_1, txtReferente_2, txtRecapito_2, txtReferente_3, txtRecapito_3, _
            txtRagione_Sociale, txtIndirizzo_2)
    
            col = col + 1
            v.Value = sh.Cells(Riga, col)
        Next
    
    End Sub
    






  • di Grograman (utente non iscritto) data: 30/11/2013 10:13:33

    Ad usare un array non ci avevo proprio pensato :)

    Al più avevo pensato ad un ciclo sull'index previo riordino, ma giusto per esercizio perché non avrebbe molto senso sia per quanto detto da Scossa che per dover scrivere il codice che modifica l'index!!



  • di alessia (utente non iscritto) data: 30/11/2013 10:25:37

    Grazie a tutti per il tempo che mi avete dedicato. Il mio problema grazie a Voi è stato risolto. Pertanto ho potuto continuare col mio progetto personale.
    Grazie a tutti...