Il blog di Gianni Giaccaglini

Blog su VBA e VSTO
Gianni Giaccaglini

My Links

News

NB - V. anche gli ARTICOLI (in fondo a questa barra)
Solo quesiti validi a: giannigiac@tin.it
Il mio nuovo libro


La mia nipotina ELISA

Foto con dedica a ME di
Bill Gates giovanissimo
nei mitici anni 80!

Categorie Post

Categorie Articoli

Archivio

Immagini

Blog Stats

Perché usare VBA per gestire file OOXML (e una chicca per estrarne i componenti in una cartella di file)

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/9165.aspx

http://blog.shareoffice.it/giannigiaccaglini/articles/9290.aspx

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.

?>

?>

posted on mercoledì 9 gennaio 2008 18.37