http://digilander.libero.it/Cenati

Comandare Excel da Vbs

home | e-mail e contatti | Introduzione al sito | Cosa e' e come imparare VbScript

 

 

 

 

 

Premessa

Quanto segue parla in particolare di Excel, ma vale anche per Word, per Access e per Powerpoint. Questi programmi hanno un linguaggio di programmazione interno che è utilizzabile, a certe condizioni e con certe limitazioni, anche dall'esterno tramite il proprio modello ad oggetti.

Qui parlo di Excel perchè l'ho usato molto in questo modo. Essendo un programma molto complesso e versatile l'ho spesso utilizzato per chiedergli di portare a termine operazioni che avrebbero altrimenti richiesto script molto complessi. Ma mi è anche capitato di creare al volo dei testi con Word usando gli stessi metodi.

Per poter utilizzare questi applicativi bisogna ovviamente averli installati sul proprio computer e creare un riferimento all'oggetto che permetta di accedere alle proprietà ed ai metodi. Per istanziare excel si usa Excel.Application (vedi oltre nel testo), per Word si usa Word.Application, per Powerpoint Powerpoint.Application e per Access Access.Application. Io Access non ce l'ho e quindi non ho molte informazioni da dare. Ma ho trovato il modo di leggere i files mdb senza avere necessariamente Access.

Dopo aver creato l'istanza all'applicazione, bisogna aggiungere un foglio vuoto: documents.add per Word, Presentations.add per PPT e Workbooks.add per Excel. Occhio che sono al plurale. Per i comandi da utilizzare fate riferimento soprattutto all'help di VBA.

Excel e Vbs

Excel è un programma molto complesso, con moltissime funzioni e con un linguaggio di programmazione incorporato (il VBA, Visual Basic per Applicazioni) molto ricco e ben documentato. L'help disponibile quando si modifica una macro è dettagliato e costituisce un importante supporto alla programmazione. Basta premere F1 su una parola chiave per averne una descrizione esauriente. E' sufficiente iniziare a scrivere del codice per essere aiutati a completare l'istruzione con tutti i parametri nel giusto ordine.

La buona notizia è che Excel espone un modello ad oggetti istanziabile da VbScript e da qualsiasi altro linguaggio che si può interfacciare con gli oggetti COM (Common Object Model). E la documentazione, fatte le dovute premesse, è utilizzabile come valido supporto al programmatore.

Chi usa Excel prima o poi comincia a registrare delle macro. Una delle più frequenti riguarda la cancellazione di una serie di celle per pulire il modulo. E' facile, basta attivare il registratore di macro ed eseguire una volta per tutte le azioni più ricorrenti. Clicca su una cella, premi il tasto canc, seleziona un'altra cella, premi Canc, spegni il registratore di macro. A questo punto è facile anche mettere un pulsante sullo schermo per chiamare la macro registrata con un click.

Alcuni utenti (molto pochi) vanno oltre e cominciano a scrivere delle applicazioni più complesse direttamente nell'ambiente di sviluppo di Excel. Non si tratta più di essere limitati da quello che è registrabile, ma si può spaziare nelle possibilità di un linguaggio di programmazione piuttosto esteso. Anche in questa fase è utile, talvolta, registrare delle macro e poi andare a modificarle. Ad esempio per vedere tutte le possibili opzioni di un comando di formattazione delle celle. Attorno al codice generato automaticamente dal registratore di macro si può scrivere la propria applicazione.

E' bene chiarire subito che il VbScript e il VBA sono però due cose diverse. Il VBA è il linguaggio per scrivere applicazioni all'interno di MS Office ed ha alcune caratteristiche diverse da VbScript. Ad esempio in VBA le variabili possono essere di vari tipi: intere, booleane, stringa (e altri tipi). Invece in VbScript esiste un solo tipo di dati: il Variant. Per questo motivo in VBScript si possono dichiarare le variabili ma non si deve specificare di che tipo sono. Per intenderci, non bisogna utilizzare la sintassi di VBA (e Visual Basic) DIM NOME AS STRING ma ci si deve limitare a indicare DIM NOME.
VBA ha alcune istruzioni non utilizzabili dall'esterno, come ad esempio quelle relative alla gestione dei files (open, print#, close). Purtroppo è così, perchè per leggere e scrivere files di testo in VbScript è piuttosto complesso.
VBA accede direttamente al modello ad oggetti dell'applicazione ospite, per cui non è necessario istanziare il relativo oggetto. In pratica per scrivere in una cella da VBA si usa il metodo cells(riga,colonna)="prova". Al contrario, per fare la stessa cosa in VbScript è necessario istanziare preventivamente l'oggetto Excel (vedremo dopo come) ed accedere ad un metodo di quella classe: oggExcel.cells(riga,colonna)="prova".
Analogamente bisogna sottolineare che in Excel si ha accesso a tutta una serie di costanti di VBA che invece non sono disponibili in VbScript. In genere sono costanti il cui nome inizia con XL, quindi quando registriamo un macro e ci imbattiamo in una di queste costanti ci dovremo ricordare di dichiararla con il giusto valore nel nostro programma. Vediamo ora come si deve fare.

