My good friend and colleague, John Goldsmith, recently blogged about the Visio SaveAsWeb feature (see http://visualsignals.typepad.co.uk/vislog/2010/03/automating-visios-save-as-web-output.html ), and mentioned that I was going to blog about automating the SaveAsWeb when a linked DataRecordset refreshes … so here it is! This is my version of a poor man’s Visio Services … which is only available with Visio 2010 Premium and SharePoint 2010 with an eCAL.
Firstly, the code is written in VBA, and utilises a module that is in the Visio SDK Samples library. The modSaveAsWeb file can be found in the Publishing category:
Secondly, this example is for Visio 2007 Pro, or Visio 2010 Pro and Premium because of the DataRecordsets that I am about to discuss…
The modSaveAsWeb module contains one useful public method, SaveDocAsWebPage( ByVal vsoDocument As Visio.Document, ByVal startPage As Integer, ByVal endPage As Integer, ByVal webFileName As String, ByVal flags As Integer) As Boolean.
You will need to insert the SDK module into the VBA project of a Visio document that contains the linked DataRecordset. For this example, I have used the sample IT Asset Management drawing that is linked to the ASTMGT.XLS file. This file can be found in the <Program Files>Microsoft OfficeOffice12Samples1033 folder for Visio 2007, or the <Program Files>Microsoft OfficeOffice14Visio Content1033 for Visio 2010. You should not edit any files in these protected folders, so copy the file to one of your own, then change the data source in your Visio document to the copy that you just created.
Whilst you have the Configure Refresh dialog open, you should change the Automatic Refresh interval. I changed it to 1 minute for testing purposes.
In this example, the network equipment shapes are linked to the Excel worksheet rows, and the Status column is linked to the Status Shape Data row. This value is linked to the icon in the top right corner of each shape. So, as you can see in the following screenshot, the red circle with a white cross denotes the Unavailable status on the server with the 10.0.1.52 IP address.
In this example code, I have saved the web page to the same folder as the Visio document.
I inserted some code into the ThisDocument class of the VBA project because this class already provides an object, Document, which has events.
I created a new Visio.DataRecordsets object, mDatasets, and set it have events with the WithEvents keyword. I don’t normally like to use WithEvents because it can be very chatty and slow down your application, but the DataRecordsets object only has three events. We only need one of them, DataRecordsetChanged, however we do not want to save the file, or generate a web page, every time the DataRecordsets changes, because this event is fired each time the DataRecordsets is refreshed, regardless of whether anything was actually changed. So, we need to check if anything has indeed changed before calling SaveDocAsWebPage. Therefore, you can check the contents of data before and after the refresh. I simply stored the previous data as an string, then checked if the new data string is the same length. You could get more sophisticated than my method, but this is just an example.
So, this listening to the DataRecordsets changes is initiated by the StartListening() method, and I have hooked that into the DocumentOpened event. Therefore, this drawing will always do at least one SaveAsWeb on open, but will only then re-SaveAsWeb if any data has changed. Again, you could get more sophisticated and preserve the last saved state within the document so that you do not do the initial SaveAsWeb on open.
The upshot of this is that the Visio document (if open) will automatically save itself as a web page when ever the data source is updated!
Of course, I haven’t put anything fancy in the browser code to force a refresh … this is not Visio Services you know!