Modifica dati inseriti



  • Modifica dati inseriti
    di alexps81 data: 31/07/2015 09:09:35

    Di nuovo un buongiorno a tutti gli esperti e un saluto particolare a coloro che in questi giorni mi hanno supportato e sopratutto "sopportato".

    Oggi volevo proporvi un quesito, credo, al quanto difficile.

    In una tabella ci sono una serie di dati COGNOME NOME UFFICIO NUMERO DI TELEFONO E-MAIL....

    Questi dati vengono inseriti tramite un pulsate INSERISCI CONTATTO. A fianco ho inserito un'altro pulsante MODIFICA CONTATTO.

    Volevo sapere se è possibile fare in modo che al click su MODIFICA CONTATTO si apre una form simile o magari proprio la stessa che viene gestita dal pulsante INSERISCI CONTATTO e che i dati inseriti, del contatto selezionato si possano modificare.

    Esempio: mi posiziono nel rigo, in una cella non specifica, di SIGNOR PINCO PALLINO 5° 123456789 pinco.pallino@email.it, e al click su MODIFICA CONTATTO si apre la form con i dai di PINCO PALLINO già inseriti e ho la possibilità di modificarli, poi click su salva e il contatto di PINCO PALLINO viene modificato.

    Grazie per l'interessamento.



  • di Vecchio Frac data: 31/07/2015 09:34:43

    Il codice dell'userform1 è complicato dal fatto che gestisci ogni singolo click dei diversi togglebutton (interruttori).
    In assenza di conoscenza sugli array di controlli, puoi almeno compattare il codice dei singoli click come segue: gestisci separatamente i diversi click ma riunisci in un'unica procedura la catena delle operazioni da eseguire (visto che è la medesima per tutti gli eventi).
    Ne guadagni in leggibilità e manutenzione futura.

    Per il codice del command button clic ti rinvio all'altra discussione cui ho appena risposto anche se l'avevi marcata "risolta".

    Nel merito, cit. "Volevo sapere se è possibile fare in modo che al click su MODIFICA CONTATTO si apre una form simile ", certo che sì, quando sei posizionato su una riga ne conosci tutti i dati e la form ne è già al corrente quando attivi la form col pulsante (la riga corrente la conosci con activecell.row).
    E quindi cosa ne deduci?
     
    Private Sub ToggleButton1_Click()
        togglebuttonclick 1
    End Sub
    
    Private Sub ToggleButton2_Click()
        togglebuttonclick 2
    End Sub
    
    Private Sub ToggleButton3_Click()
        togglebuttonclick 3
    End Sub
    
    
    'e così via per tutti gli altri eventi click
    
    
    
    
    private sub togglebuttonclick(n as integer)
    dim i as integer
        TextBox1.Value = ""
        TextBox1.Enabled = False
        for i = 1 to 20
            controls("ToggleButton" & i).Value = False
        next
        controls("ToggleButton" & n).Value = true
    end sub






  • di totygno71 data: 31/07/2015 09:59:27

    @VF
    Quanto vale n?



  • di alfrimpa data: 31/07/2015 10:26:11

    Marcello credo sia un refuso.

    Penso intendesse dire "i"

    Alfredo





  • di Vecchio Frac data: 31/07/2015 10:46:32

    No, non è un refuso, "n" è il parametro passato alla sub che identifica il controllo in uso.
    In pratica col ciclo "for i = 1 to 20" imposto tutti i togglebutton a False, poi rendo True quello che ha richiamato la procedura (perchè è stato cliccato su di esso).
    Quindi "n" vale di volta in volta il parametor che la relativa routine click gli dà.
    Il togglebutton1 per esempio chiama la sub togglebuttonclick passando il parametro 1 che identifica se stesso (il togglebutton1 appunto).

    Private Sub ToggleButton1_Click()
    togglebuttonclick 1
    End Sub






  • di totygno71 data: 31/07/2015 10:58:45

    quindi bisogna assegnare ad ogni ToggleButton la sub togglebuttonclick(n as integer) dico giusto?



  • di Vecchio Frac data: 31/07/2015 11:02:35

    Giusto.
    E' quello che ho scritto nel commento del codice: "'e così via per tutti gli altri eventi click".
    Si intende che si devono scrivere tutti gli eventi _Click() per ogni toggle button interessato e che all'interno del rispettivo codice ci deve stare il richiamo alla sub col passaggio di parametro coerente (ho riportato i primi tre come esempio).
    Questo ripeto solo finchè non impariamo che esistono gli array di controlli. tecnica non molto usuale e anche lievemente complessa da capire, imparare e gestire, ma che riduce il codice e semplifica la scrittura di routine comuni a insiemi omogenei di controlli.





  • di totygno71 data: 31/07/2015 11:58:17

    Chiedo scusa ad alexps....
    @VF
    ma...siccome mi interessa ho fatto un test ma mi da di ritorno sub non definita...
    Allego il file



  • di alexps81 data: 31/07/2015 13:36:58

    Perdonatemi ma ho capito la storia della modifica dei dati inseriti nella form, ma non ho capito come gestire il codice Activecell.row

    Dove va inserito? Ho provato ha inserirlo nel pulsante MODIFICA CONTATTO, ma credo che da solo non basta. Qualcuno mi sa dire qualcosa in più?




  • di Luca73 data: 31/07/2015 13:45:44

    Ciao
    Per risolvere il problema ho modificato la sub da private a public
    inoltre c'è un secondo problema
    non riconosce
    controls("ToggleButton" & i).Value
    risolto modificando in
    UserForm1.Controls("ToggleButton" & i).Value

    Ora però il problema è un altro
    che i comandi
    controls("ToggleButton" & i).Value = False e
    controls("ToggleButton" & i).Value = True

    a loro volta scatenano le ToggleButtonX_Click()
    e quindi entra in un loop di macro che lo rallenta tanto (se esce dal loop).








  • di Vecchio Frac data: 31/07/2015 13:59:53

    Sto riguardando quello che ho scritto...
    Il codice va tutto nell'userform.
    Ma si genera una fastidiosa ricorsione che mi impalla tutto.
    In pratica quando assegni un value al toggle button ne richiami il relativo codice. E questo genera una ricorsione paurosa.





  • di alexps81 data: 31/07/2015 14:03:31

    Per favore, qualcuno mi sa dire come si risolve la storia del pulsante MODIFICA CONTATTO?



  • di Vecchio Frac data: 31/07/2015 14:03:54

    @Luca
    Tutte le tue obiezioni della prima parte si risolvono inserendo il codice nell'userform non in un modulo separato.

    Il problema della ricorsione invece è molto peggio :)





  • di Vecchio Frac data: 31/07/2015 14:07:36

    @alexps
    Sei su una cella.
    Apri la form.
    Nel codice della form puoi sapere dove si trova il cursore con Activecell.Row.
    A questo punto hai già la possibilità di conoscere tutti i dati che si trovano su quella riga perchè ti basta leggere con Cells(activecell.row, "A") , per esempio, il contenuto della cella che si trova in colonna A, riga del cursore.
    Non ti resta da fare altro che assegnare ai vari campi della form i dati recuperati da tali celle.
    Esempio: textbox1 = Cells(activecell.row, "A")
    Sempre se non ho capito male.
    Ho già fatto la figuraccia con la storia del Click sul trigger :)





  • di Luca73 data: 31/07/2015 14:08:16

    Ciao VF è solo che ho analizzato il filetto inviato da totygno.
    Ho provato d usare un mouseup invece di click ma mi da degli errori...
    funziona solo con il tasto destra....NON CAPISCO IL PERCHE????
    Sinceramente non capisco perche il viene scatenata la click e non il change...Boh..





  • di Luca73 data: 31/07/2015 14:20:41

    Ho trovato una possibile soluzione
    Usare l'evento mouse up invece di click pero bisogna eliminare la riga
    controls("ToggleButton" & n).Value = true
    questo in quanto l'evento mouse up viene prima di modificare lo stato del bottone pertanto basta metterli tutti a falso e poi avviene il cambio che lo porta a true
    Ciao





  • di alexps81 data: 31/07/2015 14:24:53

    E al pulsante MODIFICA CONTATTI cosa devo assegnare? Userform1.show?

    Sto provando ma non succede nulla

    In pratica se mi trovo nel rigo 5 dove nel suo contenuto ci sono i dati di SIGNOR PINCO PALLINO 5° 33452564 al click su MODIFICA CONTATTO si deve aprire la form dove compaiano i dati di PINCO PALLINO



  • di Luca73 data: 31/07/2015 14:30:00

    Ciao
    Per favore allega il file Così come è adesso...
    Scusaci ci siamo un po' persi in una sottodiscussione.






  • di Vecchio Frac data: 31/07/2015 14:34:03

    Ed ecco la soluzione.
    Ho cercato un po' in giro, e funziona.
    Adesso i toggle button sono indipendenti e mutuamente esclusivi.
     
    'codice dell'userform
    Option Explicit
    
    Private Sub ToggleButton1_Click()
        SetExclusive ActiveControl
    End Sub
    
    Private Sub ToggleButton2_Click()
        SetExclusive ActiveControl
    End Sub
    
    Private Sub ToggleButton3_Click()
        SetExclusive ActiveControl
    
    End Sub
    
    Private Sub ToggleButton4_Click()
        SetExclusive ActiveControl
    End Sub
    
    Private Sub ToggleButton5_Click()
        SetExclusive ActiveControl
    End Sub
    
    
    Sub SetExclusive(ByRef TglBtn As MSForms.ToggleButton)
    Dim ctl As Control
    
        For Each ctl In Controls
          If TypeName(ctl) = "ToggleButton" Then
            If ctl.Name <> TglBtn.Name Then ctl.Value = False
          End If
        Next ctl
        
    End Sub






  • di Vecchio Frac data: 31/07/2015 14:35:01

    Sì, devo anch'io chiedere scusa ad alexps.
    Mi sono accanito con questa cosa che credevo semplice. Però adesso sono soddisfatto :)





  • di Luca73 data: 31/07/2015 14:41:24

    At VF
    però adesso mi spieghi perche questo codice non genera loop...
    alla fine modifiche lo stato del controllo da Vero a falso...






  • di alexps81 data: 31/07/2015 14:48:25

    Ho allegato il file come richiesto per la gestione del pulsante MODIFICA CONTATTI.

    P.S. ho trovato in internet un codice per la selezione in altro colore di un rigo selezionato. Lo inserito nell'evento SelectionChange. E' possibile fare in modo che modifichi non tutto il rigo ma solo il range che va da A a F?

    Grazie



  • di Vecchio Frac data: 31/07/2015 14:49:00

    Aspetta che prima rispondo ad alexps...

    Da quello che ho capito ti serve il codice seguente, che devi inserire nel codice del foglio2 ELENCO TELEFONICO (mi pare che la sub del commandbutton4_Click c'era già).
    In pratica ti posizioni su una cella qualsiasi della riga con il contatto che ti interessa, poi premi MODIFICA CONTATTO e ti appare lo stesso userform dell'inserimento con i campi recuperati dal foglio2.
    Attenzione eprò che per come è scritto il codice adesso, alla conferma del form con Ok si esegue il codice "Range("A65535").End(xlUp).Offset(1, 0).Select", che scrive il dato nella prima riga vuota disponibile mentre tu vorrai modificare la riga esistente.
    Sei in grado di fare l'aggiustamento ?
     
    Private Sub CommandButton4_Click()
    'MODIFICA CONTATTO
        Load UserForm2
        With UserForm2
            .ComboBox1 = Cells(ActiveCell.Row, "A")
            .TextBox1 = Cells(ActiveCell.Row, "B")
            .TextBox2 = Cells(ActiveCell.Row, "C")
            .ComboBox2 = Cells(ActiveCell.Row, "D")
            .TextBox3 = Cells(ActiveCell.Row, "E")
            .TextBox4 = Cells(ActiveCell.Row, "F")
            .TextBox5 = Cells(ActiveCell.Row, "H")
            .TextBox6 = Cells(ActiveCell.Row, "G")
            .Show
        End With
        
    End Sub






  • di Vecchio Frac data: 31/07/2015 14:55:52

    cit. Luca73 "però adesso mi spieghi perche questo codice non genera loop... "
    ---> Da quel che penso io, ma non è una spiegazione molto tecnica, accade che non stiamo modificando lo stesso controllo che ha generato l'evento Click (o Change), ma un suo riferimento. La variabile ctl del ciclo for each assume un riferimento all'oggetto ma non è l'oggetto stesso. Ne ha quindi tutte le proprietà ma non ne scatena gli eventi perchè non è proprio lo stesso oggetto... infatti l'ActiveControl è passato ByRef e quindi è un puntatore in memoria. Impostando la proprietà Value su False, cambi di riflesso la stessa proprietà dell'oggetto originale (perchè alla fine dell'esecuzione il puntatore punta al medesimo ActiveControl) ma non ne influenzi il comportamento... l'oggetto ctl non ha eventi da esporre, cioè non esiste un ctl_Click() (sarebbe così se ctl la dichiarassimo WithEvents in un modulo di classe: il che si fa appunto per le collezioni di controlli. Provata quella strada ma diventando lo stesso oggetto si scatenava a cascata l'evento Click).
    Guarda, non è del tutto chiaro neanche a me però funziona :)





  • di Vecchio Frac data: 31/07/2015 14:56:58

    cit. " ho trovato in internet un codice per la selezione in altro colore di un rigo selezionato. L'ho inserito nell'evento SelectionChange. E' possibile fare in modo che modifichi non tutto il rigo ma solo il range che va da A a F? "
    ---> Possibile sì, vediamo il codice?





  • di alexps81 data: 31/07/2015 14:57:55

    Ringrazio generosamente Vecchio Frac. Ovviamente questa discussione è servita più a voi che a me. Io ci capisco veramente poco e più credo di imparare, più invece penso di non aver capito nulla.
    Ho allegato il file come richiesto, per caso qualcuno mi fa le modifiche così poi le vado a confrontare con quelle fatte in precedenza e cerco di capirne qualcosa?
    Grazie

    Se ci aggiungete pure la storia della selezione e dei MODIFICA CONTATTI cosi almeno riesco a capirci qualcosina



  • di alexps81 data: 31/07/2015 15:05:28

    Adesso ho capito la storia del caricamento dei dati nei singoli campi.
    Grazie.

    Però effettivamente hai ragione....adesso va a caricare un nuovo contatto e non lo modifica.

    Ma io purtroppo non riesco a risolvere questo altro problema. Credo di aver bisogno ancora del vostro aiuto



  • di Vecchio Frac data: 31/07/2015 15:14:04

    @alexps
    Per farmi perdonare ti riallego il tuo file ("Elenco telefonico_PROVA (VF).xlsm") con alcune diverse modifiche fatte da me e che fa quello che desideri.
    Ti pregherei di visionare il codice e cercare di capire cosa fa e come.
    Mi aspetto che tu abbia qualche domanda da fare (ho inserito un meccanismo carino per far capire a Excel la differenza tra INSERISCI e MODIFICA) :)






  • di Vecchio Frac data: 31/07/2015 15:18:33

    Avendo lavorato su una versione precedente a quella che hai allegato tu da ultimo con lo stesso nome, non compare il codice che colora la riga. Ma non userei per questo l'evento SelectionChange... qual è esattamente l'obiettivo che volevi raggiungere? colorare la riga ogni volta che ti sposti di cella in cella?





  • di Luca73 data: 31/07/2015 15:20:52

    Ciao
    Per crearti giusto un po' più di confusione ti allego anche il mio file
    ho inserito le modifiche di cui abbiamo discusso in giornata con VF che semplicemente vanno a snellire il codice.
    Inoltre ho modificato la colorazione della riga solo per le prime otto celle

    Invece nulla ho fatto riguardo alla modifica in quanto dal mio computer non mi si attivano i pulsanti Active X e pertanto non riesco a lavorarci.






  • di Vecchio Frac data: 31/07/2015 15:33:27

    Avevo già scritto questo post prima che Luca73 mi precedesse, per la scrittura corretto dal SelectionChange. Lo posto ugualmente perchè è leggermente diverso da quello di Luca73.
     
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
        If Application.Intersect(Target, Range("A:H")) Is Nothing Then Exit Sub
        If Target.Row < 3 Then Exit Sub
        If Selection.Count = 1 And Target.Row > 2 Then
            If Range("Z1") = "" Then Range("Z1") = ActiveCell.Row
            Range(Cells(ActiveCell.Row, "A"), Cells(ActiveCell.Row, "H")).Interior.ColorIndex = 36
            If Range("Z1") <> Target.Row Then Rows(Range("Z1")).Interior.ColorIndex = xlNone
            Range("Z1") = Target.Row
        End If
    End Sub






  • di alexps81 data: 31/07/2015 16:00:39

    Ragazzi che vi devo dire, siete stati bravissimi e pazienti con me. Adesso appena ho tempo cerco di capire il codice da voi proposto.

    Un ultima cosa, nella selezione del rigo ho notato che cambia da vuoto a colore 36 e viceversa. Siccome ho la necessità che i colori siano solo 2, cioè da giallino (36) a verdino (35), ho provato a modificare xlnone con 35, ma ad una nuova selezione mi cambia tutto il rigo in verdino, mentre a me interessava sempre le colonne da A a H.
     
    Private Sub Worksheet_SelectionChange(ByVal Target As Range)
    If Selection.Count = 1 And Target.Row > 2 Then
    With ActiveCell
    Range(.EntireRow.Cells(1, 1), .EntireRow.Cells(1, 8)).Interior.ColorIndex = 36
    End With
    On Error Resume Next
    If [Z1] <> Target.Row Then _
    Rows([Z1]).Interior.ColorIndex = xlNone
    [Z1] = Target.Row
    End If
    End Sub



  • di Vecchio Frac data: 31/07/2015 16:21:22

    Bè in questo caso chiaramente la riga di codice che colora l'intera riga del foglio deve essere cambiata in armonia con quella precedente:
    If [Z1] <> Target.Row Then _
    Range(Cells([Z1], "A"), Cells([Z1], "H")).Interior.ColorIndex = 35