Automating SaveAsWeb when a Linked DataRecordset refreshes

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:

image

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.

image

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.

image

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.

   1: Option Explicit
   2:  
   3: Private WithEvents mDatasets As Visio.DataRecordsets
   4: Private mlastDataXml As String
   5:  
   6: Private Sub Document_DocumentOpened(ByVal doc As IVDocument)
   7:     StartListening
   8: End Sub
   9:  
  10: Public Sub StartListening()
  11:     Set mDatasets = ThisDocument.DataRecordsets
  12: End Sub
  13:  
  14: Public Sub StopListening()
  15:     Set mDatasets = Nothing
  16: End Sub
  17:  
  18: Private Sub mDatasets_DataRecordsetChanged(ByVal DataRecordsetChanged As IVDataRecordsetChangedEvent)
  19:     If Not mlastDataXml = DataRecordsetChanged.DataRecordset.DataAsXML Then
  20:         'This means that data has changed
  21:         doSaveAsWeb ThisDocument, Replace(ThisDocument.FullName, ".vsd", ".htm")
  22:     End If
  23:     mlastDataXml = DataRecordsetChanged.DataRecordset.DataAsXML
  24: End Sub
  25:  
  26: Private Sub doSaveAsWeb(ByVal doc As Visio.Document, ByVal htm As String)
  27:     SaveDocAsWebPage doc, -1, -1, htm, _
  28:         modSaveAsWeb.ShowNavigationBar Or _
  29:         modSaveAsWeb.ShowPanAndZoom Or _
  30:         modSaveAsWeb.ShowPropertiesWindow Or _
  31:         modSaveAsWeb.ShowSearchTool Or _
  32:         modSaveAsWeb.RunInBatchMode
  33: End Sub

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!

image

Of course, I haven’t put anything fancy in the browser code to force a refresh … this is not Visio Services you know!

Posted in Visio. 2 Comments »

2 Responses to “Automating SaveAsWeb when a Linked DataRecordset refreshes”

  1. Hi Says:

    Hi David
    I have a similar requirement like yours
    where i wanted to refresh the page but in my case the refresh shud also happen automatically
    What can be the possible way to achieve the same.
    Waiting for your reply.
    Thanks
    Mugdha

    • davidjpp Says:

      I’m not sure I understand what extra feature you are asking for.
      In my example, I am using the built-in autorefresh, which can be as often as every minute, then detecting if anything really has changed before bothering to do a SaveAsWeb.
      In reality, you should check how long it takes to actually do the SaveAsWeb (depends on the complexity of the document), and ensure that the autofresh period is longer than that.


Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Joanne C Klein

Compliance in Microsoft 365

JackBinnall

O365 and Power Platform

Simplify Tasks

Want to learn the simple way?

Paul Turley's SQL Server BI Blog

sharing my experiences with the Microsoft data platform, SQL Server BI, Data Modeling, SSAS Design, Power Pivot, Power BI, SSRS Advanced Design, Power BI, Dashboards & Visualization since 2009

John Goldsmith's visLog

be smart, be clear, be visual ...

Mo's blog

Personal views on Dynamics 365 for Operations and Technical Architecture.

Chris Webb's BI Blog

Microsoft Fabric, Power BI, Analysis Services, DAX, M, MDX, Power Query, Power Pivot and Excel

davecra.wordpress.com/

Solutions for Microsoft Office, and more...

Rob Fahrni

I AM FAHRNI

john Visio MVP

Life with Visio and other Microsoft Toys!

Nilsandrey's Weblog

Just another WordPress.com weblog

Things that Should be Easy

Every so often (too often in the IT industry) I encounter things that should have been very easy to do but turned out to be far too complicated. My favorite topics include SharePoint, .Net development, and software architecture, especially distributed systems.

Visio Guy

Smart graphics for visual people