Excel, Copia/Incolla e il DataObject (Oggetto DataObject). - pagina vista: volte
requisiti: conoscenza uso del menu Strumenti/Riferimenti del VBE (Visual Basic Editor))

 

Questo articolo l'ho pubblicato nell'aprile del 2007 su un sito che ospita articoli, news, aggiornamenti ecc. sulla programmazione in generale, compreso il VBA di Excel, sotto lo pseudonimo di maibe.

Non ho mai "mescolato" questo articolo con i miei di questo sito, ma il "responsabile" della sezione dove è stato inserito su quel sito, ha modificato il nome di determinate variabili, usando si, una terminologia più consona all'identificazione di variabili, ma di fatto alterando il mio lavoro, che anche se è sicuramente un lavoro da dilettante (nomino le variabili molto spesso usando semplici lettere dell'alfabeto: X, Z, Y, ecc.) funziona e svolge egregiamente il compito assegnato alla variabile, e che desideravo venisse pubblicato così come io l'avevo compilato. Per quelle modifiche non richieste, che mi sanno solo di pignoleria, e non di precisione, ho deciso di eliminare l'esclusività che a suo tempo fornii a quel sito sul sottostante articolo, e lo propongo ai lettori del mio sito.

l'articolo:

In Excel molto spesso eseguiamo operazioni di Copia/Incolla di contenuti di celle e/o di interi intervalli di celle. Il passaggio tra l'azione di Copia e il successivo Incolla avviene sfruttando un'area della memoria RAM chiamata "Appunti" o "ClipBoard". E' in quest'area che vengono collocati i dati copiati, e restano lì fino a che non verranno incollati in una destinazione appropriata, e comunque si cancelleranno allo spegnimento del computer, oppure verranno sostituiti da una nuova azione di Copia : l'ultimo dato in memoria viene sempre sostituito da ciò che viene di nuovo Copiato.

