Introduction to Validation Rules in Visio Premium 2010
Summary: Learn about the new diagram validation feature in Microsoft Visio Premium 2010 and how to use the Validation API to create your own rules and rule sets to validate Visio 2010 diagrams.
Applies to: Office 2010 | SharePoint Server 2010 | Visio 2010 | Visio Premium 2010
In this article
Overview
Prerequisites
User Experience
Structured Diagrams
Validation API Overview
Validating Structured Diagrams
Reviewing Existing Rules
Creating a New Rule Set
Example: Creating a Fault Tree Analysis Rule Set
Publishing Rules
Conclusion
Additional Resources
About the Author
Published: July 2010
Provided by: David J. Parker, bVisual Ltd | About the Author
Contents
Overview
Prerequisites
User Experience
Structured Diagrams
Validation API Overview
Validating Structured Diagrams
Reviewing Existing Rules
Creating a New Rule Set
Example: Creating a Fault Tree Analysis Rule Set
Publishing Rules
Conclusion
Additional Resources
Overview
Microsoft Visio Premium 2010 introduced an extension to the Visio Type Library called the Validation API. By using the Validation API, you can validate a Visio diagram to ensure that its construction complies with a set of rules (for example, industry-standard diagram rules, or custom rules designed for a particular company). Organizations are able to use this new feature to encapsulate business logic as validation rules, grouped within rule sets. Visio Premium 2010 contains default rule sets for use with Basic and Cross-Functional Flowcharts, Business Process Modeling Notation (BPMN) Diagrams, and SharePoint Workflow Designer diagrams.
Prerequisites
This article uses the Validation API that is found only in Microsoft Visio Premium 2010. The reader should either have experience in, or have the willingness to learn about, Visio ShapeSheet formula construction. Additional Resources are provided at the end of the article.
The rule-set development methodology described in this article uses Visual Basic for Applications (VBA) macros. Therefore, macros must be enabled in Visio.
To enable macros in Visio
On the File tab, click Options, click Trust Center, and then click Trust Center Settings.
In the Trust Center dialog box, click the Macros Settings tab.
Under Developer Macro Settings, select Trust access to the VBA project object model.
User Experience
Visio Premium 2010 contains an additional tab, Process (in the ribbon component of the Microsoft Office Fluent user interface, as shown in Figure 1), that provides access to the visible parts of the Validation API in the Diagram Validation group.
Figure 1. Process tab
The user clicks the Check Diagram button to validate the whole document against the currently enabled rule sets in the document. The Issues window, shown in Figure 2, displays any issues that the validation process raises. To easily find shapes that have issues, click an issue, and Visio selects the corresponding shape.
Figure 2. Issues window
Visio Premium 2010 provides validation support for several diagram templates, including the new BPMN Diagram and Microsoft SharePoint Workflow templates, and the improved Basic Flowchart and Cross-Functional Flowchart templates—all of which are found in the Flowchart category.
Structured Diagrams
There are many types of diagrams that can be considered as structured. A process flow diagram is one type of structured diagram, but there are many other diagrams that structure can be applied to.
A structured diagram is one where there is a set of logical relationships between shapes. Relationships bring visual organization to diagrams, and they can provide special interaction capabilities.
Visio 2010 (all editions) introduced some new features that make it easy for users to form these relationships. The containers, lists, and callouts in Visio 2010 enable shapes to determine containment, order, and association, respectively. This is in addition to the connectivity relationships that have always been possible in Visio, but are now easier to understand and navigate with the new Connectivity API.
Containment
The Containers feature in Visio 2010 makes it easy to add a visual boundary around shapes, including a label, as shown in Figure 3. Visio does all the work to maintain the relationship between the container and its contents.
Figure 3. Diagram containment
Order
Shapes that are added to a list are automatically arranged adjacent to one another. In Figure 4, the swimlanes are the list shapes in the Cross-Functional Flowchart (CFF) container shape.
Figure 4. Diagram order
Association
A callout shape moves when its target shape is moved. In Figure 5, the Evaluate Discussion Progress task shape has an associated callout that contains descriptive text.
Figure 5. Diagram association
Connectivity
Visio has always provided the capability to create connections between shapes. Originally this was only possible by using a one-dimensional (1-D) shape to connect two-dimensional (2-D) shapes together. The 1-D shape, often referred to as a connector, has a beginning and an end. Therefore, the 2-D shape glued to the beginning of a 1-D shape has an outward connector, and the 2-D shape glued to the end of the 1-D shape has an inward connector, as shown in Figure 6.
Figure 6. Connections between shapes
The direction of flow along a 1-D connector can be important for visual and programmatic comprehension. Therefore, it is often necessary to check that shapes are glued to the correct end of the connector.
Note
Lines in Visio can have arrows, and other types of line ends, at either end, both ends, or at neither end. Therefore, you cannot always assume that an arrow on a line indicates the direction of the line.
Later versions of Visio introduced the ability for two 2-D shapes (for example, the work surfaces in the Office Layout template) to be glued to one another, or even for two 1-D shapes to be glued together (for example, the pipelines in the Process Flow template).
Validation API Overview
The key objects, methods, and properties for validation are shown in Figure 7.
Figure 7. Key Validation objects, methods, and properties
The Validation API is based on three main concepts: rule sets, rules, and issues. A validation rule, or a rule, represents one type of error that can occur in your diagram. Each rule has underlying business logic that determines when the rule is broken. An issue is one case in your diagram where the validation rule is broken. Depending on your diagram, there may be multiple issues associated with the same rule. For example, if the rule requires that all shapes be labeled, validation will display an issue for each shape that is missing a label. Rule sets are logical grouping of rules, such as the BPMN and Flowchart rule sets.
Key Validation Objects and Properties
Rules sets, rules, and issues each have corresponding API objects: ValidationRuleSet, ValidationRule, and ValidationIssue, respectively. In the following sections, the key properties for each of these objects are described.
ValidationRuleSet
Every rule set has a unique NameU property that represents the universal name of the rule set. You should also specify a Description property value for each rule set. Other properties are set by default, and you have to modify them only if you want a different behavior. The key properties of the ValidationRuleSet object are shown in Table 1.
Table 1. Key ValidationRuleSet properties
Property |
Description |
---|---|
Specifies the description of the rule set. |
|
Determines whether the rule set is active or inactive. Only rules that belong to active rule sets are checked when validation is triggered. By default, rule sets are enabled. |
|
Specifies the name of the rule set that appears in the user interface (UI). By default, it is the same as the value of NameU. |
|
Specifies the universal name of the rule set. |
|
Itemizes the rules in the rule set. |
|
Determines whether the rule set appears in the UI. By default, rule sets are visible in the UI. |
ValidationRule
Every rule has a unique NameU property that represents the universal name of the rule. You should also specify a Category and Description property value for each rule, because these properties are used in the UI. The Category value should inform the user about the type of issue, and may be used to determine the rule set that triggered the issue. The Description value should be explicit enough to explain the issue so that a user can address it. The key properties of the ValidationRule object are shown in Table 2.
Table 2. Key ValidationRule properties
Property |
Description |
---|---|
Represents the text that is displayed in the Category column of the Issues window. |
|
Specifies the description of the rule that appears in the Issues window. |
|
Specifies the logical expression that determines whether the validation rule should be applied to a target object. |
|
Determines whether the validation rule is currently ignored. By default, rules are not ignored. |
|
Specifies the universal name of the rule. |
|
Returns the rule set that contains the rule. |
|
Determines the target type of the rule. A rule can target documents, pages, or shapes. The TargetType property value must be one of the following VisRuleTargets constants:
|
|
Specifies the logical expression that determines whether the target object satisfies the rule. |
ValidationIssue
Every issue has an associated rule that specifies the description and category that is displayed in the Issues window. When a user clicks an issue in the Issues window, Visio displays the page that contains the issue (if the issue targets a page or shape) and selects the target shape (if the issue targets a shape). The TargetPage, TargetPageID, and TargetShape properties are used to determine the page to display and the shape to select. The key properties of the ValidationIssue object are shown in Table 3.
Table 3. Key ValidationIssue properties
Property |
Description |
---|---|
Determines whether the issue is currently ignored. |
|
Specifies the rule that generated the issue. |
|
Specifies the page that is associated with the issue. |
|
Specifies the ID of the page that is associated with the validation issue. |
|
Specifies the shape that is associated with the validation issue. |
Validating Structured Diagrams
A document can contain multiple rule sets, each of which can be enabled or disabled for the purposes of validating the structure. Visio Premium 2010 contains a Flowchart rule set that is used in the Basic Flowchart, Cross-Functional Flowchart, and Six Sigma templates. All of the rules in the Flowchart rule set are defined in filter and test expressions. You can analyze these rules to learn how to create rule sets for other types of diagrams.
Another example of the Flowchart rule set in Visio Premium 2010 is the BPMN Diagram template, as shown in Figure 8. This rule set supports BPMN 1.2, which enables organizations that use this particular methodology to verify that diagrams are structured accordingly.
Figure 8. BPMN rule set
You can import rule sets from other open Visio documents by using the Import Rules From option. However, if the required rules are very complex, you can also write rules in code. These types of rules do not require filter and test expressions because they are invoked by the RuleSetValidated event. An example of this type of rule set in Visio Premium 2010 is the SharePoint Designer Workflow template.
Reviewing Existing Rules
To understand how to create your own rules, it is useful to examine a set of existing rules.
To create a list of existing rules
Open a Basic Flowchart template from the Flowchart category, as shown in Figure 9.
Figure 9. Basic Flowchart template
Ensure that the Developer tab is displayed in Visio:
On the File tab, click Options.
In the Visio Options dialog box, click the Advanced tab.
Under General, select Run in developer mode.
Open the VBA Editor by clicking Visual Basic on the Developer tab, and then insert a module into the VBA project.
On the Tools menu, click References, and then select Microsoft Forms 2.0 Object Library to add a reference to that library to your project. The Microsoft Forms object library provides access to the Clipboard object.
Tip
If you insert a UserForm into the VBA project, it will automatically add the Microsoft Forms reference, as shown in Figure 10. You can then remove the UserForm.
Figure 10. Microsoft Forms reference
Copy and paste the following EnumerateRules() subroutine into the module.
Public Sub EnumerateRules() Dim doc As Visio.Document Dim ruleSet As Visio.ValidationRuleSet Dim rule As Visio.ValidationRule Dim datObj As DataObject Dim txt As String Set doc = Visio.ActiveDocument txt = "EnumerateRulesSets Count = " & doc.Validation.RuleSets.Count For Each ruleSet In doc.Validation.RuleSets If ruleSet.Enabled Then txt = txt & vbCrLf & "EnumerateRules for RuleSet : " & _ ruleSet.nameu & " : Count = " & ruleSet.Rules.Count txt = txt & vbCrLf & "ID" & vbTab & "Category" & vbTab & "NameU" & vbTab & _ "Description" & vbTab & "TargetType" & vbTab & _ "FilterExpression" & vbTab & "TestExpression" For Each rule In ruleSet.Rules With rule txt = txt & vbCrLf & .ID & vbTab & .category & vbTab & .nameu & vbTab & _ .description & vbTab & .targettype & vbTab & _ .filterexpression & vbTab & .testexpression End With Next End If Next Set datObj = New DataObject datObj.SetText txt datObj.PutInClipboard End Sub
This subroutine copies into the Clipboard all the rules for enabled rule sets in the active document. You can then paste the contents into Microsoft Excel, for example, to create a table, as shown in Table 4.
Table 4. Enabled rule sets
EnumerateRulesSets Count = 1 |
EnumerateRules for RuleSet : Flowchart : Count = 11 |
ID |
Category |
NameU |
Description |
TargetType |
FilterExpression |
TestExpression |
---|---|---|---|---|---|---|
1 |
Connectivity |
Unglued or Connect |
Connector is not glued at both ends. |
0 |
ROLE()=1 |
AND(AGGCOUNT(GLUEDSHAPES(4))=1, AGGCOUNT(GLUEDSHAPES(5))=1) |
2 |
Start / End |
StartWithoutTerminator |
Flowchart shape has no incoming connectors and is not a Start/End shape. |
0 |
AND(OR(HASCATEGORY("Flowchart"),ONLAYER("Flowchart")),NOT(OR(HASCATEGORY("Start/End"),STRSAME(LEFT(MASTERNAME(750),9),"Start/End"),STRSAME(LEFT(MASTERNAME(750),10),"Terminator")))) |
AGGCOUNT(GLUEDSHAPES(1)) > 0 |
3 |
Start / End |
EndWithoutTerminator |
Flowchart shape has no outgoing connectors and is not a Start/End shape. |
0 |
AND(OR(HASCATEGORY("Flowchart"),ONLAYER("Flowchart")),NOT(OR(HASCATEGORY("Start/End"),STRSAME(LEFT(MASTERNAME(750),9),"Start/End"),STRSAME(LEFT(MASTERNAME(750),10),"Terminator")))) |
AGGCOUNT(GLUEDSHAPES(2)) > 0 |
4 |
Start / End |
NoStartTerminator |
Flowchart does not start with a Start/End shape. |
1 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(), "OR(HASCATEGORY(""Flowchart""),ONLAYER(""Flowchart""))")) > 0 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(), "AND(OR(HASCATEGORY(""Start/End""),STRSAME(LEFT(MASTERNAME(750),9),""Start/End""),STRSAME(LEFT(MASTERNAME(750),10),""Terminator"")),AGGCOUNT(CONNECTEDSHAPES(2))>0)")) > 0 |
5 |
Start / End |
NoEndTerminator |
Flowchart does not end with a Start/End shape. |
1 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(), "OR(HASCATEGORY(""Flowchart""),ONLAYER(""Flowchart""))")) > 0 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(), "AND(OR(HASCATEGORY(""Start/End""),STRSAME(LEFT(MASTERNAME(750),9),""Start/End""),STRSAME(LEFT(MASTERNAME(750),10),""Terminator"")),AGGCOUNT(CONNECTEDSHAPES(1))>0)")) > 0 |
6 |
Connectivity |
UnconnectedShape |
Flowchart shape is not connected to any other shape. |
0 |
OR(HASCATEGORY("Flowchart"),ONLAYER("Flowchart")) |
AGGCOUNT(CONNECTEDSHAPES(0)) > 0 |
7 |
Connectivity |
TerminatorinMiddle |
Start/End shape has both incoming and outgoing connectors. |
0 |
OR(HASCATEGORY("Start/End"),STRSAME(LEFT(MASTERNAME(750),9),"Start/End"),STRSAME(LEFT(MASTERNAME(750),10),"Terminator")) |
NOT(AND(AGGCOUNT(CONNECTEDSHAPES(1))>0,AGGCOUNT(CONNECTEDSHAPES(2))>0)) |
8 |
Connectivity |
TooFewOutConns |
Decision shape should have more than one outgoing connector. |
0 |
OR(HASCATEGORY("Decision"),STRSAME(LEFT(MASTERNAME(750),8),"Decision")) |
AGGCOUNT(GLUEDSHAPES(2)) > 1 |
9 |
Connectivity |
NonFlowchartShape |
Connected shape is not recognized as a Flowchart shape. |
0 |
NOT(OR(HASCATEGORY("Flowchart"),ONLAYER("Flowchart"))) |
AGGCOUNT(GLUEDSHAPES(0)) = 0 |
10 |
Text |
NoShapeText |
Flowchart shape has no text label. |
0 |
OR(HASCATEGORY("Flowchart"),ONLAYER("Flowchart")) |
NOT(STRSAME(SHAPETEXT(TheText), "")) |
11 |
Cross - Functional |
OutsideCFF |
Flowchart shapes should belong to a Swimlane. |
1 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(),"HASCATEGORY(""Swimlane"")"))>0 |
AGGCOUNT(FILTERSET(SHAPESONPAGE(),"AND(OR(HASCATEGORY(""Flowchart""),ONLAYER(""Flowchart"")),AGGCOUNT(FILTERSET(PARENTCONTAINERS(),""HASCATEGORY(""""Swimlane"""")""))=0)"))=0 |
The FilterExpression and TestExpression formulas are regular ShapeSheet functions, apart from several new special functions added in Visio 2010 especially for validation.
Table 5 lists the special functions that resemble ShapeSheet functions and can be used in the FilterExpression and TestExpression formulas.
Table 5. FilterExpression and TextExpression functions
Function |
Description |
---|---|
Role() |
Returns an integer that indicates the shape role:
|
OnLayer(LayerName) |
If called on a shape, returns a Boolean value that indicates whether the shape is a member of the specified layer. If called on a page, returns a Boolean value that indicates whether the layer exists on the page. |
ConnectedShapes(Direction) |
Returns the set of shapes that match the Direction criteria and are connected to the shape. The ConnectedShapes function skips over the connectors, whereas the GluedShapes function returns the connector shapes themselves. The value of Direction is one of the VisConnectedShapesFlags constants:
|
GluedShapes(Direction) |
Returns the set of shapes that match the Direction criteria and are glued to the shape. The ConnectedShapes function skips over the connectors, whereas the GluedShapes function returns the connector shapes themselves. The value of Direction is one of the VisGluedShapesFlags constants:
|
ContainerMembers() |
Returns the set of shapes that are members of the container or list shape. |
ListMembers() |
Returns the set of shapes that are members of the list shape. |
Callouts() |
Returns the set of shapes that are callouts on the shape. |
ParentContainers() |
Returns the set of containers that the shape belongs to. |
ShapesOnPage() |
Returns the set of top-level shapes on the page. If no page specifier precedes the function, the shape’s containing page is assumed. |
AggCount(Set) |
Counts the number of shapes in a set. |
FilterSet(Set,FilterExpression) |
Returns the subset of shapes in a set that match an expression. |
OnBoundaryOf() |
Returns the set of containers in such a way that the shape is on the boundary of these containers. |
Creating a New Rule Set
Now that you understand how rules are written, you can create your own custom rule sets. This section shows how you can write simple structured diagramming rules for the Fault Tree Analysis diagram, which currently has no validation rules attached.
First create a new Fault Tree Analysis Diagram from the Business category, as shown in Figure 11.
Figure 11. Fault Tree Analysis diagram
Later you will add some VBA code into the VBA project of this new document.
Analyzing the Requirements
The first task is to understand the shapes that you can use in the construction of the diagram type.
Drag all of the master shapes from the Fault Tree Analysis Shapes stencil and drop them onto the blank page. Then open the Document Stencil and Drawing Explorer windows (on the Developer tab) to see what layers the shapes are on by default. As you can see in Figure 12, the Dynamic connector is on the Connector layer, and all of the other shapes are on the Flowchart layer.
Figure 12. Shape layers
You can also check the shapes to see whether they contain any shape data rows (these particular master shapes do not).
Next, you can group the masters by usage. In this case, there are six gate symbols, five event symbols, one transfer symbol, and one connector.
Now you can start to think about the basic rules that you want to create. The following list shows an example set of rules:
Every connector must be connected to a shape at each end.
Every event shape must be labeled.
Every Fault Tree Analysis (FTA) shape must be connected to another FTA shape.
An undeveloped event should not have any outward connections.
Every gate shape must have only one input.
Every gate, except the inhibit gate, must have at least two outputs.
An inhibit gate should have one outward connection.
Every gate, except the inhibit gate, must connect to at least three events.
A transfer symbol must have only one connection.
To create some of these rules, you will need to clarify what a valid shape is.
First, determine whether all of the valid shapes are on the Flowchart layer. You can use the OnLayer(LayerName) function to check for this.
Next, determine the names of the master shapes. You can use the MasterName(langid_opt) function for this, but you have to exercise a bit of caution. This is because it is easy for a user to accidentally create duplicate masters in a document, in which case Visio will automatically force the duplicate master name to be unique by appending a dot and a number. Consequently, you should modify the test to be StrSame(Left(MasterName(750),n),Name), where 750 is the universal language code, Name is the name of the master to be checked, and n is the number of characters in the Name.
In the flowchart templates that already have rules supplied, the master shapes have been modified to include an additional user-defined cell, User.msvShapeCategories, which can contain a list of categories that the shape belongs to. You can then use the new HasCategory(CategoryName) function, instead of the MasterName() function, as a test. If you are creating a template that contains your own masters, you have the option of adding the User.msvShapeCategories to your masters.
Adding a Rule Set
First, you must create a rule set for the rules to belong to. The following code procedure, AddRuleSet(), adds the Fault Tree Analysis rule set, or updates it if it already exists. It is followed by a support procedure, getRuleSet(), which is used to test whether a named rule exists. It will return the Ruleset object if it exists; otherwise, it will return Nothing.
Public Sub AddRuleSet()
' Add a validation rule set to the document.
' Edit the nameU to suit.
Dim doc As Visio.Document
Dim ruleSet As Visio.ValidationRuleSet
Dim nameU As String
nameU = "Fault Tree Analysis"
Set doc = Visio.ActiveDocument
' Check whether the rule set already exists.
Set ruleSet = getRuleSet(doc, nameU)
If ruleSet Is Nothing Then
' Create the new rule set.
Set ruleSet = doc.Validation.RuleSets.Add(nameU)
End If
ruleSet.description = "Example Fault Tree Analysis rule set."
ruleSet.Enabled = True
ruleSet.RuleSetFlags = Visio.VisRuleSetFlags.visRuleSetDefault
End Sub
Private Function getRuleSet(ByVal doc As Visio.Document, _
ByVal nameU As String) As Visio.ValidationRuleSet
' Return a named rule set or nothing.
Dim retVal As Visio.ValidationRuleSet
Dim ruleSet As Visio.ValidationRuleSet
Set retVal = Nothing
For Each ruleSet In doc.Validation.RuleSets
If UCase(ruleSet.nameU) = UCase(nameU) Then
Set retVal = ruleSet
Exit For
End If
Next
Set getRuleSet = retVal
End Function
Deleting a Rule Set
You can use the following DeleteRuleSet() code procedure to delete an unwanted rule in a rule set.
Public Sub DeleteRuleSet()
' Delete a rule set from the active document.
' Edit the ruleSetNameU value to suit.
Dim doc As Visio.Document
Dim nameU As String
nameU = "Fault Tree Analysis"
Set doc = Visio.ActiveDocument
' Check whether the rule set already exists.
If Not getRuleSet(doc, nameU) Is Nothing Then
' Delete the rule set.
doc.Validation.RuleSets.Item(nameU).Delete
End If
End Sub
Adding a Rule
The following example code procedure shows how to add a rule to a rule set.
Public Sub AddRule()
' Add a rule to named rule set.
' Edit nameU and the addARule arguments to suit.
Dim doc As Visio.Document
Dim ruleSet As Visio.ValidationRuleSet
Dim nameU As String
nameU = "Fault Tree Analysis"
Set doc = Visio.ActiveDocument
' Check whether the rule set already exists.
Set ruleSet = getRuleSet(doc, nameU)
If ruleSet Is Nothing Then
Exit Sub
End If
' Add the rule.
addARule ruleSet, "Connectivity", "UngluedConnector", _
"Connector is not glued at both ends.", 0, _
"ROLE()=1", _
"AND(AGGCOUNT(GLUEDSHAPES(4)) = 1, AGGCOUNT(GLUEDSHAPES(5)) = 1)"
End Sub
Private Function getRule(ByVal ruleSet As Visio.ValidationRuleSet, _
ByVal nameU As String) As Visio.ValidationRule
' Return a named rule or nothing.
Dim retVal As Visio.ValidationRule
Dim rule As Visio.ValidationRule
Set retVal = Nothing
For Each rule In ruleSet.Rules
If UCase(rule.nameU) = UCase(nameU) Then
Set retVal = rule
Exit For
End If
Next
Set getRule = retVal
End Function
Private Sub addARule(ByVal ruleSet As Visio.ValidationRuleSet, _
ByVal category As String, ByVal nameU As String, _
ByVal description As String, ByVal targetType As Integer, _
ByVal filterExpression As String, ByVal testExpression As String)
' Add or update a validation rule in the document.
Dim rule As Visio.ValidationRule
Set rule = getRule(ruleSet, nameU)
If rule Is Nothing Then
Set rule = ruleSet.Rules.Add(nameU)
End If
rule.category = category
rule.description = description
rule.Ignored = False
rule.targetType = targetType
rule.filterExpression = filterExpression
rule.testExpression = testExpression
' Flush existing issues to ensure re-validation.
ruleSet.Document.Validation.Issues.Clear
End Sub
Deleting a Rule
You can use the following DeleteRule() code procedure to delete an unwanted rule from a rule set.
Public Sub DeleteRule()
' Delete a rule from a rule set.
' Edit ruleSetNameU and ruleNameU to suit.
Dim ruleSetNameU As String
Dim ruleSet As Visio.ValidationRuleSet
ruleSetNameU = "Fault Tree Analysis"
Set ruleSet = getRuleSet(Visio.ActiveDocument, ruleSetNameU)
If ruleSet Is Nothing Then
Exit Sub
End If
Dim ruleNameU As String
ruleNameU = "UngluedConnector"
' Check whether the rule already exists.
If Not getRule(ruleSet, ruleNameU) Is Nothing Then
' Delete the rule.
ruleSet.Rules.Item(ruleNameU).Delete
End If
End Sub
Adding a Rule from the Clipboard
To add a rule to a rule set, the AddRule() procedure shown previously works fine. However, you will have to either edit the procedure for more rules, or copy the procedure, slightly rename it, and then edit the arguments for the addARule() procedure. If you use this approach, you will have many variations of the AddRule() procedure in your module.
However, alternatively, you can enter the arguments in a Microsoft Excel table, in a format similar to the output in the EnumerateRulesets() method listed previously. You can then edit your arguments—especially the filter and test expressions—in an Excel cell, as shown in Figure 13.
Figure 13. Editing arguments in Excel
Then use the following code to add the rules from Excel to your drawing. Notice that this method will work on multiple rows, but it assumes that a header row exists and skips over that row by starting at row 2. If your spreadsheet does not have a header row, adjust the code accordingly.
' Adds rules to named rule set from Excel.
' To use this in a VBA project, add a reference to the "Microsoft Excel 14.0 Object Library".
Public Sub AddRulesFromExcel()
Dim xlWorkbook As Excel.Workbook
Dim doc As Visio.Document
Dim ruleSet As Visio.ValidationRuleSet
Dim nameu As String
nameu = "Fault Tree Analysis"
Dim category As String
Dim rulenameu As String
Dim description As String
Dim targettype As String
Dim filterexpression As String
Dim testexpression As String
Const categoryCol As Integer = 2
Const rulenameCol As Integer = 3
Const descriptionCol As Integer = 4
Const targettypeCol As Integer = 5
Const filterexpressionCol As Integer = 6
Const testexpressionCol As Integer = 7
Set doc = Visio.ActiveDocument
' Check whether the rule set exists already.
Set ruleSet = GetRuleSet(doc, nameu)
If ruleSet Is Nothing Then
Exit Sub
End If
' Get data from Excel.
' Assumes you have created an Excel spreadsheet at the path shown, that contains the rules you want to add,
' and with columns that correspond to the constants declared in this subroutine.
Dim xlApp As New Excel.Application
Set xlWorkbook = xlApp.Workbooks.Open("C:\Users\username\Documents\RuleList.xlsx")
On Error GoTo AddRulesFromExcel_Err
Dim xlWorkSheet As Excel.Worksheet
Set xlWorkSheet = xlWorkbook.Worksheets(1)
Dim numRows As Integer
numRows = xlWorkSheet.UsedRange.Rows.Count
' Assumes that a header row exists and skips over it.
For xlRow = 2 To numRows
category = xlWorkSheet.Cells(xlRow, categoryCol)
rulenameu = xlWorkSheet.Cells(xlRow, rulenameCol)
description = xlWorkSheet.Cells(xlRow, descriptionCol)
targettype = xlWorkSheet.Cells(xlRow, targettypeCol)
filterexpression = xlWorkSheet.Cells(xlRow, filterexpressionCol)
testexpression = xlWorkSheet.Cells(xlRow, testexpressionCol)
addARule ruleSet, category, rulenameu, description, targettype, filterexpression, testexpression
Next xlRow
AddRulesFromExcel_Err:
If (Err.Number) Then
Debug.Print Err.description
End If
xlWorkbook.Close
xlApp.Quit
End Sub
Example: Creating a Fault Tree Analysis Rule Set
This section describes a set of nine example rules, as introduced in the section Creating a New Rule Set, that you could apply to a Fault Tree Analysis (FTA) diagram. You can use either procedure that is described previously—AddRule() or AddRuleFromExcel()—to add each rule that is listed in this section.
The parameters are listed in the correct order for copying and pasting into Excel. You can use the Transpose command in Excel to switch the layout of each rule from vertical to horizontal. Paste the rule into Excel, press CTRL+C to copy the pasted range, right-click the selection and then, under Paste Options, click Transpose.
Rule 1: Every connector must be connected to a shape at each end.
The Flowchart rule set in the Basic Flowchart drawing already has such a rule. Therefore, you can copy Rule 1 from that default rule set.
Category |
Connectivity |
NameU |
UngluedConnector |
Description |
Connector is not glued at both ends. |
TargetType |
0 |
FilterExpression |
ROLE()=1 |
TestExpression |
AND(AGGCOUNT(GLUEDSHAPES(4)) = 1, AGGCOUNT(GLUEDSHAPES(5)) = 1) |
The FilterExpression value means that only one-dimensional (1-D) connector shapes are to be tested. The TestExpression value checks that a single two-dimensional (2-D) shape is glued at either end of the connector. The TargetType value for this rule (and for all of the other rules in this article) is the default visRuleTargetShape.
Figure 14. Every connector must be glued at both ends
Rule 2: Every event shape must be labeled.
The Flowchart rule set also contains a rule named NoShapeText. For the purpose of this example rule set, change the Description value to Event shape has no text label.
You will have to modify the FilterExpression value, because the FTA shapes do not contain the user-defined ShapeSheet cell called Categories. Therefore, you have to check for the master names specifically instead of using the HasCategory() function. The TestExpression value determines whether there is any text in the shape.
Category |
Text |
NameU |
NoShapeText |
Description |
Event shape has no text label. |
TargetType |
0 |
FilterExpression |
OR(STRSAME(LEFT(MASTERNAME(750),11),"Basic event"),STRSAME(LEFT(MASTERNAME(750),17),"Undeveloped event"),STRSAME(LEFT(MASTERNAME(750),5),"Event"),STRSAME(LEFT(MASTERNAME(750),11),"House event"),STRSAME(LEFT(MASTERNAME(750),17),"Conditional event"))) |
TestExpression |
NOT(STRSAME(SHAPETEXT(TheText), "")) |
To check that this rule is working, you can choose to ignore the first rule, UngluedConnector, by right-clicking the first rule in the Issues window, clicking Ignore this Rule, and then clicking Check Diagram.
Figure 15. Event shape has no text label
Rule 3: Every FTA shape must be connected to another FTA shape.
As in the first two rules, you can copy this rule (UnconnectedShape) from the Basic Flowchart rule set. Change the Description value to FTA shape is not connected to any other shape.
As you did with the NoShapeText rule, you will have to amend the FilterExpression value, but this time it has to check just the layer assignment. The TestExpression value verifies that there are connected shapes.
You could possibly expand this rule to specify names for the master shapes that are connected.
Category |
Connectivity |
NameU |
UnconnectedShape |
Description |
FTA shape is not connected to any other shape. |
TargetType |
0 |
FilterExpression |
ONLAYER("Flowchart") |
TestExpression |
AGGCOUNT(CONNECTEDSHAPES(0)) > 0 |
You can test this rule by randomly connecting various FTA shapes.
Figure 16. FTA shape is not connected to any other shape
Rule 4: An undeveloped event should not have any outward connections.
There is no existing rule set from which you can copy this rule, so you will have to write your own rule.
The FilterExpression value verifies that an undeveloped-event shape is to be tested. The TestExpression value checks that there are no outward glued connectors.
Category |
Connectivity |
NameU |
UndevelopedEventHasConnectionOut |
Description |
Undeveloped-event shape should not have any outward connector. |
TargetType |
0 |
FilterExpression |
STRSAME(LEFT(MASTERNAME(750),17),"Undeveloped event") |
TestExpression |
AGGCOUNT(GLUEDSHAPES(2)) = 0 |
You should now test your rule by gluing an outward connector to an undeveloped-event shape.
Figure 17. Undeveloped event should not have an outward connector
Rule 5: Every gate shape must have only one input.
The FilterExpression value checks the layer assignment and verifies that all of the gates shapes are to be tested. The TestExpression checks that there is one inward glued connector.
Category |
Connectivity |
NameU |
GateHasNoConnectionIn |
Description |
Gate shape should have one inward connection. |
TargetType |
0 |
FilterExpression |
AND(ONLAYER("Flowchart"),OR(STRSAME(LEFT(MASTERNAME(750),7),"OR gate"),STRSAME(LEFT(MASTERNAME(750),8),"AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Priority AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Exclusive OR gate"),STRSAME(LEFT(MASTERNAME(750),11),"Voting gate"),STRSAME(LEFT(MASTERNAME(750),12),"Inhibit gate"))) |
TestExpression |
AGGCOUNT(GLUEDSHAPES(1)) = 1 |
You can test the rule by adding more than one inward connector on a gate shape, or by having no inward connector at all.
Figure 18. Gate shape should have one inward connection
Rule 6: Every gate, except the inhibit gate, must have at least two outputs.
The FilterExpression value checks the layer assignment and verifies that all of the gate shapes are to be tested. The TestExpression value checks that there are at least two outward glued connectors.
Category |
Connectivity |
NameU |
GateWithoutAtLeastTwoOutputs |
Description |
Gate shape has fewer than two outward connectors. |
TargetType |
0 |
FilterExpression |
AND(ONLAYER("Flowchart"),OR(STRSAME(LEFT(MASTERNAME(750),7),"OR gate"),STRSAME(LEFT(MASTERNAME(750),8),"AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Priority AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Exclusive OR gate"),STRSAME(LEFT(MASTERNAME(750),11),"Voting gate"))) |
TestExpression |
AGGCOUNT(GLUEDSHAPES(2)) > 1 |
You can test the rule by adding fewer than two outward connectors to a gate shape.
Figure 19. Gate shape has fewer than two outward connectors
Rule 7: An inhibit gate should have one outward connection.
The FilterExpression checks that an inhibit gate shape is to be tested. The TestExpression checks that there is only one outward glued connector.
Category |
Connectivity |
NameU |
InhibitGateNeedsOneOutput |
Description |
Inhibit gate shape should have one outward connector. |
TargetType |
0 |
FilterExpression |
STRSAME(LEFT(MASTERNAME(750),12),"Inhibit gate") |
TestExpression |
AGGCOUNT(GLUEDSHAPES(2)) = 1 |
You can test the rule by adding more than one outward connector to an inhibit gate shape.
Figure 20. Inhibit gate shape should have one outward connector
Rule 8: A gate, except the inhibit gate, must be connected to at least three events.
The FilterExpression value checks that a gate shape other than an inhibit gate shape is to be tested. The TestExpression value checks that there are at least three connected events.
Category |
Connectivity |
NameU |
GateMustConnectAtLeastThreeEvents |
Description |
Gate shape has fewer than three connected events. |
TargetType |
0 |
FilterExpression |
OR(STRSAME(LEFT(MASTERNAME(750),7),"OR gate"),STRSAME(LEFT(MASTERNAME(750),8),"AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Priority AND gate"),STRSAME(LEFT(MASTERNAME(750),17),"Exclusive OR gate"),STRSAME(LEFT(MASTERNAME(750),11),"Voting gate")) |
TestExpression |
AGGCOUNT(FILTERSET(CONNECTEDSHAPES(0), "OR(STRSAME(LEFT(MASTERNAME(750),11),""Basic event""),STRSAME(LEFT(MASTERNAME(750),17),""Undeveloped event""),STRSAME(LEFT(MASTERNAME(750),5),""Event""),STRSAME(LEFT(MASTERNAME(750),11),""House event""),STRSAME(LEFT(MASTERNAME(750),17),""Conditional event""))")) > 2 |
You can test the rule by adding fewer than three connectors to any of the gate shapes.
Figure 21. Gate shape has fewer than three connected events
Rule 9: A transfer symbol must have only one connection.
The FilterExpression value checks the layer assignment and verifies that a transfer symbol shape is to be tested. The TestExpression value checks that there is only one glued connector.
Category |
Connectivity |
NameU |
Transfer |
Description |
Transfer symbol shape should have one connector. |
TargetType |
0 |
FilterExpression |
AND(ONLAYER("Flowchart"),STRSAME(LEFT(MASTERNAME(750),15),"Transfer symbol")) |
TestExpression |
AGGCOUNT(GLUEDSHAPES(0))= 1 |
You can test the rule by adding more than one connector to a transfer symbol, or by having no connectors at all.
Figure 22. Transfer symbol shape should have one connector
Publishing Rules
Rule sets are saved in Visio documents or templates. For example, you can save your blank FTA document as Fault Tree Validation Rules.vsd. Regardless of whether you use a document or template, any drawing based on your file will contain your rule set. After you use VBA code to add the rules to the file, you can safely remove that code to make your drawing file smaller and avoid the requirement to enable macros in drawings that are created from your template.
Alternatively, you could open an existing or new drawing, and then import the rule set by clicking the Check Diagram arrow, pointing to Import Rules From, and then selecting the rule set (as shown in Figure 23).
Figure 23. Importing a rule set
Conclusion
This article shows how to analyze existing validation rules in Visio Premium 2010 and how to use the Validation API to create your own rules and rule sets to validate diagrams. By using the Validation API, you can modify existing rules, or you can create complex rules and rule sets in code to validate custom diagram logic.
Additional Resources
For more information about diagram validation in Visio 2010, see the following resources.
Visio Insights Blog
SharePoint Workflow Authoring in Visio Premium 2010 (Part 1)
SharePoint Workflow Authoring in Visio Premium 2010 (Part 2)
bVisual Blog
MSDN Library
About the Author
David J. Parker is a Visio MVP and the owner of bVisual Ltd. He writes data visualization solutions, primarily using Visio and Bing Maps.
David writes a regular blog about Visio at bvisual.spaces.live.com, and he is the author of Visualizing Information with Microsoft Visio 2007. He just finished a new book, Microsoft Visio 2010 Business Process Diagramming and Validation, for Packt Publishing.