I parametri denominati e le costanti

Iniziamo a vedere un pezzo di programma che registrato con il registratore di macro di Excel.

Analizzando un programma in VBA generato automaticamente ci si imbatte nei "parametri denominati". Hanno una forma del tipo "shift:=xlUp" in una riga come

Rows(3).Delete shift:=xlUp.

Questo esempio cancella la riga numero tre, il parametro indica come far scorrere le righe restanti e in particolare dice che le celle sottostanti devono essere spostate in su.
I parametri denominati servono a capire più facilmente a cosa si riferisce il parametro n-esimo. Rendono più chiaro il codice VBA rispetto a mettere in fila tutti i parametri. Inoltre permettono di indicare i parametri (tutti o solo una parte) senza dover seguire un preciso ordine. Per trasferire una macro in VBS è necessario utilizzare l'help (F1) sul comando VBA per sapere in quale esatto ordine vanno indicati i parametri da passare alla funzione.
Dell'esempio "Rows(3).delete" bisogna dire alcune altre cose. Questo metodo vuole un solo parametro, quindi non si rischia di sbagliare posizione mettendolo al secondo o al terzo posto. I parametri denominati possono essere in qualsiasi ordine, in quanto sono definiti non dalla loro posizione dopo il comando, ma dal nome che li identifica. Inoltre è necessario specificare che per Excel la costante xlUp ha un valore, ma per VbScript invece non ne ha alcuno (tentando di utilizzare xlup, varrà zero). Per sapere quanto vale XlUp bisogna entrare nell'editor di Visual Basic incorporato in Excel (Strumenti - Macro - Visual Basic Editor). Dall'editor scegliere dal menu il comando Visualizza - Finestra Immediata.
Apparirà una piccola finestra in basso, nella quale potete dare alcuni comandi. In particolare dovrete digitare "? xlup" (senza le virgolette) per chiedere ad Excel quanto vale la costante xlup. Vi risponderà probabilmente che vale -4162. Nel nostro programma in Vbs sarà necessario specificare questo valore. Meglio ancora, potremo mantenere il nome della costante ma dichiarandolo all'inizio del programma con CONST xlUp=-4162. In questo modo il codice ne guadagnerà il leggibilità in quanto si può far riferimento alle stesse costanti utilizzate da Excel.

C'è anche un altro modo di conoscere il valore delle costanti di Excel, è descritto nel penultimo paragrafo di questa pagina.

Ecco, questo in sintesi è la principale accortezza da usare per trasferire una macro di Excel in un programma VbScript: scrivere i parametri nell'ordine giusto ed eventualmente dichiarare le costanti di excel utilizzate.

Ecco un altro esempio di codice VBA, riferito questa volta alla stampa del foglio corrente:

ActiveWindow.SelectedSheets.PrintOut Copies:=1 

Il parametro denominato "Copies" indica che si intende stampare una sola copia del foglio. In VBA questa sintassi è corretta, anche se il metodo PrintOut ammette numerosi parametri e anche se Copies non è il primo parametro da indicare. Guardando l'help in linea (nell'editor di Visual Basic scrivo Printout, ci vado sopra e premo F1) scopriamo che la sintassi completa è PrintOut(From, To, Copies, Preview, ActivePrinter, PrintToFile, PrToFileName, Collate).

L'uso dei parametri denominati permette di indicarne anche solo uno (in questo caso il terzo), senza seguire un ordine preciso. Potrei anche scrivere ActiveWindow.SelectedSheets.PrintOut ,,1 (con due virgole prima del numero uno) ed otterrei lo stesso risultato. L'uno che ho scritto è infatti in terza posizione e mettendo le virgole ho lasciato il posto ai primi due parametri, pur senza specificarne il valore.

Trasformare VBA in VBS

Dopo tante parole, veniamo al dunque. Cosa bisogna fare per attivare Excel e pilotarlo dall'esterno? Prima di tutto bisogna istanziare l'oggetto appropriato con un comando del genere Set objXL = CreateObject("Excel.Application")