In Excel usiamo le istruzioni vba Copy e Paste per svolgere le relative operazioni, istruzioni che ci consentono di "mandare" in memoria dati (Copy) o di "incollare" dalla memoria (Paste) i dati che vi sono al momento contenuti. Per queste operazioni sfruttiamo le risorse che il Sistema Operativo mette a disposizione (RAM e/o PageFile (file di scambio: area dell'hard-disk pre-destinata, dove vengono fisicamente scritti i dati mandati in memoria se la dotazione RAM del computer fosse insufficiente a contenere i dati stessi; poichè "scrivere/leggere" sull'hard-disk risulta molto più lento rispetto alla velocità di elaborazione della RAM, ecco spiegato perchè a volte l'operazione di Copia/Incolla di grandi quantità di dati  risulta all'utente più lenta, e può arrivare a bloccare il computer (risorse insufficienti).) In ogni caso, l'azione di Copy o Paste, avviene sfruttando l'area di memoria "Appunti".

In Excel (tramite il vba) è però possibile usare un'altro sistema per le operazioni di Copia/Incolla sfruttando l'"oggetto" DataObject. Per poterlo utilizzare è però necessario aver caricato, dal menu Strumenti/Riferimenti del VBE, la libreria "Microsoft Forms 2.0 Object Library "  corrispondente al file FM20.DLL che si trova nella cartella Windows/System32.

L'oggetto DataObject è un "contenitore" per dati che vengono trasferiti da un componente di origine a un componente di destinazione. I dati vengono memorizzati utilizzando l'oggetto DataObject nel formato definito dal metodo applicato. Anche se il DataObject sfrutta la memoria di sistema per contenere dati copiati, NON è da intendersi come area "Appunti".

DataObject supporta attualmente solo formati testo.

Nel DataObject è possibile inviare(Copia) e/o scaricare (Incolla) formati differenti di dati: il formato è un argomento (facoltativo) che può essere un numero intero o stringa (definiti dall'utente) che specifica il formato di DatiMemorizzati. Quando si recuperano dati da DataObject, il formato identifica i dati specifici da recuperare. In assenza della definizione di un formato, verrà assunto (di default) il formato 1, (testo). In pratica definire un formato è come se si assegnasse un numero indice che identifica in modo univoco un "lotto" di dati presenti nel DataObject.

Sia in DataObject che negli Appunti è possibile memorizzare più dati contemporaneamente, a condizione che il loro formato dati sia diverso. Se si memorizzano dati in un formato già utilizzato, questi verranno salvati mentre i dati precedenti verranno eliminati.
Tra i Metodi sopportati da DataObject, useremo solo questi metodi facendo poi degli esempi:

  • Metodo SetText   - serve per copiare (come una stringa di testo) dei dati  e inviarli nel DataObject.

  • Metodo GetFormat  -  serve per controllare se un determinato formato (un intero o una stringa) è presente in DataObject.

  • Metodo GetText  -  recupera una stringa di testo da un oggetto DataObject utilizzando il formato specificato.

  • Metodo PutInClipboard  - serve ad inviare agli Appunti (ClipBoard) i dati presenti nel DataObject.

  • Metodo GetFromClipboard  - serve per copiare dati dagli Appunti in un  DataObject.

Questi metodi sono ben spiegati nella guida in linea, e quindi passiamo agli esempi che spiegheranno sintassi e azioni, ma prima una precisazione: l'argomento DataObject è più vasto e consente operazioni più articolate di quanto presentato in questo articolo, nato solo come alternativa al tradizionale metodo Copy/Paste, quindi esamineremo solo esempi di copia/incolla di dati numerici, testuali, date, orari, o anche formule; gli stessi verranno copiati come testo, e come tale verranno restituiti; per i numeri non ci sono problemi: excel, se il formato cella è impostato a generale o a numero, lo incollerà come numero normalmente, ma le date o gli orari, verranno incollati come testo oppure incollati (le date) ma convertite nel sistema inglese (mese/giorno/anno); sarà quindi necessario per la cella destinazione, prevedere nell'istruzione anche la formattazione in data italiana. Negli esempi che seguono uso spesso ActiveCell come cella contenente il valore da copiare o dove incollare, è evidente che al posto di ActiveCell potrete usare qualsiasi riferimento preciso a foglio/cella.

Un'ultima cosa, è possibile copiare più celle in un colpo solo , concatenandole; otterremo che nell'incollaggio i valori o le formule copiate, risulteranno come una unica stringa di testo. (azione utile quando si voglia riepilogare in una cella la composizione delle formule che producono risultati nelle rispettive celle).

primo esempio: simuliamo di voler copiare solo le formule che sono in due celle (in B1 e in C1); impostiamo una variabile "x" come Nuovo DataObject, poi usiamo il metodo SetText applicato alla variabile "x" (visto ora come New DataObject) per copiare/inviare le formule delle celle nel DataObject, quindi usiamo il metodo PutInClipBoard applicato alla variabile "x", per inviare il contenuto di "x" negli Appunti.

  • Sub CopiaFormula()
    Dim x As New DataObject
    x.SetText [B1].Formula & [C1].Formula 
     'usiamo & la concatenazione per unire le formule delle due celle
    x.PutInClipboard
    End Sub

Vediamo ora come recuperare i dati che sono negli Appunti: ora usiamo il metodo GetFromClipBoard per recuperare dagli Appunti il contenuto rappresentato da "x" e inserirlo in un DataObject, e il metodo GetText che serve a recuperare il contenuto dal DataObject assegnandolo (incollandolo) nella cella ora attiva sul foglio. Poichè l'unione di due formule non verrebbe vista di buon occhio da Excel che restituirebbe FALSO (giustamente) come risultato (?) delle due formule in una unica cella, dobbiamo anteporre un'apice che serve ad Excel per capire che quello che incolliamo è testo e non formule, quindi useremo due doppi apici per definire l'apice, concatenandolo a x.GetText:

  • Sub IncollaFormula()
    Dim x As New DataObject
    x.GetFromClipboard
    ActiveCell.Formula = "'" & x.GetText
    End Sub

considerazioni: abbiamo dovuto dichiarare il dimensionamento della variabile "x" come nuovo dataoggetto in entrambe le routine, visto che le dichiarazioni espresse in una routine si esauriscono con la fine della routine stessa. Potremo inserire però la dichiarazione Dim x As New DataObject nella sezione Generale - Dichiarazioni del modulo che ospita le nostre macro, evitando di scriverle in ogni macro; se poi la variabile "x" dovesse essere visibile in tutto il progetto, potremmo dichiararla come Pubblica: Public x As New DataObject  (Public anzichè Dim). Se invece del concatenamento, vogliamo copiare/incollare una sola formula, queste le due routine:

  • x.SetText [B1].Formula   (per copiare)
    x.PutInClipboard

  • x.GetFromClipboard       (per incollare)
    ActiveCell.Formula = x.GetText

ancora : se non vogliamo copiare/incollare la formula ma solo il contenuto di una cella:

  • x.SetText [B1].Value   (per copiare)
    x.PutInClipboard

  • x.GetFromClipboard       (per incollare)
    ActiveCell = x.GetText

Non scordiamoci di dichiarare il dimensionamento della variabile nella sezione Generale - Dichiarazioni.

Ora vediamo un esempio il cui il valore copiato è una data: basterà ricordarsi nell'incollaggio di definire la formattazione nel sistema italiano:

  • x.GetFromClipboard    (per incollare)
    ActiveCell = x.GetText
    ActiveCell = Format(ActiveCell, "dd/mm/yy")

Un ultimo esempio in cui facciamo uso del formato per permetterci di inserire nel DataObject più di un dato contemporaneamente, differenziandoli appunto con un identificativo (il formato) che ci consenta poi di incollare il dato voluto. Visto che come formati possiamo usare sia numeri interi che testo, e che il numero 1 è il valore con cui si identifica il valore di default, useremo 1 per inserire un dato di una cella , ed un nome, "pippo" per inserire il dato di un'altra cella. Ci conviene usare la zona Generale - Dichiarazioni per inserire il dimensionamento della variabile che verrà usata nelle 4 istruzioni : due per copiare le celle diverse, due per incollare in due celle diverse, quindi.

  • Dim x As New DataObject     (in sezione Generale - Dichiarazioni del modulo)

  • Sub CopiaFormatouno()
    x.SetText [A1].Value, 1
     'con 1 definiamo il formato che con SetText inviamo al DataObject
    x.PutInClipboard
    End Sub

  • Sub CopiaFormatodue()
    x.SetText [B1].Value, "pippo"  
    'con "pippo" definiamo il formato che con SetText inviamo al DataObject
    x.PutInClipboard
    End Sub

Ora avremo due dati diversi nel DataObject "x", ma distinti e riconoscibili dal formato diverso; ora potremo creare due distinte istruzioni (ma va bene anche una sola, basta differenziare i riferimenti alle celle) per incollare i due diversi dati: è sufficiente

  • Sub PasteFormatouno()
    x.GetFromClipboard
    [D10] = x.GetText(1) 
    'usiamo GetText che richiede di definire, tra parentesi, il formato che ci interessa
    '[D10] = Format([D10], "dd/mm/yy") 'nel caso che si debba incollare una data
    End Sub

Per incollare il secondo dato presente nel DataObject possiamo usare un'istruzione simile a questa sopra, ma è comunque consigliabile di istruire la condizione di verificare, tramite GetFormat , se il dato da incollare corrisponde ad un preciso formato :

  • Sub PasteFormatodue()
    If x.GetFormat("pippo") = True Then
     'controlliamo con GetText che sia presente il formato "pippo", se vero
    [G12] = x.GetText("pippo")             
     'rendiamo la cella G12 uguale al corrispondente formato del DataObject
    End If
    End Sub

Relativamente a questo articolo potete chiedere chiarimenti o comunicare suggerimenti e/o commenti (non siate violenti) all'autore, maibe

L'Autore. maibe è una libera associazione di due "loschi individui", di cui solo uno si diletta nel tentare suggerimenti sul vba di excel (be=ennius), l'altro si occupa solo di VB6.