Creating and Managing Last Editor Entries in Visio 2010
Summary: Like other Microsoft Office applications, Microsoft Visio 2010 automatically keeps a record of the time and date a document was last edited, but not by whom. This article shows how to use Automation code and a Visio ShapeSheet spreadsheet to store and retrieve the name of the last editor of a Visio drawing, and how to create Visio templates that allow you to easily use this functionality in all the drawings you create.
Last modified: April 07, 2011
Applies to: Office 2010 | SharePoint Server 2010 | Visio 2010 | Visio Premium 2010
Published: June 2010
Like most documents created in a Microsoft Windows environment, Microsoft Visio 2010 drawings contain specific properties that pertain to the current document. Among these properties are the following:
Date Last Modified
Developers and users often need to know the name of the person who most recently edited a Visio drawing. One can easily discover the time the drawing was last edited, either programmatically or by examining the drawing's listing in Windows Explorer. It is not that easy, however, to determine the name of the person who was responsible for the editing.
The code you can use to programmatically retrieve the date and time of the last edit of a Visio drawing is quite straightforward, as shown in the following Visual Basic for Applications (VBA) example.
Public Sub DateOfLastEdit() ' Declare a variable to hold a Document object. Dim vsoCurrentDocument As Visio.Document ' Declare a string variable to hold the date/time value. Dim strDateTimeOfLastEdit As String ' Set the declared Document object to the currently active document. Set vsoCurrentDocument = Visio.ActiveDocument ' Retrieve the date/time value for the last-edited time stamp for the current document and convert it to a string. strDateTimeOfLastEdit = Str(vsoCurrentDocument.TimeEdited) ' Display the date/time value in a message box. MsgBox strDateTimeOfLastEdit End Sub
The code gets a reference to the current document (drawing), retrieves the date/time value from the TimeEdited property of the Document object, and then converts that value to a string. It then displays the string in a message box to inform the user of the date and time the drawing was last edited.
Here is where frustration can set in for Visio users. Nowhere in the Visio Document object model hierarchy is there a property that holds the value for the person who last edited the document.
This article shows how you can use Automation code to store and retrieve the name of the last editor. Before you can understand how this is done, however, you need a bit of background about how Visio stores property information.
Visio provides various ways to store property information about the objects in a Visio drawing, as well as about the drawing itself. Visio stores data about shapes in a drawing in a ShapeSheet spreadsheet, in the Shape Data and User-defined Cells sections. Visio also stores shape data in the Data1, Data2, and Data3 properties of the Shape object. You can set the values of cells in the Shape Data section of the ShapeSheet (formerly known as the Custom Property section) either in the user interface (by opening the ShapeSheet window for the shape) or programmatically. You can set the value of cells in the User-defined Cells section only in the ShapeSheet window. Because many users are not aware of the existence of the ShapeSheet, this offers a greater level of protection from casual manipulation of data by users.
You can set the Data1, Data2, and Data3 property values either in the user interface, in the Shape Name dialog box (on the Developer tab, click Shape Name) or programmatically. When you are storing information that should not be easily modified by the casual user, these public interfaces offer no protection against improper manipulation.
What is not commonly known is that there are actually three levels at which you can create and manipulate user-defined cells: at the levels of the shape, the page, and the document itself. The article shows how to combine this ability to create and manipulate user-defined cells for the document itself with the ability to assign code functionality to document-level events (such as when the document is saved, when it is saved under a different name, or when it is saved at a different location) to solve the problem of determining the last editor of the document.
Figure 1 shows the logic behind the code used in this article.
As you can see in Figure 1, the currently active document is already subscribed to both the DocumentSaved and DocumentSavedAs events. When either of these events occur, they call the WriteEditor() subroutine. This subroutine first obtains a reference to the Document object and checks whether a document-level user-defined cell named User.Editor exists. If the cell does not exist, the automation code creates a cell in the User-defined Cells section and names it User.Editor. It then obtains a reference to that cell. If the cell already exists, the code obtains a reference to it.
The code then examines the value, if any, stored in the User.Editor cell. If a value exists, that value is displayed in the InputBox() function as the default value. If a value does not currently exist, the value stored in the Document.Creator property is displayed as the default value in the InputBox() function. In either case, the user is asked to either modify or accept the name of the last editor. This value is then stored in the User.Editor cell of the document’s ShapeSheet. Finally, a MsgBox function displays the name of the editor to validate that the updating of the last editor was successful, and the automation code ends.
The following is the full code listing for this functionality.
' Handle the DocumentSaved event. Private Sub Document_DocumentSaved(ByVal Doc As IVDocument) ' Call the WriteEditor public subroutine. WriteEditor Doc End Sub 'Handle the DocumentSavedAs event. Private Sub Document_DocumentSavedAs(ByVal Doc As IVDocument) ' Call the WriteEditor public subroutine. WriteEditor Doc End Sub ' Write last editor information into the document passed in by the event handler. Public Sub WriteEditor(ByVal Doc As IVDocument) Dim vsoDocument As IVDocument Dim vsoCellEditor As Visio.Cell Dim intRetVal As Integer Dim strLastEditor As String Dim strThisEditor As String ' Assign vsoDocument variable to the document passed in by the event handler. Set vsoDocument = Doc ' Determine whether a cell named "User.Editor" exists in the ShapeSheet of the document. If vsoDocument.DocumentSheet.CellExists("User.Editor", 0) Then ' Assign the cell to the Cell object. Set vsoCellEditor = vsoDocument.DocumentSheet.Cells("User.Editor") ' Set the default name of the last editor to be the name already stored in the cell. strLastEditor = vsoCellEditor.ResultStr(visUnitsString) Else ' If a User.Editor cell does not exist in the ShapeSheet, create one. intRetVal = vsoDocument.DocumentSheet.AddNamedRow(visSectionUser, "Editor", visTagDefault) ' Assign the cell to the Cell object. Set vsoCellEditor = vsoDocument.DocumentSheet.Cells("User.Editor") ' Set the default name of the last editor to be the document's creator (from the document's properties). strLastEditor = vsoDocument.Creator End If ' Ask the user to enter the name of the document's creator (from the document's properties) ' as a string, using the last editor set above as the default. strThisEditor = InputBox("Click OK to accept the editor shown, or enter the current editor's name", "Set Current Editor", strLastEditor) ' Insert double-quotes around the string returned by the InputBox() function for use in a String Data-Type Cell ' and store the value in the User.Editor cell of the document's ShapeSheet. vsoCellEditor.Formula = """" & strThisEditor & """" ' Save the document, so that the user is not prompted to save when closing the document. Visio.Application.EventsEnabled = False vsoDocument.Save Visio.Application.EventsEnabled = True ' Display the value stored in the User.Editor cell to the user in a message box. MsgBox "The current editor is listed as: " & vsoDocument.DocumentSheet.Cells("User.Editor").ResultStr(visUnitsString), vbInformation + vbOKOnly End Sub
By adding this code to all the document templates you use to generate new drawings of various types, you can determine the name of the last editor of any drawing you create. The following section explains how to do that.
The following procedure shows the steps for creating a Visio drawing template that records the last editor of the drawing. You can create a template like this for each drawing type you commonly create.
To create a Visio drawing template that records the last editor
In Visio 2010, click the File tab, and then click Open.
Browse to the folder location of the template in which you want to include the last editor functionality, select the template (*.vst or *.vtx) file, and then click Open.
Press Alt+F11 to open the Visual Basic Editor.
In the Visual Basic Editor, on the Insert menu, click Module.
In the new code window that opens, paste the entire WriteEditor subroutine from the previous code example.
In the Project Explorer window, double-click ThisDocument.
In the ThisDocument module, paste the code for the DocumentSaved and the DocumentSavedAs events shown in the previous code example.
Close the Visual Basic Editor, and then save and close the template file.
When a user later creates a new drawing based on the template and saves this new drawing, either the DocumentSaved or the DocumentSavedAs event is raised (depending on which command the user selects), triggering the execution of the WriteEditor subroutine. Visio displays a dialog box that allows the user to set the current editor, as shown in Figure 2.
Users can either click OK to accept the name already displayed in the text box in the dialog box, or type their own name. When the user closes the dialog box, Visio writes the contents of the text box to the User.Editor cell of the document’s ShapeSheet. Then, to confirm that the edit was successful, Visio displays the message box shown in Figure 3.
At any time after the User.Editor cell has been created, you can get the entry in the User.Editor cell by running the following code.
Public Sub WhoWasTheLastEditor() Dim vsoDocument As Visio.Document Dim vsoCellEditor As Visio.Cell Dim strLastEditor As String ' Assign vsoDocument to the ActiveDocument object. Set vsoDocument = Visio.ActiveDocument ' Assign vsoCellEditor to a Cell object. Set vsoCellEditor = vsoDocument.DocumentSheet.Cells("User.Editor") ' Retrieve the value in the cell as a string. strLastEditor = vsoCellEditor.ResultStr(visUnitsString) ' Display the value stored in the User.Editor cell to the user in a message box. MsgBox "The last editor is listed as: " & strLastEditor, vbInformation + vbOKOnly End Sub