Poi è necessario rendere visibile la finestra del programma e dire ad Excel di aggiungere un foglio vuoto: objXL.visible=true objXL.Workbooks.add

Per accedere ad una singola cella in lettura o in scrittura si usa la funzione objXL.Cells(riga, colonna). Per selezionare un foglio si può far riferimento alla sua posizione (il numero uno, il numero due, ecc) con objXL.Sheets(1).select oppure al suo nome, con objXL.Sheets("Giovanni").select. Nell'esempio si vede anche come assegnare un nome al foglio, modificando quindi la scritta sulla linguetta in basso.

Una funzione fondamentale da conoscere è objXL.cells(riga, colonna), che serve a leggere o scrivere in una determinata cella del foglio corrente. Con questa funzione possiamo fare un po' di tutto, come ad esempio trovare la prima cella libera in una colonna. Nell'esempio riportato sotto ho creato un ciclo che partendo dalla decimillesima riga risale verso l'inizio del foglio alla ricerca de una cella non vuota. Quando la trova esce dal ciclo e la variabile "UltimaRiga" avrà come valore quello dell'ultima riga contenente qualcosa. E' un pezzo di codice utile per trovare il posto dove aggiungere dati. Ovviamente bisognerà scrivere nella riga successiva a quella trovata, per non sovrascrivere l'ultimo dato.

'Apre excel per scriverci i dati
Set objXL = CreateObject("Excel.Application")
objXL.visible=true
objXL.Workbooks.add 'Aggiunge un foglio vuoto

objXL.Sheets(1).Name = "Giovanni"
objXL.Sheets(1).select

'Ora scrivo l'intestazione nella cella B1
objXL.cells(1,2)="Intestazione"


'trova l'ultima Riga occupata dai dati...
'partendo dal fondo così risolvo eventuali celle vuote nelle intestazioni.
UltimaRiga=10000
do while objxl.cells(ultimaRiga,1)=""
     UltimaRiga=UltimaRiga-1
loop 
'Ora UltimaRiga ha un valore valido

objXL.cells(1,1).Select 'seleziona la cella a1

set obXL=nothing  

Come trovare il valore delle costanti di Excel

Dunque, abbiamo detto che per ottenere il valore di una costante di Excel bisogna usare la finestra "immediata" dell'editor di VBA. C'è anche un modo più semplice.

I files ".wsf" sono molto simili ai vbs, ma permettono di fare anche altre cose. Ad esempio incorporano la descrizione del programma e l'esempio di utilizzo. Questi dati sono ottenibili richiamando lo script .wsf dalla linea di comando.

Inoltre si possono usare i parametri denominati per passare dei dati allo script. Ma credo che le possibilità più importanti siano il fatto di poter includere librerie esterne e far convivere parti di programma in vbscript e in jscript.

Non mi dilungo sui files wsf. In questo contesto a noi interessa che è possibile collegarsi ad un oggetto condividendo la sua libreria di costanti e non solo le proprietà ed i metodi. Per farlo basta aggiungere un REFERENCE="TRUE" quando si specifica l'oggetto da istanziare.

Copia il programma riportato qui sotto in un file con estensione ".wsf" oppure scarica l'archivio zip contentente lo script. Per facilitare il copia & incolla del valore, è possibile anche usare una finestra di input per restituire il risultato. Si potrà copiare negli appunti usando ctrl-c e incollarlo nel proprio codice con ctrl-v.

<?xml version="1.0" standalone="yes" encoding="iso-8859-1" ?>
<package>
  <job id="CostantiExcel">
   <reference object="Excel.Sheet" reference="true"/>
   <script language="VBScript">
    <![CDATA[
   a = inputbox ( "Name della costante di Excel?" )
   b=inputbox("Valore di " & a , "Costanti di Excel", a & " = " & eval(a))
   msgbox a & " = " & eval(a)
    ]]>
   </script>
  </job>
</package>

Conclusione contro corrente

Se invece, dopo essere arrivati fino qui, preferite scrivere il codice direttamente in Excel. ecco come richiamare da VbScript una macro presente nel foglio. E così vediamo anche come si fa a richiamare un foglio già esistente.

filePath = "c:\Test.xls"
Set oExcel = CreateObject("Excel.Application")
oExcel.Workbooks.Open(filepath)
oExcel.Run "macro1"
oExcel.ActiveWorkbook.Save
oExcel.ActiveWorkbook.Close
oExcel.Quit
Set oExcel = Nothing

Giovanni Cenati

 

 

 

© Cenati Giovanni 2004/2010 - http://digilander.libero.it/Cenati - Reventlov at Katamail com

home | e-mail e contatti | Introduzione al sito | Cosa e' e come imparare VbScript