SendKeys:  Istruzione SendKeys e Metodo SendKeys  (sono diversi). - dal 04/09/04 pagina vista: volte

Uno degli argomenti (a mio avviso) più ermetici di Excel è sicuramente il SendKeys, che in traduzione libera, significa "invia il tasto...x" relativo ai tasti di una tastiera. Ermetici sia per l'interpretazione delle diversità tra "Istruzione" e tra "Metodo" e quindi di quando usarli, sia per i risultati che si ottengono, che sono quasi una sorpresa continua (cioè vorremmo ottenere una cosa, invece Excel ce ne restituisce un'altra). Anche le documentazioni librarie o della guida in linea, non aiutano a capire (parlo della mia esperienza) e mi sono trovato impelagato a volte in conflitti, nell'uso del SendKeys, con Excel, non riuscendo a capire se ero io che sbagliavo, o Excel che intendeva fischi per fiaschi.

Vorrei comunque provare a spiegare le diversità (col beneplacito di chi invece queste cose le conosce) ma non gli inconvenienti:

Metodo SendKeys  - intanto stiamo parlando di un "Metodo", cioè di una "azione" applicata ad un "oggetto", quindi un'azione che un "oggetto" può compiere. L'oggetto a cui si applica il metodo SendKeys è l'oggetto "Application", quindi Excel stesso. Ora sappiamo che in molte istruzioni in cui si debba fare riferimento ad un "oggetto", se l'oggetto è "Application" possiamo omettere di indicarlo. Questo è un primo punto che mi genera perplessità, infatti se scrivo:

  • Application.SendKeys "{DOWN}", True    oppure solo    •   SendKeys "{DOWN}", True  

Excel docile esegue, spostando la selezione di una cella alla cella successiva; ma il dubbio nel secondo esempio è: cosa avrà accettato Excel, il Metodo SendKeys, o l'Istruzione SendKeys che sintatticamente è uguale a SendKeys "{DOWN}", True (senza Application) e che provocherebbe lo stesso effetto?

Suggerirei quindi di usare il Metodo (con o senza Application) quando vorremo interreagire con Applicativi esterni ad Excel compatibili con Excel stesso, come in questo esempio tratto dal libro di Gianni Giaccaglini "Excel 2002 VBA" (e modificato in due piccoli errori), dove si chiama tramite la Shell, la Calcolatrice di Windows, e gli si invia una sequenza di tasti equivalenti a numeri presi da celle del foglio di lavoro, con copia del risultato di una moltiplicazione in memoria e incollaggio dalla memoria (ClipBoard) nella cella in quel momento attiva del foglio attivo:

  • Sub Calcolatrice()
    chiama = Shell("C:\Windows\system32\Calc.exe", 1)
    '(in WinXP: Shell("C:\Windows\System32\Calc.exe", 1))
    mdo = [B1].Value
     'variabili per prendere i numeri da moltiplicare (moltiplicando) dalle celle
    mre = [C1].Value  
    'variabili per prendere i numeri da moltiplicare (moltiplicatore) dalle celle
    SendKeys mdo & "*" & mre & "="
     'si inviano i valori concatenandoli con gli operatori * e =
    SendKeys "^c"   
    'equivale a CTRL + c (Control Copia) 
    ActiveSheet.Paste 
    'si incolla il risultato nella cella attiva
    SendKeys "%{F4}", True 
    'si chiude la calcolatrice; equivale a ALT + F4
    End Sub

La routine così funziona, ma accadono a volte inconvenienti che fanno supporre un bug (ripetendo le prove, si chiude la calcolatrice, ma si apre la finestra di Esplora Risorse, oppure Excel si riduce a icona, e non sempre).

