domenica 30 dicembre 2007

Filtrare un report Access per l'esportazione

Ok, visto che finora qui su questo blog non ho fatto poi molto il nerd, è il caso di recuperare un po'...ma neanche troppo, visto che Access e VBA non sono roba da veri programmatori.

Comunque, oggi ho sfarfugliato un po' per un progetto a cui sto lavorando, e la soluzione che ho trovato è abbastanza interessante e tricky, per cui ho deciso di condividerla.

L'obiettivo è "ho un db Access, vorrei un file di Word per ciascun record che appare in un form con una lettera da mandare a ciascuno dei record stessi (che rappresentano dei clienti)"

Access, molto gentilmente, ha la macro built-in DoCmd.OutputTo che consente di esportare qualsiasi cazzimma, sia essa report, tabella, form o che altro su file Xls, Rtf, Html o Txt; capita a fagiuolo per esportare un report costruito ad-hoc in Rtf, per poterlo poi editare in Word, stamparlo e/o mandarlo per email (oltretutto Rtf è pure open standard, che è cosa buona e giusta).

Quindi, morale, aggiungo nel form un pulsante che faccia DoCmd.OutputTo blablabla per salvarmi su file il mio report (oltretutto Access, nel wizard dei pulsanti, ha pure quello per fare l'esportazione su file di un report, segno che è, effettivamente, un'operazione comune)...ma....problema!

Clicco sul mio meraviglioso pulsante nuovo, e il report non è filtrato, mi mostra tutti i record della tabella anzichè solo quelli che comparivano nel form.

Come risolvere? La soluzione, come vi avevo anticipato, è abbastanza tricky, non è l'apice dell'eleganza nè della manutenibilità, ma pare essere l'unica per filtrare un report prima di esportarlo con DoCmd.OutputTo.

In sostanza, bisogna creare una query fasulla, anche vuota, e settarla come origine dati del report; dopodichè, a runtime, bisognerà iniettare l'SQL desiderato nella query stessa:

Dim qd As DAO.QueryDef
Set qd = CurrentDb.QueryDefs("QueryTestReport")
qd.SQL = "Select * from persona where id_persona = " & idPersona

Dove, ovviamente, "QueryTestReport" è il nome della query dummy che usiamo per popolare il report.
In questo modo, posso popolare il report con dell'SQL arbitrario, settandogli la where clause come più mi pare e piace e filtrando quindi il report in base ai parametri che mi fanno comodo.

A questo punto, però, mi serve anche di aggiungere la logica che esporta un report separato per ciascuna riga del form...come si fa: a sto giro è abbastanza banale, visto che il form stesso consente di accedere al proprio RecordSet, sia per riferimento che per copia, banalmente con

Dim rs As Recordset
Set rs = Me.RecordsetClone

Posso quindi looparmi tutto il recordset (while not rs.EOF) e prendere le proprietà di ciascuna riga (rs("id_persona")), per usarle nel processo di esportazione del report.

Et voilà :)

Nessun commento: