Perché usare VBA per gestire file OOXML
Anticipo che in fondo a questo post fornisco una chicca per chi comincia ad apprezzare la gestione OOXML mediante VBA...
Prima consiglio caldamente di leggere questi miei specifici interventi sul tema OOXML:
http://blog.shareoffice.it/giannigiaccaglini/articles/9292.aspx
http://blog.shareoffice.it/giannigiaccaglini/articles/9361.aspx
Sul nuovo formato aperto di Word, Excel e PowerPoint 2007 ho già dato vari esempi didattici di gestione mediante macro VBA. Un paio li ho anche inseriti nel sito degli sviluppatori OOXML (http://openxmldeveloper.org/forums), inoltre sto facendo altre interessanti scoperte vincendo dure battaglie con l’assai lacunoso e oscuro Help fornito da VBA + DOM (ossia macro VBA con riferimenti a MS XML, libreria per gestire file XML secondo il paradigma DOM, Document Object Model). Nel frattempo mi sono reso conto che Microsoft offre abbondante supporto al tema, anche con un nuovo SDK ad hoc, nonché con la nuovissima creatura che arricchirà l’ultima versione di Visual Studio. Si chiama LINQ (Language Integrated Query) ed è dedicata tra l’altro alle query XML in generale e, credo, OOXML in particolare.
Troppa grazia davvero, specie a fronte della sorte francescana riservata a VBA +DOM. Allora perché intestardirsi con le macro? E qualcuno infierisce: che senso ha gestire file Excel 2007 (.xlsx o .xlsm) con macro contenute in un file Excel?
Rispondo, con tre buone ragioni:
· Il valore didattico, per chi vuol familiarizzarsi con OOXML, è indubbio e include i professionisti informatici, se costoro permettono;
· le operazioni fondamentali si possono fare pure col VBA, con una sintassi (divinamente, per me) molto più semplice rispetto a VB o C# e con tempi di sviluppo e debug ben più rapidi e immediati;
· soprattutto, specie con Excel, l’ambiente in cui recuperare dati (da componenti di file OOXML su disco) e, magari, compiere ulteriori elaborazioni fornisce già gratis et amore dei la griglia (o un documento Word) con comandi e funzioni di grande pregio; tutte cose che vanno create nei pur ricchi mondi dei programmatori pro; costoro magari si avvarranno di componentware specifico, attualmente mitico e di là da venire, però che pena, non li invidio…
Battute a parte, ovviamente i software tool più potenti sono indispensabili per creare degli emuli o cloni di Office (lo stanno facendo diversi produttori di suite open source per office basate su ODF – Open Document Format, formato standard ISO rivale di OOXML - tra cui la stessa Sun MicroSystem col suo Openoffice.org) e, soprattutto, per gestire query XML su molteplici database documentarie, su server aziendali.
Una lacuna di VBA + DOM e una chicca per colmarla
Da ultimo debbo ribadire che nel nostro beneamato mondo VBA arricchito col DOM brilla per la sua assenza la possibilità di accedere direttamente ai vari componenti di un file OOXML “zippati” in cartelle e archivi XML (e non solo). Anche se la faccenda non riguarda direttamente i power user, non guasta sapere che i succitati SDK & LINK permettono di farlo con istruzioni specifiche (per il resto, a parte formalismi, i paradigmi DOM e Xpath restano in ballo, quasi pari pari).
Dapprincipio noi poveri ci accontentiamo di questa serie di operazioni manuali:
1. cambio dell’estensione da, putacaso, xlsx in zip;
2. doppio clic sull’archivio rinominato e copia delle cartelle e file contenuti nello “zippo”;
3. incollaggio in una cartella di file predisposta allo scopo;
4. ri-battesimo del .zip nell’originario xlsx o quant’altro.
Premesso che nel web si trovano utility specifiche (le migliori a pagamento, ahimè) ecco la chicca con cui ci si può arrangiare:
Sub ZippaFileOOXLMEstraiInCart(Target As String, CartDestin As String)
Dim OggShell As Object, Estens As String, ZipTarget As String
'Controllo essenziale sul formato file
If Left(Right(Target, 5), 1) <> "." Then
MsgBox "Formato file non valido..."
Exit Sub
End If
'Cambia l'estensione del target in zip
Estens = Right(Target, 4)
ZipTarget = Replace(Target, Estens, "zip")
Application.DisplayAlerts = False 'Tacita le proteste
'sul cambio estensione
'Rinomina il target come file zip
Name Target As ZipTarget
'Controllo del n° elementi di ZipTarget (solo per debug)
Set OggShell = CreateObject("Shell.Application")
'Incredibile a dirsi: senza "" & nell'argomento
'di Namespace si ha ERRORE!!!
MsgBox "Numero item: " & OggShell.Namespace("" & ZipTarget).Items.Count
For Each oF In OggShell.Namespace("" & ZipTarget).Items
OggShell.Namespace("" & CartDestin).Copyhere (oF)
Debug.Print oF
Pausa 0.5 '500 millisec.
Next oF
Set OggShell = Nothing
'Rinomina il file zip come l'originario Target
Name ZipTarget As Target
End Sub
Sub Pausa(t As Single)
Dim TempoIniz As Single
TempoIniz = Timer
While Timer < TempoIniz + t
Wend
End Sub
Fornisco tale Sub come ricotta offerta però ai più esperti, che sono invitati a migliorarla (per un miglior controllo errori, tra l’altro). Ed ecco una banale routine di test, relativa a un file e a una cartella-ospite, per semplicità posti entrambi in C:\, ossia MioSpread.xlsx e MiaCartTemp:
Sub ProvaZippaEstrai()
ZippaFileOOXLMEstraiInCart Target:="C:\MioSpreadxlsx", _
Destin:=C:\MiaCartTemp"
End Sub
Il resto della storia? Consiste in lavori che i sullodati esperti interessati dovranno fare da soli (coraggio, io speriamo che ve la cavate!): per la creazione ex-novo di una certa MiaCartTemp (sugg. di nome ricavato da quello dell’originario OOXML, diciamo CartTempMioSpread nell’esempietto); per svuotare e/o eliminare la stessa al termine delle operazioni di elaborazione dei suoi contenuti; e soprattutto, nel caso di modifiche al file OOXML, di una Sub opposta ovvero per tradurre una cartella come la nostra MiaCartTemp in un file originario OOXML (o una sua copia aggiornata, se occorre).
Non per vantarmi ma queste cose le ho già fatte: sono tediose ma fattibili. A buon intenditor non ho altro da aggiungere.
?>
?>