Vorrei segnalare, anzi precisare una cosa, fonte di alcune domande postemi: SendKeys è attivo ed agisce sulla finestra in quel momento attiva (quindi un foglio di Excel, o come nell'esempio sopra, sulla calcolatrice). Se usiamo SendKeys lanciato da un pulsante posto su una UserForm, con l'intenzione di agire sul foglio di lavoro, non otterremo nessun risultato in quanto la finestra attiva in quel momento sarà la UserForm e non già il foglio sottostante. Inoltre azioni che prevedano ad esempio lo spostamento della selezione di una cella, non potranno mai avvenire se non avremo impostato la proprietà ShowModal della UserForm a False; ricordo che con questa proprietà impostata a True (di default) non è possibile agire altro che sulla UserForm (tranne che su Excel97 che rifiuta l'impostazione a False). Suggerisco un modo semplice di ovviare all'inconveniente: si nasconde l'UserForm, si lancia SendKeys in modo che possa agire sul foglio, e si richiama la UserForm, esempio per spostare la selezione alla cella sottostante :

  • Private Sub CommandButton1_Click()
    Application.ScreenUpdating = False
    UserForm1.Hide
    SendKeys "{DOWN}", True
    UserForm1.Show
    End Sub

Concluderei le note sul Metodo SendKeys senza anteporre Application, dicendo che quando usiamo SendKeys in genere stiamo usando il metodo, anche se probabilmente non lo sappiamo, anche perchè l'Istruzione SendKeys viene sfruttata con determinati eventi.

Unica controindicazione per entrambe : SendKeys non può inoltre essere utilizzata per inviare il tasto STAMP {PRTSC} a nessuna applicazione.

L'Istruzione SendKeys può venir utilizzata per inviare alla finestra attiva una o più sequenze di tasti, come se queste fossero state immesse tramite tastiera. In parole più semplici, consente di sostituirsi alla pressione su un tasto della tastiera (che decidiamo noi via codice) come se si fosse premuto quel tasto o combinazione di tasti. Le tastiere usano codici caratteri ANSI, che sono americani. Ma procediamo con ordine e vediamo cosa sono i "codici carattere".

Le tastiere utilizzano un set di caratteri  ANSI, set di caratteri a 8 bit dell'American National Standards Institute (ANSI) che consente di rappresentare fino a 256 caratteri (0–255) utilizzando la tastiera. I primi 128 caratteri (0–127) corrispondono alle lettere e ai simboli di una tastiera standard americana. I successivi 128 caratteri (128–255) rappresentano caratteri speciali, quali lettere di alfabeti internazionali, accenti, simboli di valuta e frazioni. Per scoprire come si "identifica" un codice ANSI, si può premere la combinazione dei tasti ALT + un numero di codice (ottenuti dai numeri del tastierino numerico) e nel documento vedremo comparire il carattere corrispondente. Se premiamo per esempio, ALT + 123, quando lasceremo il tasto ALT vedremo comparire una parentesi graffa aperta : { , se premiamo ALT + 125 vedremo una parentesi graffa chiusa : } . Ora, al di là di voler scoprire come comporre delle "emoticon", la conoscenza di questa procedura ci consente di, conoscendo il set ANSI, ottenere caratteri che non vediamo sulla tastiera, ma soprattutto di saper individuare il codice necessario per identificare i caratteri quando si lavora con l'Istruzione SendKeys.

Intanto allego a queste note, i due set di caratteri ANSI:    set 0-127      set 128-256
Il primo set di caratteri (0-127) corrisponde al Codice ASCII; si legge nella guida: Set di caratteri a 7 bit dell'American Standard Code for Information Interchange (ASCII) utilizzato diffusamente per rappresentare lettere e simboli delle tastiere standard americane. Il set di caratteri ASCII equivale ai primi 128 caratteri (0–127) del set di caratteri ANSI.
Comunque sono reperibili dalla guida in linea, cercando la parola ANSI, dove potete trovare anche la tabella delle Costanti dei codice dei tasti (vedere).

L'istruzione SendKeys  si può utilizzare solo in un evento preciso: cioè quando si preme un tasto della tastiera. Questo evento in realtà si divide in tre eventi, messi nell'ordine in cui si attivano:

  • KeyDown - quando l'utente preme un tasto, e a seguire, in simultanea:

  • KeyPress - quando viene premuto o inviato un tasto

  • KeyUp - solo quando l'utente rilascia un tasto

Di questi tre eventi, solo il KeyPress possiede come argomento della funzione il KeyAscii. Argomento necessario a creare la condizione di controllo Questi eventi,  non appartengono ad un foglio di lavoro, ma solo agli "Oggetti ActiveX", quali UserForm, CommandButton, TextBox, ecc. ecc.. Quindi tentativi di voler usare l'istruzione SendKeys su eventi del Workbook o del Worksheet come ad esempio il  Worksheet_SelectionChange o  Worksheet_Change falliranno in quanto il Worksheet non possiede gli eventi visti sopra. Ma passiamo ad esempi:

  • Controllo inserimento in una textbox : vogliamo solo numeri e non caratteri. Intanto precisiamo che Key (chiave) in questi casi è assimilato a "tasto". L'istruzione si può spiegare così. se il tasto (premuto) è inferiore al codice Ascii  48 oppure maggiore di 57 (da 48 a 57 sono i codici ascii corrispondenti ai numeri da zero a 9), allora invia  (SendKeys)  il comando al tasto Cancella (Del o Delete in inglese), ed avvisa con un messaggio, indi azzera il comando. In pratica se si preme una lettera, è come se si inviasse il comando a Canc (Delete) e la lettera non viene scritta:

  • Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If KeyAscii < 48 Or KeyAscii > 57 Then
    SendKeys "{DEL}", False
    MsgBox "Inserire solo numeri"
    KeyAscii = 0
    End If
    End Sub

Attenzione alla sintassi con la quale si scrive l'istruzione SendKeys: se si vuole come restituzione un qualsiasi carattere della tastiera, sarà sufficiente racchiudere il carattere tra doppi apici, per esempio se vorremo la A maiuscola, scriveremo:

SendKeys "A", False

se invece vogliamo usare caratteri ai quali non corrisponde una visualizzazione, quali INVIO o TAB, e tasti che rappresentano azioni piuttosto che caratteri, utilizzare i codici della seguente tabella allegata. Questi codici andranno inseriti tra due parentesi graffe chiuse tra due doppi apici, così:

SendKeys "{TAB}", False

Proseguendo con gli esempi, possiamo vedere come assicurarci di inserire una virgola quando vorremo essere sicuri che un numero decimale scritto in una textbox sia effettivamente impostato con la virgola e non col punto, usando il tasto del punto ( . )sul tastierino numerico. infatti questo tasto è in realtà un separatore di decimali, ma non dobbiamo scordarci che per gli inglesi il separatore decimale è proprio il punto ( . ), ed il codice "ragiona" in inglese. Per cui vedremmo nella textbox comparire un punto, anche se nel trasferimento del valore contenuto nella textbox in una cella, sarà riportata giustamente una virgola. Il codisce Ascii della virgola è 44, quello del punto è 46, quindi:

  • Immissione della virgola quando si preme il punto.

  • Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If KeyAscii = 46 Then
    SendKeys ",", False
    KeyAscii = 0
    End If
    End Sub

  • Non bisogna scordarci comunque che quando si trasferisce il contenuto numerico di una textbox ad una cella, è sempre meglio indicare il "tipo di dati" che si sta trasferendo, per cui, supponendo di usare un commandbutton per questa azione, dovremo scrivere il tipo di dati, che essendo un numero decimale, andrà preceduto da CDbl (tipo di dati Double), esempio:

  • Private Sub CommandButton1_Click()
    [A18].Value = CDbl(TextBox1)
    End Sub

Vediamo un altro caso di controllo inserimento dati: limitare l'inserimento a due lettere più numeri. Potrebbe essere il caso di codici articoli alfanumerici. In questo esempio simuliamo di poter inserire solo le lettere "a" (97) e/o "c" (99); i numeri ammessi saranno da 0 a 9. Se le lettere inserite sono "a" oppure "c" si esce dalla routine, se saranno diverse, con Else passiamo al SendKeys ed al messaggio. Se saranno numeri la prima condizione non si verifica e si passa al secondo controllo se (If).

  • Immissione di lettere e numeri.

  • Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If KeyAscii = 97 Or KeyAscii = 99 Then
    Exit Sub
    Else
    If KeyAscii < 48 Or KeyAscii > 57 Then
    SendKeys "{DEL}", False
    MsgBox "Inserire solo numeri op. lettere a o c"
    KeyAscii = 0
    End If
    End If
    End Sub

Se poi si volesse inserire anche un controllo per verificare il numero di caratteri immessi e limitarne l'introduzione, potremmo usare un'altra condizione nella stessa istruzione senza ricorre ad altri eventi della textbox. Nell'esempio sotto ripetiamo quello sopra ma con questa condizione: inserimento di max 7 caratteri, sfruttando la funzione Len applicata alla textbox:

  • Immissione lettere e numeri con limitazione del numero totale caratteri immessi.

  • Private Sub TextBox1_KeyPress(ByVal KeyAscii As MSForms.ReturnInteger)
    If Len(TextBox1) = 7 Then
    MsgBox "Inserire 7 crt. Max"
    Exit Sub
    End If
    If KeyAscii = 97 Or KeyAscii = 99 Then
    Exit Sub

    Else
    If KeyAscii < 48 Or KeyAscii > 57 Then
    SendKeys "{DEL}", False
    MsgBox "Inserire solo numeri op. lettere a o c"
    KeyAscii = 0
    End If
    End If
    End Sub
     

Come vedete, bastano poche istruzioni per ottenere ciò che si desidera. Un interessante argomento sul tema, potete leggerlo Metodo ONKEY"



Buon lavoro.

 

prelevato sul sito www.ennius.altervista.org