Comando o azione 'incolla' non disponibile

di il
18 risposte

Comando o azione 'incolla' non disponibile

Buonasera,
in una form che ha sempre funzionato senza problemi, ha cominciato ad uscire il msg in oggetto quando duplico il record corrente. Il pulsante di duplica ha una routine che esegue la copia (non riesco ad inserirla perché sto scrivendo dal cell).
Comunque è la "classica" routine DoCmd.Copy, ecc.
Non ha la macro dei pulsanti creati con il wizard.
La form ha 6 controlli da copiare, ma se apro gli appunti di access vedo la copia ma solo di tre controlli.
Qualche spunto?

18 Risposte

  • Re: Comando o azione 'incolla' non disponibile

    Esponi dettagliatamente il problema:
    - nomi propri di tutti i controlli
    - il codice VBA completo
    - spiega anche perchè vuoi fare questa operazione
  • Re: Comando o azione 'incolla' non disponibile

    Sicuramente hai fatto qualche modifica che ha portato a questo. Modificato qualche origine dati, qualche query, o trasformato una query. Normale in una query di aggregazione?
  • Re: Comando o azione 'incolla' non disponibile

    OsvaldoLaviosa ha scritto:


    Esponi dettagliatamente il problema:
    - nomi propri di tutti i controlli
    - il codice VBA completo
    - spiega anche perchè vuoi fare questa operazione
    Nella form ho i seguenti controlli (i nomi sono semplificati per maggiore chiarezza...):
    -IDore (PK)
    -IDdipendente (FK) da casella di riepilogo a 2 campi (IDdipendente non visibile e nome) appoggiata a tabella Elenco dipendenti
    -Data
    -Commessa (FK)
    -Operazione
    -Orelavorate
    -Note
    + ulteriori caselle di testo non associate che utilizzo come appoggio di dati (ved.sotto).
    La form e' usata per inserire le ore giornaliere dei dipendenti con la relativa commessa e l'eventuale operazione specifica della commessa. Ogni dipendente giornalmente compila un rapportino che settimanalmente ritiro e inserisco nel DB.
    Il comando duplica lo uso per non digitare ogni volta l'IDdipendente e la data, ma duplico, cambio commessa, operazione ed eventualmente le ore lavorate, oppure duplico, cambio data, commessa, operazione e ore.
    La routine duplica e' la seguente:
    Private Sub cmdfrmOLduplica_Click()
    On Error GoTo Err_cmdfrmOLduplica_Click
        
        DoCmd.RunCommand acCmdSelectRecord
        DoCmd.RunCommand acCmdCopy
        DoCmd.RunCommand acCmdRecordsGoToNew
        DoCmd.RunCommand acCmdSelectRecord
        DoCmd.RunCommand acCmdPaste
        
        frmOLDATAtabOLda.SetFocus
    Exit_cmdfrmOLduplica_Click:
        Exit Sub
    
    Err_cmdfrmOLduplica_Click:
        MsgBox Err.Description
        Resume Exit_cmdfrmOLduplica_Click
        
    End Sub
    Facendo il debug, ho notato che dopo il comando acCmdSelectRecord si attiva l'evento Current della maschera con cui chiamo la seguente function:
    Public Function OreGiorno()
    On Error GoTo Err_OreGiorno
        
        Dim dbs As DAO.Database
        Dim qdf As DAO.QueryDef
        Dim rst As DAO.Recordset
          
        Set dbs = CurrentDb
        Set qdf = dbs.QueryDefs("QryGiornalieroOreDip")
            qdf.Parameters![Maschere!FormOreLavorate!frmOLDATAtabOLda] = Me.frmOLDATAtabOLda
            qdf.Parameters![Maschere!FormOreLavorate!frmOLNUMtabOLIDtabEDid] = Me.frmOLNUMtabOLIDtabEDid
        Set rst = qdf.OpenRecordset
        Me.frmOLNUMOreGiorno = rst.Fields(2).Value
        rst.Close
        qdf.Close
        Set dbs = Nothing
        
    Exit_OreGiorno:
        Exit Function
    
    Err_OreGiorno:
        MsgBox Err.Description
        Resume Exit_OreGiorno
    
    End Function
    Esplicito:
    I parametri della QryGiornalieroOreDip sono i valori Data (frmOLDATAtabOLda) e IDdipendente (frmOLNUMtabOLIDtabEDid), la query restituisce la somma delle ore di quel giorno, copio poi il valore in una casella di testo non associata (frmOLNUMOreGiorno). Questo valore mi serve per controllare se i dipendenti hanno segnato correttamente tutte le ore della giornata (spesso non arrivano a contare fino ad 8....).
    Ho provato ad eliminare l'evento della maschera, ma continua a dare l'errore (non sempre purtroppo) ma ogni tre quattro dupliche, per cui penso ci sia qualcosa che interferisca quando esegue il Paste. volevo provare a rimuovere il controllo e rifarlo con il wizard, per vedere se con la macro invece che con il codice da' lo stesso problema
  • Re: Comando o azione 'incolla' non disponibile

    Scusa ma farlo da codice non ti piace invece che scrivere codice di quel tipo ingestibile...?

    Su record Corrente hai un Pulsante DUPLICA...

    Ovviamente sostituisci "ID" con il Nome della tua PK ovviamente che non devi duplicare...!
    Private Sub DuplicaCorrente_Click()
        Dim rs  As DAO.Recordset
        Dim fld As DAO.Field
        Dim vID As Variant
        Set rs = DBEngine(0)(0).OpenRecordset("SELECT * FROM T1 WHERE ID=" & Me.ID, dbOpenSnapshot, dbReadOnly)
        With Me.RecordsetClone
            .AddNew
            For Each fld In rs.Fields
                If fld.Name <> "ID" Then
                    .Fields(fld.Name) = fld
                End If
            Next
            .Update
            .Bookmark = .LastModified
            vID = .Fields("ID")
            Me.Requery
            .FindFirst "ID=" & vID
            Me.Bookmark = .Bookmark
        End With
        rs.Close
        Set rs=Nothing
    End Sub
  • Re: Comando o azione 'incolla' non disponibile

    @Alex ha scritto:


    Scusa ma farlo da codice non ti piace invece che scrivere codice di quel tipo ingestibile...?
    Bisognerebbe dirlo a Microsoft che il codice e' ingestibile, visto che e' quello che fa Access se si inserisce con il wizard un pulsante duplica record....
    Comunque grazie Alex per il suggerimento: lo dovro' studiare perche' la mia conoscenza di VBA non e' cosi' approfondita e voglio capire come funziona la parte che gestisce l'incremento dell'ID.
  • Re: Comando o azione 'incolla' non disponibile

    Mailman ha scritto:


    Bisognerebbe dirlo a Microsoft che il codice e' ingestibile, visto che e' quello che fa Access se si inserisce con il wizard un pulsante duplica record....
    No, MS mette a disposizione tante cose, anche le Macro ad esempio che a me fanno ribrezzo, ma c'è chi le usa... spesso chi non ha molta conoscenza tecnica di base e proprio per questo non ha la sensibilità di capire il motivo per cui sono limitate, e nemmeno capire perchè il vba offre una completa gestibilità del prodotto.
    Lo stesso concetto si applica ai comandi rapidi, come appunto quelli introdotti dalla conversione delle macro in codice, la maggior parte attinenti alla Classe Ducmd.Runcommand ecc...

    Penso sia bene conoscere TUTTI i metodi messi a disposizione dallo strumento che si usa, ed avere la capacità di capire poi quale sia quello più adatto, ovvio che se ne conosci solo 1 diventa complesso mettersi in discussione...

    Quindi io mio è proprio uno spunto a te, magari è bene riuscire a fare un passo tecnico in avanti...?
    Penso ne avrai grandi benefici.

    Mailman ha scritto:


    Comunque grazie Alex per il suggerimento: lo dovro' studiare perche' la mia conoscenza di VBA non e' cosi' approfondita e voglio capire come funziona la parte che gestisce l'incremento dell'ID.
    L'incremento ID è automatico(se il campo è di tipo Counter Autoincrementale)... quindi non va gestita infatti come vedi nel mio codice in sostanza lo SKIPPA, poi recupero il valore in quanto dopo l'inserimento del NUOVO CLONATO, devo fare il Requery della maschera, che riporterebbe il Puntatore(Bookmark) al primo, mentre a me piace di più che venga spostato a quello appena inserito, sicchè allineo il Bookmark del RecordsetClone con quello di maschera e sposto al NUOVO.

    In ogni caso se vorrai analizzare nel dettaglio il codice suggerito sempre disponibile.
  • Re: Comando o azione 'incolla' non disponibile

    Penso sia bene conoscere TUTTI i metodi messi a disposizione dallo strumento che si usa, ed avere la capacità di capire poi quale sia quello più adatto, ovvio che se ne conosci solo 1 diventa complesso mettersi in discussione...

    Quindi io mio è proprio uno spunto a te, magari è bene riuscire a fare un passo tecnico in avanti...?
    Penso ne avrai grandi benefici
    Ehh, il problema infatti e' conoscerli TUTTI, ce ne sono talmente tanti che sapere per ognuno cosa fa e come applicarlo ci vogliono anni e anni...
    Comunque io sempre pronto a fare passi avanti.
    In effetti sul problema evidenziato mi ero fatto una idea, forse bizzarra, ma ve la sottopongo: ho notato che nella cartella appunti, dopo aver fatto il DoCmd.RunCommand acCmdCopy apparivano tutti i campi presenti nella maschera (anche quelli non associati), per cui ho pensato che forse lui va ad incollare il recordset copiato fatto di 12 campi, in una tabella che ne ho solo 7.
    Potrebbe essere?
    Taborelavorate


    Frmorelavorate in modalita' foglio dati


    Ad ogni modo ho adattato il codice come suggerito da Alex e ho messo dei commenti (edit)...:
    Private Sub cmdfrmOLduplica_Click()
    On Error GoTo Err_cmdfrmOLduplica_Click
    
        Dim rs  As DAO.Recordset    'dichiaro la variabile rs
        Dim fld As DAO.Field        'dichiaro la variabile fld
        Dim vID As Variant          'dichiaro la variabile vID
        Set rs = DBEngine(0)(0).OpenRecordset("SELECT * FROM TabOreLavorate WHERE IDtabOLid=" & Me.frmOLIDtabOLid, dbOpenSnapshot, dbReadOnly) 'apro il recordset _
                                                                        selezionando dalla tabella quello che ha ID uguale all'ID corrente della maschera
        With Me.RecordsetClone      'clono il recordset
            .AddNew                 'e lo aggiungo
            For Each fld In rs.Fields               'copio tutti i valori del RSClone nel nuovo recordset
                If fld.Name <> "IDtabOLid" Then     'ad eccezione dell'ID,
                    .Fields(fld.Name) = fld         'in base al nome del campo
                End If
            Next
            .Update                                 'aggiorno il recordset
            .Bookmark = .LastModified               'metto un segnalibro sull'ultimo recordeset modificato
            vID = .Fields("IDtabOLid")              'associo la variabile vID all'ID dell'ultimo modificato, perche??
            Me.Requery                              'Faccio il riordino della tabella
            .FindFirst "IDtabOLid=" & vID           'sincronizzo il recordset con quello che ha ID = al valore della variabile (quindi l'utimo modificato)
            Me.Bookmark = .Bookmark                 'sposto il segnalibro della maschera sul recordset sincronizzato
        End With
        rs.Close
        Set rs = Nothing
        Me.frmOLDATAtabOLda.SetFocus    ' sposto il focus sul campo data
    Exit_cmdfrmOLduplica_Click:
        Exit Sub
    
    Err_cmdfrmOLduplica_Click:
        MsgBox Err.Description
        Resume Exit_cmdfrmOLduplica_Click
        
    End Sub
    
  • Re: Comando o azione 'incolla' non disponibile

    Mailman ha scritto:


    ...
    ho messo dei commenti per chiedere a voi se ho capito la sintassi della routine:
    ...
    è un forum ... non un corso
  • Re: Comando o azione 'incolla' non disponibile

    è un forum ... non un corso
    Giusto, ho rimosso
  • Re: Comando o azione 'incolla' non disponibile

    Un suggerimento [Mailman], quando commenti il codice, limitati ad inserire commendi UTILI.
    Questo ad esempio lo trovo inutule in quanto è OVVIO che siano dichiarazioni di variabili...
    
    Dim rs  As DAO.Recordset    'dichiaro la variabile rs
    Dim fld As DAO.Field        'dichiaro la variabile fld
    Dim vID As Variant          'dichiaro la variabile vID
    Potrebbe esser epiù utile ad esempio
    
    Dim vID As Variant          ' ID(PK) del Nuovo Record Clonato
    I Recordset, e di conseguenza la Maschera, sono una sorta di Elenco, questi elenchi hanno un riferimento di Item Corrente, quello che in quel momento è "attivo"... questo è il Bookmark(Segnalibro).
    Il RecordsetClone di maschera è sempre Sincronizzato con il Recordset di maschera, salvo quando si opera sul RecordsetClone per Ricerca/Edit/AddNEw/Delete, in quel momento i 2 Bookmark possono non essere più allineati.

    Ora è fondamentale sapere che il RecordsetClone, al contrario del Recordset di Maschera non si porta dietro gli eventi di Maschera, e questo è il motivo per cui si usa questo.
    Mi spiego meglio, se sposti il Bookmark del Recordset di maschera si scatenano gi eventi di Repaint di maschera, di conseguenza è come usare il Pulsante Avanti/Indietro.
    Questo sistema non ha senso se si deve ciclare l'intero recordset, in quanto è LENTISSIMO proprio per la necessità di ridisegnare la maschera e gestire gli eventi correlati(Current).

    Per questo motivo si usa il RecordsetClone che, appunto Clona il Recordset di Maschera, non genera Repaint ed Eventi, consente la manipolazione, però alla fine richiede la sincronizzazione

    Nel codice sopra la necessità di Sinctronizzazione avviene in 2 Momenti per 2 motivi diversi.
    PRIMO CASO
    
    Me.RecordsetClone.Update                                
    Me.RecordsetClone.Bookmark = Me.RecordsetClone.LastModified
    In questo caso dopo aver fatto l'ADDNEW, e di conseguenza l'UPDATE, è come aver fatto il Requery, ma non della maschera del RecordsetClone, quindi il Bookmark torna al 1° dell'elenco.
    Noi però dobbiamo ricavare l'ID del NUOVO, e per farlo dobbiamo tornare con il Bookmark al Record Aggiunto, per questo si usa il Riferimento a LastModified.

    SECONDO CASO
    Me.Bookmark = Me.RecordsetClone.Bookmark
    Fatto l'aggiornamento del Clone, e recuperato l'ID memorizzandolo in [vID], faccio il requery della Maschera, questo fa allineare il Recordset di Maschera, in quanto quando si è in presenza di Azioni come AddNew o Delete, serve rieseguire la Query, ed anche il RecordsetClone in quanto l'azine di Requery di maschera li riporta al 1° entrambi.
    Noi però se vogliamo andare al [vID] spostiamo il Clone, e poi riallineiamo la maschera.

    Sembra complicato... ma è tutto molto pulito e lineare... cpaita la filosofia.
  • Re: Comando o azione 'incolla' non disponibile

    Grazie Alex tutto molto chiaro
  • Re: Comando o azione 'incolla' non disponibile

    Buonasera,

    chiedo consiglio riguardo ad una modifica del codice di duplicazione records pubblicato nei post precedenti: in una maschera, oltre al campo ID, avrei altri due campi che non posso duplicare in quanto anch'essi indicizzati e duplicati non ammessi, per cui ho fatto questa modifica che funziona ma non so se e' il modo corretto di procedere. Mi potete dare consiglio?

        ...
        With Me.RecordsetClone
            .AddNew
            For Each fld In rs.Fields
                If fld.Name = "IDtabANid" Then			'campo ID da non duplicare
                GoTo 10
                End If
                If fld.Name = "DEStabANcespite" Then	'campo indicizzato, duplicati non ammessi
                GoTo 10
                End If
                If fld.Name = "DEStabANcodice" Then		'campo indicizzato, duplicati non ammessi
                GoTo 10
                End If
            .Fields(fld.Name) = fld
    10:
            Next
            .Update
    ...
  • Re: Comando o azione 'incolla' non disponibile

    Elimina l'uso del GoTo.

    For Each fld In rs.Fields
        If fld.Name Not IN ("IDtabOLid", "DEStabANcespite", "DEStabANcodice") Then
             .Fields(fld.Name) = fld
        End If
    Next
  • Re: Comando o azione 'incolla' non disponibile

    Buongiorno Phil,

    grazie per la risposta ma il suggerimento sembra non funzionare (dopo IN da errore “Previsto: espressione”).  La funzione "IN" e' SQL e non VBA. Vedi il seguente post:

    https://www.access-programmers.co.uk/forums/threads/using-an-in-statement-in-vba.219298/

    Sto testando sia con Eval che con Select Case, faccio sapere

Devi accedere o registrarti per scrivere nel forum
18 risposte