Diagram Validation is a new Visio 2010 feature that provides a way for users to check their diagrams for common errors and for companies to ensure that employees are following certain diagramming standards. The basics of diagram validation and creating custom validation rules have been previously discussed on this blog. In this post, we focus on the details of using the validation API to create validation rules, trigger validation, and manage validation issues.
Visio provides an extensive Diagram Validation API that allows companies to develop custom validation rules based on their own needs. For example, you can build rules to check that a network diagram includes mandatory components, or that a process diagram complies with company policies. The ability to verify the correctness of a diagram and raise issues to end-users is also crucial for solutions that need a certain diagram structure to work. For example, Visio uses validation for Microsoft SharePoint Workflow diagrams to ensure that SharePoint workflows are structured correctly before exporting them. As a developer, you can leverage Diagram Validation to support diagram verification for the diagram types and the issues that are important to you.
Validation API overview
The key objects, methods and properties for validation are shown below.
The validation API is based on three main concepts: rule sets, rules and issues. A validation rule, or simply a rule, represents one type of error that can occur in your diagram. Each rule has some underlying business logic which determines when the rule has been broken. An issue is one case in your diagram where the validation rule has been 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, then validation will display an issue for each shape without 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, namely ValidationRuleSet, ValidationRule and ValidationIssue. Below we explain the key properties for each of these objects.
ValidationRuleSet
Every rule set has a unique NameU property representing the universal name of the rule set. You should also specify a Description for each rule set. Other properties are set by default, and only need to be modified if a different behavior is desired. The key properties of the ValidationRuleSet object are shown below.
Property | Description |
Description | Specifies the description of the rule set. |
Enabled | Determines whether the rule set is active or inactive. Only rules belonging to active rule sets are checked when validation is triggered. By default, rule sets are enabled. |
Name | Specifies the name of the rule set that appears in the UI. By default, it is the same as NameU. |
NameU | Specifies the universal name of the rule set. |
Rules | Itemizes the rules in the rule set. |
RuleSetFlags | Determines whether the rule set appears in the UI. By default, rule sets are visible through the UI. |
ValidationRule
Every rule has a unique NameU property representing the universal name of the rule. You should also specify a Category and Description for each rule set, as these properties are used in the UI. The Category should inform the user about the type of issue, and may be used to identify the rule set that triggered the issue. The Description should be explicit enough to explain the issue so that a user can address it.
The blog post on creating custom validation rules describes two approaches for creating custom validation rules: you can store validation logic in a Visio template, or you can express validation logic in code and deploy this logic as part of a Visio solution. If you decide to store validation logic in a Visio template, the FilterExpression, TestExpression and TargetType are the fundamental properties for detecting and reporting issues during validation. If you decide to write validation logic in code, these fields should be left blank. The FilterExpression, TargetType and TestExpression properties are described in more detail in the section titled Defining ValidationRule.FilterExpression and ValidationRule.TestExpression.
The key properties of the ValidationRule object are shown below.
Property | Description |
Category | Represents the text displayed in the Category column of the Issues window. |
Description | Specifies the description of the rule that appears in the Issues window. |
FilterExpression | Specifies the logical expression that determines whether the validation rule should be applied to a target object. |
Ignored | Determines whether the validation rule is currently ignored. By default, rules are not ignored. |
NameU | Specifies the universal name of the rule. |
RuleSet | Returns the rule set that contains the rule. |
TargetType | Determines the target type of the rule. A rule can target documents, pages, or shapes. |
TestExpression | Specifies the logical expression that determines whether the target object satisfies the rule. |
ValidationIssue
Every issue has an associated Rule which specifies the description and category that is displayed in Issues window. When a user clicks on an issue in the Issues window, Visio will navigate to the page of the issue (if the issue targets a page or shape) and will select the target shape (if the issue targets a shape).The TargetPage, TargetPageID and TargetShape properties are used determine the page to display and the shape to select. The key properties of the ValidationIssue object are shown below.
Property | Description |
Ignored | Determines whether the issue is currently ignored. |
Rule | Specifies the rule that generated the issue. |
TargetPage | Specifies the page that is associated with the issue. |
TargetPageID | Specifies the ID of the page that is associated with the validation issue. |
TargetShape | Specifies the shape that is associated with the validation issue. |
Validation methods for adding rule sets and rules
Validation methods can be divided into different groups. We will start by describing the first group of methods, which allows developers to add validation rule sets and rules to a document. Typically, these methods are executed once to populate a template or diagram with validation rules. In fact, the rules can be pre-populated in a template, and then the template can be deployed to end-users without any solution code.
For each of the following API methods, we give a brief description on what the method does, along with an explanation of the method’s arguments.
ValidationRuleSets.Add(NameU)
Adds a new, empty ValidationRuleSet object to the ValidationRuleSets collection of the document.
- NameU: The universal name to assign to the new validation rule set.
ValidationRules.Add(NameU)
Adds a new, empty ValidationRule object to the ValidationRules collection of the document.
Example
The following VBA code adds a rule set and a rule that targets a shape to the active document.
Set vsoDocument = Visio.Activedocument | |
'Add a validation rule set to the document | |
Set vsoValidationRuleSet = vsoDocument.Validation.RuleSets.Add("Connectivity") | |
vsoValidationRuleSet.Description = "Verify that shapes are correctly connected in the document." | |
vsoValidationRuleSet.Enabled = True | |
vsoValidationRuleSet.RuleSetFlags = Visio.VisRuleSetFlags.visRuleSetDefault | |
'Add a validation rule to the document | |
Set vsoValidationRule = vsoValidationRuleSet.Rules.Add(“Unglued2DShape”) | |
vsoValidationRule.Category = "Shapes" | |
vsoValidationRule.Description = "This 2-dimensional shape is not connected to any other shape." | |
vsoValidationRule.Ignored = False | |
vsoValidationRule.TargetType = Visio.VisRuleTargets.visRuleTargetShape | |
'The validation function Is1D() returns a Boolean value indicating whether the shape is | |
'1D (True) or 2D (False) | |
vsoValidationRule.FilterExpression = "NOT(Is1D())" | |
'The validation function GLUEDSHAPES returns a set of shapes glued to the shape. | |
'It takes as input one parameter indicating the direction of the glue. | |
'The direction values are equivalent to members of VisGluedShapesFlags: | |
'0 = visGluedShapesAll1D and 3 = visGluedShapesAll2D | |
'The validation function AGGCOUNT takes a set of shapes as its input, and returns | |
'the number of shapes in the set. | |
vsoValidationRule.TestExpression = "AGGCOUNT(GLUEDSHAPES(0)) + AGGCOUNT(GLUEDSHAPES(3)) > 0" |
Validation methods for managing issues
When you set the TargetType, FilterExpression and TestExpression of a rule, Visio will manage issues associated with the rule for you. For very complex validation rules, it will be easier to omit these properties and write the validation logic in solution code. For this approach, the solution should listen for the appropriate RuleSetValidated event and use its own logic to determine the list of issues to add to the document.
We give a brief description of the two key methods that you will use to manage issues, along with an explanation of the method’s arguments.
ValidationRule.AddIssue([TargetPage],[TargetShape])
Creates a new validation issue that is based on the validation rule, and adds it to the document.
- TargetPage(Optional): The page that either has the issue or has the shape with the issue.
- TargetShape(Optional): The shape that has the issue.
ValidationIssue.Delete()
Deletes the ValidationIssue object from the document.
Example
The following VBA code adds an issue to an existing rule. It assumes that vsoValidationRule is a valid Visio.ValidationRule object, vsoShape is a valid Visio.Shape object and vsoPage is a valid Visio.Page object.
'Add a custom issue to the vsoValidationRule validation rule and associate it with | |
'shape vsoShape on page vsoPage | |
Set vsoValidationIssue = vsoValidationRule.AddIssue(vsoPage, vsoShape) | |
vsoValidationIssue.Ignored = False |
Using the API to validate a document
If you have a custom solution that needs a certain diagram structure to function properly, you can use the Validation.Validate method to validate the diagram and raise issues to end-users. This method validates a particular validation rule set (if specified) and updates the Validation. LastValidatedDate property. It will also trigger the RuleSetValidated event. It is recommended that you omit the rule set parameter, and validate against all active rule sets. This gives end-users a clear and consistent view of the issues currently in their document.
Validation.Validate([RuleSet As ValidationRuleSet], [Flags As VisValidationFlags])
Validates the specified validation rule set.
- RuleSet (Optional): The rule set to validate across the entire document.
- Flags (Optional): Whether to open the Issues window after validation.
Example
The following VBA code validates all rule sets in the document and launches the Issues window.
'Validate the document | |
Call Visio.Activedocument.Validation.Validate(, Visio.VisValidationFlags.visValidationDefault) |
Defining ValidationRule.FilterExpression and ValidationRule.TestExpression
When you validate a diagram by calling the Validation.Validate method or by clicking Check Diagram on the Process tab, Visio will automatically use any validation logic stored in the document to detect errors. This validation logic is expressed in the ValidationRule.TargetType, ValidationRule.FilterExpression and ValidationRule.TestExpression properties. The FilterExpression and TestExpression should be written as Boolean expressions that can be evaluated on every object of type TargetType. During validation of a rule, for every object of type TargetType, Visio uses the FilterExpression to determine whether the object must satisfy the validation rule. If the filter expression evaluates to True, Visio uses the TestExpression to determine whether to generate an issue for the object. If the filter expression evaluates to False, Visio does not apply the validation rule to the object.
The syntax for the FilterExpression and TestExpression properties are the same as that of a ShapeSheet expression (you can get more details here and here if you're unfamiliar with the ShapeSheet). For example, since NOT(IS1D()) is a valid Boolean expression for the ShapeSheet of a shape, "NOT(Is1D())" is a valid FilterExpression or TestExpression for a validation rule with TargetType = Visio.VisRuleTargets.visRuleTargetShape. In addition to the standard ShapeSheet functions, the following validation functions can be used in a FilterExpression or TestExpression.
Function | Description |
Role() | Returns an integer indicating the shape role: {Element = 0, Connector = 1, Container = 2, Callout = 4}. |
OnLayer(LayerName) | Returns a Boolean indicating whether the shape is a member of the specified layer. Returns a Boolean indicating whether layer exists on page if called on a Page. |
ConnectedShapes(Direction) | Returns the set of shapes, matching the Direction criteria, connected to the shape. |
GluedShapes(Direction) | Returns the set of shapes, matching the Direction criteria, glued to the shape. |
ContainerMembers() | Returns the set of shapes that are members of the container / 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 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 such that the shape is on the boundary of these containers. |
The validation expression functions ConnectedShapes and GluedShapes correspond to connectivity API functions with the same names. Similarly, the possible values of the Direction input parameter for ConnectedShapes and GluedShapes correspond to the VisConnectedShapesFlags and VisGluedShapesFlags enumerations, respectively.
Feedback welcome!
We hope that this overview of the validation API provides the necessary details to start writing your own validation rules. We’re interested to hear what developers think of this API functionality, so please use the Send a Smile feedback tool or leave a comment below.