Microsoft Visio 2010 Developer Training



Microsoft Visio 2010 Developer TrainingVolume 3: Programming with the Visio Object ModelDISCLAIMER? 2010 Microsoft Corporation. All rights reserved. Microsoft?, Internet Explorer, and Windows? are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries.The names of actual companies and products mentioned herein may be the trademarks of their respective owners.The contents of this package are for informational and training purposes only and are provided "as is" without warranty of any kind, whether express or implied, including but not limited to the implied warranties of merchantability, fitness for a particular purpose, and non-infringement.No part of the text or software included in this training package may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording, or any information storage and retrieval system, without permission from Microsoft?. Because Microsoft must respond to changing market conditions, it should not be interpreted to be a commitment on the part of Microsoft, and Microsoft cannot guarantee the accuracy of any information presented after the date of publication. The names of actual companies and products mentioned herein may be the trademarks of their respective owners.To obtain authorization for uses other than those specified above, please visit the Microsoft Copyright Permissions Web page at This content is proprietary and confidential, and is intended only for users described in the content provided in this document. This content and information is provided to you under a Non-Disclosure Agreement and cannot be distributed. Copying, disclosing all or any portion of the content and/or information included in this document is strictly prohibited.Table of Contents TOC \o "1-3" \h \z \u VBA Primer PAGEREF _Toc253092173 \h 10Event Driven vs. Procedure Based Programming PAGEREF _Toc253092174 \h 11Visual Basic Editor PAGEREF _Toc253092175 \h 12Variables PAGEREF _Toc253092176 \h 15Dimensioning PAGEREF _Toc253092177 \h 16Data Types PAGEREF _Toc253092178 \h 18Using Hungarian Notation PAGEREF _Toc253092179 \h 20Manipulating Variables PAGEREF _Toc253092180 \h 21Exercise 1 PAGEREF _Toc253092181 \h 23Other Operations PAGEREF _Toc253092182 \h 25Exercise 2 PAGEREF _Toc253092183 \h 27Data type conversions and variable scope PAGEREF _Toc253092184 \h 29Exercise3 PAGEREF _Toc253092185 \h 31Constants PAGEREF _Toc253092186 \h 33Control structures PAGEREF _Toc253092187 \h 34Branching Statements PAGEREF _Toc253092188 \h 34Looping Statements PAGEREF _Toc253092189 \h 36Jumping Statements PAGEREF _Toc253092190 \h 37Procedures PAGEREF _Toc253092191 \h 38Functions PAGEREF _Toc253092192 \h 38VBA Primer Conclusion PAGEREF _Toc253092193 \h 40Introduction to Automation PAGEREF _Toc253092194 \h 41Introduction PAGEREF _Toc253092195 \h 43Automation Basics PAGEREF _Toc253092196 \h 44Programming a Server's Objects PAGEREF _Toc253092197 \h 46VBE Tools Menu PAGEREF _Toc253092198 \h 49Object Browser PAGEREF _Toc253092199 \h 51Review: Introduction to Automation PAGEREF _Toc253092200 \h 52Automation and Visio Technology PAGEREF _Toc253092201 \h 53Overview PAGEREF _Toc253092202 \h 54The Visio Object Model PAGEREF _Toc253092203 \h 55A Sample Visio Program PAGEREF _Toc253092204 \h 58Getting and Setting Properties PAGEREF _Toc253092205 \h 60Invoking Methods PAGEREF _Toc253092206 \h 62Compound References PAGEREF _Toc253092207 \h 64Lab 3.1: Get the Name of an Open Visio Document PAGEREF _Toc253092208 \h 65Coding Issues PAGEREF _Toc253092209 \h 66Running Your Program PAGEREF _Toc253092210 \h 68RUNADDON(“string”) PAGEREF _Toc253092211 \h 70CALLTHIS PAGEREF _Toc253092212 \h 72Where to Find Visio Automation Information PAGEREF _Toc253092213 \h 73Lab 3.2: Running VB Add-ons PAGEREF _Toc253092214 \h 75Review: Automation and Visio PAGEREF _Toc253092215 \h 76Generating Drawings PAGEREF _Toc253092216 \h 78Creating a Document PAGEREF _Toc253092217 \h 79Getting a Reference to the Master PAGEREF _Toc253092218 \h 81Dropping the Master on the Page PAGEREF _Toc253092219 \h 82Adding Text to Shapes PAGEREF _Toc253092220 \h 84Getting Formulas of Shapes and Pages PAGEREF _Toc253092221 \h 85Getting a Formula or Its Result PAGEREF _Toc253092222 \h 87Setting a Formula PAGEREF _Toc253092223 \h 89Tips for Positioning Shapes PAGEREF _Toc253092224 \h 90Tips for Positioning Shapes (Continued) PAGEREF _Toc253092225 \h 91Connecting Shapes PAGEREF _Toc253092226 \h 92Getting the Cell to Glue PAGEREF _Toc253092227 \h 93Gluing to the Other Shape PAGEREF _Toc253092228 \h 94AutoConnect Mode PAGEREF _Toc253092229 \h 96Adding Data to Shapes PAGEREF _Toc253092230 \h 99Adding Sections and Rows PAGEREF _Toc253092231 \h 100Lab 3.3: "Hello World" PAGEREF _Toc253092232 \h 101Review: Generating Visio Drawings PAGEREF _Toc253092233 \h 102Getting Data From Drawings PAGEREF _Toc253092234 \h 104Overview PAGEREF _Toc253092235 \h 105Iterating Through a Collection PAGEREF _Toc253092236 \h 106Getting Data from Documents PAGEREF _Toc253092237 \h 108Noteworthy Document Properties PAGEREF _Toc253092238 \h 109Getting Data from Pages PAGEREF _Toc253092239 \h 111Getting Data from Shapes PAGEREF _Toc253092240 \h 112Getting Data About Connections PAGEREF _Toc253092241 \h 113Connect Object for a Control Handle to a Shape PAGEREF _Toc253092242 \h 115Connect Object for a 1-D Between 2-D Shapes PAGEREF _Toc253092243 \h 116More Connectivity API options PAGEREF _Toc253092244 \h 118Getting a Selection Object PAGEREF _Toc253092245 \h 124Working with Windows and Selected Shapes PAGEREF _Toc253092246 \h 126Getting Cells with CellsSRC PAGEREF _Toc253092247 \h 128Determining Shape Proximity PAGEREF _Toc253092248 \h 130SpatialRelation PAGEREF _Toc253092249 \h 131Lab 3.4: Calculate the Area of a Shape PAGEREF _Toc253092250 \h 132Review: Getting Data from Drawings PAGEREF _Toc253092251 \h 133Managing Events PAGEREF _Toc253092252 \h 135Learning Objective PAGEREF _Toc253092253 \h 136Introduction PAGEREF _Toc253092254 \h 137Cell Dependencies PAGEREF _Toc253092255 \h 138Force Dependencies with DependsOn PAGEREF _Toc253092256 \h 139DependsOn Example PAGEREF _Toc253092257 \h 140SetAtRef ShapeSheet Function PAGEREF _Toc253092258 \h 142Use the ShapeSheet to Manage Events PAGEREF _Toc253092259 \h 144Use Formulas Over Code PAGEREF _Toc253092260 \h 145Visual Basic for Applications Code Behind Events PAGEREF _Toc253092261 \h 146Supported Events PAGEREF _Toc253092262 \h 147Hierarchical Event Sets PAGEREF _Toc253092263 \h 148Built-In Document Events PAGEREF _Toc253092264 \h 149WithEvents Keyword PAGEREF _Toc253092265 \h 151Controls PAGEREF _Toc253092266 \h 153Query Events PAGEREF _Toc253092267 \h 155Query Events (Continued) PAGEREF _Toc253092268 \h 157Marker Events PAGEREF _Toc253092269 \h 158Scoping Methods PAGEREF _Toc253092270 \h 160Lab 3.5: Create a Shape Area Calculator PAGEREF _Toc253092271 \h 161Points to Consider PAGEREF _Toc253092272 \h 161Other Considerations PAGEREF _Toc253092273 \h 162Review: Managing Events PAGEREF _Toc253092274 \h 164Automating Data Graphics PAGEREF _Toc253092275 \h 165Lesson 1: Data Graphics Concepts PAGEREF _Toc253092276 \h 167Overview of Objects / Methods / Properties PAGEREF _Toc253092277 \h 167Creating Data Graphics Masters PAGEREF _Toc253092278 \h 170Creating Data Graphics Items PAGEREF _Toc253092279 \h 173Managing Data Graphic Masters PAGEREF _Toc253092280 \h 195Lesson 2: Related Topics PAGEREF _Toc253092281 \h 198Shape Data Management PAGEREF _Toc253092282 \h 198Lab 3.6: Data Graphics PAGEREF _Toc253092283 \h 204Exercise 1: Create a Pie Chart data graphic item PAGEREF _Toc253092284 \h 204Exercise 2: Test the New Pie Chart data graphic item PAGEREF _Toc253092285 \h 207Exercise 3: Add a data bar to the Data Graphic that totals the 9th, 10th, 11th, and 12th grade slots for a class section. PAGEREF _Toc253092286 \h 209Additional Resources – Data Graphics PAGEREF _Toc253092287 \h 210Review: Automating Data Graphics PAGEREF _Toc253092288 \h 212Managing External Data Sets PAGEREF _Toc253092289 \h 214Lesson 1: Data Link Concepts PAGEREF _Toc253092290 \h 215Overview of Objects / Methods / Properties PAGEREF _Toc253092291 \h 215Data Sources PAGEREF _Toc253092292 \h 221Lesson 2: Managing Data sets PAGEREF _Toc253092293 \h 230Linking data to shapes PAGEREF _Toc253092294 \h 231Managing Refresh PAGEREF _Toc253092295 \h 237Changing data locations PAGEREF _Toc253092296 \h 242Lab 3.7: Data Linking PAGEREF _Toc253092297 \h 244Exercise 1: Connect to an external data set PAGEREF _Toc253092298 \h 245Exercise 2: Link the Instructor shapes to rows in the Teacher DataRecordset PAGEREF _Toc253092299 \h 245Exercise 3: Drop and link the Section shapes to the rows in the Section DataRecordset PAGEREF _Toc253092300 \h 246Exercise 4: Change the external data, refresh the drawing, and manage changes required by the data PAGEREF _Toc253092301 \h 246Additional Resources – External Data PAGEREF _Toc253092302 \h 247Review: Managing External Data Sets PAGEREF _Toc253092303 \h 249Visio Software Development Kit (SDK) PAGEREF _Toc253092304 \h 251Lesson 1: Setup / Overview PAGEREF _Toc253092305 \h 252Software Requirements for Visio 2010 SDK Tools and Samples PAGEREF _Toc253092306 \h 253Documentation PAGEREF _Toc253092307 \h 255Containers PAGEREF _Toc253092308 \h 256TypeLibs Included PAGEREF _Toc253092309 \h 259Changes from Visio 2010 SDK PAGEREF _Toc253092310 \h 260Visual Studio 2005 and 2008 Add-in Wizards PAGEREF _Toc253092311 \h 260Lesson 2: Tools PAGEREF _Toc253092312 \h 267Event Monitor PAGEREF _Toc253092313 \h 267Demo: Use Event Monitor to track actions in Visio PAGEREF _Toc253092314 \h 269About Using the Persistent Events Tool PAGEREF _Toc253092315 \h 270Print ShapeSheet PAGEREF _Toc253092316 \h 273Publish Component PAGEREF _Toc253092317 \h 275Lab 3.8: Build and run the Visio SDK Flowchart sample PAGEREF _Toc253092318 \h 281Exercise 1: Build and run the Flowchart () sample code from the SDK PAGEREF _Toc253092319 \h 281Exercise 2: Code review. PAGEREF _Toc253092320 \h 283Additional Resources - SDK PAGEREF _Toc253092321 \h 285Review: SDK PAGEREF _Toc253092322 \h 287Visio Drawing Control PAGEREF _Toc253092323 \h 289Lesson 1: Concepts PAGEREF _Toc253092324 \h 290Requirements / Containers PAGEREF _Toc253092325 \h 290Demo: Drawing Control PAGEREF _Toc253092326 \h 291Lesson 2: Creating an application PAGEREF _Toc253092327 \h 301Best Practices PAGEREF _Toc253092328 \h 301Porting existing code PAGEREF _Toc253092329 \h 302The Controls SDI (single document interface) PAGEREF _Toc253092330 \h 303Getting a reference to the Visio Application Object PAGEREF _Toc253092331 \h 304Loading a document PAGEREF _Toc253092332 \h 304Saving a document PAGEREF _Toc253092333 \h 305Integrating the control with the host container PAGEREF _Toc253092334 \h 306Page sizing and zoom PAGEREF _Toc253092335 \h 307Window management PAGEREF _Toc253092336 \h 308Integrating menus and toolbars PAGEREF _Toc253092337 \h 309Handling events PAGEREF _Toc253092338 \h 310Using the Visio Control with the Internet Explorer Browser Control PAGEREF _Toc253092339 \h 312Lab 3.8: Using the Visio Drawing Control PAGEREF _Toc253092340 \h 313Exercise 1: Set the Src property of the document and display the External Data window PAGEREF _Toc253092341 \h 314Exercise 2: Add menus to place and delete Sections PAGEREF _Toc253092342 \h 314Exercise 3: Add SaveAs menu PAGEREF _Toc253092343 \h 315Additional Resources – Drawing Control PAGEREF _Toc253092344 \h 316Review – Visio Drawing Control PAGEREF _Toc253092345 \h 318Adding the Office Fluent UI to an existing Add-in PAGEREF _Toc253092346 \h 320Getting started PAGEREF _Toc253092347 \h 321Updating References PAGEREF _Toc253092348 \h 321Preparing the add-in for Ribbon support PAGEREF _Toc253092349 \h 321Creating the Ribbon PAGEREF _Toc253092350 \h 324Callbacks PAGEREF _Toc253092351 \h 328Manage Ribbon control state PAGEREF _Toc253092352 \h 329CommandBars and Ribbon PAGEREF _Toc253092353 \h 332Sample Code PAGEREF _Toc253092354 \h 333VBA PrimerThis supplement is designed to be a primer for programming with Visual Basic and Visual Basic for Applications. Upon completion of this supplement, you should be familiar with some basic coding concepts such as:VariablesObjectsMethodsPropertiesConditionalsFunctions and ProceduresVisual Basic Editor EnvironmentEventsCOM – Object ModelsExamples and exercises will demonstrate basic coding concepts, and will use the VBA programming language.Event Driven vs. Procedure Based ProgrammingVisual Basic is a structured programming language derived from the BASIC language. VB is event-driven, in contrast to some other programming languages and architectures that are procedure-based. In conventional programming, the sequence of operations for an application is determined by a central controlling program (e.g., a main procedure). In event-driven programming, the sequence of operations for an application is determined by the user’s interaction with the application’s interface (forms, menus, buttons, etc.).For example, rather than having a main procedure that executes an order entry module followed by a data verification module followed by an inventory update module, an event-driven application remains in the background until certain events happen: when a value in a field is modified, a small data verification program is executed; when the user indicates that the order entry is complete, the inventory update module is executed, and so on. Event-driven programming, graphical user interfaces (GUIs), and object-orientation are all related since forms and the graphical interface objects on the forms serve as the skeleton for the entire application. To create an event-driven application, the programmer creates small programs and attaches them to events associated with objects. In this way, the behavior of the application is determined by the interaction of a number of small manageable programs rather than one large program.Visual Basic EditorThere are a number of ways to open the Visual Basic Editor. You can access it from the Tools > Macros menu or by pressing Alt-F11. You can also add the Developer toolbar to your Visio user interface to expose the Visual Basic Editor toolbar button.You will first notice that there are several windows in the VBE: Project, Code, Properties, Immediate, and others. If you do not see these windows, go to the View menu to turn them on.Figure 1: The Visual Basic Editor windowThe Project window displays a hierarchical list of the projects and all of the items contained in and referenced by each of the projects. From the Project window, you can view the code contained in modules and forms and you can view form objects. From the Properties window, you can view and modify design time properties for objects in a project. From the Immediate window you can execute code. This is extremely useful when debugging to view the values of variables and expressions. It can also be used to set values of variables to test extreme or unusual conditions. To view the value of a variable or expression, place a question mark (?) before the code. To execute a line of code, enter it into the Immediate window and press the Enter key.Demonstration: Visual Basic EditorIn the Immediate window of VBE, type:Msgbox "This is my message."Press Enter. The code will execute displaying a message box with the text.Create a Visio drawing with a few shapes and select some or all of them.Return to the Visual Basic for Applications Editor and in the immediate window type: ?Application.ActiveWindow.Selection.Count Press enter. The immediate window returns the number of shapes you have selected in the Visio drawing.VariablesA variable is a part of memory that is given a name by a programmer. This part of memory is used to store important pieces of information that will be used in a program. Variables are containers for information that you wish to store in your application.The following code shows three variables, one a string of text, the other an integer, and the last a date:Dim Capitol as StringDim NumberOfStates as IntegerDim IndependenceDay as DateCapitol = “Washington D.C.”NumberOfStates = 50IndependenceDay = #7/4/1776#Variables are empty until you put information in them. Variables are stored in memory, and can be retrieved or replaced with new data at any time during the running of an application. DimensioningTo create a variable in a program, it is good practice to first declare the variable. Declaring a variable is done by putting the keyword Dim (which stands for Dimension) in front of the variable name, like so:Dim myFirstVariable as StringDimensioning a variable sets aside the name and space in memory for the variable. The variable is empty and contains nothing until the variable is assigned a value. The following example assigns the variable a value:myFirstVariable = “Some String of Text…”The previous example declared the variable explicitly. It is possible to implicitly declare a variable in your code by simply assigning a value to the variable without declaring it first with the Dim keyword, like so:myFirstVariable = “Another String of Text…”It is generally good practice to explicitly declare all of your variables, to avoid creating unnecessary variables and to help debug your programs by using Option Explicit.Option ExplicitOption Explicit is a line of code that you add to ensure that all your variables are explicitly declared. If using Option Explicit, an error will be generated if a variable is implicitly declared. This helps debug your programs because errors will be thrown if you ever misspell a variable name. For ASP scripts that use VBScript, you can add the line Option Explicit to the first line of your code. For VBA you can do this by choosing Options from the VBA Tools menu. This displays a tabbed dialog box. Choose the Editor tab. One of the check boxes on this tab is “Require Variable Declaration.” Checking this option causes the keywords Option Explicit to be inserted at the beginning of any new module or form added to the project. It does not, however, add Option Explicit to already existing forms and modules. Option Explicit forces any variable name used in code to be explicitly defined. This is very helpful at design time in catching any mistyped variable names.Data TypesIn most programming languages, data types are specified for each variable, such as String, Integer, Date, Boolean, etc. In VBA, you specify the data type when you declare a variable with the As keyword:Dim BabyFirstWord As StringBabyFirstWord = “Googoo”To create concise and fast code, it is recommended to explicitly specify a data type. If you use Option Explicit it will force all of your variables to have explicit data types. You can of course declare a variable without specifying a data type. In this case, VB assigns the variable to a special data type called Variant.VariantsWhen you do not specify a data type for a variable, the variable is assigned to the data type called Variant. The Variant is a special type of variable that can store a value of any type. Depending on the value and the context VBA will automatically assign the Variant one of the following sub-types: Null, Numeric, String, Date/Time, Boolean, or Object.NULL Data TypeA NULL subtype is an unusual subtype that is used in conjunction with databases. NULL refers to a field that contains no data. NULL does not mean zero, or even empty. Zero is a valid value, and empty is a data type that has nothing assigned to it yet. NULL means “nothing”, no data and no data type.Numeric Data TypesNumeric Data Types include the following:Integer – Whole numbers within the range of -32,768 to 32,767.Byte – Integers within the range of 0-255Long – Similar to Integer, but supports ranges from -2,147,483,648 to 2,147,483,647Single – A single precision floating point numberDouble – A double precision floating point numberCurrency – Accepts numbers up to four decimal placesString Data TypeA string holds textual information or words. String values are usually put in quotes. You cannot perform mathematical functions on strings, even if numbers are present in the string:Number1 = “12”Number2 = “14”Number3 = Number1 + Number2 ‘Will Produce “1214”Date/Time Data TypesDate/Time data types store dates and times, and must be enclosed in # characters:myBirthDate = #5/4/1965#Boolean Data TypesBoolean data types store values as either TRUE, or FALSE.Object Data TypesThe Object data type stores a reference to an object. Objects will be discussed further a bit later in this supplement.Naming VariablesIt is important to establish a good naming convention for your variables. Your naming convention should be easily understood by another developer who might look at your code later. Some tips for naming:NameFirst and NameLast are better than FirstName and LastName because they will appear together in a search.Within a procedure or function you may want to prefix your variables with a p_ or f_ type code letter.Create names with multiple words, capitalizing the first letter of each word.Using Hungarian NotationThe Hungarian notational convention is to use the first three letters of the variant’s name to distinguish the sub-type, as shown in the following table:Data TypePrefixExampleBooleanblnblnMemberBytebytbytByteDate / TimedatdatTodayDoubledbldblDoubleIntegerintintSalaryLonglnglngLongObjectobjobjConnSinglesngsngSingleStringstrstrTextBoxFor your applications, you do not have to use the Hungarian notation, but something similar is recommended. Note: Naming conventions and coding style standards evolve over time. Check if your organization has a defined naming convention and coding standard to use.Manipulating VariablesIn order for variables to be of any use, you will need to manipulate them in some way. You can manipulate variables using a number of different operators and by concatenating or converting them.Assignment OperatorThe assignment operator is the ‘equal’ (=) sign. With it, you can assign a value to variable. The variable name goes on the left, and the value to be assigned on the right side of the equals sign.intMyFavoriteNumber = 11The assignment operator can also be used to assign a new value to a variable, as in the following mathematically unsound formula:intMyFavoriteNumber = intMyFavoriteNumber + 1In the above case, it may look like we are saying 11 = 11 + 1. However, we are simply reassigning a new value to parison OperatorsComparison Operators are the following:Equality: =Inequality: <>Less than: <Greater than: >Less than or equal to: <=Greater than or equal to: >=Arithmetic OperatorsYou can use the following arithmetic operators to perform mathematical operations on your variables:Addition: +Subtraction: -Multiplication: *Division: /Exponentiation: ^Negation: -Modulus: MOD or \Exercise 1This exercise will use VBA to declare some variables, assign numbers to them, and then perform some simple mathematical operations on them.ExerciseOpen the VBA window in Visio (Alt-F11).In the VBA window add a new module to the project using the menu Insert > Module. You can give the new module a name or leave it as the default name.In the Project window, double click the module name. This will display the code window for the new module.Click in the code window and choose the menu Insert > Procedure. Give the new procedure a meaningful name such as “Excercise1”. Set Type to Sub and Scope to Public. Choose OK to close the dialog. Add the following code to the new aubroutine.Public Sub Exercise1() 'Dimension the Variables Dim intNumber1 As Integer Dim intNumber2 As Integer Dim intNumber3 As Integer 'Assign them values intNumber1 = 10 intNumber2 = 20 intNumber3 = intNumber1 + intNumber2 'Display the operations in the Immediate widow Debug.Print "intNumber1 = " & intNumber1 Debug.Print "intNumber2 = " & intNumber2 Debug.Print "intNumber3 = " & intNumber3End SubOther OperationsLogical OperatorsThe three most common logical operators are:ANDNOTORThese are mostly used in Conditional statements (IF THEN ELSE), which will be discussed shortly.Concatenating VariablesOften times you will want to combine strings together, a process called concatenation. You concatenate strings together in VB with the ampersand character (&). The following code combines two strings together, with a space added in between:Dim strPeter as StringDim strPan as StringDim FullName as StringstrPeter = “Peter”strPan = “Pan”strFullName = strPeter & “ “ & strPanExercise 2This exercise will use VBA to declare some variables as strings, assign values to them, and then concatenate them.ExerciseAdd another subroutine to your coding module. Call it “Exercise2”.Add the following code to the new subroutine:Public Sub Exercise2() 'Dimension the Variables Dim strNameFirst As String Dim strNameMiddle As String Dim strNameLast As String Dim strNameFull As String 'Assign them values strNameFirst = "Thomas" strNameMiddle = "Alva" strNameLast = "Edison" strNameFull = strNameFirst & " " & strNameMiddle & _ " " & strNameLast 'Display the results in the Immediate window Debug.Print "The full name is:" & strNameFullEnd Sub Note: The underscore character at the end of the statement assigning a value to strNameFull is a line continuation charater in VBA. It signifies that the code for this statement wraps to the next line.Data type conversions and variable scopeConversionsOften times you will have to convert values in order to work with them better. This might mean converting a decimal number into a whole number, or a numerical sequence into a string. You can do this through several conversion functions that are built into VBA. There are many conversion functions, and we will not cover all of them in this supplement. We will only look at two functions, CInt and CStr. The CInt function will convert a number variant into an integer and rounds it to the nearest even number. The CStr function will convert an integer into a string subtype. Variable ScopeVariables can be either local or global in scope. The variables we have seen so far have been global in nature, that is, they are valid for the entire block of code that we have written. Sometimes you may wish to break your code into functions or procedures, which are blocks of code that you can reuse throughout your application. In this case, if you declare a variable in a procedure or a function, the variable is only valid for the time that the procedure or function is executed. Note: Global variables must be defined at the top of the module before any subroutines or functions are defined.Exercise3This exercise will demonstrate local variables that are used in sub-procedures.ExerciseDefine the global variable. This must be done outside of any subroutine or function and must be defined at the top of the module before any subroutines or functions are definedDim strFirst as StringAdd the following code to the module. Sub Procedure_1() strFirst = "I'm a string in procedure 1" Debug.Print "Calling Procedure 1:" & strFirstEnd SubSub Procedure_2() strFirst = "I'm a string in procedure 2" Debug.Print "Calling Procedure 2:" & strFirstEnd SubPublic Sub Exercise3()'Display the results in the Immediate window Procedure_1 Procedure_2End SubTo run the code, click within subroutine Exercise3 and choose hit F5. The results are displayed in the Immediate window.ConstantsConstants are declared with the Const keyword. Constants are valuable when you want to assign a value to a variable and have it remain fixed throughout the execution of the code. The syntax for Constants is as follows:Public | Private Const name [As type] = ExpressionA variable or constant with Public scope is available to all procedures in all modules in a project.A variable or constant with Private scope is only available to procedures in the module that defines it, but not to procedures in other modules.ExamplesDefine the mathematical constant pi.Public Const pi As Double = 3.14159Control structuresIn VBA, control structures are used to determine what should happen, when it should happen, and under what circumstances it should happen. The three most common control structures are branching statements, looping statements, and jumping statements.Branching statements perform a test, and then execute some lines of code but not others.Looping statements execute a portion of code again and againJumping Statements pause the execution of the current code, jump to a different block of code, and then return back to the original code.Branching StatementsBranching statements include the familiar If … Then conditional, as well as the Select Case statement. Branching statements test for conditions, and then execute certain blocks of code if the conditions are TRUE, and different blocks of code if they are FALSE. If/ThenThe If …Then conditional is probably the most widely used control structure in programming. The syntax for an If statement is as follows:If logical_expression Then ‘Code to execute if True Else ‘Code to execute if FalseEnd IfIt is entirely possible to nest If statements, but be careful of doing this too many times as the code can become unmanageable very fast. To nest If statements, use a skeleton like the following:If condition_1 Then ‘Second If Statement If condition_2 Then ‘Code if True Else ‘Code if False End IfElse ‘Code if condition_1 is FalseEnd IfIf you want to have multiple tests in a single If statement, you can use ElseIf. ElseIf will enable you test a condition multiple times. Use the following skeleton for an ElseIf statement:If strBreakfast = “Sausage” Then ‘Code if TrueElseIf strBreakfast = “Donuts” Then ‘Code if TrueElseIf strBreakfast = “Green Eggs and Ham” Then ‘Code if TrueElse ‘Code if none of the above are TrueEnd IfSelect CaseSelect Case is used when you need to make a choice among several different answers. The following example carries out one of five actions depending on what is contained in the variable varCurrentMood. There can be multiple lines of code for each Case.Select Case varCurrentMood Case "Sad" 'code for Buy Kleenex and Sob Case "Mad" 'code for Punch the pillow Case "Happy" 'code for Smile Case "Homesick" 'code for Write a letter Case "Irritated" 'code Smirk Case Else 'The catch-all phrase for anything that doesn't fit the above. 'None of the above? Then you must be bored. Go out and play.End SelectLooping StatementsLooping statements perform the same action over and over again. There are two main looping structures, For …Next, For Each …Next, and Do …While.For … NextTypically the For …Next statement is used when the number of required loops is known, or is stored in a variable. Here is the syntax:For varCounter = X to Y ‘Code to execute hereNextvarCounter is a variable that the script uses to keep track of the current count. You could name it whatever you want. X and Y can be either numbers, or can be variable names that store numbers. X signifies the starting number to set the counter to, and Y is the end number of loops to perform. Dim DateStart As DateDim DateEnd As DateDim NumberOfDays As IntegerDim varCounter As IntegerDateStart = #7/1/2002#DateEnd = #7/15/2002#NumberOfDays = DateEnd - DateStartFor varCounter = 0 To NumberOfDays 'Code to execute hereNextFor Each … NextThe For Each …Next statement is used for looping through items that are in an array or a collection. The syntax is as follows:For Each Item In varVariable ‘Code to execute hereNextvarVariable can either be the name of an array, or a collection of objects.Do … WhileThe Do …While statement is used when you are not sure of the number of loops to perform. On each loop a test is performed, and as long as the condition is met the loop will continue to occur. The syntax is as follows:Do While varVariable1 < varVariable2 ‘Code to execute here varVariable1 = varVariable1 + 1LoopTypically, the value of varVariable1 will change within the loop. In the example it is incremented by 1 each time through the loop. At some point it will become bigger than the value in varVariable2 and the loop will end.Jumping StatementsJumping Statements are useful when you need reusable chunks of code that need to be called at specific moments. These are essentially mini-programs that force the main program to jump from the main body of code, run through the commands of the mini-program, and then return to the main body of code. There are two types of jumping statements: Sub procedures – Used to carry out actions. A sub procedure does not return values.Functions – Used to carry out actions and to return an answer to the main body of code.ProceduresSub procedures are used to execute a bit of code, and then return to the main body of the code. The syntax is as follows:Sub nameofsub() ‘Code to Execute Goes HereEnd SubYou can then execute a sub procedure by calling it using the Call command:Call nameofsubFunctionsFunctions are used to execute a bit of code and to return a value back to the main code. The syntax is as follows:Function NameOfFunction(Parameter) As Integer 'Code to Execute Goes Here 'Assign a value to the function before it ends 'This will be the value that the function returns NameOfFunction = 10End FunctionFunctions can take parameters, meaning they can accepts values from the main body of code and use them during the execution of the function. Inside the parenthesis () you can place the name of a variable that you want to pass to the function. For example, to create a function to calculate the next time to change the oil of a car (current mileage + 3000 miles), you can pass a variable that stores the current mileage into the function, as in the following code:Dim dCurrentMileage as DoubledCurrentMileage = 145000Function FindNextOilChange(dCurrentMileage) as DoubleWhen functions are finished performing their calculations, they return the result as a value of a new variable, which is the name of the function. When you create a function and give it a name, that name becomes a variable that will store the resulting value of the function’s calculations. It is not necessary to Dim this variable, it is available for use automatically. So, the code above becomes complete when we assign the value to the function name:Function FindNextOilChange(dCurrentMileage) as Double FindNextOilChange = dCurrentMileage + 3000End FunctionIt is common to create a new variable, and make the variable equal to the function. This invokes the function and stores the function’s value as a global variable.Sub CalculateNewMileage()Dim dCurrentMileage As DoubleDim dNewMileage As DoubledCurrentMileage = 145000dNewMileage = FindNextOilChange(dCurrentMileage)MsgBox “The mileage for your next oil change is” & “ “ & dNewMileageEnd Sub VBA Primer ConclusionThere are many more topics that could be covered to help get you started using VBA. Defining and using an application’s objects will be covered in the next few lessons as will learning to manage events within VBA.Introduction to AutomationWe’ve covered a few of the techniques that can be used for developing SmartShapes symbols. Now let’s cover how to use these symbols as part of a larger solution. Automation can be used to control Visio shapes, documents, and the Visio drawing environment, as well as other applications.Following a brief introduction to general Automation (previously referred to as ActiveX Automation or OLE Automation), you will cover the basics of automation and Visio—the Visio object model and how to access the Visual Basic Editor (VBE).A common application of automation and Visio technology is the automatic generation of Visio documents. It is common to store descriptive information in a database or a spreadsheet (describing a network, for example). It is very advantageous to get a graphical view of this data by creating a Visio document. Many times the generation of this document can be automated through the extraction of data and the creation of a document through automation. You can open a document, drop master shapes on the page, and position and size the newly created shape. All these steps can be done through automation and the techniques will be covered in Generating Drawings.Once a drawing is created, you often need to ask questions or extract information about the drawing. These requests can be satisfied though automation. An example of this would be getting an inventory of the shapes in the drawing, starting an application such as Microsoft Excel, and creating a Bill of Materials with part numbers and price information. In Getting Data from Drawings, we will cover the basics of accessing document, page, shape, and cell properties.As you work with drawings, you often need to know when something has occurred, a new piece of equipment has been added, or a network connection has been made. To validate the drawing, you can trap events and if needed, prompt the user for action. Managing Events covers these topics. IntroductionLet’s start by reviewing what is meant by Automation as well as some Visual Basic for Applications fundamentals. These early exercises focus on the Visio object model and not on development environments. As such, examples are shown using Visual Basic for Applications. This should not be considered a recommendation that you use VBA for all of your application development. It’s just that VBA is a very convenient platform for learning about an application’s object model.Automation BasicsWith Automation, one program can incorporate the functionality of another by using objects exposed by the other program.Automation encompasses several services defined under the OLE 2 specification, such as linking and embedding objects and in-place editing. The foundation of this technology is COM (Component Object Model). COM defines the interfaces for the objects an application exposes. It is this interface structure that allows COM objects to make their services available to other applications.The program that controls the automation is sometimes called a controller, client, or container application. This is a program you write in a language that supports Automation, for example, Visual Basic, Visual Basic for Applications, C#, or Microsoft Visual C++. You are going to focus on Visual Basic for Applications in this module, but you can use the Visio object model with Visual Basic, Visual C++, or any Microsoft Visual Studio .NET language as well. The program being automated is sometimes called a server or source application. This is the program that exposes the objects for the controller application to use. The objects have properties and methods that the controller can use to manipulate the objects. The Visio application is the ActiveX server you are interested in today.Some applications can act as both controllers and servers by embedding Visual Basic for Applications. Many of the Microsoft Office applications contain VBA, such as Word, Excel and Visio. Programming a Server's ObjectsObjects accessed through Automation remain with the object’s server. They are not incorporated in your program. Everything you do with a server’s object is done by way of a reference to that object, which you assign to an object variable in your program. You manipulate the objects remotely, from your program, by setting properties, and invoking methods through the object variable.An object reference is similar to a pointer; it is valid at run time but it is not something you can store between executions. Furthermore, having a reference doesn’t guarantee that you have an object. For example, you can get a reference to a shape on a page. However, if the user deletes the shape, you still have the reference but it’s not referring to anything useful.Demonstration scenario:The Visio drawing shows the Tech ED 97 General Session Theater which seats 10,000 and was the actual location for the original showing of this program.This demonstration is a nice example of how multiple applications can work together by accessing the object models of each other’s application. In this scenario, Visio controls Excel by gathering information from the Visio drawing and writing it to an Excel spreadsheet. When a row is selected in the Excel spreadsheet there is code that controls Visio and selects and centers the drawing on the selected object. There is a third application which unfortunately cannot be demonstrated here, but was part of the original demo. That is the automated control of an air cannon gun that was on stage and used to fire t-shirts into the crowd. The air cannon is represented by a shape in the Visio drawing. As you move the pointer for the air cannon in Visio, the coordinates from the Visio drawing were being fed to the actual air cannon on the stage through Rockwell’s own automation interface for this device..The drawing depicts seating, stage, demonstration machines, project units, controls, etc. Contents of the drawing can be pushed to an Excel spreadsheet by right clicking on the page and selecting "Create Asset Report". This add-on starts Excel, opens the template file TechED.xlt, and writes each component of the drawing to the spreadsheet.Each item in the drawing has shape data which capture the manufacturer, description, number of individual items and unit cost. When placed into the spreadsheet the total cost of each item is also calculated. If any item is greater than $10,000 the row item is made Red, Bold, and a larger point size.The Wet Bar is priced at $25,000 so it gets flagged in the spreadsheet.From the spreadsheet there are events tied to the up and down arrow keys so that as you move through the spreadsheet using the arrow keys the corresponding Visio object is selected and centered in the drawing. NOTE: Be sure to set the option "Center selection on zoom" in the File > Options > Advancced tab for the centering to occur.In the Visio drawing there is a T-shirt firing Air Gun on the stage. A control on the Air Gun allows you to direct the gun by moving it around the drawing. Right click on the Air Gun to either display its shape data or to display a form with the trajectory coordinates.Try it! TechEdMinimize all windows except the Visio window.From your student CD, open <install path>\Demos\Vol3\Introduction to Automation\TechEd.vsd.Right-click on the drawing page and select Create Asset Report. This starts Microsoft Excel and creates a Bill of Materials for all of the objects in the drawing.In Visio select File > Options > Advanced tab. Set Center Selection on Zoom. The demonstration will take advantage of this feature as you select the Visio drawing objects from the Excel spreadsheet.Tile the Excel and Visio windows. Select a row in Excel. Notice that the corresponding item is selected in the Visio window (you may have to zoom in or out in Visio to get a better view).VBE Tools MenuFrom the VBE Tools menu you can get to some very useful menu options.Choose the Options menu under Tools. This displays a tabbed dialog box. Choose the Editor tab. One of the check boxes on this tab is “Require Variable Declaration.” Checking this option causes the keywords Option Explicit to be inserted at the beginning of any new module or form added to the project. It does not, however, add Option Explicit to already existing forms and modules. Option Explicit forces any variable name used in code to be explicitly defined. This is very helpful at design time in catching any mistyped variable names.Objects other than Visio objects can be accessed by Visual Basic for Applications, but the Visual Basic for Applications environment must first be notified. This is done from the References menu under Tools. The dialog box displays all object libraries installed on the local machine. Just check the ones that you want to access. For example, if you want to control Excel from the Visio application, from the References menu, check the appropriate Excel object library.The functionality of Digital Signatures was added to Visio 2002. Digital Signatures allow you to add an extra level of security to your VBA projects. Using digital certificates, a developer can digitally sign a project and be identified as a trusted source. When a Visio document with a VBA project is loaded, Visio checks to see whether the project has been digitally signed by a trusted source before loading it. If it has, the project will be loaded under any security level. If it has not, Visio will load the project based on the current security level set for the Visio application. Macro security settings in Visio can be found in the Trust Center. For more information on Microsoft Office security, search the Microsoft Developer Web site (msdn.) for “Digital Signing”.Object BrowserOnce an object library is part of the project, its objects can be viewed with the Object Browser. Choose View > Object Browser (or F2) to use the browser.From the Object Browser you can view the hierarchical structure of any object library. You can search for objects by name. Once an object is selected, you can view its properties, methods, and events. Values of constants defined in a type library can also be determined from the object browser.To turn off the Object Browser, just close the window.Review: Introduction to AutomationQuestionsDefine Automation.What actually happens when one program uses Automation to drive another program?What allows Visio to be a controller and a server at the same time?What function does a digital signature provide?AnswersAutomation allows one program to incorporate the functionality of another by using objects exposed by the other program.The server application returns a handle to an object. The controller application can use this handle to ask the server application to do things with this object.Because Visio has embedded VBA it can be used as a controller. Because it exposes its object model it can be used as a server.Using digital certificates, a developer can digitally sign a project and be identified as a trusted source.Automation and Visio TechnologyIn this section, we will tie together some of the concepts that were learned in the ShapeSheet modules with Automation objects from the Visio object model.We have spent a good deal of time learning about the ShapeSheet. The ShapeSheet is important to understand in order to effectively automate Visio because each cell in the ShapeSheet is effectively a property that you can control through automation. However, most ShapeSheet cells will not be found directly in the Visio Object Model. Instead, you will access them indirectly through the Cells or CellsU property of the Shape object.OverviewNow you will learn about how you can use SmartShapes as part of a larger solution by using Automation to control the Visio application and the objects within it.In this module you will look in depth at the Visio Object Model. You will analyze each object and begin the process of discovering its methods and properties.You will learn different strategies for when and how to run your programs and issues to consider when choosing a platform for your program. Finally, we will look at other resources that are available to help in you in learning about and using the Visio Object Model. The Visio Object ModelThis slide shows a portion of the Microsoft Visio object model. A richer, but not complete view of the Visio object model is on the following page. The image shows the object model of Visio 2003, but at this high level view it is still shows the major components and the basic structure of the model.It is not as complicated as it looks; many of the objects are used primarily to access other objects, and you’re unlikely to use all of the objects in a given program. For example, you’ll probably do more with shapes than you will with documents and pages; you may never manipulate layers from a program, although Visio exposes layer objects so you can if you need to.Many objects in the model correspond to items you can see and select in Visio windows. For example, a Page object corresponds to a drawing page; a Shape object can represent anything on the drawing page that you can select with the pointer tool—a shape, a group, a guide or guide point, or an object that is linked or embedded in a Visio drawing.The Application object represents a running instance of the Visio application, and this is where you’ll typically start. In some circumstances you can start at the document or the page. The Application object has properties that return references to “next objects” in the model—for example; the Documents property returns a reference to the Documents collection, which represents all of the documents that are open in the instance. You would retrieve a particular document by using the Item property of the Documents collection. Use the Pages property of that Document object to get its Pages collection, and so on, down to a particular shape or even a particular formula of that shape, represented by a Cell object.The Microsoft Visio global object is automatically available to Microsoft Visual Basic for Applications (VBA) code that is part of the VBA project of a Visio document. The Visio global object is not available to code in other contexts. The global object holds references to such properties as ActiveWindow, ActiveDocument, and ActivePage. These properties are also available through the Application object if you are building your solution outside of VBA within Visio.A Sample Visio ProgramCode sample conventionsCode samples in the demonstration files and code displayed on slides generally follow a simple Hungarian notation. Variable names start with a lower case letter or letters that designate the data type of the variable. Following the data type designator will be a name describing the variable that starts in upper case.Below are some examples of variable names:oDocs – a data type Object referencing a Documents collectionoDoc – a data type Object referencing a single DocumentsShapeName – a data type String containing a shape’s nametxtShapeName – a text box control containing a shape’s namedCellResult – a double precision variable containing the contents of a ShapeSheet cellTry it! A Sample Visio ProgramRun an instance of Visio, and from your student CD open <install path>Demos\Vol3\ Automation and Visio\Sample Code.vsd.Right-click on the page to run the add-on GetShape (or from View > Macros > ThisDocument.GetShape). We will look at the VBA code for this add-on in step 5.Close the GetShape add-on.Press Alt+F11 to open Visual Basic for Applications.In the Project Window, open the Forms folder and right-click on frmGetShape. Select View Code and look at the following line:Set oDocs = Visio.DocumentsDocuments is a property of the Application object and also of the <global> object (accessed through the application name Visio). It returns the Documents collection.Set oDoc = oDocs.Item(1)Item is a property of the Documents collection (and of most other collections, too). It happens to be the default property, so you can omit Item but not (1). The rest of the code establishes a reference to each collection and collection member. Set oPages = oDoc.PagesSet oPage = oPages.Item(1)Set oShapes = oPage.ShapesSet oShape = oShapes.Item(1)sShapeName = oShape.NameThe Name property of a shape returns a string, which can be assigned to the Text property of our text box.txtShapeName.Text = sShapeNameGetting and Setting PropertiesOnce you get the object you want, you’ll probably become interested in its other properties. For example, in addition to the Name property, a Shape object has a Text property that returns its text, and a Type property that identifies the type of shape—whether it’s a group, a guide, or other kind of shape. Most properties that don’t return objects return strings or integers.The PageSheet property of the page returns a reference to the page’s ShapeSheet. This is a Shape object that has Type=visTypePage.You can set properties too, as long as they’re read-write or write-only. Here are some examples of property types:Read-only: A shape’s Sheet.#Read-write: ShapeSheet cellsWrite-only: Custom menu or toolbar setsThe Developer Reference help file contains a list of objects with their properties and methods. This reference also has an alphabetical list of properties and methods, whether they’re read-only, read-write, or write-only, and their return type. Note: When making an assignment to a variable of type Object, the Set keyword must be used. When making an assignment to a variable that is not an object (such as a string variable), the Set keyword is not used.Invoking MethodsThere were no methods used in the demonstration program of getting the shape’s name, but their syntax is similar to properties. Methods often correspond to Visio commands. For example, a Shape object has a Copy method that performs the same action as selecting the shape and choosing Copy from the Edit menu in Visio.Other methods correspond to actions. For example, a Window object has an Activate method that makes that window the active window.If a method creates an object, it typically returns a reference to that object. Methods that don’t create objects typically don’t return anything.Both properties and methods sometimes take arguments. For example:A Shape object’s Cells property takes the name of the ShapeSheet cell to return.The Documents collection’s Add method takes the name of a template on which to base a new document. Passing an empty string is equivalent to choosing File > New Drawing from the menu or New from the pound ReferencesThe examples in this course tend to declare an object variable and set it for every object in the model that we need a reference to. You don’t have to do this as you can concatenate Visio object references, properties, and methods as you can with Visual Basic objects.However, there are some tradeoffs and sometimes, simple references are better. If you use any of the intermediate objects in your program—for example, if you’re going to be working with more than one shape from the Shapes collection—it makes sense to assign the intermediate objects to variables so you have them available for other uses. This requires less overhead than repeatedly calling a compound statement, and enhances performance.A compound statement can also be harder to debug. Each expression is evaluated and its return value plugged into the statement before the next expression can be evaluated. If one fails, you’ll get an error at the statement but it may not be obvious where the failure occurred.Lab 3.1: Get the Name of an Open Visio DocumentPoints to ConsiderEstablish each object reference separately.Consider the document properties Description, Path or Subject for your additional information.ExerciseFrom your student CD, open <install path>\Labs\Vol3\Start\Get Doc.vsdFrom Visio, choose View > Macros > ThisDocument.Solution. This will display a form with the title GetDoc.Click the button on the form to display the name of the document.Without looking at the code for how the solution was produced, develop code to retrieve the document’s name and place it in frmExercise. When complete, run the macro.Coding IssuesIf an object is defined to be a specific type at design-time, as with the following statement Dim oDoc as Visio.Document it is bound to that data type at design time. This is called early binding. Many design-time checks can be made such as testing assignment statements to ensure the correct data type is being used. This creates more efficient run-time code. If late binding is used, as with the statement Dim oDoc as Object the type of the object must be determined at run time, and assigning the wrong type of data to the object can cause a run-time error.Using early binding of objects also allows you to take advantage of the Visual Basic Intellisense feature, giving you property, method, event and parameter information.Using Visual Basic for Applications code makes distribution of your add-on easy since the Visual Basic for Applications code is part of the drawing file. Updating the code, however, is more difficult.Demonstration: Protect Your VBA CodeOpen a new Visio drawing, and open the Visual Basic Editor window.From the Tools menu, choose <document name> Properties.Click the Protection tab, and click the Lock project for viewing checkbox.Enter a password and confirm it. Save and close the file. The next time the file is opened and the VBE is accessed, the project is locked and a password must be entered to view or edit the project.Running Your ProgramTo run your program:When Visio is launchedPut the .exe or .vsl file into a designated Startup folder. To set the Startup folder go to File > Options > Advanced > File Locations…Register the COM-Addin and set its load behavior to Load at Startup.From the ribbon under View > Add-ons Put the .exe or .vsl file into a designated Add-ons folder. To set the Add-ons folder go to File > Options > Advanced > File Locations… Use the Add method of the application's Addons collection to programmatically add the add-ons. Note: You have to restart Visio to refresh its Add-ons list before you’ll see your program on the menu. You can also use the file paths refresh method.From the ribbon under View > Macros Create a Macro through the Visio interface.Add a public procedure into a module or ThisDocument of the VBA project for the drawing. Macros in any one open project can be accessed by another open project.When the user opens a documentPlace your code or a reference to it in the DocumentOpened event in the ThisDocument module in Visual Basic for Applications.When a shortcut menu command is chosenCreate an entry in the Actions section of the ShapeSheet and make sure the add-on is either a public procedure within the Visual Basic for Applications project or is in the Add-ons path specified in the File > Options > Advanced > File Locations… dialog. Note: Beginning with Microsoft Visio 2003, you can publish your add-ons, templates, stencils and other files as components to be integrated with the Visio application. Publishing components is the preferred method of integrating add-ons and other content with Visio. It offers tighter integration with the Visio application, and better performance on add-on discovery. Publish Components will be covered in the section on the Visio Software Development Kit.RUNADDON(“string”)RUNADDON can execute a macro or call an add-on. Visio will first check for a macro of name “string” and execute that macro if one is found. If “string” is not recognized as a macro, the RUNADDON function looks for “string” in the add-on list and executes the add-on if it is found. If no add-on can be found, Visio reports no error and does nothing. Examples:Launch an add-on called Calendar.exeRUNADDON("Calendar.exe")Launch the (VSL-implemented) add-on whose name is Array Shapes.RUNADDON("Array Shapes")Call the ReportStatistics macro in the ThisDocument module in the document project containing this function call. To invoke a macro in the ThisDocument module, you must preface the string with "ThisDocument" as shown.RUNADDON("ThisDocument.ReportStatistics")Call the ReportStatistics macro in ModuleName in the document project that contains this function call.RUNADDON("ModuleName.ReportStatistics")For more information, see the demonstration file <install path>\Demos\Vol3\Automation and Visio\RunAddon.vsd for some examples of using the RUNADDON function.CALLTHISEven though RUNADDON is a very powerful function, there are times where the add-on being executed needs to get a reference to the shape that initiated the action.CALLTHIS is a variation of RUNADDON that automatically passes a reference to the shape that caused the add-on to be executed. Notice that the reference to the shape is very much like the "this" argument passed to a C++ member procedure; hence, the name "CALLTHIS." In effect, a cell that contains a formula with CALLTHIS is saying, "Call procedure and pass it a reference to my shape."The demonstration file CallThis.vsd has some good examples of using the CALLTHIS function.Where to Find Visio Automation InformationThere are many ways to get helpful information on the Visio automation model. A good place to start is with the Visio help files. The Developer Reference help file contains material for the automation model. Help information for the ShapeSheet is contained in the Visio SDK.Demonstration: Developer ReferenceOpen the Developer Reference help file, Help > Search > Developer Reference.In the Table of Contents select Visio Automation Object Model Reference.Display an object topic. This describes the object and lists its properties and methods.Display the topic for one of the object’s methods. Review what is in each property and method topic.Use some of the other jumps in the method topic to related properties and methods or other objects that have the same method.Other sources of information include the Visio Developer Portal on msdn.. This is the key entry point to gaining access to the latest articles, examples and downloads related to Visio. There are also Visio discussion groups where you can post questions and get answers. Visio SDK provides sample applications, code librarian code snippets, documentation, and tools—including the Event Monitor, Persistent Events, Print ShapeSheet, and Solution Publishing.A great way to explore the object model and really get a feel for how everything ties together is through the Object Browser. From the Visual Basic Editor choose View > Object Browser to display the Object Browser window. From the Object Browser you can explore the entire Visio Object Model.You can also explore a live Visio application by using the Immediate window from VBE. Choose View > Immediate Window. From the Immediate window investigate objects, properties, and methods of the current running instance of Visio.The Watch Window and the Locals Window are great places to view data values when exercising or debugging code in VBA.The Macro Recorder can be used to develop snippets of code for performing some function in Visio. Turn on the Macro recorder, perform the function you wish to automate, and then turn off the recorder. Viewing the generated code will show you how the operation is performed through automation.There are, however, limitations on the actions that can be captured by the Macro Recorder. Dialog only commands and Solution-specific commands are generally not recorded - so you could not automate the dropping and property setting of Database Model entities, for example. Also, you cannot record the action of shutting down the application, or any actions which leave Visio in a Modal state. The API programmability model for Themes, Data Graphics, and Pivot diagrams does not cover everything that can be done in the user interface so use of the macro recorder in these areas has been short circuited.Lab 3.2: Running VB Add-onsFor the lab, follow the directions listed on the slide. Note: Check File > Options > Advanced > File Locations for the appropriate add-on folder.Review: Automation and VisioQuestionsWhat are some of the objects in Visio’s object model? How might you use them in a program?Once you’ve finished building your custom solution, what are some of the different ways you can run it?How might this influence the design of your program?AnswersApplication, Document, Shape, Window, Cell, etc. Visio drawings can be created using automation or existing drawings can be interrogated for information. Solutions can be set up to run from a shape with a right-click action or a double-click. Add-ins and macros can also be executed from the View tab of the ribbon. A fundamental decision is between creating a macro and creating an add-in. Macros are useful for fairly simple one-off type solutions. Generating DrawingsIn this section let’s begin by using automation to create a document, drop masters in a drawing, and set the text of shapes. Along the way you’ll see more generally how to get and set shape properties, including how to access a particular formula and get either the formula as a string, or the value that is its result.Creating a DocumentTo create a new drawing, add a Document object to the Documents collection of the Application object.As you may recall, the Application object has a Documents property that returns its Documents collection. Because this is an object, you need to assign it to an object variable using Set. The first three code statements are equivalent in VBA because the global Visio is predefined and contains a reference to the Application object and the Documents object. If working outside of VBA it will be necessary to get a reference to the active instance of Visio’s Application object in order to access the Documents collection.If no documents are open in the instance, its Documents collection is empty. This can be important to remember if, for example, you run Visio and attempt to get a document without opening one first. Attempting to get an object from an empty collection causes an error.To create a new document, use the Add method. For a Documents collection, Add takes the filename of a template as an argument. Visio searches for the template in the template location defined under the menu File > Options > Advanced > File Locations. Alternatively, you may specify the file path explicitly.If you don’t want to base the new document on a template, use a null string. This creates a new blank document.The Open and OpenEx methods can be used to open existing document files. OpenEX takes the additional parameter that flags how to open the file. See the Microsoft Visio Developer Reference for more information. Getting a Reference to the MasterIf you base a new drawing on a template, it probably opens one or more stencils for you. This means the Documents collection now has more than one object in it. It has the new document you created plus each stencil opened by the template.When you use automation to drop a master in a drawing, you’ll be working with two Document objects—one that represents the new drawing, and the other that represents the stencil containing the master. Note: Every Visio document has a stencil which holds the master shapes that have been added to the drawing, so every Document object has a Masters collection. But the Masters collection of a new drawing is generally empty. Just make sure that you set your object reference to the Masters collection of the stencil, not the drawing.Dropping the Master on the PageHaving obtained a reference to the master, you now need a page on which to drop it. The next step is to get a Page object.A new document has at least one page, so its Pages collection will contain at least one Page object. To drop a master, use the Drop method of the Page. Drop takes three arguments: a Master object and a pair of x,y coordinates that indicate where to place the pin of the new shape (the instance of the master). The coordinate arguments to Drop must be expressed in inches, which are the units that Visio uses internally. Unfortunately, this means you may have to convert the arguments before dropping the master, if for example, you’re working in a scaled drawing or an unscaled drawing in metric units. The ConvertResult method of the Application is a handy tool for solving these unit conversion problems. Tip: Because you are going to do more to the new instance of the master, assign the object returned by Drop to an object variable, such as oShape. You’ll usually want to do this, but it’s not required.Adding Text to ShapesWhen you are creating a drawing from a program, you’ll usually set the text in shapes at run time. You might get the text from another file, or have the user type it in a form, for example.You assign text to a shape by setting its Text property to a string. You can, of course, concatenate strings and variables with the Visual Basic concatenation operator, and insert special characters (such as the linefeed shown here) using the VB Chr$() function or vbCrLf. The Text property of a shape can contain up to 64K of character data, which will be ample for most purposes.Use the Characters object to control field codes within the stream of text, just as you can do through the user interface.Getting Formulas of Shapes and PagesCompared to everything you can do to a shape in Visio, Shape objects have relatively few properties and methods (although they have many compared to some other objects in the model). So it might seem that your options are limited.They’re not, however, because you have full access to the ShapeSheet through Cell objects. A Cell object represents a particular formula, such as a shape’s Width formula. Once you have a Cell object, you can get the formula or the value it represents, just as you can choose Formulas or Values when viewing the ShapeSheet. Change the contents of a cell by setting its Formula property.Most commonly, you’ll get the values of certain formulas so you can use them to construct your drawing, such as the width and height of the page, or the drawing scale.To get a Cell object, get the Cells property of a shape object and specify the name of the cell. Use the same names for cells as are used in the ShapeSheet. The ShapeSheet reference under help lists all of the ShapeSheet cells alphabetically by name. To get page cells, first get the PageSheet property of the page, which returns a Shape object. Then use the Shape object’s Cells property to get the formula of a particular cell. Tip: When should you use Cell vs CellU and Cells vs CellsU. If you are faced the possibility of having to localize your solution, using CellU instead of Cell and CellsU instead of Cells will save you some work. CellU and CellsU take the universal name (not localized) name of a cell as their argument. The universal names never change in localized versions of Visio.Getting a Formula or Its ResultOnce you have a Cell object, use its Formula property to get its formula as a string.If you want the formula’s value instead, use one of the Result properties. Result and ResultIU return a double precision value as a floating-point number with 15 significant digits.ResultInt returns a long integer.ResultStr returns the value as a string.You can specify units for the value returned by a Result property by passing any valid unit string or one of the unit constants defined in the Visio type library.For example, you can use visDrawingUnits to get a result expressed in units defined for the drawing. To explicitly specify a unit-less number, use visNumber. Tip:Use VBA’s Intellisense to help view available Visio constants. In VBA just type “vis”, hold down the Ctrl key and press the space bar. Also check the Developer Reference help file for a complete list of these constants. Tip: Visio’s internal units are inches, for cells that measure linear dimensions or radians for cells that measure angular dimensions.Setting a FormulaWhen you set formulas from a program, you probably won’t need to construct the kinds of complex formulas you’ve been building in the class to control shape behavior. Those more complex formulas will most likely already be in place in your solution. Note: Using the equal sign (=) is optional, just as it is when you type in the ShapeSheet windowTo set a cell value to a constant, set either the Result or the Formula. If you’re working with a cell whose formula is guarded, you’ll need to use the “force” equivalents of Formula and Result:FormulaForceResultForceResultIUForce ResultFromIntForceTips for Positioning ShapesPositioning shapes in a drawing can be a challenge, and exactly how you do this will depend on the kind of drawing your program creates. The Drop method requires the position to be in drawing units (not page size). Only when you have an unscaled drawing are these the same.One simple technique involves calculating the shape’s position relative to the page’s width and height. For example, if you know you want to center a shape on the page, you can drop its pin at (PageWidth*0.5, PageHeight *0.5).Another technique is to position one shape at a constant offset from another–by getting the PinX and PinY values of one shape and adding the offset to them for the other.Tips for Positioning Shapes (Continued)There may be functionality in your solution that requires page size to change based on how many shapes are added or deleted from the page.Visio provides the ResizeToFitContents method for Master and Page objects. This method resizes the page to fit tightly around the shapes that are on it. This method is the equivalent of clicking the Size to fit drawing contents on the Page Size tab in the Page Setup dialog.Because the page is resized using this method, the PinX and PinY values in your shapes will typically change. If your solution keeps track of shape position, this fact may ultimately be a deterrent of using the ResizeToFitContents method. Note: Using this method, the page extents are right at the edge of the outer most shapes on the page. Consider using a page margin offset and the CenterDrawing method together to enhance shape position on the final page.Connecting ShapesTo create a connected diagram from a program, you work with cells, but in a slightly different capacity. You are not interested in their formulas or results; instead, you use them to indicate what gets glued to what.Assume that you are working with two shapes on the drawing, A and B. To connect the shapes:Use the Cells property of shape A to get a Cell object that represents the part of the shape you want to glue, such as a control handle.Use the GlueTo method of that Cell object and indicate a cell that represents the part of shape B you want to glue to, such as a connection point. (You do not necessarily need to get a Cell object for shape B.)Or, use the GlueToPos method of shape A’s Cell object and indicate the shape you want to glue to shape B with a position relative to shape B’s width-height box.Getting the Cell to GlueHere are a few examples of how you can indicate various parts of a shape you want to glue.In this example, Controls.X1 refers to the first row of the Controls section in the ShapeSheet. If the shape had more than one control handle, you can indicate a different row. To do this, the control handle must be able to be glued (some aren’t), which depends on the CanGlue setting in the ShapeSheet.Control handles and the begin and end points of 1-D shapes are defined by two cells—one for X and one for Y. You do not need both cells in order to glue the item, and you can use either one. If you’re gluing a 2-D shape to a guide or guide point, you can indicate which edge of the shape you want to glue. The shape edge that you specify needs to be appropriate for the type of guide—AlignLeft, AlignCenter, or AlignRight for a vertical guide, and AlignTop, AlignMiddle, or AlignBottom for a horizontal one.For example, if you try to glue the right edge of a shape to a horizontal guide, you’ll get an Inappropriate Target Cell error. You may not get this error with a guide point, but you will get odd results.Gluing to the Other ShapeOne type of cell you can glue to using the GlueTo method is a connection point. As when specifying the cell to glue, you only need one cell of the X,Y pair.This example does not have a Cell object to represent the glue destination. If it did, the statement would be:celObj1.GlueTo celObj2You can glue to the same items you can in Visio, such as a vertex (Geometry1.Xn or Geometry1.Yn).If you want to glue to a selection handle, use AlignLeft, AlignRight, AlignTop, or AlignBottom to indicate the selection handle in the center of that edge of the shape (rather than the whole edge). AlignCenter and AlignMiddle both glue to the center of the shape.Internally, a guide is a shape, like anything else on the page. To create a guide you use the AddGuide method of a Page object. If you check a guide’s Type property, it returns visTypeGuide. If you want to glue to a guide, use GuidePosX for a horizontal guide or GuidePosY for a vertical one. For a guide point, you can use either.GlueToPos takes slightly different arguments: a Shape object and the X,Y coordinates of a position relative to the shape’s width-height box. In this case, 0.5, 0.5 indicate the center of the shape’s width and height.AutoConnect ModeThe AutoConnect feature added can be accessed programmatically as well as through the user interface. Use Shape.AutoConnect to simulate Auto-Connect. Try It!Below are two procedures for connecting a dynamic connector between two shapes. To run the code open the file Autoconnect.vsd from the Samples folder for the class. Execute the macros and see that the connector is placed and glued.Sub ConnectWithGlue() 'Glue a connector between two shapes using the GlueTo method Dim vsoConnector As Visio.Shape 'Drop the connector shape Set vsoConnector = Application.ActivePage.Drop _ (Application.ActiveDocument.Masters.ItemU _("Dynamic connector"), 0#, 0#) Dim vsoCellFrom As Visio.Cell Dim vsoCellTo As Visio.Cell 'Get references for the cell to glue from and the cell to glue to for 'the beginning of the connector Set vsoCellFrom = vsoConnector.CellsU("BeginX") Set vsoCellTo = _ Application.ActivePage.Shapes.ItemFromID(1).CellsSRC(7, 2, 0) 'Glue the cells vsoCellFrom.GlueTo vsoCellTo 'Get references for the cell to glue from and the cell to glue to for 'the end of the connector Set vsoCellFrom = vsoConnector.CellsU("EndX") Set vsoCellTo = _Application.ActivePage.Shapes.ItemFromID(2).CellsSRC(7, 2, 0) 'Glue the cells vsoCellFrom.GlueTo vsoCellToEnd SubSub ConnectWithAutoConnect() 'Glue a connector between two shapes using Autoconnect Dim vsoShapeFrom As Visio.Shape Dim vsoShapeTo As Visio.Shape 'Get a reference to the two shapes Set vsoShapeFrom = Application.ActivePage.Shapes.Item("Process") Set vsoShapeTo = Application.ActivePage.Shapes.Item("Decision") vsoShapeFrom.Autoconnect vsoShapeTo, visAutoConnectDirNoneEnd SubA quick inspection reveals that it takes about one-half the lines of code to glue shapes using Autoconnect. The reason for this is that the Autoconnect method hooks up both ends of the connector with one command. Using the GlueTo method requires that each end of the connector be handled separately.Enable/Disable AutoconnectAutoconnect can be enabled or disabled within the File > Options > Advanced tab. When Autoconnect is turned on, hovering the mouse over a shape presents the four autoconnect triangles around the shape. Clicking on one of these triangles connects the shape to another shape. When autoconnect is turned off these triangles do not appear.Below are VBA code snippets for turning autoconnect on or off.Sub EnableAutoConnect() Application.Settings.EnableAutoConnect = TrueEnd SubSub DisableAutoConnect() Application.Settings.EnableAutoConnect = FalseEnd Sub Note: It is not necessary for EnableAutoConnect to be set to True in order to use the Autoconnect method through automation.Adding Data to ShapesEarlier you learned about getting cells that represent formulas. Sometimes you may need to add cells to a shape, just as when you’re developing a shape in Visio.For example, if a shape does not have Shape Data, you can add a Shape Data section, add rows to it, and then set formulas of cells in those rows.Adding Sections and RowsTo add a section, you use the AddSection method and specify the type of section . Constants for these are defined in the VBA object browser. The example uses visSectionProp, which is the constant for the Shape Data section.Unlike adding a section in the ShapeSheet (which automatically gives you one row), when adding a section from your program you need to add the rows explicitly. To do this in a shape data section, use the AddNamedRow method, specify the section, the row name, and a row tag of zero. Note: The row tag should be zero for any kind of row except the Geometry section rows; for those it’s used to indicate the row type, such as LineTo.Once you’ve added the row, you can access its cells in the usual way. You don’t need to explicitly add cells to the new row.If you try to add a section that a shape already has, you’ll get an error. To avoid this, either use the SectionExists property to test whether the shape already has the section, or just add the row. If the section doesn’t already exist, it will be created automatically.Lab 3.3: "Hello World"Points to ConsiderDo the procedure manually first, and note each step and the names of your template, stencil, and master.Use X and Y coordinate variables to make dropping the four masters on the page more ments have been developed in a partially completed exercise to guide you through the process. Do not look at the solution code before attempting the exercise.Review: Generating Visio DrawingsQuestionsIf you opened a new blank drawing, how many items would the documents collection contain?What does a Cell object represent?Why are drop-coordinates always in inches?What object property would you use to replace a guarded cell formula?AnswersThere would be only one document in the Documents collection since a blank drawing has no stencils opened.A Cell is an object representing a single cell in the ShapeSheet.Visio maintains internal units in inches.FormulaForce or ResultForceGetting Data From DrawingsOverviewNow you’re going to approach Visio objects from a slightly different perspective—by retrieving information about the objects that already exist in the drawing. Here’s what you are going to cover in this section:You’ll learn about how to iterate through a collection so you can get something from, or do something to, each object in the collection.You’ll read briefly about documents, pages, and shapes, and the kinds of information you can get from them that you might use in a program, plus you’ll discover another way of getting a Cell object using CellsSRC.It is frequently necessary to access objects selected in the drawing. The Selection object, or set of shapes selected in a window, can be accessed through the Selection property of the Window object. The Selection can be accessed through automation or can be created through automation.Iterating Through a CollectionYou’ve seen how you can retrieve objects from collections, by name or by index. You can iterate through a collection to perform the same operation on every member, or check each member until you find the one you want.Some Things to Remember about Collections Most Visio collections are indexed starting at 1. Generally, only the UI object collections are indexed starting at 0, but be careful. Hyperlink collections also start with 0. Be sure to check before you start writing code. The Count property returns the number of items in the collection at the time you get the property; however if you add or remove objects from the collection, the value of Count will change. This could make a difference in the example above, where Count is evaluated for each pass through the loop.Collections associated with a valid Visio object always exist, but the collections may be empty, in which case Count returns 0.A good way to iterate through collections like page or shape collections is with the For Each… Next statement. Use it to build your object references and process shape data.When you delete objects from a collection using an iteration loop, decrement the counter rather than incrementing it. For example:For i = oDocs.Count to 1 Step -1A collection is not like an array; items don’t keep a fixed index position. Instead, as you delete an item, the next item moves into that position. But if you’ve incremented your counter, you skip that item and delete the next one, until sooner or later you overreach Count and try to delete an item with an invalid index, which causes an error.Try it! CollectionsOpen the file <install path>Demos\Vol3\Getting Data from Drawings\ Collections.vsd. Run the sample code via right-click on the page. Each macro is an example of working with collections.ColorShapes adds a color to each shape.Form some group shapes on the page. Use CountShapes to count all of the shapes in the groups, including the groups themselves.DeleteShapes deletes all of the shapes on the page. Note that the For loop in the code counts down from the highest indexed shape.Getting Data from DocumentsThe Open method opens a document as an original (that is, for read/write access), which is not good for stencils and templates, because you probably don’t want your users changing those.Use OpenEx with the appropriate flag to open a file as read-only. Open a stencil docked in a drawing window, or open a file without adding it to Visio’s file menu of most recently used files.For best results, try to use a full path when opening a document. Using relative path names can be unpredictable at times. Do not hard code the path but instead use the common Open dialog box to get the user to indicate the path. Under some circumstances you might be able to construct the path from the Path property of a document that is already open.If the document you want is already open, you can get it by its filename or its index in the collection.Noteworthy Document Properties These are a few of the Document object properties available through the object model. You’ve already see the Masters and Pages collections, but a Document object also has Styles, Fonts, Colors, and Visual Basic Project collections, with objects that represent those items.The Name, Fullname, and Path properties contain the short filename, full filename, and just the path portion of a document’s full filename, respectively.Description, Keywords, Subject, and Title correspond to options of the same name in the document’s summary information. (Properties command from the File menu.) Creator corresponds to Author in the File Properties dialog.ReadOnly, Saved, and InPlace are Boolean properties that indicate whether a document was opened as read-only, has been changed since it was opened (the Saved property is really a dirty flag) or has been opened for in-place editing in a container document rather than in a standalone instance of Visio.To determine whether a document has been saved, check its Path property. If an existing document has been opened or a new document has been saved, its Path property will be set.TimeCreated, TimeEdited, TimeSaved and TimePrinted return the date and time of each action. The return value is a date formatted like this one: 4/6/10 1:50:21 PMThere are several Print… properties that allow you to set properties for printed output, such as Printer, PrintCenteredH, PrintPagesDown, PrintFitOnPages, etc. Set these properties first and then use the Print method to print your document.Getting Data from PagesGetting a page is similar to getting an open document; you can get the page by its name or by its index in the Pages collection.The ActivePage property is a quick way of getting a page without going through a document. However, it only works if the active window is a drawing window. If a stencil window had focus and you attempted to get the ActivePage, an error would occur in your solution.This will make more sense a little bit later in the session, when you learn about windows and the selection object. We have already seen that a Page has a Shapes property for accessing the shape collection on the page. The Page also has a Layers property for accessing information about Layers defined for the page and a Connects property for getting information about connections that exist on the page.Getting Data from ShapesYou’ve already worked with shapes and used some of their properties, such as Text and Cells. When you’re working with shapes from a program, the definition is somewhat expanded. A page’s Shapes collection includes basic shapes, groups, guides and guide points, and linked or embedded objects (bitmaps, metafiles, Excel spreadsheets, and so forth.).Obviously, these various items differ quite a bit in what you can do with them. So if you’re iterating through a Shapes collection, you’ll almost always want to check a shape’s type before continuing with whatever you’re doing to the shape. The Type property of a Shape object returns a constant describing the shape. Recall getting the PageSheet property in the last session. That property returns a Shape object so you can use its Cells property to get page formulas. If you check that Shape object’s Type property, it returns visTypePage.A few interesting Shape properties include AreaIU, which returns the area of the shapes geometry in internal units, Characters, which contains the shapes text and the fields that control that text, Connects and FromConnects, which contain shape connection information, and Layer, which contains information about the layers a shape is assigned to.Getting Data About ConnectionsEarlier you saw how to connect shapes in a drawing through Automation. The relationship between a shape and the object that it is glued to is represented by a Connect object.Every shape has a Connects collection. If the shape isn’t glued to anything, the collection is empty.If the shape is glued to one other shape (or guide), its Connects collection contains one Connect object representing that relationship. You access the Connects collection differently depending upon whether the shape is a one-dimensional or two-dimensional shape.You can get information about the connection by getting properties of the Connect object.The FromSheet and ToSheet properties return Shape objects for the shapes involved in the connection.The FromPart and ToPart properties return integers that indicate which parts of the shapes are involved. These are represented by constants such as visControlPoint and visConnectionPoint.The FromCell and ToCell properties return Cell objects that correspond to the FromPart and ToPart values.For example, if FromPart is visControlPoint, FromCell returns a Cell object that represents that control handle in the ShapeSheet.Connect Object for a Control Handle to a ShapeStudy the following case, and for simplicity’s sake, assume that shape A has only one control handle and shape B only one connection point:Shape A has a geometry that is tied to its control handle. The control handle is glued to a connection point on shape B.If you get the Connects collection of shape A, it contains one Connect object with these properties:FromSheet = AToSheet = BFromPart = visControlPoint + 0ToPart = visConnectionPoint + 0FromCell = Cell objects for FromPartToCell = Cell object for ToPart Connect Object for a 1-D Between 2-D ShapesHere’s a more common case:Shape C is a one-dimensional connector glued to shapes A and B. Shape C’s Connects collection contains two Connect objects because it’s glued to shape A and shape B.A and B aren’t glued to shape C, nor are they glued to each other.In this case, the begin point of shape C is glued to the third connection point of shape A (first row + 2 = row 3), and the end point of shape C is glued to the fourth connection point of shape B (first row + 3 = row 4).See the Developer help file for more information about the Connects object.Try it! Connect ObjectOpen <install folder>\Demos\Vol3\Getting Data from Drawings\ Connect Object.vsd.Select the dynamic connector, and remove its connection to Shape 1.A message box will appear describing the action that occurred, and the shapes that were involved. Re-glue the connection you just removed.Open the Visual Basic Editor and review the code in the ConnectionsAdded and ConnectionDeleted page events.The message box utilizes the From/ToSheet and From/ToCell properties of the connect object to relay its information.More Connectivity API optionsOne of the very nice features of Visio has always been the ability to maintain and interrogate connected diagrams through automation. However, it does get tedious to use the Connects objects to retrieve this connectivity information. Visio 2010 introduces several new methods that make these efforts a lot easier.Use Shape.ConnectedShapes(Flags, CategoryFilter) to return an array of identifiers (IDs) of shapes that are one degree of separation away from the given shape (i.e. separated by a 1-D connector). In other words you no longer have to go through the connector to see what is on the other side. The IDs can be filtered as incoming or outgoing connections.Try it! ConnectedShapesOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page ConnectedShapes and follow the directions on the page.Open the VBA Window (Alt—F11) and turn on display of the Immediate Window (View > Immediate Window). The results of running the macros are written to this window.Public Sub GetIncomingShapes_WithCategories()'Use Shape.ConnectedShapes to get the shapes that are incoming connections to a shape Dim shp As Visio.Shape Dim shpIDs() As Long Dim i As Integer If ActiveWindow.Selection.Count = 0 Then MsgBox ("select a shape with connections") Exit Sub Else Set shp = ActiveWindow.Selection(1) End If shpIDs = shp.ConnectedShapes(visConnectedShapesIncomingNodes, "Square") Debug.Print "Incoming shapes" For i = 0 To UBound(shpIDs) Debug.Print ActivePage.Shapes(shpIDs(i)).Name NextEnd SubFlags: Filters the list of returned shape IDs by the directionality of the connectors. CategoryFilter: Filters the list of returned shape IDs by limiting it to IDs of shapes that match the specified category. A shape’s categories can be found in the User.msvShapeCategories cell of its ShapeSheet. In the sample code above the method only returns shapes that are in the category “Square” which is designated in the shape’s User.msvShapeCategories cell.Use Shape.GluedShapes(Flags, CategoryFilter, [pOtherConnectedShape]) to return an array of identifiers for the shapes that are glued to a shape. The returned IDs can be filtered by 1D vs. 2D and by incoming vs. outgoing connections. You can optionally specify another shape to which any returned shapes must also be glued.Try it! GluedShapesOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page GluedShapes and follow the directions on the page.The results of running the macros are displayed in VBA’s Immediate window. Dim shpIDs() As Long shpIDs = shp.GluedShapes(visGluedShapesIncoming1D, "") Debug.Print "Incoming 1D shapes" For i = 0 To UBound(shpIDs) Debug.Print ActivePage.Shapes(shpIDs(i)).Name NextFlags: Specifies dimensionality and directionality of connectors of shapes returned. CategoryFilter: Specifies category of shapes returned. pOtherConnectedShape: Optional additional shape to which returned shapes must also be glued A method that parallels the AutoConnect feature is Page.DropConnected(ObjectToDrop, TargetShape, PlacementDir, [Connector]). This creates a shape, positions it relative to the target shape and adds a connector from the target shape to the new shape. You can optionally specify a specific connector to use if you need to override the default connector.Try it! DropConnectedOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page DropConnected and follow the directions on the page. Six Process shapes are dropped and connected on the page.Sub DropConnected()'use Page.DropConnected to drop several Process shapes Dim lastDrop As Visio.Shape Dim i As Integer Set lastDrop = ActivePage.Drop(ActiveDocument.Masters("Process"), 4.5, 8) For i = 1 To 5 Set lastDrop = _ ActivePage.DropConnected(ActiveDocument.Masters("Process"), _ lastDrop, visAutoConnectDirDown) NextEnd SubObjectToDrop: The shape to be added to the page TargetShape: The existing shape from which to align, space, and connect PlacementDir: The direction from TargetShape in which to place ObjectToDrop . The example drops shapes using visAutoConnectDirDown.Connector: The connector to use (optional). This overrides usage of the default Dynamic Connector.To drop a new shape on a connector and split the connector, use Page.SplitConnector(ConnectorToSplit, Shape). Pass it the connector to split and the shape to drop. Try it! SplitConnectorOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page SplitConnector and follow the directions on the page. Shape 2 is inserted between shape 1 and shape 3 and the existing connector is split. Set connector = ActiveWindow.Selection(1) Set ovShape = ActiveWindow.Selection(2) Set newConnector = ActivePage.SplitConnector(connector, ovShape)ConnectorToSplit: The connector to split. Must be a routable 1-D connector. Shape: The shape to use to split the connector. Must be a 2-D shape. Connectors can be unglued and the end of the connector moved away from the original glue position with a single method call. Use Shape.Disconnect(ConnectorEnd, OffsetX, OffsetY, Units) and specify the end of the connector to disconnect, the offset, and the units. Try it! DisconnectOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page GluedShapes and follow the directions on the page to run macro ShapeDisconnect. Both ends of the connector are unglued and moved away from the connection points by .25 inches in each direction. If ovShape.OneD Then ovShape.Disconnect visConnectorBothEnds, 0.25, 0.25, visInches End IfConnectorEnd: The end of the connector to disconnect OffsetX: The x-distance that the connector end is moved away from the shape OffsetY: The y-distance that the connector end is moved away from the shape Units: The units of measure for the assigned offset values To add many connections quickly, use Page.AutoConnectMany(FromShapeIDs(), ToShapeIDs(), PlacementDirs(), [Connector]). This method automatically draws multiple connections in the specified directions between the specified shapes. It returns the number of shapes connected.Try it! AutoConnectManyOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page AutoConnectMany and follow the directions on the page. The selected shapes are connected and repositioned from left to right.Public Sub AutoConnectMany()'use Page.AutoConnectMany to create connectors between shapes If ActiveWindow.Selection.Count < 1 Then MsgBox "Select at least two shapes in the order they are to be connected" Exit Sub End If Dim fromShapeIDs(10) As Long Dim toShapeIDs(10) As Long Dim placementDirs(10) As Long Dim i As Integer For i = 1 To ActiveWindow.Selection.Count - 1 fromShapeIDs(i) = ActiveWindow.Selection(i).ID toShapeIDs(i) = ActiveWindow.Selection(i + 1).ID placementDirs(i) = visAutoConnectDirRight Next ActivePage.AutoConnectMany fromShapeIDs(), toShapeIDs(), placementDirs()End SubFromShapeIDs(): An array of identifers of the shapes from which to draw a connection ToShapeIDs(): An array of identifers of the shapes to which to draw a connection PlacementDirs(): An array of constants that represent the directions in which to draw the connection Connector: The connector to use (optional). This overrides usage of the default Dynamic Connector.DeleteEx(Flag) will delete additional shapes associated with a shape or selection, such as connectors and unselected container members, when the selection is deleted.Try it! DeleteExOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Connections API.vsd.Select page DeleteEx and follow the directions on the page. The selected shapes are connected and repositioned from left to right.When the option to heal connections is chosen the two hanging connectors resulting from the shape delete are merged into one. Not the third example on this page. It is not possible to heal the connectors in this case because there are two incoming connectors and two outgoing connectors and therefore the result is indeterminate. ovShape.DeleteEx VisDeleteFlags.visDeleteHealConnectorsFlag: can specify that unselected connectors, shapes within a container, or callouts are to also be deleted. The flag must be a bitwise combination of the following constants.visDeleteNormal=0 – match the deletion behavior that is in the user interfacevisDeleteHealConnectors=1 – delete connectors that are attached to deleted shapesvisDeleteNoHealConnectors=2 – do not delete connectors that are attached to deleted shapesvisDeleteNoContainerMembers=4 – do not delete unselected members of containers or listsvisDeleteNoAssociatedCallouts=8 – do not delete unselected callouts that are associated with shapesGetting a Selection ObjectThe Selection object, or set of shapes selected in a window, can be accessed through the Selection property of the Window object.The easiest way to get the Selection object is to access the selection in the current active window:Dim oSelection as Visio.SelectionSet oSelection = Application.ActiveWindow.SelectionOne very good use for a Selection object is to allow users to indicate the shapes they want to work with. You can also create a Selection object through automation as a means of working with a subset of shapes on the page.The order of items in the collection follows the order in which the corresponding shapes are selected in the drawing window. The first shape selected is the first item in the collection. If the shapes have been selected by dragging out a selection rectangle, then they are put in the selection in front to back order, with the forward-most shape being the first shape in the selection.Probably the most important thing to keep in mind about a Selection object is this: It’s not bound to the selection in the drawing window. After you get a Selection object, the user can change the selection, but the changes won’t be reflected in your program unless you get another Selection object. For this reason, it’s best to get a Selection object just before you plan to use it.Working with Windows and Selected ShapesAn Application object has a Windows collection, which includes all of the drawing, ShapeSheet, stencil, and icon edit windows that are open in the instance. One thing to remember about the Windows collection is that it may grow or shrink by more than one item at a time, depending on other actions. You can iterate through a Windows collection in the usual way, but more often you’ll be interested in a particular kind of window. You can check the Window object’s Type property to find out what kind of window it is. For a drawing window, you may also want to check its SubType property to make sure you have the right kind of drawing window. Note: If the type property of a Window object returns any value other than visDrawing, the subtype property returns the same value as the type property.Not surprisingly, the ActiveWindow property returns the active window. If your program has just run an instance of Visio and created a drawing, you can probably assume that the active window is a drawing window. However, it is always good to make sure. Many of a Window object’s methods are only relevant in a drawing window.Here are some ways to utilize a Window object’s properties and methods:Use the Activate method of a Window object to make it the active windowGet the document displayed in the window by getting its Document propertyChange the magnification with the Zoom propertyGet shapes selected in a drawing window by getting the Selection propertyGetting Cells with CellsSRCYou used the Cells property in the last module to get cells by name. This is almost always the preferred way to get a particular cell. However, sometimes you might want to iterate through rows or cells, or even sections such as in a shape with multiple Geometry sections. You can do this using section, row, and cell indexes.The example on the slide uses CellsSRC to get the Controls.X3 cell. (Rows are indexed starting with the row index constant as the base, so you need to add an integer offset for the second and subsequent rows.) This might seem like a lot of work to get a single cell, but iterating through each of the Control section rows and getting the same cell from each one is easier using CellsSRC. All you have to do is increment the row offset instead of constructing a cell reference string.You can also use these indexes to see if the shape has a particular section, row, or cell, or use them to add sections to a shape, as you’ll see later in this session.Try it! CellsSRCFrom your student CD, open <install path>\Demos\Vol3\Getting Data from Drawings\Collections.vsd. Select one of the shapes on the drawing page and run the macro View > Macros > Sample_Code.SampleCode.PrintGeometry. Open the Immediate window (also known as the Debug window) in VBA. The macro prints all cell formulas from the Geometry section to the Immediate window.Determining Shape ProximityVisio offers several properties for determining shape proximity.DistanceFrom property of the shape returns the distance between two shapesSpatialRelation property describes the relationship between two shapesSpatialNeighbors property of a shape returns shapes meeting relationship criteria (For an example, see Spatial Relation Office.vsd)SpatialSearch property of shape, page, or master returns shapes near a point (For an example, see Which Shapes are in View.vsd)SpatialRelationThe SpatialRelation property is used to determine the relationship between two shapes. It can determine if two shapes overlap or touch, or if one is inside the other.Demonstration: Shape RelationshipsOpen <install folder>\Demos\Vol3\Getting Data from Drawings\Spatial Relation.vsd.Note: Before you establish the shape relationship, both shapes need to be selected.Move the small square so its edge touches the edge of the large square, and click the Relationship button.Move the small square so it overlaps the large square, and click the Relationship button.Move the small square so it is within the bounds of the large square, and click the Relationship button.Repeat step five, but this time, change the shape selection order.Lab 3.4: Calculate the Area of a ShapePoints to ConsiderArea based on width and height (parameters of shape alignment box) will be larger than area based on geometry.Look for a Shape property that calculates area based on shape geometry.Review: Getting Data from DrawingsQuestionsWhat would be an advantage of using the ActivePage property? What would be a disadvantage?What is the difference between Open and OpenEx?Under what circumstances would you use CellsSRC?How would you find out whether a Shape object represents a group shape?AnswersThe ActivePage property is a quick way of getting a page without going through a document object. However, it only works if the active window is a drawing window.The Open method opens a document as the original. The OpenEx method has an additional parameter that is use to specify how the document is to be opened, e.g., as read-only.Use CellsSRC when a section has an non-fixed number of rows or when the number of cells in a row can vary, such as in the geometry section.Use the shape’s Type property to test whether it is a group.Managing Events Learning ObjectiveEven though you can respond to user events through the ShapeSheet, Visio has a more robust, programmable event mechanism. This Event object model allows the programmer to set up event handling for a larger set of events. In this section you will see how your solution can respond to ShapeSheet events. You will also get an introduction to the Visio event object model and learn how to use Visual Basic for Applications to create code behind events.You will first look at handling basic events through the management of ShapeSheet cells. When something happens to a shape, such as when it is moved or resized, some cell values change. You can detect these changes in the ShapeSheet and cause another action to occur as a result.More directly, the ShapeSheet has an Event section that has event cells (TheText, EventDblCick, EventXFMod, and EventDrop) in which formulas can be placed. These cells evaluate whenever the event occurs.Beyond the ShapeSheet, events can be handled through Visual Basic for Applications as code behind events. This uses the underlying Visio object model to create and respond to events.IntroductionBefore diving into code behind events, you should be clear about what is an event.A dictionary definition of an event is “an occurrence or incident, especially one of significance.” As a programmer, you want to know when these “events” occur and do something in response to the event.Keep in mind that events can occur as a result of a user action or as a result of a program being run that controls Visio.Cell DependenciesWithin the formula of a cell can be references to other cells. This creates intercell relationships or cell dependencies.These dependencies are implied by the cell names used in the formulas. In the slide example, PinY depends on BeginY and EndY. EndY, in turn, depends on a connection point in Sheet.2. Because of the dependency that has been established, when the value of the connection point changes, the value of the EndY cell is recalculated. If the value of the EndY cell changes, the PinY cell is recalculated. Note: The Visio product engine does not recalculate all cells whenever a shape changes. Instead it establishes a dependency network so that it only recalculates cells that have the potential to change.Force Dependencies with DependsOnIn addition to creating intercell dependencies through the use of another cell’s name, you can force cell dependencies by using the DependsOn function. DependsOn creates a cell reference dependency on the cells specified in the list of trigger cells. The function always returns FALSE (the value 0) and thus has no effect on the final value of the cell when used in this fashion. A typical use of the DependsOn function is to cause some action to occur whenever a cell’s value changes. In the slide, the first example runs an add-on whenever the trigger cell changes. The second example will reset “Cell” to some formula or value whenever a trigger cell changes. In these examples the final result of the User-defined or Scratch cell is irrelevant. However, the developer’s use of DependsOn is not limited to these types of examples. DependsOn ExampleHere is a more practical example. Suppose you want to set a shape’s color from the shape data dialog, but don’t want to interfere with the user’s ability to change a shape’s color using the normal user interface tools. In addition, if the user does change the shape’s color through the user interface, you would like the shape data field to hold the current value.A shape’s color is kept in its FillForegnd cell. Assume that a shape data cell, Prop.Color, has been created to hold the value to be displayed in the shape data dialog. It is not sufficient to just display the FillForegnd cell in the shape data dialog by referencing it from Prop.Color. A change to Prop.Color would overwrite this formula.The solution lies in creating two User-defined cells. In these cells place the formulas:=DependsOn(Prop.Color)+Setf(“FillForegnd”,Prop.Color) =DependsOn(FillForegnd)+Setf(“Prop.Color”,FillForegnd)The first resets FillForegnd whenever the user changes color though the shape data dialog. The second changes the value displayed in the shape data dialog whenever the user changes the shape’s color using other user interface tools.Using this method insures the information in each place is the most current. Tryit! DependsOnFrom your student CD, open <install path>\Demos\Vol3\Managing Events\DependsOn Example.vsd.Display the shape data window. Data > Shape Data Window.Change the shapes fill color through the user interface. Note that the shape data field is updated.Change the shape data value. Note that the shape’s fill color updates. Note: The Visio product engine allows circular references in situations like this and prevents the cells from being recalculated infinitely.SetAtRef ShapeSheet FunctionThe SetAtRef ShapeSheet function creates a cell dependency just as we saw in the DependsOn example, but it gives greater control over what action is to be taken when the cell change occurs. Demonstration: SetAtRefFrom your student CD, open <install path>\Demos\Vol3\Managing Events\SetAtRef Example.vsd. Note that there are 3 examples on 3 separate pages in the drawing.Example 1Choose drawing page SetAtRefDisplay the shape data window. Data >Shape Data Window.This example is similar to the DependOn example we looked at earlier except that the cells being controlled are the Width and Height cells. Modify the shape’s Width or Height by using any of the UI tools or by modifying the shape data fields.Note the SetAtRef formulas in the shape’s Width and Height cells. The SetAtRef function redirects any changes to the Width and Height cells to go to the corresponding shape data cells.Example 2Choose drawing page SetAtRefExprThis example uses SetAtRefExpr to force the shape to snap to a custom grid, in this case a 1 inch by 1 inch grid. View the ShapeSheet to see the formulas.Example 3Choose drawing page Associate without glueingThe ShapeSheet formulas are in the Child shape’s PinX and PinY cells. Example shows use of SetAtRef, SetAtRefExpr, and SetAtRefEval together to create a shape that snaps to a fixed grid size. The grid size is defined in User cells.Use the ShapeSheet to Manage EventsThe Event section cells of the ShapeSheet provide the next level of event management for the Visio developer. These cells can be used to program events triggered when:The text is changed (TheText)The shape is double-clicked (EventDblClick)The shape’s position, size, or orientation on the page is changed (EventXFMod)The shape is dropped (EventDrop)Multiple shapes are dropped on the page at the same time (EventMultiDrop)You will see an Event cell called TheData. This currently does nothing and has been in the product since its earliest days. Use Formulas Over CodeThis completes our discussion of handling events through the ShapeSheet. As you have seen several times in this class, putting capabilities into the ShapeSheet is preferred to writing code. The ShapeSheet offers a rich set of features and functions that make the development of code behind events unnecessary. Shapes are easily transferred when drawing files are exchanged. However, if you need a more robust and expandable solution, writing event handling code in an add-on may be easier to maintain. But remember - shapes are part of the Visio drawing file, while add-ons are not! Visual Basic for Applications Code Behind EventsObjects have events defined for them, such as the ShapeAdded event when a shape is added to a Visio document and the Click event of a button on a form when the button is pressed.Take a look at how Visual Basic and Visual Basic for Applications have helped programmers set up event handlers. Always keep in mind that Visual Basic for Applications uses the underlying Event Object Model defined in the Visio Type Library to respond to events. It utilizes this event model to allow you to put code behind events.Supported EventsThere are many supported automation events in Visio. Certain events are only available on particular source objects. For example, you can only respond to the AfterModal event on an Application source object. One key point about the Before events is that they are just notifications that the event is about to happen. You cannot programmatically stop the event from occurring. For example, when the BeforeSelectionDelete event is triggered, the selection passed to the event handler is committed to be deleted. You cannot stop the deletion.Hierarchical Event SetsSome events, such as the ShapeAdded event, can be sourced by different objects. The ShapeAdded event can be detected at the page level, at the document level, or at the application level. The number of events your code will process can be very different depending upon which object you choose as the source object for your event. For example, at the application level, the ShapeAdded event will fire any time a shape is added to any page in any open drawing in the application. If the page object is used as the source object, the event fires only when a shape is added to that page, but not when a shape is added to any other page in the application.You can determine which objects source an event by using either the Object Browser in Visual Basic for Applications or the Developer Reference help from the Visio Help menu.Built-In Document EventsLike other Microsoft Office applications that contain Visual Basic for Applications, Visio has implemented a class known as ThisDocument. A large number of events have already been provided, which means you have the ability to use the Visual Basic code framework and write your own procedures associated with any of these events.Try it! Add Code Behind Events for ThisDocumentIn a blank drawing, open the Visual Basic for Applications code window.In the Project Window, right-click ThisDocument and choose View Code. In the code window for ThisDocument, in the left-hand drop down list box, choose Document.In the right-hand drop down list box, choose ShapeAdded.The Document_ShapeAdded event procedure is created. Add the code: Msgbox “Shape added to the document”Go back to the Visio drawing and add a shape to the page. This will trigger the ShapeAdded event and execute the Msgbox statement above. WithEvents KeywordVisual Basic for Applications supports the keyword WithEvents that allows you to set up event handling for any source object.Use the Visual Basic for Applications keyword WithEvents to declare an object variable for the Visio object whose events you want to handle. For example:Dim WithEvents oPage as Visio.PageIn addition to the usual access to the page object’s properties and methods, this declaration gives the oPage variable the capacity to handle events when bound to a particular instance of a page. Assigning Visio.ActivePage to oPage enables oPage to source events for the page represented by Visio.ActivePage at the time of the binding. Demonstration: WithEventsIn a blank drawing, open the Visual Basic for Applications code window.In the General Declarations section of ThisDocument, add the code: Dim WithEvents oPage as Visio.PageNote that oPage is added to the left-hand drop down list box in the code window and you now have access to the events that a page object can source.In the Document_RunModeEntered event procedure, add the code: Set oPage = Visio.ActivePageIn the oPage_ShapeAdded event procedure, add the code: Msgbox “A Shape was added to Page: ” & oPage.NameClick the Design Mode button twice to toggle from Design to Run mode, and back.Add shapes to the new drawing page. The message box should be displayed each time a shape is added to the page.ControlsYou do have the ability to add controls to your Visio drawing. Visio has a Design Mode and a Run Mode to allow you to work with the controls. In Design Mode you can place controls in the drawing and set their properties. The drawing must be in Run Mode for the control’s events to fire and allow the user to interact with the controls as she would in a typical Windows application.Try it! Add a Control to a Visio DrawingOpen a Blank Visio drawing.From the Developer tab, choose Insert and choose a CommandButton.Move and size the control as needed. You can do this, as with any shape, by using the selection handles.Edit the control by setting its properties. You can do this by right-clicking and choosing CommandButton_Object > Control Properties, or by editing the control’s properties from the VBA properties window.In the Click event for the command button, add the following code. Note that the name of the control has been added to the code window in the left-hand drop down list box.MsgBox “I am a live control!”Put the drawing in Run Mode (Developer tab and toggle the Developer Mode switch) and click the button.Query EventsQuery events give you a way to cancel the event action before it occurs. For example, if you have shapes in your custom solution that you do not want the user to delete from the page, you would include the QueryCancelSelectionDelete event in your event sink. Once you sign up for this event, you can add code to respond to it. Then, if a user selects a shape on the page, and presses the delete key to delete it, you can cancel the delete action, and notify the user.Query events are triggered only by actions from the UI – not through automation.Here are some of the Query events that Visio provides:QueryCancelConvertToGroupQueryCancelDocumentCloseQueryCancelMasterDeleteQueryCancelPageDeleteQueryCancelSelectionDeleteQueryCancelUngroupQueryCancelQuitQueryCancelWindowCloseQuery Events (Continued)This is the event sequence for the QueryCancelSelectionDelete event, as it occurs in Visio. Note: The Before events fire if the Query event is not cancelled.Try it! Query EventsOpen <install folder>\Demos\Vol3\Managing Events\Query Events.vsdSelect one of the shapes and click the command button.This calls a simple Selection.Delete method, and the BeforeSelectionDelete and BeforeShapeDelete fire.From the Quick Access Toolbar, choose Undo (or use the shortcut, Ctrl-Z).Select another shape on the page, and press the delete key on your keyboard.This time, the QueryCancelSelectionDelete event is called.Click the Yes button on the message box, to cancel the deletion.Repeat step 5, but choose the No button on the message box for a different result.Open the Visual Basic Editor and review the code.Marker EventsMarker events may be used to ignore events caused by other events. Sometimes your event handler modifies the drawing, and this can cause additional events to fire. Was the event caused by user or by some other event handler? This situation can cause loops responding to self-caused events.The classic example is when the CellChanged event resets the value of cell. This causes another CellChanged event, which may cause the value of the cell to change again. You need to be able to distinguish between the original event and those that are generated by the event manager.Unlike other events that Visio fires, a client program causes the MarkerEvent to fire by invoking the QueueMarkerEvent method. The MarkerEvent passes both the context string and sequence number to the MarkerEvent, event handler. Either the context string or sequence number can be used to correlate QueueMarkerEvent calls with MarkerEvent events. This way, your program can distinguish events it caused, from those it did not cause.For more information on Marker Events, see the sample file, Marker Events.vsd, and search the Visio Developer Reference’s Automation section for the MarkerEvent event and the QueueMarkerEvent method.Scoping MethodsVisio also provides scoping methods BeginUndoScope and EndUndoScope to set a scope range. These methods start and end a transaction for Visio’s Application object. Note: If you call the BeginUndoScope method, you should call the EndUndoScope method as soon as you are finished with the actions that comprise the scope.These methods in turn cause the event procedures EnterScope and ExitScope to fire. When EnterScope fires, it records extra information in the EventInfo property of the Application object. This textual description is then accessible in the MoreInfo argument of the VisEventProc.Together, these methods and events can be used to produce results similar to using Marker events.For more information on Scoping methods, see the files Undo Scope I.vsd and Undo Scope II.vsd in the Demos student files.Lab 3.5: Create a Shape Area CalculatorPoints to ConsiderUse ActivePage for your page reference.Make sure the area that you add to the total is for shapes only.Other ConsiderationsYou can actually shut event handling down altogether. This might be useful when debugging. It can be done through the Trust Center or through the object model by setting the Application.EventsEnabled property.To start Visio without automation events and without VBA:Start Visio normally. Enter the Trust Center (File > Options > Trust Center > Trust Center Settings…) Click Macro Settings, and then click Disable all macros without notification. Click Add-ins. Click to select the Disable all Application Add-ins check box. Click OK. Exit Visio, and then restart Visio.It is sometimes necessary to build a model to contain run-time data to support your drawing. But how does this model get reconstructed when a drawing is closed and then reopened? The DocumentOpened event can be used to make data persist. This works fine when you are through with development and are ready to distribute your solution. However, it can be a nuisance during the development process to always be opening and closing the drawing in order to reinitialize data.Instead of DocumentOpened, use RunModeEntered to initialize run-time data. When a document is opened, both the DocumentOpened and the RunModeEntered events fire. However, it is much easier to initialize your run-time data during the development process by just switching to Design Mode and then back to Run Mode. Review: Managing EventsIn this module you have seen how to handle events in Visio by using simple cell dependency techniques in the ShapeSheet, by utilizing ShapeSheet event section cells, and by using the WithEvents keyword in Visual Basic for Applications. Here are some questions based on the material you just covered.QuestionsUnder what circumstances would you want to use Automation event handling over ShapeSheet event handling?What is the name of Visio’s pre-defined base class?What does the WithEvents keyword allow you to do?AnswersAutomation event handling is preferred when a more robust solution is required, beyond what can be accomplished in the ShapeSheet.ThisDocumentSet up event management for any source object.Automating Data GraphicsIn this module we will take an in-depth look at data graphics. The implementation of data graphics beginning with Visio 2007 primarily utilizes the existing environment and objects of Visio 2003. Data graphics and data graphic items are maintained as masters in the Visio object model (albeit hidden except through the Drawing Explorer window). Therefore, when working with data graphics you are working with Visio master objects.The GraphicItem and GraphicItems objects are new for Visio 2007. The GraphicItem holds the detailed information about a data graphic item, such as its position, and the GraphicsItems object is a collection of the individual items that make up the data graphic. The GraphicsItems collection has been added as a property to the Master object. The Shape object has a DataGraphic property that holds the reference to the data graphic applied to the shape. Data graphics can be customized. There are several built in text and data bar callouts as well as several built in icon sets. These callouts and icon sets can be modified and new ones can be created, most easily by copying and modifying existing data graphic items.When a data graphic is applied to the shape, the data graphic master and the shape are grouped. You can then work with the elements of the group just as in previous versions of Visio or you can modify the data graphics within the Data tab of the ribbon. When these masters are modified the changes are then reflected throughout the drawing just as when a master is modified in the Document Stencil. Note: Modifications made using the Data Graphics within the ribbon will override any manual modifications made to the grouped shape. Module ObjectivesAfter completing this module you will be able to:Work with data graphics with the Visio user interface to add text and data bar calloutsUnderstand how data graphics are managed by Visio and where information about them exists in the Visio object modelUnderstand key ShapeSheet cells required by data graphicsCustomize data graphics with the Visio user interface to add additional graphic items to data graphicsModify data graphic items to fine tune their behavior within the drawing environmentCreate icon setsCustomize and manage data graphics with automation codeManage data graphics in the drawing environment by making data graphics available for new drawingsLesson 1: Data Graphics ConceptsMicrosoft Visio offers tools for visualizing information. Data can be connected from external sources and linked to individual shapes. A variety of graphics can be applied to the shapes to display information about the data they contain. The data can be refreshed from the external source and the graphics can update automatically based on the values stored in the data.Data Graphics lets you present information in a concise, understandable format. Text, geometry, formatting, and graphics are combined to help users identify issues, illustrate patterns in data, and communicate status. Data Graphics can be expressed in many different ways to give the user a wide variety of options for visualizing his data. This lesson covers that full range of options for creating and customizing Data Graphics.Lesson ObjectivesAfter completing this lesson you will be able to:Create new data graphics and customize existing data graphicsApply text, data-bar, and icon set callouts and use color-by-value to visualize dataCreate new text, data-bar, and icon-set calloutsManage Data Graphics objects in a documentGo beyond the basics and customize your own data graphic itemsOverview of Objects / Methods / PropertiesIncluded in this section is a description of the objects, methods, and properties related to creating and managing data graphics in Visio. There are other objects, properties, and methods that come into play when developing solutions with data graphics. These will be covered as they are needed.Where appropriate, there are bits of sample code sprinkled throughout this lesson which illustrate how to use these features programmatically.Data GraphicsA GraphicItem is responsible for a single adornment such as a data bar or text callout shown on a Data Graphic. A GraphicItems collection of these make up a single Data Graphic which is held in Visio in the form of a hidden Master on a stencil. The master is of type visTypeDataGraphic.The relationship of the data graphic objects to other portions of the Visio object model is shown in the graphic below.MethodsGraphicItem objectDescriptionGetExpressionReturns the current expression for the primary key column corresponding to the specified field.SetExpressionSets the value of the expression string that is part of a GraphicItem object's rule, against which shape data is evaluated.GraphicItems objectDescriptionAddCopyAdds a copy of a GraphicItem object to the GraphicItems collection.Master objectDescriptionDataGraphicDeleteDeletes the Master object of type visTypeDataGraphic from the Masters collection of the document.Masters objectDescriptionAddExAdds a master of the specified VisMasterTypes object to the Masters collection.PropertiesGraphicItem objectDescriptionDataGraphicReturns the Master object of type visTypeDataGraphic that is the parent of the GraphicItem object, the GraphicItems collection, the Selection object, or the Shape object.HorizontalPositionGets or sets the horizontal position of a graphic item relative to a container or shape, as VisGraphicPositionHorizontal.PositionRelativeToGets or sets whether the graphic item is positioned relative to a container or to a primary shape, as VisGraphicPositionRelativeTo.TagGets or sets an expression that stores extra data needed for your program. For example, the name you want to apply to a graphic item. Not used by Visio.UseDataGraphicPositionGets or sets whether a GraphicItem object inherits the DataGraphicHorizontalPosition property setting and DataGraphicVerticalPosition property setting of the data graphic master to which it belongs (when set to True), or whether to apply the GraphicItem object's own HorizontalPosition setting and Vertical Position setting (when set to False).VerticalPositionGets or sets the vertical position of the graphic item relative to a container or shape, as VisGraphicPositionVertical.GraphicItems objectDescriptionDataGraphicSee GraphicItem object.Master objectDescriptionDataGraphicHiddenDetermines whether the data graphic is visible in the Data Graphics task pane.DataGraphicHidesTextIf set to True, hides the text of the primary shape when a data graphic master is applied. The default is False.DataGraphicHorizontalPositionGets or sets the horizontal position of a data graphic relative to the shape it is applied to, based on the specified VisGraphicPositionHorizontal value.DataGraphicShowBorderGets or sets whether a border appears around GraphicItem objects whose UseDataGraphicPosition property is set to True, or that occupy the same position as the data graphic of which they are a part.DataGraphicVerticalPositionGets or sets the vertical position of a data graphic relative to the shape it is applied to, based on the specified VisGraphicPositionVertical value.GraphicItemsReturns the GraphicItems collection of the Master object. Read-only.Creating Data Graphics MastersData graphics can be added to a drawing at any time. They may already be part of a drawing if the template used to create the drawing contained data graphics or if shapes dropped on a page had a data graphic associated with them.Data graphics can be created from scratch or can be copied from existing data graphics and then modified.Basics of creating a Data Graphics MasterA new data graphic can be created easily using the Visio interface that is presented in the Data tab (Data > Data Graphics). Within the task pane completely new data graphics can be created using the command New Data Graphic. To create a data graphic from an existing data graphic, right-click the data graphic and choose Duplicate. To modify any data graphic, right-click the data graphic and choose Edit Data Graphic…Try it!From the Samples folder open Viewing Data Graphics.vsd Display the Document Stencil and note which masters are displayed.Display the Drawing Explorer window and note which masters are displayed. Are they the same?Create a new data graphic (Data > Data Graphics > Create New Data Graphic…). Give it a meaningful name that you will recognize. Does it show in the Document Stencil? Does it show in the Drawing Explorer?Viewing a data graphics masterOnce a new data graphic has been created, it can be viewed in the Drawing Explorer window. Don’t look for it in the Document Stencil because the data graphics master is “hidden”. There is a property of the master object, the Hidden property, that is used to control the display of the master in the stencil window. However, this property is ignored by the Drawing Explorer, which shows every master regardless of the Hidden property value.Try it!Open the VBA window. Make sure the Immediate window is displayed.In Visio use File > Options > Advanced to check the number of Undo levels. Set the number to at least 30.Run the macro “ListMasters”. All masters, along with their Hidden property are displayed in the Immediate window.Run the macro “MakeAllMastersShow”. This changes the value of the Hidden property of all masters to False so that they will show in the Document Stencil window.Note the data graphics masters in the Document Stencil and then Undo (Ctrl-Z) the results of running the macro to again hide the data graphics masters.Creation with automation Note: When Visio’s macro recorder is turned on the Data Graphics menu is deactivated. Thus recording anything that happens in the data graphics task pane is not possible.The file Working with Data Graphics.vsd in the Sample folder has the following sample code in it for creating a data graphic master.Public Sub AddEx_Example() ‘Create an empty data graphic master Dim vsoMaster As Visio.Master Set vsoMaster = Visio.ActiveDocument.Masters.AddEx(visTypeDataGraphic) Debug.Print vsoMaster.NameEnd SubTry it!Open Working with Data Graphics.vsd from the Samples folder. Run the macro (View > Macros > InterestingMacros.AddEx_Example).A new master can be seen in the Drawing Explorer window. The name of the new master is displayed in VBA’s Immediate window.The empty data graphic also shows in the Data Graphic task pane, but does not show in the Document Stencil. The AddEx method makes it hidden automatically.There is a data graphic called DGDisposition included in this file. Run the macro DuplicateDataGraphic to copy this data graphic.The new data graphic shows in the Data Graphic task pane.The code for DuplicateDataGraphic is below.Sub DuplicateDataGraphic() 'Copy the data graphic named "DGDisposition" ActiveDocument.Masters.Drop _ ActiveDocument.Masters.Item("DGDisposition"), 86, 121End SubCreating Data Graphics ItemsOverview of Data GraphicsA data graphic is a collection of data presented in a diagram either as a set of graphical widgets or by formatting shapes that contain data. The widgets are known as callouts. These callouts are placed on or next to a shape that contains data, referred to as the target shape in this document. The data displayed is typically Shape Data, but other shape information and custom expressions can also be displayed. Note: Don’t confuse the data graphics term callout with the new Callout shapes that are introduced with Visio 2010. These are two separate entities. Visio provides three types of callouts, as listed in REF _Ref161568569 \h Table 1.Table 1. Data Graphics callout typesTypeDescriptionText calloutsDisplay data as text.Data-bar calloutsDisplay data by modifying some visual aspect of the callout, such as the amount filled in a progress bar.Icon-set calloutsDisplay data by using icons that appear or disappear based on conditional statements.A fourth way of displaying data in a shape is by using Color by Value. This method applies conditional formatting to the shape itself rather than displaying information in a callout.Figure 1. Data Graphic applied to regular shapeFigure 2. Data Graphic applied to pivot nodeA data graphic consists of the set of callouts and Color by Value rules used to display data on a shape. Each shape can have only one data graphic applied at a time, but a data graphic can consist of many callouts and Color by Value rules. You apply data graphics in the Data Graphics task pane. More Information: On the drawing page, a data graphic is a set of special shapes added to a target shape that contains the data to be displayed. When you apply a data graphic, the target shape becomes a group (if it is not already a group) and the data graphic shapes are added as subshapes of that group. Data graphic shapes usually appear on top of any existing subshapes that are included in target shapes.Create Data Graphics Item with the Visio user interfaceThere are many built-in text, data-bar, and icon-set callouts available with Visio. As built in callouts, they do not show in the Masters collection of the Drawing Explorer window. However, once one of these callouts is added to a data graphic it is added to the Masters collection.Visio recognizes a shape as a data graphics callout if the topmost shape in the master contains the user-defined cell User.msvCalloutType.Text callouts and Data bar calloutsThere are eight built-in text callouts provided with Visio. These are shown in the graphic below.There are eleven built-in data bar callouts in Visio. Most of them are shown in the graphic below.These callouts can be added to any data graphic. Once they are added, they show in the Masters collection in the Drawing Explorer window. Once in the Masters collection of the drawing they can be edited and renamed to form a customized callout.Working with Text callouts and Data bar callouts are very similar.Try it!Create a new blank drawing.Create a new data graphic (Data > Data Graphics > Create New Data Graphic…). The New Data Graphic dialog is displayed.Select new Item.For Data field: choose More Fields… and then select Geometry and Width.For Displayed as: choose Text. The New Text dialog is displayed.Select the Text callout.Under Details > Value Format choose the browse button and then General and check Show Units.Under Details set Label to “Width”.Close the dialog. In the Drawing Explorer note that two new masters are added, Data Graphic and Text callout.Draw a rectangle and apply the data graphic to it. It will display the shape’s width.In the Drawing Explorer window click the Text callout and change its name to My Text callout.Right click My Text callout and choose Edit Master shape. Change the line color and the text color in the master. Close the master editing window. (Note: you may have to force a redraw in the drawing for the results to be seen. Moving the shape should do it or reapply the data graphic).In the Data Graphics work area choose Edit Data Graphic and choose New Item. Choose any field for the data then choose Text. Note that the My Text callout is in the list as well as the original built-in Text callout. Close the Edit Data Graphic dialog. Note: The built-in callouts cannot be changed. If you use one in a data graphic and modify it as was done above, but don’t rename it, you will see two versions of the callout in the callout list, the one you modified and the original built in version. It is best to rename a callout if it is being modified so that it can be more easily identified in the callout list.Select the My Text callout master in the Masters collection of the Drawing Explorer window. Right click and choose Edit Master Shape. In the master drawing window right click the shape and choose Show ShapeSheet. The first user-defined cell is shown below. Note that the callout type is set to “Text Callout”.In the same ShapeSheet look at the Shape Data section. Note that the first seven Prop.msv… rows correspond to the elements in the Details section of the New Text dialog we saw when editing the data graphic. The last row Prop.msvCalloutField holds the value of the data element being displayed.The Shape Data rows define the presentation in the Details section of the New Text dialog. The Label specifies the label displayed. The Type field controls the type of data (boolean, string, list, etc.). Format specifies list elements. A very important column, not seen in this figure, is the Invisible column. Note that Visio uses Shape Data rows in callouts in highly specialized ways and that these rows are not intended to be used as standard Shape Data properties. For this reason, the Invisible cell should always be set to True to hide these rows from the user.Put a custom formula in a calloutIt is easy to modify a data graphic to display Shape Data from a shape. It is also possible to display other information about a shape, such as its Width or a user-defined cell. It is even possible to display calculated data that is derived from several data elements.To create and display a custom formula choose More Fields… in the Data field section of the Text or Data bar callout. The following dialog is presented. Note that it is very similar to the dialog for a Text Field and it is used in exactly the same way. In the image below Geometry is chosen as a category and then Width is chosen as the Field name. Note that there are several other categories and each of them contains several fields that can be chosen.The real power in this dialog comes from the last Category Custom Formula. From here one can create calculated fields and format the data using the Format function.Try it!Create a new data graphic. Add a New Item…For Data field choose More Fields… Choose Custom Formula. The Custom formula field at the bottom becomes active.Enter into the Custom formula field="Aspect Ratio = "&Format(Width/Height,"0.0")Let’s take this formula apart from the inside out. Width and Height are references to the shape’s Width and Height cells. Width divided by Height is commonly referred to as the aspect ratio. Format is a function that takes a value and formats it based on a formatting string which in this case is the string “0.0”. This says to display a number to one decimal place. On the left side of the formula is the constant string “Aspect Ratio” followed by & which is the concatenation operator for putting strings together.For Displayed as: choose Text and choose callout Heading 3.Select OK to close this dialog.In the New Data Graphic dialog set the Callout position to Left and Above Shape.Select OK to close the dialogs.Draw a rectangle and apply the data graphic. Resize the rectangle and observe that the aspect ratio value changes.Add a field to a data graphicIn this lesson we will add a new field to an existing data graphic that will be used to control the fill color of the header bar within the data graphic.Visio recognizes a shape as a data graphic through the user-defined cell User.msvCalloutType. This is set to “Text Callout” or “Heading” for a text callout, “Data Bar” for a data bar callout and “Icon Set” for an Icon set callout.You can define properties for text callouts or data bars to expose in the Edit Item dialog. Shape Data rows are used to define the fields to be displayed when editing a data graphic. Important:The names of the Shape Data rows used to display fields in a callout must begin with Prop.msvCalloutProp…Try it!Start from the data graphic used in the last section to display the aspect ratio in a Heading 3 callout.In the Drawing Explorer window rename the Heading 3 callout to My Heading.Right-click My Heading and choose Edit Master Shape.Right-click the shape and choose Show ShapeSheet.In the ShapeSheet for the My Heading master add a row to the Shape Data section.Fill in the following cell values for the new row.Name the row Prop.msvCalloutPropColor. Don’t type “Prop.” This will be added automatically.Label = “Heading Color”Prompt = “List”Type = 1Format = “Red;Green;Blue”Value = Index(1,Prop.msvCalloutPropColor.Format)Invisible = TrueClose the ShapeSheet and the master drawing window. Choose Yes to update My Heading.Check what has been done so far in the Data Graphics task pane. Edit the data graphic and edit the Text callout and look for the new properties. The changes may not update automatically. Force a refresh by changing the Callout to something different and then back again. You should now see the new row Heading Color and be able to choose between the colors Red, Green, and Blue.Close the dialogs for editing the data graphic.In the Drawing Explorer window right-click My Heading, choose Edit Master Shape, and then select the shape and choose Show ShapeSheet.Set the FillForegnd cell in the Fill Format section to =GUARD(LOOKUP(Prop.msvCalloutPropColor,Prop.msvCalloutPropColor.Format)+2)This formula returns the values 2, 3, and 4 which correspond to the colors Red, Green, and Blue when used in the FillForegnd cell.Close the ShapeSheet and close the master drawing window. Choose Yes to update My Heading.Edit the Data Graphics (Data > Data Graphics > Edit Data Graphic…) by changing the color in the field Heading Color. Below is the result when the color Red is chosen.Icon-set calloutsYou can use existing icon sets or create your own either as Visio geometry or by using image files.An icon-set callout is a shape that can display up to five different images, depending on a value provided by the Data Graphics feature. Icon-set callouts are different from text callouts and data-bar callouts because the icon-set callout does not use the data-field value directly. In the Edit Icon Set dialog box, you can define a set of conditional statements for icon-set data that determines which icon should be displayed. From the conditional statements, Visio creates a single ShapeSheet formula that returns a number that corresponds to a particular icon.Visio recognizes a shape as a data-graphics callout if the topmost shape in the master contains the user-defined cell User.msvCalloutType whose value is set to "Icon Set" (quotation marks required).A second user-defined cell named User.msvCalloutIconCount tells Visio how many icons the callout supports. This cell should have an integer value of 1, 2, 3, 4, or 5.A third user-defined cell named User.msvCalloutIconNumber receives the formula from Visio that determines which icon to display. This formula evaluates to -1 when none of the user's conditional statements are true. Otherwise, the formula evaluates to an integer of 0, 1, 2, 3, or 4.Figure 3. Icon set callout user defined cellsThe code sample below will add the three user-defined cells and set their values.Sub AddUserCellsForIconSet() 'Add the user-defined cells required for an icon set to the currently 'selected shape If ActiveWindow.Selection.Count = 0 Then MsgBox "Select a shape before using this macro" Exit Sub End If Dim fExistsLocally As Boolean fExistsLocally = False With ActiveWindow.Selection(1) 'Check to see if the cell already exists. If so, don't add it again. If Not (.CellExists("User.msvCalloutType", fExistsLocally)) _ Then .AddNamedRow visSectionUser, "msvCalloutType", visTagDefault If Not (.CellExists("User.msvCalloutIconCount", fExistsLocally)) _ Then .AddNamedRow visSectionUser, "msvCalloutIconCount", _ visTagDefault If Not (.CellExists("User.msvCalloutIconNumber", fExistsLocally)) _ Then .AddNamedRow visSectionUser, "msvCalloutIconNumber", _ visTagDefault 'Set the values into the cells .Cells("user.msvCalloutType").Formula = """Icon Set""" .Cells("user.msvCalloutIconCount").Result(visNumber) = 5 .Cells("user.msvCalloutIconNumber").Result(visNumber) = 0 End WithEnd SubTry it!Open from the Samples folder the file Working with Data Graphics.vsdUse the drawing tools to create a shape on the page.Select the shape just created and run the macro AddUserCellsForIconSetCheck the ShapeSheet to verify that the user cells were addedRunning this macro again on this same shape will still work because the macro checks to see if the cells already exist before attempting to add them.By convention, you should hide the callout shape when User.msvCalloutIconNumber is -1, although it would be possible to use this state to display another graphic. To hide a shape completely, you must hide all of its geometry, text, and images.Using geometryA common way to draw an icon is by using shape geometry. A shape can have multiple geometry sections in it, and you can show or hide each section independently, depending on the value you set in the User.msvCalloutIconNumber cell. Similarly, a shape can be a group containing additional subshapes, and you can show or hide the geometry in those subshapes independently. REF _Ref161716401 \h Figure 4 provides an example of an icon-set callout that has two geometry sections.Figure 4. Icon set callout geometry exampleThe circle is shown for icon values 0, 2, and 4 (displaying the numbers 1, 3, and 5). The square is shown for icon values 1 and 3 (displaying the numbers 2 and 4). REF _Ref161716485 \h Figure 5 shows a geometry section.Figure 5. Icon set callout geometry sectionThe NoShow cell in each geometry section controls the visibility of the section. REF _Ref161716773 \h Table 2 lists the complete formulas for the NoShow cells.Table 2. Icon set callout NoShow formulasCellFormulaGeometry1.NoShowIF(OR(User.msvCalloutIconNumber=0,User.msvCalloutIconNumber=2, User.msvCalloutIconNumber=4),FALSE,TRUE)Geometry2.NoShowIF(OR(User.msvCalloutIconNumber=1,User.msvCalloutIconNumber=3),FALSE,TRUE)Note that when User.msvCalloutIconNumber is -1, both formulas evaluate to TRUE and no geometry is shown.Using image filesAnother way to show an icon is by using a picture image, such as a bitmap or a metafile. In this case, the callout shape must be a group shape that contains the image or images as subshapes. Put the user-defined cells for the icon set into the group shape. You can show or hide the images by specifying the value in the group's User.msvCalloutIconNumber cell.When working with images, it is easier if all the pictures are the same size. Also, the images should be combined into an image strip—a single picture that contains the images arranged in an evenly spaced row. You can perform these manipulations either in Visio or in another graphics editor, such as Paint. REF _Ref161717788 \h Figure 6 shows an example of an icon set based on images.Figure 6. Icon set callout image exampleTo create this icon set, draw a rectangle to the final callout size you want. Convert the rectangle to a group and add the required user-defined cells for the icon set. Then add the image strip to the page, and lock its aspect ratio. Resize the image strip until it is exactly 5 times the width of the rectangle (or a different multiple if there are fewer icons in the set).Figure 7. Icon set callout image example: Step 1Using the Crop tool, crop the image strip down to the width of the rectangle. Align the image strip on top of the rectangle and add it to its group. You can delete or permanently hide the rectangle's geometry section.Figure 8. Icon set callout image example: Step 2The final step is to tie the image strip to the group's icon number. In the ShapeSheet of the image strip, the Foreign Image Info section controls the size and position of the picture. Only a portion of the picture is visible in the shape, and the rest is cropped out of view. The ImgOffsetX cell controls what portion of the image is seen. This cell moves the image based on the icon value of the group.The formula in the ImgOffsetX cell refers to Sheet.5. This is the group shape that contains the images.Figure 9. Icon set callout Foreign Image Info section Note: There are significant differences when working with image strips created as bitmaps vs. those created as enhanced metafiles. For bitmaps, if the image does not completely fill the frame, then the background must be of some color (let’s assume white). When these images are applied in an icon set, the icons will have a white border around the image. If the user puts a color on the page other than white, the icon doesn’t look so good. Second, the image quality may degrade. Image strips created as enhanced metafiles have a transparent region around the shape and the image quality does not degrade. Using enhanced metafiles instead of bitmaps for the image strip creates a much better looking icon set.Try it!Open the file Working with Data Graphics.vsd. An example of creating the icon set described above is covered in this drawing on page “The making of an icon set”.Edit a data graphic and add a new graphic item. The new Icon Set is displayed along with the other icon sets.Choose the icon set (its name is not displayed) in the New Icon Set dialog.Working with data graphics using automationData graphics can be managed through the Visio user interface. But what about doing some these same tasks or accessing the information about data graphics and graphic items through automation? In the file Working with Data Graphics.vsd in the Samples folder there is VBA code for the following.Return a data graphic assigned to a shapeThrough automation you can get the data graphic assigned to a shape. The information is in the DataGraphic property of the shape. Try it!Open Working with Data Graphics.vsd from the Samples folder. Select a shape that has a data graphic assigned to it and run the macro WhichDataGraphicAssigned from the Tools menu.The data graphic assigned to the shape is displayed in a message box.View the code.Apply a data graphic to a shapeYou can also set the data graphic for a shape through code.Try it!Open Working with Data Graphics.vsd from the Samples folder. Go to the page named Data Graphics. Right-click one of the shapes and choose Set to next DG. This runs the procedure SetDGToNextInList which finds the current data graphic assigned to the shape and then searches all of the data graphics in the document to find the next data graphic. It then assigns this data graphic to the shape.View the code.Interrogate Graphic ItemsYou can interrogate properties for graphic items.Try it!Open Working with Data Graphics.vsd from the Samples folder. Go to the page named Data Graphics. Select a shape that has a data graphic assigned to it. Run the macro ListDataGraphic. This will write information about the data graphic and each of the graphic items that make up the data graphic to VBA’s Immediate window.View the code.Set information into a data graphicRight click one of the shapes and choose SetDGToNextHorizontalPosition. This runs the procedure SetDGToNextHorizontalPosition which increments the horizontal position of the data graphic. Note: Editing a data graphic in the Data Graphic task pane is equivalent to editing the master in the Drawing Explorer window. To do the equivalent operation in code you must edit the master. This requires that 1) the master be Opened (which creates a copy), 2) edits are made to the copy, and 3) close the copy. On close the changes are copied back to the master and the update happens in the drawing.View the code.There is also a procedure SetDGToNextVerticalPosition.Set information into a data graphic itemOn the page named Data Graphics make sure there is a data graphic assigned to one of the shapes.Edit this data graphic and edit the item within it so that it does NOT use the default position of the data graphic (uncheck the box Use default position) and then reposition the Text callout or Data Bar callout.Select the shape that has the data graphic just modified and run the macro ResetGraphicItemsToDefaultPosition. This macro steps through each of the graphic items for the data graphic assigned to the shape and sets the property UseDataGraphicPosition to True. This is equivalent to editing the graphic item and checking the checkbox Use default position.View the code Note: Like editing a data graphic, editing a graphic item is equivalent to editing a master. We therefore need to open the master, edit the copy, and close the master.Other things to do with a data graphicThere are two check boxes in the Edit Data Graphic dialogShow border around items at default position. Get or set the property DataGraphicShowBorder.Hide shape text when data graphic is applied. Get or set the property DataGraphicHidesText.Other things to do with a data graphic itemSet details as in the Edit Item dialog. The details fields come from the Shape Data rows in the master. Setting the Shape Data cells through automation is equivalent to opening the Edit Item dialog and changing details values.Set data field as in the Edit Item dialog. Use the SetExpression method of the GraphicItem.Guidelines for constructing data graphic callout shapesUse of common design practices helps ensure consistency and ease of use for callout shapes.Callout NameFor text callouts and data bars, the name assigned to the callout master is the name displayed in the Callout drop-down list in the Edit Item dialog. Icon sets are only displayed graphically.Sample ValuesVisio uses the callout master shape as a thumbnail in the Edit Item dialog. The master shape also appears in the Data Graphics viewing area as part of the data graphic thumbnails. To help your users understand how your callout displays information, choose an appropriate sample data value for the shape.Controlling callout sizeVisio applies special formulas to your callout shape to control its size and position relative to the parent shape in the drawing. In general, these formulas size the callout to match the width and height of the parent shape. To specify a fixed size or a size controlled by logic within the callout, place GUARD expressions in the Width cell or in the Height cell in the callout, or in both cells. In REF _Ref161719779 \h Figure 10, in the first example, the Width cell value is matched to the width of the parent shape, but the Height cell value is determined by the callout. Also in REF _Ref161719779 \h Figure 10, in the second example, both the width and height remain fixed.Figure 10. Callout sizing examplesControlling marginsCallout shapes are often stacked together or aligned along the edges of the parent shape. This may make the geometry or graphical images in the callouts appear crowded. It is often helpful to build a margin into the callout shape's geometry or image strip. The icon set example, discussed previously, includes a margin to inset the geometry of the callout, as shown in REF _Ref161720018 \h Figure 11.Figure 11. Callout margin example Geometry sectionsIn this example, a user-defined cell named Margin was created to specify the spacing to be used. When you use fixed dimensions in a shape, include a factor for the page scale so that the shape is usable in scaled drawings. You can do this by multiplying the fixed dimension by the value of the DropOnPageScale cell.Figure 12. Callout margin example user-defined sectionProtection cellsWhen you design callout shapes, you must decide what you want to allow your users to manipulate in the callout after they apply it to a parent shape. The Protection section in the ShapeSheet enables you to lock down specific behaviors or properties in the callout shape.This is an example of changing the text size in callouts.??In the flowchart above, a data graphic is applied to the three process steps. The data graphic has two text callouts displaying the Cost and Duration shape data fields. The default text size for the flowchart shapes and the text callouts is 8 points. What happens if we do a Select All and change the text size to 12 points???The flowchart shape text has increased in size, but the callout text has not. Normally when you apply formatting to a group shape, Visio automatically pushes that formatting to all sub-shapes as well. However, Data Graphics callouts are designed to prevent this automatic propagation. There are many scenarios where it is desirable to maintain separate formatting for the shapes and the callouts. Visio 2007 introduced a new protection on shapes to prevent group formatting from propagating to sub-shapes.??Group formatting protection does not prevent all formatting changes on a shape - just those pushed from groups. You can directly select (or sub-select) a shape and still format it. Data Graphics callouts work this way. Not all Visio shapes allow selection of sub-shapes. This is controlled by the group selection behavior property found in the Developer > Behavior dialog. If the Selection property is set to Group Only, you will have to right click the shape and choose Group > Open Group to make any formatting changes.As was shown earlier, the master callout can be edited to effect global callout changes.The following table shows Protection section cells useful for controlling callout behavior.CellExplanationLockAspectUseful for icon sets if the Width cell and the Height cell are not protected with the Guard function.LockFormatPrevents users from making formatting changes to the callout.LockCustPropPrevents users from deleting Shape Data properties from the callout.LockGroupPrevents users from deleting subshapes that make up the callout.LockFromGroupFormatPrevents formatting changes made by users to the target shape from also being applied to the callout. Direct formatting of the callout shape is still allowed.LockThemeColorsPrevents color themes from changing the formatting of the callout.LockThemeEffectsPrevents effect themes from change the formatting of the callout.Performance, memory, and file sizeBecause data-graphics callouts are Visio shapes and can contain complex graphics, they can significantly affect the size and responsiveness of a Visio drawing. If an average callout shape includes two subshapes and an average data graphic includes three callouts, Visio adds nine shapes to the document every time you apply a data graphic to a target shape. For some drawing types, such as flowcharts, the data-graphics shapes are far more complex than the shapes that constitute the drawing itself. The file size and memory requirements for a drawing that contains data graphics might be an order of magnitude larger than those of a drawing without data graphics. This affects the performance of the document.The most important factor that influences performance, memory, and file size is the number of shapes per callout. Ideally, each callout should be a single shape. If you must combine multiple callout shapes into a group, ensure that the group itself is used for its geometry or text. Shapes support multiple geometry sections, so an additional shape is often not necessary. You can individually show or hide each geometry section based on the configuration of the callout. Additional shapes are necessary when a callout needs multiple formats or pieces of text, but try to keep the total number of shapes to a minimum. Also, avoid creating groups nested inside other groups.Another performance factor is the time required for Visio to add new ShapeSheet cells to the callout when you use it in a drawing. Visio generates several additional user-defined cells to implement some of the data graphics behavior in the callout. Including these cells in the callout master shape saves time and file size. REF _Ref161721394 \h Table 3 lists named rows that you must add to callout masters.Table 3. Callout user-defined cells used by data graphicsRowValueUser.visDGCalloutItemblankUser.visDGDefaultPosblankUser.visDGStackHeightblankIf you design target shapes to work with data graphics, you can add some of the named rows listed in REF _Ref161721592 \h Table 4 to target masters.Table 4. Target shape user-defined cells used by data graphicsRowValueUser.visDGDisplayFormatblankUser.visDGDefaultPosblankUser.visDGCBVFillblankUser.visDGOldColorsblankUser.msvThemeColorsblankUser.msvThemeEffectsblankBy pre-creating the user-defined cells needed by data graphics, you can reduce the time needed to apply data graphics to shapes.One final performance issue to be aware of is the use of the ShapeSheet functions TEXTWIDTH and TEXTHEIGHT. These functions calculate the geometric boundary of shape text—which is useful information for precisely arranging text and geometry together. However, they require Visio to fully compose and lay out the shape text each time the function is evaluated. These functions are very expensive relative to other ShapeSheet expressions, so use them sparingly.Managing Data Graphic MastersWhere are they stored and how do you see them?There are a number of built-in data graphics, callouts, and icon sets. These do not show anywhere in the user interface except in the data graphics viewing area on the ribbon.Once assigned to a shape, these data graphics, callouts, and icon sets are added to the masters collection of the drawing and can be seen using the Drawing Explorer window. As masters, they have a Hidden property that is set to True. This prevents them from be displayed in the Document Stencil window, but not in the Drawing Explorer.Making a data graphic part of a documentThe built-in data graphics are always included in any Visio document. Other data graphics can be added and saved with a document.Add a data graphic to a documentTo copy a data graphic from one document to another, apply the data graphic to a shape in the current drawing. Then copy the shape and paste it into the other document. This action copies the data graphic definition to the other document, and it copies the callouts used by the data graphic. You can then delete the shape from the first document, but the data graphic remains available in the second document.Try it!Open a drawing from the Visio Samples. File > New > Sample Diagrams > Process Improvement. Create a new drawing that has no data graphics in the template. File > New > General > Basic Diagram.Look at the Masters in the Drawing Explorer for each drawing. There shouldn’t be any in the second drawing.In the first drawing select a process shape that has a data graphic applied to it. Paste it into the second drawing.Check the masters collection after pasting the process shape. Depending on the shape chosen there may be several masters added. For example, the masters collection will look something like this:Bubble calloutData bar 2ProcessProcess 2Status iconsText calloutCheck the Document Stencil. The Process shape should be there.Within the new document delete the process shape. There should be no shapes left on the drawing page. The Masters collection and the Document Stencil are unchanged meaning that the data graphic is still part of this drawing. Check the Data Graphic task pane to verify this.Delete the Process shape from the Document Stencil. Check the Masters collection and the Data Graphics task pane. The Data Graphics remain. Make a data graphic part of a templateThe process above can also be used to add any data graphic to a template. Open the template for editing, add the data graphic, and save the template. When a drawing is created from the template the data graphic will show in the Data Graphics task pane. More Information: It is not possible to define a data graphic in a central location for use in all documents, so building the data graphic into the template is the best approach.Make a master with a data graphic already applied.One additional option is to pre-associate a data graphic with a master shape. This method is useful for diagrams in which data graphics are an integral part of the drawing and in which each shape can use the same data graphic to display information. To build a data graphic into a master shape, apply the data graphic to a shape on the page and then drag the shape to a stencil to create a master. Note that, by doing this, you remove the association that the shape had with its previous master. Visio makes a new master from this union of shape and data graphic. Visio also places a copy of the data graphic and any callout masters in the stencil.Try it!Open a drawing from the Visio Samples, File > New. Choose Samples Diagrams and then open Process Improvement. Create a new stencil.Drag one of the process shapes that has a data graphic applied to it into the blank stencilCreate a new drawing that has no data graphics in the template. File > New > General > Basic Diagram.Tile the windows so that both windows can be seen. Drag the master from the new stencil into the new basic diagram drawing. Check the masters collection and the Data Graphic task pane. The data graphic is there!Use the Drawing Explorer to review the shape. Note that it is a group shape and that each of the data graphic items are also members of the group.Hidden masters and removing hidden informationNormally, unused masters can be removed using the Remove Hidden Information tool of Visio. However, some custom solutions include data graphic masters in the document and the solution depends on these graphics being present.To protect a hidden data graphic (or any master) from removal by the RHI tool, create a user-defined cell User.msvRHIPreventRemoval to the master’s PageSheet and set its value to 1. The Remove Hidden Information tool will then ignore this master and NOT remove it.Lesson 2: Related TopicsData Graphics heavily utilizes Visio’s Shape Data features. The custom solution developer must recognize that there while be Shape Data fields created by the end user and also Shape Data fields created for use by Data Graphics. Lesson ObjectivesAfter completing this lesson you will be able to:Distinguish between Shape Data used to define Data Graphic fields and Shape Data used to store general information within a shape.Understand the relationship of Shape Data and Data Graphics and use Shape Data to define the property fields of text callouts and data bar calloutsShape Data ManagementWith the advent of data graphics and data linking in Visio 2007 the Shape Data section of the ShapeSheet takes on additional responsibilities. Previously, it was used mostly as place to store extra data to be associated with a shape. This data could be viewed through the Shape Data window and reports could be generated from it using the Reports tool. If the data was to be viewed visually, the shape needed to be programmed to do something with the data. As an example, consider the timeline shapes that hold information about the timeline in shape data. This data is used to control the graphical output of the shape.Beginning with Visio 2007, in addition to serving as the repository of data associated with shapes, Shape Data is also used to define fields in data graphic callouts. These fields control the display of the prompts in the Edit Item dialog.The data linking features of Visio automatically add shape data fields for each field in a record being linked to a shape if that shape data field does not already exist in the shape.How to add shape dataThe basic techniques of adding shape data have not changed, although the menus changed with Visio 2007 from Custom Properties to Shape Data. Define Shape Data dialogThe Shape Data dialog still exists with the revised interface of Visio 2010. There are a couple of options for viewing the dialog.Right-click in the Shape Data window and choose Define Shape DataRight-click a shape (or selection) and choose Data > Shape DataThe ShapeSheetShape Data fields can be created in the ShapeSheet window by adding rows to the Shape Data section and filling in the values for each of the cells in the row.Shape Data setsShape Data Sets allow the copying of a group of shape data fields in mass from one shape to another. This feature is available as a right-click menu of the Shape Data window.Effect of LockCustProp cell in Protection sectionThere is a Protection section cell named LockCustProp that affects the user’s ability to add shape data through the user interface. This cell is available only through the ShapeSheet. It is not displayed in the user interface in the Protection dialog.This cell determines whether the user can add, delete, or modify shape data in the user interface using the Define Shape Data dialog box or the shortcut menu for the Shape Data window.When the cell has a value of True the Define button does not appear in the Shape Data dialog box, and the Define Shape Data command on the shortcut menu in the Shape Data window is disabled.A value of TRUE does not prevent a user from changing the value of a shape data item or changing the Shape Data section in the ShapeSheet window.Relationship of shape data and data graphicsVisio places the data to be displayed in a Shape Data row named Prop.msvCalloutField. Design the callout to make use of the information in this row in whatever way is desired. Note that Visio uses Shape Data rows in callouts in highly specialized ways and that these rows are not intended to be used as standard Shape Data properties. For this reason, you should set the Invisible cell value in these Shape Data rows to TRUE to hide these rows from the user.Figure 13. Text and Data Bar callout Shape Data cellsVisio puts the following information into cells in the Prop.msvCalloutField row when the callout is used in a data graphic.Table 5. Prop.msvCalloutField cells written by VisioCellValueLabelNot set by Data Graphics.PromptNot set by Data Graphics.TypeNot set by Data Graphics.FormatIf data field is a Shape Data property, Format of Shape Data property.If data field is not a Shape Data property, not set by Data Graphics.ValueReference to data field value.SortKeyIf data field is a Shape Data property, Label of Shape Data property.If data field is not a Shape Data property, not set by Data Graphics.InvisibleNot set by Data Graphics, TRUE recommended.AskNot set by Data Graphics.LangIDIf data field is a Shape Data property, LangID of Shape Data property.If data field is not a Shape Data property, LangID of target shape.CalendarIf data field is a Shape Data property, Calendar of Shape Data property.If data field is not a Shape Data property, not set by Data Graphics.You specify the data field to be shown in the callout when you include the callout in a data graphic. You can define additional properties for text callouts or data bars to expose in the Edit Item dialog. These properties enable you to configure the callout in special ways.You define custom callout properties by creating additional Shape Data rows that have names beginning with the prefix Prop.msvCalloutProp.Figure 14. Custom callout property cellsVisio interprets these cells in the property rows in the following ways.Table 6. Custom callout property cells read by VisioCell Value LabelProperty label to be displayed in dialog boxes.PromptControl type of property (defined below).TypeNot used.FormatFor List control types, semicolon-delimited list of choices.For Field control types, format of data field or empty if field is not a Shape Data property.For String control types, optional default value for the property.InvisibleNot used by Data Graphics, TRUE recommended.AskNot used.Visio puts the following information back into these cells in the property rows.Table 7. Custom callout property cells written by VisioCellValueValueProperty value.SortKeyFor Field control types where data field is a Shape Data property, Label of Shape Data property.LangIDFor Field control types where data field is a Shape Data property, LangID of Shape Data property.For Field control types where data field is not a Shape Data property, LangID of target shape.For Format control types, LangID of data format picture.CalendarFor Field control types where data field is a Shape Data property, Calendar of data field.For Format control types, Calendar of data format picture.Visio supports a variety of input controls in the Edit Item dialog. The Prompt cell specifies the control to be displayed. Other cells might be interpreted in different ways, depending on the control type.Table 8. Custom callout property control typesControl TypePrompt cell valueControl used in dialog boxString"String"Text boxNumber"Number"Text box requiring numeric inputList"List"Drop-down list box with choices supplied by the Format cellBoolean"Bool"Drop-down list box with yes and no choicesDate"Date"Text box with date pickerField"Field"Data-field drop-down list boxData Format"Format"Text box with Data Format buttonFigure 15. Custom callout property examplesField controls offer the same choice of fields as the data-field drop-down list box, with the addition of a [Not Used] choice. If you select [Not Used], Visio places the formula NA() in the property's Value cell.Lab 3.6: Data GraphicsDuring this lab, you will create a data graphic item to represent a pie chart and then create two data graphics to test the data bar item.Estimated time to complete this lab: 60 minutesBefore You BeginTo complete this lab, you will need:Participants should have completed the Try This! Sections of this module before completing this lab.Visio 2007 or higher installed and configured.Lab files needed:ScheduleBuilder.vssWhat You Will LearnAfter completing this lab, you will be able to:Create a new data graphic item from an existing shapeAdd the data graphic item to a new data graphicApply the data graphic to a shapeChange the display size of a data graphic item on a shapeExercise 1: Create a Pie Chart data graphic itemScenarioYou need to include a pie chart in a data graphic, but the standard data bar items do not include a pie chart. You will have to create a new pie chart data bar data graphic item.TasksCreate a new blank drawing.A basic pie chart shape is needed. You don’t need to create one from scratch because we’ll start with a variation of an existing Visio Pie Chart shape and turn it into a data bar item. It has the basic pie chart features needed. Open the stencil from the Labs folder (from the Shapes window More Shapes > Open Stencil and then traverse to the Labs folder and open ScheduleBuilder.vss.Drag the New Pie Chart shape to the page. Use the RMA commands to set Number of Slices and Slice Sizes.This is a modified version of the Pie Chart shape from the Charts and Graphs stencil. It is limited to 5 sections. Enter a value for each slice. The value is “normalized” to be a percentage of the total of the five slices.Note: The shape is “themed”. Browse through some of the subshapes of the group and look at the FillForegnd cells. They have Theme formulas that reference the different accent colors of the Theme.Open the ShapeSheet for the Pie Chart group shape. Look at the User-defined section and the Shape Data section. Note that there are Shape Data cells to contain the values for each slice. There are User-defined cells that calculate normalized values for the cells. These User-defined cells are referenced from the group’s subshapes.Turn this shape into a data bar data graphic item by editing the master in the Document Stencil. Add the User-defined cell User.msvCalloutType. Set its value to “Data Bar”. Close the Master editing window and save the changes.Check if it worked. In the Data Graphics task pane create a new Data Graphic. Add a new graphic item of type Data Bar. The New Pie Chart shape should show as a new data bar option to choose from.Now you need to set up the fields that are to be displayed on the data graphic by turning the existing shape data fields into data graphic fields. Edit the New Pie Chart master from the Document Stencil window. Open the ShapeSheet for the New Pie Chart group shape.In the Shape Data section delete the row Prop.Slices. This will be driven from the data graphic, not by user choice.Change the name of Prop.Pie1 to Prop.msvCalloutField and set the following column values:Label=No FormulaValue=0Invisible=TrueChange the name of Prop.Pie2 to Prop.msvCalloutPropField2 and set the following column values:Prompt=”Field”Value=0Invisible=TrueChange the name of Prop.Pie3, Prop.Pie4, Prop.Pie5 to msvCalloutPropField3, msvCalloutPropField4, and msvCalloutPropField5 respectively. Set the Prompt, Value, and Invisible fields the same as msvCalloutPropField2.Delete the Actions section from the ShapeSheet. This is no longer needed.In the User-defined section delete the row User.Pies. This is no longer needed.Close the master window and save the changes.Check if it worked. In the Data Graphics task pane create a new Data Graphic. Choose a Data field. Any field will do for the moment so choose More Fields…>Geometry>Width. Set Displayed as: to be Data Bar. Select the New Pie Chart graphic item. The New Item dialog should look like the following. You should see Pie2 through Pie5 in the Details section and the values are displayed as [Not Used].Make the new master graphic item hidden. You can create a macro for this or use the Immediate Window in VBA. From the Immediate Window type:activedocument.Masters("New Pie Chart").Hidden=trueThe master can still be seen from the Drawing Explorer window, but not from the Document Stencil.Exercise 2: Test the New Pie Chart data graphic itemScenarioTo test the new graphic item you will link a shape to a row in an external data set and then create a data graphic and apply it to the shape.TasksChoose Data > Link Data to Shapes and choose the file ScheduleBuilder.xls from the Labs folder. Specify the Sections worksheet in the Excel file. The Sections data will appear in the External Data window. Accept all defaults to finish the wizard.Draw a rectangle on the page and link it to the first row of data. Note that a default data graphic is assigned to the shape.Choose Data > Data Graphics > Create New Data Graphic . Add a New Item.Set the Data Field to 9. This is the number of students in grade 9.Set Displayed as to Data Bar and set the Style to New Pie Chart. Set the following:Pie2=10Pie3=11Pie4=12Leave Pie5 unchanged.Set the callout position of the data graphic item to Center and Middle.Apply the data graphic to the shape. Does the data graphic appear the right size for the shape? By default it scales to the size of the shape.From the Drawing Explorer window edit the New Pie Chart master. Open the ShapeSheet and set these formulas into the Width and Height cells. Width=Guard(0.5 in*DropOnPageScale)Height=Guard(Width)Close the master editing window and save the changes.The data graphic will not update on the shape automatically so apply the None data graphic and then reapply the new data graphic. It should now appear in a fixed size of 0.5 inches.Rename this data graphic to “DG Pivot”Exercise 3: Add a data bar to the Data Graphic that totals the 9th, 10th, 11th, and 12th grade slots for a class section.ScenarioCreate a new data graphic based on “DG Pivot” and add a data bar item.TasksCreate a duplicate of “DG Pivot”. Choose Data > Data Graphics. Right click the data graphic and choose Duplicate.Rename the new data graphic “DG Section”.Edit “DG Section”. Add a New Item.Under Data Fields choose More Fields… and then Custom Formula. In the Custom formula text field enter ={9}+{10}+{11}+{12}Set the Displayed as field to Data Bar and set the Style to Data Bar 3.Set the callout position to Right – Bottom.Set the Maximum value to 35.Set the Label to “Total”. Close the Data Graphic dialog.Draw a rectangleLink it to a row of dataApply the data graphicYou should see something similar to the image below.Save the drawing. You will use the data graphics just created in the next module.Additional Resources – Data GraphicsBuilding Data Visualization Solutions with Visio 2007A PowerPoint presentation giving an overview of the features of Visio 2007 from the Visio Developers conference in January, 2006. These are just the slides. No notes are included.: Let data tell its story with data graphicsAn online demo showing the new features of Visio 2007. : With Microsoft Office Visio 2007, Every Picture Tells a Richer StoryWhile a picture may be worth a thousand words, having the right pieces of data associated with that picture can be invaluable to IT professionals and business managers in making better-informed decisions. Graphics: visualizing data on your diagramA high level review of applying and modifying data graphics 2007: Customizing Data Graphic ItemsCreating a custom data graphic item 2007: More on Customizing Data Graphic Items: Icon SetsShows constructing and icon set including what is required in the ShapeSheet. Custom Data Graphics for Visio 2007?A very good article by Mark Nelson on creating and customizing data graphics. Several good examples and specific how to do it! Data GraphicsProvides good insight on why trying to apply formats to data graphics through the user interface gives unexpected results. The author also tells you how to solve the problem. Formulas in Data GraphicsNice example of creating a custom formula in a data graphic Displaying Data Graphically: Automating Data GraphicsQuestionsWhat new objects are added to the Visio object model to support data graphics?What two places in the Visio drawing environment can you see a data graphic?True or False. A good way to learn about automating data graphics is to use the macro recorder.What are the four types of data graphic items that can be displayed in a data graphic?What distinguishes a data graphic master from other masters in the masters collection?Data graphic masters that are callouts have what user-defined cell to describe what type of callout they are.Instead of referencing just a Shape Data row, a custom formula can be displayed in a data graphic item. In the object model, which method is used to set the custom formula?Additional fields can be added to a callout by adding rows to Shape Data. What naming convention is required to enable the data in these rows to be displayed as “Details” in the Edit Item dialog?What three user-defined cells are required for the icon set callout?What property of the shape is set to assign a data graphic?True or False. You can edit the data graphic master directly using automation.True or False. Data graphics are not very expensive in terms of size and performance in a drawing.What is a way to make a data graphic always be part of a drawing?How can you add a data graphic from one drawing to another drawing?Since Shape Data is used to create data graphics fields, how do we prevent these fields from being displayed in the Shape Data window?AnswersGraphicItem and GraphicItemsThe Data Graphic task pane and the Drawing Explorer windowFalse. The macro recorder will not work with data graphics. If the macro recorder is started, the Data Graphics task pane is immediately closed and cannot be opened until the macro recorder is turned off.Text callout, data bar callout, icon set callout, and color by value.The data graphics master is hidden so that it does not show in the Document Stencil and the master type is visTypeDataGraphic.User.msvCalloutType which has values “Text Callout”, “Heading”, “Data Bar”, or “Icon Set”.SetExpression of the GraphicItem object.The Shape Data row name must start with msvCalloutProp…User.msvCalloutType, User.msvCalloutIconCount, User.msvCalloutIconNumber.The DataGraphic property.False. You most Open the data graphic master, which creates a copy. This copy can then be modified and when the master is closed the changes are pushed back to the master.False. Data graphics can be very expensive because a data graphic can be made up of several masters. When applied to many shapes in a drawing you can quickly double, triple, or more the size of the drawing.Add the data graphic to a template. Then it will exist in all drawings created from the template.Copy a shape that has the data graphic applied and then delete the shape. The data graphic will remain as part of the drawing.Shape Data rows have an Invisible cell which is set to True in the ShapeSheet.Managing External Data SetsA key feature of Visio is the ability to pull external data from a variety of data sources into the Visio environment and link shapes from the drawing to this data. The linking process updates a shape to import data into existing Shape Data fields, and adds new fields as needed.Each of the actions that can be performed through the user interface can also be performed programmatically. Using programming techniques to add datarecordsets, create and link shapes, add data graphics, refresh data, and detect and respond to changes after refresh are the topics of this module.Module ObjectivesAfter completing this module you will be able to:Add data to Visio programmatically from different data sourcesDescribe the objects, properties, and methods that control data linking Link shapes to records within the dataManage the links programmaticallyRefresh the dataDetect and react to changes in the data on refreshLesson 1: Data Link ConceptsThe first part of managing linked data is getting connected to the data. There are three variations of the Add method for creating a new datarecordset: Add, AddFromConnectionFile, and AddFromXML.The key to using these methods is setting up the connection string and the command string. The connection string identifies the data’s location of the data and any security information needed for accessing the data. The command string is used to specify what part of the data is desired.At the end of this lesson we will review an example that is more extensive than the simple code snippets in the Help files. This example adds datarecordsets, adds shapes, links the shapes to the data, adds and modifies a data graphic, and lays out the drawing. The final solution is an organizational chart created from data in an Excel file, but uses simple rectangle shapes and data graphics to display the organizational information on the shapes.Lesson ObjectivesAfter completing this lesson you will be able to:Identify the new objects added to Visio 2007 for managing data linking and where they fit in the object modelIdentify the properties, methods, and events of the new objectsCreate datarecordsets programmatically from different data sources using different Add methodsManage the DataConnection object to modify the connection stringOverview of Objects / Methods / PropertiesBig changes occurred to Visio 2007 in the area of data support. Visio now provides a general purpose tool for bringing data into the Visio environment and linking that data to shapes within the drawing (data linking and pivot diagrams). There are also new tools for displaying data associated with shapes (data graphics). These tools utilize heavily and also enhance the preexisting Shape Data features (formerly Custom Properties) of Visio that allow any data to be associated with Visio shapes. Data LinkingThe DataRecordSets object is part of the Document. This collection is empty until data is added to the drawing either through the user interface or through one of the automation methods that creates a DataRecordSet object. There may be multiple DataRecordSet objects within a document, each pointing to a different data source.The data in a DataRecordSet contains columns of data, each column representing a field. The DataColumns is the collection of all of the columns. The DataColumn object allows custom mapping of the column to a ShapeSheet cell.The DataConnection object holds the information for making the connection to the data source.When data recordset rows are added, changed, or deleted, and when data recordset columns are added or deleted, in each case as a result of a data recordset being refreshed, properties of the DataRecordsetChangedEvent object return arrays of the affected rows or columns.The relationship of the data linking objects to other portions of the Visio object model is shown in the graphic below.MethodsDataRecordSetsDescriptionAddFromConnectionFileAdds a DataRecordset object to the DataRecordsets collection, associates it with a new or existing DataConnection object, and fills it with data from an OLEDB or ODBC data source by using the connection and query information stored in a specified ODC connection file.AddFromXMLAdds a DataRecordset object to the DataRecordsets collection and fills it with data from an XML file, without requiring a DataConnection object.GetLastDataErrorGets the ActiveX Data Objects (ADO) error code, ADO description, and data recordset ID associated with an error that results from adding a new data recordset or refreshing the data in an existing recordset.DataRecordSetDescriptionGetAllRefreshConflicts Returns an array of all the shapes in the data recordset that have refresh conflicts.GetDataRowIDs Returns an array of data recordset row IDs that match the rows in the data recordset specified in the criteria string passed to the method.GetMatchingRowsForRefreshConflict Returns an array of IDs of data rows that may have a broken link to a specified shape after a refresh operation.GetPrimaryKey Returns the name of the primary key column of the data recordset.GetRowDataReturns an array of values for each column in the specified data row. Returns an array of column names when data row 0 is specified.Refresh Refreshes the data in the data recordset.RefreshUsingXML Refreshes the data in a data recordset that has no data connection.RemoveRefreshConflict Removes all conflict information from the drawing file.SetPrimaryKeySets the column name of the primary key column used during a refresh operation.DataColumnsDescriptionSetColumnPropertiesSets the properties of the specified columns to the values specified.DataColumnDescriptionGetPropertyReturns the value of the data column property passed in as VisDataColumnProperties.SetPropertySets the specified property (as VisDataColumnProperties) to the specified value.PageDescriptionDropLinked Creates a shape linked to data on the page.DropManyLinkedU Creates many shapes linked to data on the same page.GetShapesLinkedToData Returns an array of shapes on the page linked to a specific data recordset.GetShapesLinkedToDataRow Returns an array of shapes on the page linked to a particular data row in a data recordset.LinkShapesToDataRowsLinks an array of shapes to an array of data rows from a particular data recordset on a one-to-one basis, by matching positions in the arrays. Optionally, applies a data graphic to linked shapes.SelectionDescriptionAutomaticLink Automatically matches shapes to data rows by comparing shape-attribute values with recordset-data-row values and finding the best match. You can specify the column (field) in each row of data and the shape attribute upon which to base the comparison.BreakLinkToData Breaks the link between one or more shapes and the data row or rows to which the shape or shapes are linked.GetIDsReturns an array of the IDs of shapes in a selection so that you can link them to data.LinkToData Links a single data-recordset row to a shape or to all shapes in a selection. Optionally, applies a data graphic to linked shapes.ShapeDescriptionBreakLinkToDataBreaks the link between one or more shapes and the data row or rows to which the shape or shapes are linked.GetCustomPropertiesLinkedToDataReturns an array of indices of shape data linked to a particular data recordset.GetCustomPropertiesLinkedColumnReturns the name of the column in the specified data recordset that is linked to the specified shape-data field.GetLinkedDataRecordsetIDs Returns an array of the IDs of data recordsets linked to a shape. GetLinkedDataRow Returns the ID of the row to which a shape is linked in the specified data recordset.IsCustomPropertyLinked Determines whether a specified shape data item is linked to a particular data recordset. LinkToData Links a single data-recordset row to a shape or to all shapes in a selection. Optionally, applies a data graphic to linked shapes.PropertiesDataRecordsetDescription CommandString Gets or sets the command string used to query the data source.DataAsXML Permits exporting data in XML format from Visio. Gets the XML string describing the data recordset following the ADO XML schema. Contains all the rows in the data recordset with Visio row IDs pre-pended to them. Read-only.DataColumns Returns the DataColumns object associated with the DataRecordset object.DataConnection Returns the DataConnection object associated with the DataRecordset object. Returns Nothing for a connectionless DataRecordset object. Read-only.LinkReplaceBehavior Gets or sets how existing links between shapes and data rows are handled during application of the Selection.AutomaticLink method.RefreshInterval Gets or sets the refresh interval for the data recordset in minutes. Default value is 0, which means that refreshing by interval never occurs. Minimum value is one minute.RefreshSettings Gets or sets refresh settings for the data recordset, as a combination of VisRefreshSettings values. TimeRefreshed Returns the date and time of the last refresh operation. Read-only.DataConnectionDescription ConnectionString Gets or sets the connection string used to access an existing DataConnection object or to create a new DataConnection object.Timeout Gets or sets how long (in seconds) to attempt to establish a data connection before terminating the attempt and generating an error. Default is 15 seconds.DataColumnDescription DataRecordset Returns the DataRecordset object associated with the parent object.DisplayNameGets or sets the display name for the data column in the External Data window and the label for the associated text box in the Shape Data dialog box for the linked shape or shapes.DataRecordsetChangedEventDescription DataColumnsAdded Returns an array of the IDs of columns added to the data recordset as part of a refresh operation. Read-only.DataColumnsChanged Returns an array of the IDs of columns in the data recordset whose type changed as part of a refresh operation. Read-only.DataColumnsDeleted Returns an array of the IDs of columns deleted from the data recordset as part of a refresh operation. Read-only.DataRecordset Returns the DataRecordset object associated with the parent object.DataRowsAdded Returns an array of the IDs of rows added to the data recordset as part of a refresh operation. Read-only.DataRowsDeleted Returns an array of the IDs of rows in the data recordset whose type content was changed or deleted as part of a refresh operation. Read-only.ApplicationDescription DataFeaturesEnabled True if data features are enabled for the current instance of Visio. Read-only.Document Description DataRecordsets Returns the collection of DataRecordset objects associated with the Document object.Window Description SelectedDataRecordset Gets or sets the DataRecordset object that is selected on the active tab of the External Data window.SelectedDataRowID Gets or sets the row ID of the selected row displayed on the active tab of the External Data window.Data SourcesThe Data Selector wizard enables the Visio user to connect to external data sources and bring that data into the Visio environment. Data sources you can connect to include Microsoft Office Excel worksheets, Microsoft Office Access databases, Microsoft SQL Server databases, Microsoft SharePoint lists, and other OLEDB or ODBC data sources, such as an Oracle database.To connect your Visio drawing to a data source programmatically, use the new additions to the Visio API for data connectivity which include the following objects and their associated properties, methods, and events:DataRecordsets collection objectDataRecordset object DataConnection objectDataRecordsetChangedEvent objectDataColumns collection objectDataColumn objectFigure 1. Data objects as they appear in the user interface.Each Visio Document object has a DataRecordsets collection, which is empty until you make a connection to a data source. To connect a Visio document to a data source, you add a DataRecordset object to the DataRecordsets collection of the document. A DataRecordset object has a DataColumns collection of DataColumn objects, each of which is mapped to a corresponding column (field) in the data source. When you add a DataRecordset object by connecting to an data source, Visio abstracts the connection in a DataConnection object, and the DataRecordset object is said to be connected.You can also add a DataRecordset object by using an XML file that conforms to the ActiveX Data Objects (ADO) XML schema as the data source. The resulting DataRecordset object is said to be connection-less. An example of using this technique to create a DataRecordset is presented later in this material.The connection between a data source and a DataRecordset object goes only one way—from the data source to the Visio drawing. If data in the source changes, you can refresh the data in the drawing to reflect those changes. You cannot, however, make changes in the data in the drawing and then push those changes back to the data source. Visio can only read the data source. It cannot update the data in the rmation is stored in the DataConnection objectAn easy way to discover what information is required in a connection string is to use the macro recorder within Visio. Accessing different data sources only requires a modification to the connection string used that describes the location of the data.Try it!Open from the Samples directory Working With DataRecordsets.vsd.Use the Data Selector wizard (Data > Link Data to Shapes...) to import the data in Orgdata.xls data from the Samples folder. When the import is finished, the data is displayed in the External Data window.Run the macro to display the DataConnection object (View > Macro > InterestingMacros.GetDataConnectionObject). The connection string is displayed in the Immediate window. The code and the connection string are listed below. Public Sub GetDataConnectionObject() 'Displays the connection string from the DataConnection object 'for the most recently opened datarecordset Dim vsoDataConnection As Visio.DataConnection Dim vsoDataRecordset As Visio.DataRecordset Dim iCount As Integer iCount = ActiveDocument.DataRecordsets.Count Set vsoDataRecordset = ActiveDocument.DataRecordsets(iCount) Set vsoDataConnection = vsoDataRecordset.DataConnection Debug.Print vsoDataConnection.ConnectionStringEnd SubSample connection string for Excel data source:Provider=Microsoft.ACE.OLEDB.12.0;User ID=Admin;Data Source=C:\Program Files\Microsoft Office\OFFICE12\Samples\1033\ORGDATA.XLS;Mode=Read;Extended Properties="HDR=YES;IMEX=1;MaxScanRows=0;Excel 12.0;";Jet OLEDB:System database="";Jet OLEDB:Registry Path="";Jet OLEDB:Engine Type=35;Jet OLEDB:Database Locking Mode=0;Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Global Bulk Transactions=1;Jet OLEDB:New Database Password="";Jet OLEDB:Create System Database=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:SFP=False;Jet OLEDB:Support Complex Data=FalseSample connection string for SharePoint list:PROVIDER=WSS;DATABASE={05F6AF30-326C-4932-83C1-35BF2015F718};Sample connection string for SQL Server:Provider=SQLOLEDB.1;Integrated Security=SSPI;Persist Security Info=True;Data Source=localhost\sqlexpress;Initial Catalog=WhitePaperSamplesAdd a DataRecordsetDataRecordsets.AddThe Add method adds a DataRecordset object to the DataRecordsets collection by connecting to and retrieving data from an ODBC or OLEDB data source.Try it!From the file Working with DataRecordsets.vsd run the macro View > Macro > InterestingMacros.AddDataRecordsetFromConnectionObject. The macro will create two DataRecordsets from the sample data in ORGDATA.xls.View the code for this macro. The first time the Add method is used, the connection information is passed as a string. Upon completion of this first Add the DataRecordset object is created and its DataConnection object is established.Set vsoDataRecordset = ActiveDocument.DataRecordsets.Add( _ strConnection, strCommand, 0, "Org Data")The second time the Add method is used the DataConnection object previously created is passed as the parameter to the Add method. This creates another DataRecordset from the same data in ORGDATA.xls.Set vsoDataRecordsetTwo = ActiveDocument.DataRecordsets.Add( _ vsoDataRecordset.DataConnection.ID, _ strCommand, 0, "Org Data") Tip:Anytime a DataRecordset exists, there will be a DataConnection object containing the connection information for the data used to create the DataRecordset (except for connectionless DataRecordsets). This DataConnection can be used to create more instances of the same data.DataRecordsets.AddFromConnectionFileCreating a DataRecordset from an Office Database Connection file (.odc) is done with the AddFromConnectionFile method of the DataRecordsets object. If an .odc file exists pass the path of the .odc file in the first parameter of the method similar to the code presented below.Public Sub AddFromConnectionFile_Example() 'Create a DataRecordset from an .odc file using the 'AddFromConnectionFile method Dim strFile As String Dim strName As String Dim vsoDataRecordset As Visio.DataRecordset strFile = "C:\Documents and Settings\System Admin\My Documents\" & _ "My Data Sources\Northwind Employees.odc" strName = "Data from ODC" Set vsoDataRecordset = _ ThisDocument.DataRecordsets.AddFromConnectionFile( _ strFile, 0, strName)End Sub Note: An .odc file can be created in different ways including using tools in SharePoint and tools in Access and Excel. The .odc file used for this example was created with the Data Connection Wizard in Excel.Try it! (optional)Use Excel to create an .odc file. This can point to any Excel file or easily accessible database such as Northwind.mdb. Note the path where the .odc file is saved.Modify the macro AddFromConnectionFile_Example in the file Working with DataRecordsets.vsd to create a DataRecordset based on the new .odc file just created.DataRecordsets.AddFromXMLAdds a DataRecordset object to the DataRecordsets collection, and fills the resulting data recordset with data supplied in the form of an XML string.In contrast with data recordsets created by using the Add or AddFromConnectionFile methods, data recordsets created by using the AddFromXML method are not associated with a DataConnection object. Note: Because DataRecordsets created using AddFromXML have no DataConnection object, they are referred to as a connection-less data source.What's more, Visio never refreshes a data recordset you created by using the AddFromXML method automatically, regardless of the setting of the DataRecordset.RefreshInterval property. To refresh the data in such a data recordset, you must call the DataRecordset.RefreshUsingXML method.Try it!From the file Working with DataRecordsets run the macro View > Macro > InterestingMacros.AddFromXML_Example. The macro will create a DataRecordset from the XML data defined within the macro.View the code. Following is the XML data used to create the DataRecordset. Compare this to the VBA code to see how the XML data is put into a string.<xml xmlns:s='uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882'xmlns:dt='uuid:C2F41010-65B3-11d1-A29F-00AA00C14882'xmlns:rs='urn:schemas-microsoft-com:rowset'xmlns:z='#RowsetSchema'><s:Schema id='RowsetSchema'><s:ElementType name='row' content='eltOnly' rs:updatable='true'><s:AttributeType name='c1' rs:name='Cities'rs:number='2' rs:nullable='true' rs:maydefer='true' rs:write='true'><s:datatype dt:type='string' dt:maxLength='255' rs:precision='0'/></s:AttributeType><s:extends type='rs:rowbase'/></s:ElementType></s:Schema><rs:data><z:row c1='Seattle' /><z:row c1='Redmond' /></rs:data></xml>Run the macro GetDataConnectionObject. This will trip the error handler when checking for the DataConnection object and display a message in VBA’s Immediate window.Accessing data in the DataRecordsetWhen you import data, Visio assigns integer row IDs, starting with the number 1, to each data row in the resulting datarecordset, based on the order of the rows in the original data source. Visio uses data row IDs to track the rows when they are linked to shapes and when data is refreshed. If you want to access data rows programmatically, you must use these data row IDs.Two important methods for retrieving information from DataRecordsets include GetDataRowIDs and GetRowData. Use GetRowData to retrieve all columns of data within a given row. Use GetDataRowIDs to retrieve a subset of IDs within the DataRecordset that satisfy a given criteria string.A sample of how to use these methods is included in the following demonstration code.Try it!Make sure a datarecordset exists and then run the macro GetDataRecords. This macro is a simple example of using GetRowData and GetDataRowIDs and writing the information to the VBA’s Immediate Window.Run the macro View > Macro > BuildOrgMacros.DoItAll. This macro builds an organizational chart. It creates a DataRecordset, drops shapes on the page and links them to the data records, drops connectors on the page and glues them between the employee and its Reports_To shape, modifies the data graphic that displays the organizational data, and then lays out and resizes the page. Look at the code in the macro AddDataRecordSet. This macro is used by the DoItAll macro. Note that it uses the DataRecordSets.Add method to create the datarecordset. It also sets the primary key field of the datarecordset.Look at the code in the macro DropManyLinkedShape. This macro is used by the DoItAll macro and sets up the DropManyLinkedU method to add a shape linked to each record in the datarecordset. Note that the data graphic is added at the same time the shapes are created.Look at the code in the macro AddAndGlueConnectors. This macro utilizes GetRowData and GetDataRowIDs to extract the needed information.The key segment of code follows. Each record contains the data for one employee and in that record is the “Reports_To” field which gives us the name of the person they report to. GetRowData is used to extract the fields from a row in the form of an array of variant data. The data in the Reports_To field is used to construct a criteria string which is then passed to the method GetDataRowIDs to retrieve the ID of the record within the datarecordset of that employee. An example criteria string is “Name = ‘Joseph Goldberg’”Given the ID of this record we use GetShapesLinkedToDataRow to find the shape on the page that is linked to the row in the datarecordset.This is enough information to give us the “from shape” and “to shape” so that we can add and glue the connectors. 'Get the shape id of the "Reports_To" shape varRowData = vsoDataRecordset.GetRowData(ShapeRowID) strReportsTo = varRowData(2) 'Find the datarecordset row that has this "Reports_To" data 'in the "Name" field strCriteria = "Name = '" & strReportsTo & "'" lngNameRowIDs = vsoDataRecordset.GetDataRowIDs(strCriteria) 'Find the shape linked to this data row ActivePage.GetShapesLinkedToDataRow vsoDataRecordset.ID, _ lngNameRowIDs(0), lngShapeIDsThe macro ModifyDataGraphicMaster modifies the default data graphic applied to the shapes to add another text callout that displays the employee’s “Title” information.The final step is in LayoutAndResize. This macro applies the Layout method to arrange the drawing and resizes the drawing page so that the entire organization chart fits on the page.We will explore the other macros in this file later in this module.Lesson 2: Managing Data setsAfter creating a datarecordset, the next step is to link shapes to its rows. A shape can be linked to only one row within a single datarecordset, but it can be linked to multiple datarecordsets – one row in each. Multiple shapes can be linked to the same row. The steps of creating the shapes, linking the shapes, and adding a data graphic can be done in a single step.Datarecordsets can be refreshed. They can be refreshed on demand or they can be refreshed automatically at prescribed intervals.When a datarecordset is refreshed, it may change. These changes can lead to conflicts with the linking that was previously established. Visio provides tools for detecting these conflicts and detecting changes to the datarecordset so that your program can react appropriately to the changes.At the end of this lesson we will review a macro that refreshes the datarecordset for the organization chart created in the previous lesson. After the data is refreshed the code checks for conflicts in the data and for additions and deletions to the data.Lesson ObjectivesAfter completing this lesson you will be able to:Link existing shapes to rows in a datarecordsetAdd shapes to a drawing and link them at the same timeLink many shapes to a row in a datarecordsetLink shapes to rows in multiple datarecordsetsAutomatically link shapesAdd data graphics to linked shapesDiscover existing linksBreak linksManage refreshDiscover and manage conflicts after refreshLinking data to shapesAfter you connect your Visio drawing to an external data source, you can link the shapes in the drawing to data from that source programmatically. You can link one or more shapes to a single row of data in a data recordset or to multiple rows of data in different data recordsets. However, you cannot link shapes to multiple rows of data in the same recordset.You can link existing shapes to data, one shape at a time or many at a time; or, you can create shapes and link them to data simultaneously. Creating shapes linked to dataWhen you want to create shapes that are already linked to data, on a drawing page that either does not contain any shapes or contains shapes other than the ones you want to link, you can use the Page.DropLinked method and the Page.DropManyLinkedU method to create one or more additional shapes already linked to data. These methods resemble the existing Page.Drop and Page.DropManyU methods in that they create additional shapes at a specified location on the page; but they also create links between the new shapes and specified data rows in a specified data recordset.An example of using DropLinked follows. Set vsoShape = ActivePage.DropLinked(vsoMaster, dblX, dblY, _ lngDataRecordsetID, lngRowID, True)vsoMaster is a reference to the master that is being dropped on the pagedblx, dbly define the drop location and correspond to the created shape’s pin locationlngDataRecordsetID is the ID of the datarecordset being linked tolngRowID is the ID of the row within the datarecordset being linked tothe last parameter (True) is a Boolean that specifies whether a data graphic is to be applied to the shape automaticallyvsoShape is a returned reference to the created shapeTry it!In the file Working with DataRecordsets.vsd, run the macros AddFromXML_Example (although any open datarecordset will do) and then DropLinkedShape. View the code in DropLinkedShape.An example of DropLinkedManyU was covered in an earlier example. The complete code can be viewed in the macro DropManyLinkedShape. The core piece of code follows: 'Create one shape record for each record in the datarecordset lngReturned = ActivePage.DropManyLinkedU(avsoMaster, _ dblXY, vsoDataRecordset.ID, _ lngRowIDs, True, alngShapeIDs)avsoMaster is an array of shapes to be dropped, one per record in the datarecordsetdblxy is an array of x, y coordinates that determine the drop locations for the new shapesvsoDataRecorset.ID is the ID of the datarecordset being linked tolngRowIDs is an array of row IDs within the datarecordset that determine the row that each shape is linked tothe next to last parameter (True) is a Boolean that specifies whether a data graphic is to be applied to the shapes automaticallyalngShapeIDs is an array of IDs for the created shapeslngReturned is a returned value specifying the number of created shapesLinking existing shapes to dataLink a single shape to a single rowTo link a single shape to a single row LinkToData method of the shape as shown below.vsoShape.LinkToData vsoDataRecordset.ID, lngRowID, boolAddDataGraphicThe following information is needed:vsoShape is a reference to the shape to be linkedvsoDataRecordset.ID is the ID of the datarecordset being linked tolngRowID is the ID of the row within the datarecordsetboolAddDataGraphic is a Boolean specifying whether a data graphic is to be applied automatically to the shapeLink a shape to multiple datarecordsetsA single shape can be linked a single row within a single datarecordset, but it can still be linked to a different row within a different datarecordset.To link a shape to rows in multiple datarecordsets apply the LinkToData method multiple times, once for each datarecordset.Link multiple shapes to a row in a datarecordsetThis is the same as linking an individual shape except the LinkToData method of the Selection object is used.If Visio cannot establish a link between a shape and the data row, Visio skips that shape and goes on to the next shape in the selection. After you run the method, to determine if all shapes in the selection are actually linked to the data row, call the Shape.GetLinkedDataRow method on each shape in the selection. If that method fails for any shape, it indicates that the shape is not linked to the data row. Visio will usually succeed in linking a row to a shape unless the shape is already linked to data and the link-replacement-behavior setting for the datarecordset specifies that the link should not be replaced.Link multiple shapes to multiple rowsThe Page.LinkShapesToDataRows method is similar to the Selection.LinkToData method because it links multiple shapes. The LinkShapesToDataRows method links shapes to multiple data rows. The LinkToData method of the Selection object links multiple shapes to a single row. ActivePage.LinkShapesToDataRows vsoDataRecordset.ID, alngDataRowIDs, alngShapeIDs, boolAddDataGraphicTo link shapes, pass the LinkShapesToDataRows method a pair of arrays: one for shapes, and one for data rows. Note that the matching array positions must correspond. As a result, for example, the shape at position 1 in the shape array is linked to the data at position 1 in the data row array. Again, when you call the method, you can optionally specify whether to apply an existing data graphic to linked shapes.Automatically link shapes and data rowsIf you are unsure about the correspondence between shapes and data rows, but you know a match exists between a specific attribute of every shape and the data in one column in the data recordset, the Selection.AutomaticLink method provides a way to link a selection of existing shapes to multiple rows of data. Note that it must be the same attribute for all shapes.The help file for the AutomaticLink method gives a coding example for setting up an automatic link where a single column to be matched is specified. Let’s set up an example for matching multiple columns and let’s use the record macro feature of Visio to create the code.Try it!Open Working with DataRecordsets.vsd and run the macro BuildOrgMacros.AddDataRecordset to create a datarecordset from ORGDATA.xls.Drop three rectangles on the page and link them to the first three records in the datarecordset. This will add shape data fields to the rectangles.Unlink the three shapes.Turn on the macro recorder.Select the three shapes.Right-click in the External Data window and choose Automatically Link. The Automatically Link wizard is presented.On the first page choose Selected Shapes and then Next.Choose Data Column = Name and Shape Field = Name. Then click the and button.Choose Data Column = Title and Shape Field = Title. Click Next and Finish. This will link the three selected shapes.Stop the macro recorder and look at the code.The last portion of the code should look similar to the following. ColumnNames1(0) = "Name" FieldTypes1(0) = visAutoLinkCustPropsLabel FieldNames1(0) = "Name" ColumnNames1(1) = "Title" FieldTypes1(1) = visAutoLinkCustPropsLabel FieldNames1(1) = "Title" Application.ActiveWindow.Selection.AutomaticLink 41, ColumnNames1, _ FieldTypes1, FieldNames1, visAutoLinkReplaceExistingLinks, _ IDsofLinkedShapes1We are passing to the method arrays for column names, field types, and field names. In this case we are specifying that multiple columns and fields must match before the shapes can be linked.The penultimate parameter specifies the auto link behavior. Use values from the VisAutoLinksBehavior enumeration. These enumerated values provide options to customize the method, for example to replace existing links with new ones. The last parameter returns an array of shape IDs of the linked shapes.Discovering linksDiscovering information about links is very straight forward. The sample code in the Visio help files gives examples using these methods. Some key methods include:Page.GetShapesLinkedToData – given a datarecordset, returns an array of shape IDs on a page linked to the datarecordsetPage.GetShapesLinkedToDataRow – given a datarecordset and a row ID, returns an array of shape IDs on a page that are liked to that rowShape.GetLinkedDataRow – given a datarecordset, returns the ID of the row the shape is linked toShape.GetLinkedDataRecordsetIDs – returns a list of IDs of all datarecordsets that are linked to by this shapeShape.GetCustomPropertyLinkedColumn – given a datarecordset ID and a shape’s Shape Data row ID, returns the name of the data column linked to this shape data rowShape.GetCustomPropertiesLinkedToData – given a datarecordset ID, returns an array of Shape Data row IDs that are linked to the data columns in the datarecordsetShape.IsCustomPropertyLinked - given a datarecordset ID and a shape’s Shape Data row ID, returns whether that Shape Data item is linkedBreaking linksBreaking links through automation is handled with the Shape.BreakLinkToData and the Selection.BreakLinkToData methods.In addition, actions in the user interface can cause links to be broken, such as deleting a datarecordset or deleting the Shape Data item in a shape that is linked. Regardless of how the link was broken, the Shape.ShapeDataLinkDeleted event is fired.A note on the use of IDs in VisioVisio keeps unique IDs for shapes, datarecordsets, and rows within the datarecordsets.Shape IDsShape IDs are unique to the page. Shape IDs are reused when one shape is deleted and then another shape is added.Shape UniqueIDsUnique IDs are GUIDs. They are unique within the scope of the application. To convert between shape IDs and unique IDs, you can use two methods of the Page object, ShapeIDsToUniqueIDs and UniqueIDsToShapeIDs.By default, a shape does not have a unique ID. A shape acquires a unique ID only if you set its UniqueID property. If a Shape object has a unique ID, no other shape in any other document will have the same ID.DataRecordset IDsDataRecordsets have unique IDs accessible via the DataRecordset.ID property. These ID values are not reused if a DataRecordset is closed. Generally, the DataRecordset.ID value will NOT be the same as the position of the DataRecordset within the DataRecordsets collection. There is no index value for a DataRecordset.Row IDs within a DataRecordsetRows of data within a DataRecordset generally have unique IDs starting with a value of 1, but they may not run consecutively depending on recent refresh operations.Because shapes are linked by their shape IDs to specific data rows, when Visio refreshes linked data, it must determine which rows in the linked data recordset or recordsets were added, changed, or removed since the last time the data was refreshed.To identify these rows, Visio uses the row IDs assigned to the rows in the data recordset. Visio can assign these row IDs two ways, depending on whether you designated primary keys for the data recordset when you created it.Refreshing Data Recordsets That Do Not Have Primary KeysWhen you create a data recordset, Visio assigns row IDs to all the rows in the recordset based on the existing order of the rows in the data source. Accordingly, the first row in the recordset is always assigned row ID 1, the second is assigned row ID 2, and so on.Subsequently, data rows can be added or removed from the original data source. Then, when data is refreshed, the data recordset reflects those changes. As a result, row order in the data recordset may change.For example, in a five-row data recordset, if the fourth row in the data source is removed, when Visio refreshes the data recordset connected to that data source, the fifth row in the data recordset becomes the new fourth row and is assigned row ID 4. Row ID 5 is removed from the data recordset. As a result, shapes linked to row ID 5 lose their links, and shapes linked to row ID 4 now get data from the row previously in the fifth position.As you can see, not assigning primary keys to data recordsets when you create them can result in broken links between shapes and data, or in Visio linking shapes to rows other than the ones to which you want them linked.Refreshing Data Recordsets That Have Primary KeysYou can help prevent these broken or mismatched links by assigning primary keys to data recordsets. A primary key identifies the name of the data column or columns that contain unique identifiers for each row. The value in the primary key column for each row uniquely identifies that row in the data recordset. Primary keys are often ID values, but you can set any column or combination of columns to be the primary key. However, to get consistent results when you refresh data, it is essential that you make the primary key column value (or set of values for multiple primary key columns) unique for each row.As a result, when you refresh or when Visio refreshes a data recordset that includes primary keys, its rows retain the same row IDs they had before the refresh operation. Because Visio links shapes to data rows by ID—shape ID to row ID—and because row IDs remain the same after a refresh operation, data-linked shapes remain linked to the correct row. Note that row IDs are never recycled for a given a data recordset.Managing RefreshDataRecordsets can be refreshed programmatically using the DataRecordset.Refresh method. Calling this method executes the query string associated with the datarecordset and then updates the linked shapes with the data returned by the query.When a datarecordset is created it does not refresh automatically. To enable automatic refresh set its refresh interval to some value greater than zero.'Set the refresh interval to 2 minutesvsoDataRecorset.RefreshInterval = 2To turn off automatic refresh set the refresh interval to zero.'Turn off automatic refreshvsoDataRecorset.RefreshInterval = 0If calling Refresh results in conflicts, Visio displays the Refresh Conflicts task pane in the UI, unless you set the RefreshSettings property to include the visRefreshNoReconciliationUI (=2) enumerated value. By default RefreshSettings=0. As a developer, you should reconcile refresh conflicts programmatically by using the GetAllRefreshConflicts, GetMatchingRowsForRefreshConflict, and RemoveRefreshConflict methods.'Don’t display refresh conflicts in the Refresh Conflicts task panevsoDataRecorset.RefreshSettings = visRefreshNoReconciliationUIIdentify changes and resolve conflicts When a datarecordset is refreshed conflicts are displayed in the Refresh Conflicts task pane. If a data row has been deleted and a shape was linked to it, that shape is displayed and the user is prompted for what to do with it.If a new data row is added that is a duplicate of a previous row that was linked, the link is removed and the user is presented with the duplicate data and prompted for how to deal with it.If a new data row is added that is not a duplicate, there is no conflict. From the user interface the new record is apparent by looking at the External Data window and noting the unlinked records.The automation model provides tools to handle each of these scenarios.GetAllRefreshConflicts This method returns an array of shapes that are linked to data rows in a datarecordset that have non-resolved conflicts after a datarecordset is refreshed. Conflicts can result when a single shape is linked to more than one row in the same data source, or when a shape is linked to a row in the data source that has been deleted. If the shape would be linked to multiple rows, the link is removed and the conflict is presented in the Refresh Conflicts task pane. Use GetMatchingRowsForRefreshConflict to retrieve all of the rows in the datarecordset that match with this shape.If no conflicts exist, an empty array is returned.GetMatchingRowsForRefreshConflictWhen a shape is potentially linked to multiple rows in a datarecordset after a refresh, the list of matching rows can be retrieved with this method. It returns an array of row IDs from the datarecordset that each match the shape in conflict.Conflicts can also occur when a previously data-linked row from the data recordset is removed. When this occurs, the method returns an empty array. RemoveRefreshConflictOnce a conflict has been dealt with it can be removed from the list by using the RemoveRefreshConflict method of the shape.DataRecordsetChanged event and DataRecordsetChanged objectRetrieving conflict information is great for when changes to the datarecordset results in conflicts, but this does not help when new rows are added to the datarecordset. For example, when a new row is added the user may want to add a new shape that is linked to the new rows.Fortunately, there is a way to retrieve this information programmatically. Use the DataRecordsetChanged event to detect that the datarecordset has changed. Within the DataRecordsetChanged event you have access to the DataRecordsetChanged object which contains a wealth of information about what has changed in the datarecordset including data columns that have been added, changed, or deleted, and data rows that have been added or deleted.Try it!The sample code in Working with DataRecordsets.vsd has a macro that will Refresh a datarecordset and then check for and process changes using the methods and events just described. If you already have the file open, it is best to close it and then reopen it. Some of the code is not bullet proof, but it does illustrate how to use the methods.Open Working with DataRecordsets.vsd from the Samples folder.Run the macro BuildOrgMacros.DoItAll. This builds the organization chart we saw earlier using the OrgData.xls file.Run the macro BuildOrgMacros.RefreshDataAndResolveConflicts. This macro refreshes the Org Data datarecordset by modifying the connection string to point to a modified version of the Excel file OrgDataModified.xls and then using the Refresh method.The following changes are made to the organizational data:The record for Toby Nixon is changed to Toby Dixon. In the code this is handled as one deleted record and one added record. The original Toby Nixon shape is deleted and a new shape is added.The record for Meng Phua is changed to report to Toby Dixon. There is no conflict created by this change. The datarecordset and the shape data are updated on the refresh, but because the Toby Dixon record is new, the connector has to be changed to point to the correct “Reports_To” shapeA new record is added for Fred Taylor who reports to Toby Dixon and a duplicate record for Fred Taylor is also created. If both records are added at the same time there is no conflict because there is no shape linked to these rows. A new shape is added for Fred Taylor. When the second new Fred Taylor shape is processed it is ignored because it is a duplicate.Look at the code for RefreshDataAndResolveConflicts. Only the refresh code is here. The resolution of the conflicts is handled in the event procedure vsoDataRecordsets_DataRecordsetChanged which is in the ThisDocument module. Note: It is best to put the resolve conflicts code inside the event procedure. The event code does not fire immediately after the Refresh method so if you have some code in the event procedure and some code following the Refresh method, you won’t be able to determine which code is executed first.Look at the event procedure code. Conflicts are handled first using GetAllRefreshConflicts and then processing the conflict list. If a row has been deleted, the corresponding shape is deleted. If duplicate rows are created which have a corresponding shape, the shape is linked to one of the rows and the other row is ignored.New rows added to the datarecordset are handled next. If a new row is added which does not represent a duplicate, a new shape is added to the drawing and linked its “Reports_To” shape.All resulting changes in the drawing are in the lower right hand area of the drawing page.Warning for VBA users implementing code samples from Help filesBelow is the code sample provided in the Help file for GetMatchingRowsForRefreshConflic. Note that after the call to GetAllRefreshConflicts and to GetMatchingRowsForRefreshConflic there is an If test that uses the function IsEmpty to test for an empty array being returned by the methods.Unfortunately, this test does not work in VBA. The IsEmpty function is designed to work with variables of type Variant and does not reliably return information for other data types. It returns False even when the array has no data.There are several similar methods that return arrays and similar code samples that use IsEmpty to test these arrays. All of these samples will be problematic in VBA.Public Sub GetMatchingRowsForRefreshConflict_Example() Dim vsoDataRecordset As Visio.DataRecordset Dim intRecordsetCount As Integer Dim intShapeCount As Integer Dim vsoShapes() As Visio.Shape Dim intRowCount As Integer Dim vsoShapeInConflict As Visio.Shape Dim alngRowIDs() As Long Dim lngvsoRowID As Long intRecordsetCount = Visio.ActiveDocument.DataRecordsets.Count Set vsoDataRecordset = Visio.ActiveDocument.DataRecordsets(intRecordsetCount) vsoDataRecordset.Refresh vsoShapes = vsoDataRecordset.GetAllRefreshConflicts If IsEmpty(vsoShapes) Then Debug.Print "No conflict" Else For intShapeCount = LBound(vsoShapes) To UBound(vsoShapes) Set vsoShapeInConflict = vsoShapes(intShapeCount) alngRowIDs = vsoDataRecordset.GetMatchingRowsForRefreshConflict(vsoShapeInConflict) If IsEmpty(alngRowIDs) Then Debug.Print "For shape:", vsoShapeInConflict.Name, "Row deleted." Else For intRowCount = LBound(alngRowIDs) To UBound(alngRowIDs) lngvsoRowID = alngRowIDs(intRowCount) Debug.Print "For shape:", vsoShapeInConflict.Name, "Row ID of row in conflict:", lngvsoRowID Next intRowCount End If Next intShapeCount End If End SubAlternatives to using IsEmptySometimes, but not always, the UBound function will work and return a value of -1 if the array is empty. However, in some cases the UBound function will throw a ‘subscript out of range’ error.If using UBound does not work the only reliable alternative is to create an error handler to trap and process the error.Changing data locationsSometimes data locations change or network connections are lost. Is there a way to build some resiliency into your code so that if your access to the data changes your program does not fall over?Let’s examine some common scenarios:If the data changes location you may have to change the connection string in your code to point to the new location. We’ve already seen that the connection string can be changed and the datarecordset refreshed so straightforward to build this kind of change into your code.You can isolate your program from the data by using a data connection file and using the AddFromConnectionFile method. Connect to the data via a connection file with the assumption that the connection file stays in a fixed location and if the data moves, the connection file is updated with the new location.The third variation is when the data becomes unavailable unexpectedly such as when a network connection is lost or if the data is moved, but you don’t know where it is. In this scenario we can’t reconnect to the data, but we can detect that the data could not be found and then fail as gracefully as possible. To detect a failed connection use the Timeout property of the DataConnection object. This property is used to set a timeout interval (default is 15 seconds). If the interval elapses without success an error is raised. An error handler must be written to trap the error. An example follows showing a portion of the subroutine which refreshes a datarecordset and displays the error message when an error occurs: 'Set the connection string into the DataConnection object to point to 'the desired data vsoDataRecordset.DataConnection.ConnectionString = strConnection 'Set up error handler to catch the timeout error On Error GoTo ErrorHandler vsoDataRecordset.DataConnection.Timeout = 15 'Refresh the data. This will fail if the file cannot be reached vsoDataRecordset.Refresh Exit SubErrorHandler: Debug.Print "Error: ", Err.DescriptionEnd Sub ? Lab 3.7: Data LinkingDuring this lab, you will recreate a portion of the ScheduleBuilder program. In the process you will also fix some program errors that exist in the lab version of the file.You will use automation code to:Fix the error in finding and loading the Section DataRecordset from an external Excel data file.Link the Instructor shapes to rows in the Teacher DRS. (LinkSelectedInstructors)Drop and link the Section shapes to rows in the Section DRS. (DropSectionShapes)Refresh the Section DRS after changing the Excel file to add one or more records, delete one or more records and modify one or more recordsFix a problem in the linking/refresh conflicts logic that is preventing the conflict resolution from working properly.Estimated time to complete this lab: 90 minutesBefore You BeginTo complete this lab, you will need:Participants should have completed the Try This! Lessons of this module before completing this lab.Visio 2007 or later installed and configured.The following files are needed to complete this lab:Lab Module 3 Start.vsdScheduleBuilder.vssScheduleBuilder.xlsCompleted Visio drawing created in lab 3.6 (a completed file is provided)What You Will LearnAfter completing this lab, you will be able to:Attach to an external data set via automation codeAutomatically link shapes to rows in a DataRecordsetDrop multiple shapes onto a drawing and link them to rows in a DataRecordsetManage Refresh of external data and resolve refresh conflictsExercise 1: Connect to an external data setScenarioThere is an error when opening the drawing Lab 3.8 Start.vsd. The error appears when trying to connect to an Excel file. You must diagnose the error and repair the code.TasksStart Visio and open the file Lab 3.8 Start.vsd. The following error message appears.Select Debug and review the comments in the code. Recode the CreateLink procedure to load the DataRecordset properly.Exercise 2: Link the Instructor shapes to rows in the Teacher DataRecordsetScenarioThe Instructor shapes must be linked to their respective rows in the Teacher DRS in order to later drop the Section shapes properly.TasksLook at the macro LinkSelectedInstructors. It is incomplete. Read the comments in the code and complete the macro.Exercise 3: Drop and link the Section shapes to the rows in the Section DataRecordsetScenarioThe macro DropSectionShapes will drop a Section shape for each record in the Section DRS.TasksFind the macro DropSectionShapes. It is incomplete.Read the comments in the macro and complete the code.Exercise 4: Change the external data, refresh the drawing, and manage changes required by the dataScenarioChange the Excel file containing the Section data so that some new records are added, some existing records are deleted, and some existing records are changed. Refresh the DataRecordset from the user interface. You find that the conflicts are not being refreshed correctly.TasksLook at the event procedure sectionRecordset_DataRecordsetChanged. This event procedure listens for changes to the DRS and then evaluates and processes the changes. It adds new Section shapes for each new record added, deletes Section shapes for any deleted records. You will find that the updates are not happening properly. Your task is to figure out why and make the necessary changes.Additional Resources – External DataWhat’s New for Developers in Visio 2007 (Part 1 of 2)This article introduces new features of interest to developers in Microsoft Office Visio 2007 and explains how to use them. Author: Saul Candib.’s New for Developers in Visio 2007 (Part 2 of 2)This article describes all new objects and members of the Visio 2007 VBA object model and newly deprecated existing members. Author: Saul Candib. Developer Portal Visio 2007 and Microsoft SQL Server 2005Learn how you can integrate Microsoft Office Visio 2007 with Microsoft SQL Server 2005, to create data-driven diagrams from stored SQL data. Visio 2007 and Access 2007Use Automation code to create a Visio drawing from data defining the contents of a drawing and the connectivity between shapes stored within Access tables. 2010 Beta: Software Development KitThe Microsoft Office Visio Software Development Kit (SDK) contains the latest documentation, samples, header files, libraries and tools that you need to develop custom solutions for Microsoft Visio. As of this writing the 2010 Beta version was the latest version available. Connecting to Data in Visio Linking Shapes to Data: Managing External Data SetsQuestionsWhat are the three methods of the DataRecordsets object for creating new datarecordsets?What is different about the datarecordset created using the AddFromXML method?Where can the connection string be found in the object model?Where can the command string be found in the object model?When adding a datarecordset, how is the primary key set?Which property of the DataConnection object is key to catching errors thrown when a data source cannot be reached?True or False. When creating and linking shapes using the DropLinked and DropManyLinkedU, the shapes are created and linked at the same time, but a data graphic has to be added as a separate step.True or False. A shape can be linked to multiple datarecordsets with a single command.True or False. To link multiple shapes to a single row you can use the Shape.LinkToData method multiple times.How does a programmer reliably detect when a shape link has been broken, either through programmatic actions or through user actions.True or False. GetAllRefreshConflicts can be used by the programmer to discover all changes that occur during a refresh operation.How does the programmer control display of the Refresh Conflicts task pane?True or False. The DataRecordsetChanged event will fire immediately following the Refresh method.AnswersAdd, AddFromConnectionFile, and AddFromXMLIt is a connectionless datarecordset.It is in the DataConnection object which is part of the DataRecordset object.The DataRecordset object.The primary key is set as a separate step from the Add. Use the SetPrimaryKey method of the DataRecordset object.Set the Timeout property. When the interval is exceeded and error is thrown.FalseFalse. The LinkToData method must be called once for each datarecordset.True. This will work, but use the Selection.LinkToData to do it in one step.Use the ShapeDataLinkDeleted event.False. This only gives information on conflicts. Use the DataRecordsetChanged event and DataRecordsetChanged object to get additional data on records added or deleted and columns changed, added, or deleted.vsoDataRecorset.RefreshSettings = visRefreshNoReconciliationUIFalse. There can be a time lag between the Refresh and the firing of the event which means code following the Refresh may execute before code in the event procedure. Put any conflict resolution code or code that looks for datarecordset changes inside the event procedure.Visio Software Development Kit (SDK)This module covers all aspects of the Visio 2010 SDK. The SDK is made up of code samples, sample applications, tools, and documentation to support developers creating shapes, creating code, and delivering their own custom solutions on Visio. Note: At the time of this writing the Visio 2010 SDK was still in beta. Little of the documentation has been updated and some sample files have not been released and therefore are not covered. The reader may find differences between the discussion in the final version when the RTM version of the SDK is released. Hopefully those differences will be minor.Module ObjectivesAfter completing this module you will be able to:Understand all of the parts that make up the Visio SDKUse the tools delivered with the SDK to aid in manage events and publish solutionsUse the sample code from the code library in your own programs Use the sample applications as examples for creating add-ins and add-ons for VisioLesson 1: Setup / OverviewThe Microsoft? Office Visio? 2010 Software Development Kit (SDK) contains the latest documentation, samples, header files, libraries, and tools that you need to develop custom solutions for Microsoft Office Visio 2010.Visio SDK 2010 ContentsTo open the Visio 2010 SDK, click Start > All Programs > 2010 Microsoft Office Developer Resources > Microsoft Office Visio 2010 SDK.The Visio 2010 SDK includes:Microsoft Office Visio Code Samples Library. A database of Visio code samples. In the Code Samples Library, you can select a code item from the tree-view Explorer window, or you can search and select the desired code item from the Search Results tab. You can use the Code Samples Library to view and copy many reusable classes, functions, and procedures. To open the Code Samples Library, click the Start button, point to Microsoft Office 2010 Developer Resources, then point to Microsoft Office Visio 2010 SDK, and then click Microsoft Office Visio Code Samples Library. Sample applications.?? The provided sample applications can be used to experiment and to become acquainted with features. These sample applications are written both to demonstrate aspects of developing on the Visio platform and to be used as a starting point for your custom applications. Tools.?? Customization and extensibility tools are provided to increase your productivity and reduce development time. These tools include the Persistent Events, Print ShapeSheet, Solution Publishing, and Event Monitor tools. The SDK also includes wizards to set up new Visio add-ons and Component Object Model (COM) add-ins in Microsoft Visual C#?, Microsoft Visual Basic? .NET, Microsoft Visual C++? and Microsoft Visual Basic?. Documentation?? The documentation includes the full set of Visio references and articles. You do not need to have the Microsoft Office Visio 2010 application installed on your computer to be able to install the Visio 2010 SDK; however, for selected code samples or tools to run properly, Visio is required. Locating the SDK Files By default, the Visio 2010 SDK is installed in the following folder:C:\Program Files (x86)\Microsoft Office\Office14\visSDK\ for the 32 bit version of the Visio SDK.To uninstall the SDK at any timeIn Control Panel, click Add or Remove Programs, click Microsoft Office Visio 2010 SDK, and then click Remove. Software Requirements for Visio 2010 SDK Tools and Samples Although you do not need to have Visio 2010 installed on your computer to be able to install the Visio 2010 SDK, the following tools and samples will not run correctly unless the following software dependencies are met. Table 2. Visio 2010 SDK software requirements for tools and samples Tool or sample Software requirementsPersistent Events tool Visio 2010Event Monitor tool Visio 2010Print ShapeSheet toolVisio 2010Visio Solution Publishing toolVisio 2010Microsoft Visual Studio 2005 Visio Add-in wizardMicrosoft Visual Studio 2005Microsoft Visual Studio 2008 Visio Add-in wizard Microsoft Visual Studio 2008Microsoft Visual Basic 6.0 Flowchart sample applicationVisio 2010 Microsoft Office Excel 2007Microsoft Office Word 2007 (to embed the drawing into a Word document)Microsoft Visual Basic .NET Flowchart sample applicationVisio 2010Excel 2007Word 2007 (to embed the drawing into a Word document)Microsoft .NET Framework 1.1 or Microsoft .NET Framework 2.0Visual Studio .NET 2005 or Visual Studio 2008C# Flowchart sample applicationVisio 2010Excel 2007Word 2007 (to embed the drawing into a Word document)Microsoft .NET Framework 1.1 or Microsoft .NET Framework 2.0Visual Studio .NET 2003 or Visual Studio 2005C++ Flowchart sample applicationVisio 2010Excel 2007Word 2007 (to embed the drawing into a Word document)Visual Studio .NET 2005, Visual Studio 2008, or Visual C++ 6.0 (Service Pack 3 or later)TreeView sample applicationVisio 2010Microsoft .NET Framework 1.1 or Microsoft .NET Framework 2.0Visual Studio .NET 2005 or Visual Studio 2008 (to build the sample code)Office Plan sample applicationVisio 2010Microsoft .NET Framework 1.1 or Microsoft .NET Framework 2.0Visual Studio .NET 2005 or Visual Studio 2008Visio 2010 Code Samples Library Visio 20102007 Microsoft Office SystemKnown Issues and NotesSome sample applications and code samples in the Visio 2010 Code Samples Library require the installation of Microsoft Office applications or Visio 2010 solutions and wizards. See Visio 2010 SDK Samples located in the Samples folder in this SDK for more information about specific requirements.In versions of Visio previous to Visio 2007, Shape Data was called Custom Properties. In the Visio 2010 SDK, these terms are used interchangeably; they both refer to the concept of attaching user data to Visio shapes. In order to compile SDK samples in Visual Studio running on the Microsoft Windows Vista operating system, you must have administrative rights in Visual Studio. Microsoft SQL Express 2005 is available as a free download at the following URL: . DocumentationThis documentation contains reference material describing the Visio 2010 Automation Interface, the Save as Web Page Interface, the ShapeSheet interface and the XML schema documentation.Visio 2007 Automation ReferenceProvides an overview of Automation in Visio. It includes information about the Visio object model, the Visio type library, and about extending the functionality of Visio with macros, add-ons, and COM (Component Object Model) add-ins. A sample Microsoft Visual Basic for Applications (VBA) macro is also provided. This reference provides details on Visio objects, properties, methods, and events.Save as Web Page ReferenceProvides an overview of using the Save as Web Page API with Microsoft Office Visio 2007. Details about the Save as Web Page methods, objects, enumerations, and properties are provided. There is also an example of a Microsoft Visual Basic example of the Save as Web Page object model.ShapeSheet ReferenceProvides an overview of the ShapeSheet spreadsheet in Visio, including information about working with formulas, strings, date and time values, units of measure, and information about common ShapeSheet tasks, such as adding and deleting ShapeSheet sections and referencing cells from formulas. Details on each section, row, and cell in a ShapeSheet spreadsheet and details on functions you can use in formulas are provided. XML ReferenceProvides an overview of XML for Visio. Detailed information is provided for the XML for Visio schema, inheritance, working with sheets and formulas, geometry, text, loading XML files created outside Visio, round-tripping XML data, embedding custom XML data, units of measure, and errors and warning messages.ContainersFolders Installed with the Visio 2010 SDKThe following table describes the folders that are installed with the Visio 2010 SDK. Table 1. Visio 2010 SDK foldersFolder nameDescription\Docs \References and articles\Libraries\Support files \Samples \Sample applications that demonstrate how to use the Visio programming model \Tools \Development, customization, solution-publishing, and extensibility tools \Wizards\ Wizards to simplify developing Visio applications Docs foldervisSDK.chm – entry point into help files for Visio 2010 SDK DocumentationLibrariesCPP folder – C and C++ filesIncludeAddSink.h – contains the prototype for the event call back function (VISEVENTPROC) along with the class definitions for VEventHandler and CVisioAddonSink.Helpers.h - contains the definitions of helper classes to be used with the wrapper code in Visiwrap.h. You can choose to use no helpers, or non-MFC helpers or MFC-aware helpers.Ivisreg.h - contains helper functions for launching the Visio application.Vaddon.h - contains the definition of a superclass for Visio add-ons.Vao.h - contains definitions that define the interface between Visio and VSLs.Visio.h - this ALWAYS GENERATED file contains the definitions for the interfacesVisio_i.c - this ALWAYS GENERATED file contains the IIDs and CLSIDsVisiwrap.h - contains a set of wrapper classes and their implementations for the Visio automation APISourceAddSink.cpp - contains implementation of Visio's Advise Sink event handling.Helpers.cpp - contains the implementation of helper classes to be used with the wrapper code in Visiwrap.h.Ivsireg.cpp - contains helper functions for starting Visio and getting access to the IVisioApplication interface.Vaddon.cpp - provides the entry point for a Visio VSL. It also provides an add-on 'manager' superclass called VAddon. You can use VAddon as the base class for Visio add-ons.Vao.c - This file provides implementations for the routines prototyped in vao.h.Vdllmain.c - contains an implementation of DllMain for Win32 VSL's.Vexe.cpp - implements the standard Windows message loop and window procedure for EXE based VAddon subclasses. It allows VAddon-derived classes to be compiled into an EXE with no additional effort.TypeLib folder – contains the following type library filesVisio.tlb – 2010 type librarySaveAsWeb.tlb – Visio 2010 Save as Web type libraryVisOCX.tlb – Visio 2010 Drawing Control type librarySamplesThe Samples folder contains the Code Samples Library folder which contains a .chm file with many examples of common tasks done in Visio through automation. Directions are provided on how to copy code directly from the help file into your project.It also contains three complete projects:FlowChart - shows how to create a Component Object Model (COM) add-in that automates the creation of a flowchart drawing from a Microsoft Office Excel? spreadsheet, uses command bars in the Visio user interface, and publishes the drawing to the Web or to a Microsoft Office Word document. The code is available in C++, C#, VB, and VB .NET.OfficePlan - shows how you can use the Microsoft? Visio? 2010 Drawing Control to create an application that takes advantage of the drawing features of Microsoft Visio 2010 in a Microsoft Windows Form. The sample application can be used to select furniture from an inventory list and plan the space for a conference room or office. The code for this application is in C#.TreeView - shows how to create a hierarchical drawing and its accompanying tree view in Microsoft? Office Visio? 2010. The sample application provides a summary view of a drawing that has many shapes and which therefore can be hard to view on the page. The sample application is a Visio COM add-in, written in Microsoft Visual Basic? .NET. Note: The final Visio 2010 SDK is expected to have a new VSTO Add-in Sample Application that uses a "ClickOnce" post-deployment action to install Visio template and stencil files and also samples for API functionality added in Visio 2010.ToolsThis folder contains Help files and for using a set of tools provided with the Visio 2010 SDK:Event Monitor – tool that monitors events that are fired by an instance of Visio and reports events based on options you select in the Event Monitor user interface.Persistent Events - provides a user interface that lets you add persistent events in an active Visio document and modify existing persistent events.Print ShapeSheet - provides a user interface that lets you print ShapeSheet data for one or more shapes, a document, or a page, or lets you print ShapeSheet data for all document styles.Solutions Publishing – tool that provides a user interface that lets you generate entries to insert in the PublishComponent table in a Windows Installer (.msi) file for publishing Visio content. Note: Each of these tools is covered in more detail later in this module.WizardsThe Visio 2010 SDK contains two add-in wizards, one for Visual Studio 2005 and the other for Visual Studio 2008. These wizards create a shell add-on or add-in project in Microsoft Visual Studio? .NET 2003, in Microsoft Visual Basic? .NET, Microsoft Visual C#?, and Microsoft Visual C++?, to help speed the development process and demonstrate suggested practices for developing Visio add-ons or Component Object Model (COM) add-ins. Note: This tool is covered in more detail later in this module.TypeLibs IncludedThe Microsoft? Visio? 2010 Software Development Kit (SDK) provides type libraries for three application programming interfaces (APIs) that Microsoft Office Visio 2010 exposes. The following type libraries are included in the TypeLib folder, the path to which is SDK\Libraries:Library ContentsVisio.tlbVisio type librarySaveAsWeb.tlbSave as Web type libraryVisOcx.tlbMicrosoft Office Visio Drawing Control type library Visio type libraryAn overview of the Visio type library was given in the beginning of Volume 3 of this course.Save As Web type libraryThe Save As Web interface is not covered in this class, but there is a good example of how to use it provided in the Flowchart sample program in the SDK. The Flowchart sample uses this interface to save Visio drawings as web pages.Visio Drawing Control type libraryThe Visio Drawing Control can be used to embed the full functionality of the Visio drawing surface into your applications. You can take advantage of the full Visio object model (API) and you can pick the aspects of the Visio user interface you want to expose to better integrate Visio seamlessly into the user interface of your application.Use of the Visio Drawing Control will be covered in the next module of this course: Module 5: Visio Drawing Control Changes from Visio 2010 SDKThe following are changes to the SDK since the 2003 version.Shape Studio has been removed Visual Studio 2005 and 2008 Add-in WizardsThe Visio SDK installs wizards for creating Visio add-on projects in Microsoft Visual Studio 2005 and Microsoft Visual Studio 2008. These Wizards let you set up new Visio add-on projects in Microsoft Visual Basic .NET, Microsoft Visual C#, and Microsoft Visual C++, and create corresponding setup programs to install add-ons. Once you have used the wizard to create a Visio project, you can explore the project code and settings to learn more about how Visio add-ons should work. Microsoft Visual Studio 2010 also includes wizards to generate Visio 2010 VSTO add-in projects. The Visio SDK is not required to use these wizards.The Visio projects that you create by using this wizard are compatible only with Microsoft Office Visio 2003 or later. They will not work with other versions of Visio.Projects created by these wizards provide examples of recommended Visio development practices. Once you have used the wizard to create a Visio project, you can explore the project code and settings to learn more about how Visio add-ons and add-ins should work. Depending on the programming language that you choose with this wizard, you can create different types of projects. When you use the wizard for the Visual Basic .NET or C# programming languages, you can create projects of the following types:Executable add-ons (EXEs) COM add-ins (DLLs)When you use the wizard for the C++ programming language, you can create projects of the types listed previously as well as VSL add-ons. In the next steps we will build an add-on without the wizard and then build one with the wizard and contrast the two projects in Visual Studio.Try it! Create a project using the Windows Application template.We will contrast this with using the add-in wizard afterwards.Create a simple Visio add-on as a Windows Application. This add-on will start Visio, open a stencil and build a simple flowchart. Follow the directions from the article How to Automate Visio with Visual Basic .Net listed in the REF _Ref163356044 \h Additional Resources section of this module. Note: This example is a little out of date. Add a reference to the Visio 2010 type library instead of Visio 2002. Second, you will need to add one line of code at the beginning of Module1 to work with the Visio 2010 PIAs. See the next step for details. Third, there are a couple of uninitialized variable warnings that should be fixed.To make this example work with the Microsoft Office PIAs, add the following line of code at the beginning of Module 1.Imports Microsoft.Office.Interop Note: A finished example of this project is in the Samples folder for this course under the folder WindowApplication1.Copy the WindowApplication1.exe file to the desktop.From Visio modify the add-ons file path to include the Desktop. Close Visio.Restart Visio and run the add-on from the Tools menu.Try this! Create an add-on project using the Visio wizard for Visual Studio.Create another project using the Visio add-in wizard. Choose File > New > Project… This opens the New Project dialog. Give the Project and the Solution a name such as MyAddOn.Under Project Types choose Visual Basic.Under Templates choose Visio add-in or add-on. This starts the wizard. Choose Next.For the add-on type choose Create a Visio EXE add-on. Choose Next.Choose Finish to close the wizard and create the project. The default project displays the argument string that is passed to the add-on in a dialog box. We won’t change the default code.In Visual Studio build the project, Build > Build MyAddOn. This creates an .exe file in the project bin folder.Copy MyAddOn.exe to the desktop and make sure the add-ons paths in Visio is set to search this folder. You may have to restart Visio in order for the add-on to show in the Tools menu.From Visio run the add-on from the Tools menu: Tools > Add-Ons > MyAddOn. The add-on will display the dialog below.Add a shape to the drawing and run the macro from the double click event of the shape. You can use the Format > Behavior dialog or enter the formula =RUNADDON("MyAddOn.exe")directly in the EventDblClick cell in the ShapeSheet. Double click the shape. The add-on will display a dialog similar to the one below. Note: An add-on can be run when a cell formula is evaluated. When this happens, Visio automatically sends a command string to the add-on with the following information: /visio=instanceHandle /doc=docIndex /page=pageIndex /shape=NameIDThis information can be used by the add-on to access the shape that caused the add-on to execute.Try it! Create a COM Add-in project using the Visio wizard for Visual Studio.Create another project using the Visio add-in wizard. Choose File > New > Project… This opens the New Project dialog. Give the Project and the Solution a name such as MyAddIn.Under Project Types choose Visual Basic.Under Templates choose Visio add-in or add-on. This starts the wizard. Choose Next.For the add-on type choose Create a Visio COM add-in. Choose Next.Give the add-in a meaningful name and description. Choose Next.Select Load the add-in when the Visio application loads. Choose Next.Choose Finish to close the wizard and create the project. The default project will display a message box when the add-in is loaded.In Visual Studio build the project, Build > Build Solution. This adds the generated .dll to the Windows registry.Close Visio and then start Visio. The add-in loads when Visio starts and displays the message “MyAddIn connected”.Contrast the three projects in Visual StudioLet’s take a look at these three projects.Using Windows Application templateThe project is a bare bones project when it is created. A default form is created, but that is about it. The developer has to do everything else. In this example we completed the form and then added a module and code that launched Visio and built the drawing. The form is the startup for the application by default, but you can change this in the Project Properties window.There is also no setup project created for us.Using the Visio template to create an .EXEA default project is built with code that parses the command string that is sent to the add-on. When creating your own add-on this code can be deleted if it is not needed by the add-on. In addition to this code, the following is created as part of the project. There is a main procedure in VisioEXEAddon.vb that serves as the startup location for the project. Whether a form is displayed is controlled by this code.There is a setup project constructed by default.There is a default application icon file.There is a default assembly created and default project resource strings.Using the Visio template to create a COM add-inA default project is built with code that displays a message box when the add-in is first loaded. Also created for this project: A Connect.vb module. This module contains code that implements the interface for connecting to a COM add-in.There is a setup project constructed by default.There is a default assembly created and default project resource strings.Lesson 2: ToolsThe Visio 2010 SDK comes with a set of tools to aid developers in managing events and publishing solutions. These tools can all be found in the SDK Tools folder. The Event Monitor, Persistent Events tool, and Print ShapeSheet can all be started from the Developer tab in Visio once the SDK is installed. The Solution Publishing tool can be started from the SDK or from the Start menu.Lesson ObjectivesAfter completing this lesson you will be able to:Use the Event Monitor tool to track events fired in Visio Use the Persistent Events tool to add, edit, or delete persistent events in drawingsUse the Print ShapeSheet tool to write the ShapeSheet data to the Clipboard, to a file, or to the printerUse the Publish Components tool to bind stencils, template, drawings, and other files to a Visio solution that you createEvent MonitorThe Microsoft? Visio? Event Monitor tool watches for events that are raised in an instance of Visio and logs all events of the types that you specify in the Event Options dialog box. The Event Monitor can help you determine which events to handle in your own solutions. The Event Monitor uses the AddAdvise method of the EventList collection of the Visio Application object to monitor and report events by the Visio Application object. The Event Monitor reports all events that are sourced by the Application object, except for events that are raised by keystrokes and targeted at an add-on window (the OnKeystrokeMessageForAddon event). For the list of events that the Visio Application object can raise, see the Microsoft Office Visio Automation Reference. (On the Help menu, click Developer Reference.) Note: Because the Event Monitor runs in a separate process from Visio, depending on the order in which processes are suspended, the Event Monitor may be suspended before Visio and, hence, may not monitor and report the BeforeSuspend, QueryCancelSuspend, and SuspendCancelled events, even if you include them in the Events to monitor list. To start the event monitor from Visio choose Developer > Event Montior.The Event Monitor tool automatically connects to a running instance of Visio, or if Visio isn't already running, the Event Monitor starts a new instance of Visio. When the Event Monitor starts, the log displays the following information: The version of Visio that it has connected to or started The Microsoft Office Visio Type Library version number The process ID of the Visio instance The list of monitored event types and their status; that is, that they are set to be monitored. Event types previously set to be ignored in the Event Options dialog box are not listed at startup. When all events in the Visio events queue have been processed, Microsoft Visio fires the NoEventsPending event. When Visio has emptied its message queue, Visio fires the VisioIsIdle event. When there has been no activity in Visio for a time, you will see these two events at the bottom of the list in the event window. When a monitored event fires, the Event Monitor tool displays its name and, depending on the event and your Event Monitor settings, additional data about the event. For example, if you drag a Rectangle shape onto the drawing page, the ShapeAdded event fires. In the log window, the Event Monitor reports the event firing as follows:21365 | ShapeAdded Rectangle [/doc=1 /page=1 /shape=Sheet.1] In this log entry: 21365 is the event sequence number, which is determined by the number of events that have fired since Visio was started. Visio gives each event a unique sequence identifier to distinguish between separate firings of the same event, and then passes that number as one of the arguments to the VisEventProc function you write to handle that event. ShapeAdded is the name of the event that fired. Rectangle is the name of the master of the shape that was added. Within the brackets, the Event Monitor tool displays the index number within the Documents collection of the document in which the event fired, the name of the page where the shape was added, and the name of the shape itself. Information within the brackets is displayed only if the Include additional event information box is selected in the Monitor Options dialog box. Demo: Use Event Monitor to track actions in VisioStart the Event Monitor from Visio. It lists the events being monitored and then lists results for each new event as it fires. Note that there are a lot of MouseMove events every time the cursor moves in the Visio window.From the Event Monitor choose Tools > Event Options. Remove MouseMove from the list. There are still a lot of events firing when the mouse moves. Stop monitoring MustFlushScopeBeginning, MustFlushScopeEnding, and NoEventsPending. Now it is easier to see some of the other events that fire when an action occurs in Visio.Add a shape from a stencil.Copy and paste a shape.Duplicate a shape.Draw a shape using one of the drawing tools.Note that each of these actions causes a ShapeAdded event, but ShapeAdded doesn’t tell you how a shape was added. How can we distinguish between these actions?Note that there is always an EnterScope event that occurs for each of these actions and within the EnterScope event we can test the command ID that was just executed. Add a shape from stencil is done with command ID 1246 – Drop on Page. Paste a shape is done with command number 1022. Duplicate is 1024. Control drag duplicate is 1184. Drawing shapes with the drawing tools gives unique commands for each tool used. Therefore it is possible to tell exactly how any shape gets created! Tip:This is really handy if you want to do something different for shapes added to a drawing, depending on how they are added. Just be sure to test for performance as EnterScope gets called a lot!Close Visio. Note the message displayed in the monitor.Connection to Visio has been terminated.To restart Visio, click Tools, then click Connect to Visio.From the Event Monitor choose Tools > Connect to Visio. Visio is restarted and monitoring is resumed.About Using the Persistent Events ToolThe Persistent Events tool provides a user interface that enables you to add and modify persistent events in the active Microsoft? ? Visio? Document object's EventList collection.By persisting events in a document or template, you can make Visio run add-ons in response to user actions, usually when users create a Visio document based on a template or open a Visio document or template. The Persistent Events tool displays the list of events persisted in the active document or template and for each event, shows the add-on that runs when that event fires and any arguments passed to that add-on.For more information about persistent events in Visio, see the Microsoft Office Visio Developer Reference (on the Help menu, click Developer Reference). Many solutions that are a part of the Visio product persist events in their templates. For example, the DocumentCreated event is persisted in the Organization Chart template, and when this event fires, its action is to run the Organization Chart add-on. You can see evidence of this by opening a new or existing organization chart document (drawing) based on the Organization Chart template and then, after making sure that this document is active, opening the Persistent Events tool. In the tool's list of persistent events for the active document, you'll see a row that contains the following data: DocumentCreated OrgC11 /cmd=DocCreated On this line, DocumentCreated is the name of the persistent event that fired, OrgC11 is the universal name for the Organization Chart add-on in Microsoft Visio, and /cmd=DocCreated is the argument passed to the add-on by the event. Whenever a new document is created based on the Organization Chart template, the DocumentCreated event fires, calls the OrgC11 add-on, and passes the argument /cmd=DocCreated to the add-on to indicate that DocumentCreated was the event that fired. For add-ons to run and take the appropriate action, they must know which event fired. When writing an add-on solution, add persistent events that call your add-on in the Event Properties dialog box (which is accessible from the Persistent Events tool). In the Event Properties dialog box, in the Event box, you can select from the following list of persistable events sourced by the document object: DocumentCreated DocumentOpened MasterAdded BeforeMasterDelete PageAdded BeforePageDelete ShapesDeleted The Universal name list box is populated with the names of all add-ons in the Add-ons collection of the Visio Application object. To specify the add-on to run when the event fires, either select it from the list, or, for a new add-on, type its name. Note: You must first install the new add-on before persisted events will run it. Note: If the add-on's name you type doesn't exist, Visio doesn't display an error message; however, you can use the TraceFlags property of the Application object to view errors in the Immediate window. Optionally, pass an argument to the add-on. When the event you selected in the Event list fires, the value you enter in the Argument box gets passed to the add-on; you can use it to inform the add-on which event called it. This feature is useful if the add-on needs to handle different events differently. For example, you may want your add-on to respond differently if a new document is created than if an existing document is opened. You can also use the Persistent Events tool to edit existing persistent events, for example, to change an argument string, or to delete persistent events. Try it!Create a new organization chart drawing in Visio.Start the Persistent Events tool: Developer > Persistent Events. The dialog below is displayed. Note that the DocumentOpened and DocumentCreated events are persisted in the organization chart template.Add a new persistent event for PageAdded and hook the event to the add-on created in the last section of this module, MyAddon. This add-on displays the command string passed to it. You should see something similar to the dialog below.Persistent Event information in the Visio object modelPersistent Events can be added, edited, and deleted by using the Visio object model. The Event object has a Persistable property (read-only) and a Persistent property (read-write). Set the Persistent property to True. The Target and TargetArgs properties contain the add-on name and the argument string. The Event property of the Event object contains the event code, e.g., the code for PageAdded is visEvtAdd+visEvtPage. Note: There is a known problem that causes an overflow error when working with event codes with values greater than &H8000. To get around the problem pass the event code argument using the hex representation instead of the Visio constants.Try it!Open PersistentEvents.vsd from the Samples folder. This drawing was created from an organization chart template so it already has some persistent events in it.Start the Persistent Events tools and view the existing persistent events.Run the macro PrintPersistentEvents. This prints the persistent event information from the object model to the Immediate Window. View the code.Run the macro EditOrAddPersistentEvent. This will edit an existing PageAdded persistent event if it exists or add it if it does not. View the code.Print ShapeSheetThe Microsoft? Visio? Print ShapeSheet tool provides a user interface that lets you print ShapeSheet spreadsheet information for one or more selected shapes, a Visio document, the styles defined in the document, or the current drawing page. You can send the result to the Clipboard, a file, or a printer. You can use the Print ShapeSheet tool to print data from various sections of the ShapeSheet and to search for cell references and dependencies in various formulas. To start the Print ShapeSheet tool, from Visio choose Developer > Tools > Print ShapeSheet. The Print ShapeSheet dialog is displayed below.Under Sheet type: choose from: Selected shapes, Document, Styles, Page, and All Shapes. The default choices under Include sections will change depending upon the choice made. Use this section to choose which ShapeSheet sections are to be captured in the output.Under Send to: choose from File, Clipboard, and Printer.If there are grouped shapes on the drawing page and you want to print data for individual shapes within groups, select Include group subshapes.Sample output that was sent to a text file is shown below.Note that both a cell’s value and it’s formula are included.Publish ComponentBeginning with Microsoft Visio 2003, you can publish your add-ons, templates, stencils and other files as components to be integrated with the Visio application. Publishing components is the preferred method of integrating add-ons and other content with Visio. It offers tighter integration with the Visio application, and better performance on add-on discovery. The publish component functionality enables developers to include a PublishComponent table in the Microsoft Windows Installer file that they create to install content (such as add-ons, templates, stencils, or other files). Each PublishComponent table entry contains information pertaining to how a specific file to be installed should be displayed in the Visio user interface. During installation, these entries are published to the Visio registry. Visio uses this information to display the add-on in its user interface, and install on-demand or repair the file as needed.Publishing Content Tip:The following content is derived from the Visio Insights blog produced by the Visio team at Microsoft. This is a great source of practical “how to” information.Publishing a piece of content to Visio adds entry points to the user interface side-by-side with content created by Microsoft. For a stencil this translates into a menu entry added to the File > Shapes fly-out menu while for a template this means an entry in Visio’s startup screen (as seen below) and in the File > New fly-out menu. ??Method #1: Sharing Templates using Path DiscoveryThe simplest way to publish a template to Visio is to use the Path Discovery method described below:Copy your template and supporting stencils to a known location on a drive.Add the location defined in step 1 to Visio’s “Template Paths”; this tells Visio where to find extra content to populate its startup screen. Restart Visio – your template should appear in the (Other) category.The advantages of this approach are:It is simple.It is supported across most versions of Visio. It however has a few drawbacks:Your users may be subjected to potentially long and error prone manual work. Your templates will always end up in the (Other) content category in the startup screen. You don’t have any way of repairing content on a user’s machine if it gets damaged.You cannot control which language of Visio will load your stencils and templates. This approach does not scale well. The Path Discovery publishing method does just that: every time you boot Visio it searches a user’s hard drive for content files – an expensive operation. Sharing templates through Path Discovery is good for small scale content deployments as well as deployments to older versions of Visio.Method #2: Sharing using the PublishComponent SystemThe PublishComponent system introduced in Visio 2003 lets developers use Windows Installer technology for template distribution to register their content with Visio in a rich and robust way. The main advantages of this method are quite interesting:The Windows Installer setup wizard is familiar to users and easy to use.You benefit from Windows Installer repair, install-on-demand and add/remove features. You may choose what language versions of Visio to publish your content to. The approach scales well: Visio only rebuilds its content cache, a moderately expensive operation, when new content is published. The approach is tried and tested since the product publishes its own content this way since the 2003 release. That said, using the Publish Component system is:A little more complicated than the Path Discovery method.Will only work for Visio 2003 and or later.To use this method you’ll need Visual Studio .NET or later, the Visio 2003 SDK or later. Try it!Create a simple template and stencil that will be added to the published solution. Save the files.Create a setup project in Visual Studio. Select the "Application folder" and change its default location property to your target install location. Add your template and their supporting stencils to this location by dragging files into the folders. Your project should look something like the figure below at this point.?Build the project. This will produce an MSI file - a multi-table installation database that is used by windows to coordinate setup.Install the package as is. Visio will not discover the files the MSI installed. To notify Visio on the whereabouts of these files, the next thing to do is populate the PublishComponent table of the MSI produced above with registration data. Once installed, this extra information will force Visio to rebuild its content cache and incorporate and display the new templates and stencils.Start the Solution Publishing Tool that is included with the Visio SDK (a.k.a the publish component tool). This tool may be found in the Start menu entry for the Visio SDK. On the File menu, select New. It will prompt you for an MSI. Navigate to the one that you've just built. This will present the Visio Files that are in MSI. You must now, for each entry: Set the LCID of the language for which you want the templates to be accessible in. Do the same for the supporting stencils. Set the position in the Visio startup screen hierarchy you want the template to live in. This is defined by separating different levels of the hierarchy by “\” symbols for example: “MyTemplateCategory\MyTemplateSubCategory\MyTemplateName”. Do the same with the supporting stencils, setting their location in the File > Shapes fly-out. Note: For VSL files that contain more than one add-on, select the file in the list and click Add Add-on on the Edit menu to specify information about the additional add-ons implemented in the VSL.To make the changes described above double click on each entry to bring up the “Template Information” dialog seen below, or its counterpart the “Stencil Information” dialog.?Press the "!" button in the tools toolbar; this will make modifications to the MSI's Publish Component table. Install the MSI.The MSI can now be distributed; Windows Installer and Visio will do the rest. Although we haven’t discussed it here, the same techniques can be used to publish add-ins and help files. Lab 3.8: Build and run the Visio SDK Flowchart sampleDuring this lab, you will:Build and install the SDK Flowchart sample add-on for Review the basics of how this sample application is put togetherEstimated time to complete this lab: 60 minutesBefore You BeginTo complete this lab, you will need:Participants should have completed the review of this module before completing this lab.Visio 2010 SDK installed and configured.Software required for the SDK Flowchart code sample:Visio 2010 Excel 2007Word 2007 (to embed the drawing into a Word document)Microsoft .NET Framework 1.1 or Microsoft .NET Framework 2.0Visual Studio 2005 or laterWhat You Will LearnAfter completing this lab, you will be able to:Build and run the Flowchart example from the Visio 2010 SDKUnderstand the software architecture for this sampleExercise 1: Build and run the Flowchart () sample code from the SDKScenarioBuild the Flowchart code sample in Visual Studio, install the COM Add-in, create a drawing from the Flowchart(VB .NET) and run.TasksCopy the project files from the SDK folder to the Visual Studio 2005 Projects folder. From the SDK folder you can copy everything from …\visSDK\Samples\Flowchart.In the Visual Studio 2005 Projects folder double-click …\FlowChart\VBNet\Visual Studio 80\FlowchartSample.sln to open the project in Visual Studio 2005.In the Solution Explorer window right-click on FlowchartSample and choose Build.In the Solution Explorer window right-click on FlowchartSampleSetup and choose Build. This creates FlowchartSampleSetup.msi in the \Visual Studio 80\bin\Debug\Setup folder.Double-click FlowchartSampleSetup.msi to install the COM Add-in.Start Visio and verify the add-in is loaded.Choose File > Options > Add-insFind FlowchartSample () in the Active Application Add-ins listCreate a new drawing from the Flowchart () template, File > New > SDK > Samples > Flowchart (). The following dialog will be displayed:Choose Yes. The add-in will build a multi-paged flowchart. Choosing No will do the same thing, but screen updating is turned off so you won’t see anything until the process is complete.Note that a new toolbar has been created: SDK Flowchart Publication. It has two buttons for publishing the drawing to Word and publishing the drawing to the web.Click the button to publish to Word. This copies the active page to a Word document. To put the other pages into Word you would need to go to each page individually and click the button to publish to Word.Click the button to Save Document as a Web Page.Right-click a flowchart shape and choose Number Of Connections… This command displays a message box show the number of connections and the name of the connectors glued to the shape.Exercise 2: Code review.ScenarioThis is a high level break down of how the add-in has been architected.Code componentsConnect.vbThis class implements the IDTExtensibility2 interface, allowing it to serve as a COM add-in for Microsoft Office Visio and initializes the Visio Application object's EventList with events, for which the Flowchart Sample add-in will listen.EventSink.vbThis class is an event sink for Visio events. It handles events from Visio which were specified using AddAdvise. It handles event notification by implementing the IVisEventProc interface, which is defined in the Visio type library.In order to be notified of events, an instance of this class must be passed as the EventSink argument in calls to AddAdvise. The Flowchart Sample calls AddAdvise once in Visio on the Connect module where it registers for Marker events sourced by the Application object. The code in this class processes marker events created by this Flowchart sample. It listens for three events:DocumentCreate – creates a new drawing when a user creates a new document based on the Visio SDK Flowchart Sample templateDocumentOpen – creates a custom command bar when a document created from the SDK Flowchart Sample template is openedhandleRightMouseClick – handles the case where the user does a right mouse click on a flowchart shape and chooses Number of Connections…DocumentCreator.vbThis class creates a Visio document containing flowchart drawings, based on data contained in a Microsoft Office Excel worksheet. The drawing process is driven by the CreateDrawing procedure which is initiated from the DocumentCreate event handler.CustomCommandbar.vbCreates the custom command bar "SDK Flowchart Publication" and adds it to the Visio CommandBars. It also contains methods to handle the click events for the buttons on the custom command bar.Publisher.vbThis class provides procedures to export a document to either a Web page or a Microsoft Office Word document.Shared.vbLow level shared utilities and constants.Assemblyinfo.vbProvides the assembly information for the Flowchart Sample Add-in.Other componentsFlowchart ().vst – Visio template file for creating the drawings.Flowchart.xls – Excel file containing the shape and connection information for the flowchart.Additional Resources - SDKIntroducing the Microsoft Visio 2010 Beta SDKVisio Insights blog about the first beta release of the 2010 SDK. 2007: Software Development KitThe Microsoft Office Visio 2007 Software Development Kit (SDK) contains the latest documentation, samples, header files, libraries and tools that you need to develop custom solutions for Microsoft Office Visio 2007. Office Visio 2007 SDK Release Notes 2003 Software Development Kit (SDK)The Visio 2003 SDK contains sample applications, code librarian code snippets, documentation, and tools, including the ShapeStudio, Event Monitor, Persistent Events, Print ShapeSheet, and Solution Publishing tools. 2002 Technical ArticlesTechnical articles from the Visio 2002 SDK. Many of the technical articles are still relevant, but they aren’t repeated in later versions of the SDK.(office.11).aspxVisio Developer Portal to automate Visio with Visual Basic .NETThis article demonstrates how to automate Visio using Visual Basic .NET. It does not use the add-in wizard for Visual Studio.: SDKQuestionsWhat kind of add-ins and add-ons can be created for Visio with the add-in wizard in the SDK.What versions of Visio do projects created with this wizard work with?What are some reasons for using the event monitor?What are persistent events?What is the advantage of using Publish Components over using Visio’s File Paths to detect file locations?AnswersDepending on the programming language you choose:VSL add-ons (can only be created with C++)Executable add-ons (EXEs) COM add-ins (DLLs)Only Visio 2003 and later.Discover what events fire when certain actions occur in Visio.These are actions defined to be kicked off when an event occurs. They are saved with the drawing and do not need to be reestablished each time the drawing is opened – thus they “persist”.It offers tighter integration with the Visio application, and better performance on add-on discovery.Visio Drawing ControlThe Microsoft??Visio? Drawing Control offers the full functionality of the Visio application through the rich Visio object model, as an embeddable component. You can drive the Visio drawing control programmatically by events or by code in your hosting application. Alternatively, the Visio drawing control can provide a diagramming environment for application users within the context of your own application's user interface (UI). Module ObjectivesAfter completing this module you will be able to:Describe how that drawing control can be used to provide a graphics rich application without using the Visio user interfaceIdentify the features of the Visio drawing control and example use scenarios. Describe best practices for creating new applications that use the drawing control. Embed the Visio drawing control in a variety of host applications.Use the properties of the Visio drawing control API to manage Visio from your host application.Deploy the Visio drawing control with your application. Lesson 1: ConceptsThe Visio Drawing Control is a Microsoft ActiveX control that provides full access to the Visio object model (API) and user interface so that you can integrate the Visio user interface, customize its appearance, and automate Visio in your applications. The Visio Drawing Control is provided with all version of Visio and is installed when you install Visio.The Visio Drawing Control allows the developer to provide Visio functionality within the context of another application. This level of integration allows the developer full control over the Visio user interface integration with the host application. The new functionality provides more power than just simply embedding a Visio drawing into an OLE container document, like Word. Using a Visio drawing as an OLE object allows you to view the diagram in the container application, link the OLE object to the actual Visio document to reflect changes, and edit the Visio drawing by activating the Visio application from within the container document.In the case of in-place OLE activation, you are still working within the Visio user interface. You cannot create your own UI. You are also limited to application hosts that implement an OLE container, which rules out technologies such as .NET Windows Forms. The Visio drawing control, however, provides functionality to address these scenarios, and allows you to develop new Visio solutions that go beyond creating add-ons and add-ins for Visio. With the drawing control you can create your own application with its own interface and be in control of how much of the Visio user interface is presented to the user.Lesson ObjectivesAfter completing this lesson you will be able to:Describe how that drawing control can be used to provide a graphics rich application without using the Visio user interfaceDescribe the requirements of deploying an application containing the drawing controlDescribe the types of container applications that can host the drawing controlRequirements / ContainersThe Visio drawing component is essentially an ActiveX? wrapper for the main Visio library. Like any ActiveX component, it can be embedded in custom host applications developed using Visual Studio .NET 2003 and later, Office 2003 and later containers (such as Microsoft Word), Microsoft Internet Explorer 5.5 and greater, and other ActiveX component containers. Although the component uses the ActiveX architecture, it is more of an embeddable application component than the typical ActiveX control found on a Web site. The Visio component provides the full functionality of the Visio application rather than a small subset of features. Because it essentially repackages the Visio application engine in a component, the Visio control is installed with the Visio application setup program and requires the Visio client application to initialize. If the user does not have the Visio client application installed on the machine, the control will fail to initialize in the host container. Host container applications that support the Visio Drawing ControlYou can embed the Visio Drawing Control in Microsoft Visual Basic 6.0, Microsoft Visual C++ 6.0, Microsoft Visual Studio 7.1 and higher, and other ActiveX control containers. However, you cannot embed the Visio Drawing Control in another Visio drawing, another ActiveX control, a Microsoft Visual Basic for Applications (VBA) form in Visio, or a Visio solution window.Security considerationsThe Visio Drawing Control is targeted for use in an intranet environment. The Visio Drawing Control does not support the IObjectSafety interface. Before it is run in any version of Internet Explorer, the control warns the user that it is an unsafe file (unless the end user's browser security level is set to Medium, Medium-Low, or Low). Run-time requirements and distribution of your applicationMicrosoft Visio must be installed on any computer where the Visio Drawing Control will be used. When you distribute your application, all users must have licensed copies of a version of Visio that supports the Visio Drawing Control on their computers to use it. Note: To install the Visio Drawing Control, install Visio. The Minimal Install option of Visio will install the Visio Drawing Control.Demo: Drawing ControlThe Office Plan Sample Application included with the Visio SDK shows how you can use the Drawing Control to create an application that takes advantage of the drawing features of Visio in a Microsoft Windows Form. The sample application can be used to select furniture from an inventory list and plan the space for a conference room or office. The sample creates a simple office floor plan that permits the end-user of the application, presumably a corporate administrative assistant, to do the following: Click any of three furniture shapes to add them to the drawing. View dynamically updated information about the furniture that has been added. View dynamically updated information about the total retail and wholesale costs of the current contents of the office plan. Save the results to a Visio drawing file and then re-open the file. The code for this sample application is written in the C# programming language, and is designed to work with Microsoft Visual Studio 2005 or Microsoft Visual Studio 2008. Demo of Office Plan sample from the SDK.The code for this sample is included in the Visio 2010 SDK. Programming features implemented in the Office Plan Sample applicationThis sample application shows how to do the following: Embed the Drawing Control in a Windows Form. Use the Drawing Control interactively Respond to various Visio events fired by user actions Use mouse events to capture the right-click actions on a drawing shape Use the MarkerEvent event and the EventDblClick ShapeSheet cell to respond to when the user double-clicks shapes in the drawing. Create a custom Windows form to display shape product information in an adjacent DataGrid control Use events to keep track of the shapes within the drawing and to calculate total price information for these shapes Save Visio drawings created by using the Drawing Control Open Visio drawings in the Drawing ControlTo build the sample code in the Office Plan Sample in Visual Studio 2005Double-click OfficePlanSample.sln in the following folder:C:\Program Files\Microsoft Office\Office14\VisSDK\Samples\Office Plan\CSharp\Visual Studio 80. Note: The folder path may differ depending on where the SDK was installed.In Visual Studio 2005, click Debug > Start Without debugging. The application is started. The application image is shown below.Add shapes to drawingClick on the furniture buttons on the form. A shape is added for each click. The drop location on the page is adjusted so that the shapes do not lie in exactly the same place.As each shape is added the Total Price figures on the form are updated and the Product data grid is updated. It maintains an accurate total of all of the shapes in the drawing.Keyboard shortcuts are availableMany Visio keyboard shortcuts are supported in the drawing control.Multi-select shapes and enter the keyboard shortcut Ctrl-G. The shapes are grouped together.Zoom in/Zoom out using Ctrl-Shift left mouse/right mouse.Zoom to whole page with Ctrl-W.Delete shapesDelete an individual shape from the drawing. Delete a grouped shape from the drawing. In both cases the Total Price and Products grid are updated.Save the drawingChoose File > Save… and enter a file name in the Save Visio Document dialog.Start a new drawingChoose File > New. A new blank drawing is created.Choose File > Open and open the file saved earlier. Try this! Application Architecture ReviewNow let’s take a look at how this application was architected. The following sections describe the structure of the Office Plan code sample. Go through each section and view the code and shapes to see how it works.Embed the Drawing Control in a Windows Form. When the application is started the frmOfficePlanSample form is displayed.In Visual Studio in the Solution Explorer window, right-click frmOfficePlanSample.cs and select View Designer. Right-click frmOfficePlanSample.cs again and choose View Code. Both the code and design view for the form are displayed.Look for the Main procedure in the code view of the form. This is the main entry point for the application. It creates a new instance of the form.Just above the Main procedure is the following code:public OfficePlanSampleForm() {// Initializing the components of the form is required for// Windows Form Designer supportInitializeComponent();}This code is executed when the form is created. The InitializeComponent procedure is code that is generated by the forms designer. It contains all form variable initialization, control initializations, and menu definitions.View the design view of the form. Click on the drawing control and scan its properties in the Properties window. Note its name.Click on the Events button in the Properties window for the drawing control. Scroll through the list and note there are two event procedures defined for the drawing control: MouseUpEvent and VisibleChanged.The code for the VisibleChanged event is in onDrawingControlVisibleChanged. This event is triggered initially when the form is created. Within the event procedure is a call to setUpVisioDrawing.Within setUpVisioDrawing is the code to establish the connection to the Visio application object. It hides all Visio docked windows and then turns off display of rulers, grid, page tabs, scroll bars. It then gets the viewing size of the window rectangle and does some calculations for positioning shapes when they are created. It then initializes an event sink to watch for Visio events with a call to initializeEventSink.Event managementWhen using the Office Plan application the user is directly interacting with the Office Plan application and indirectly interacting with Visio through the Visio drawing control. Events can be fired and listened to for both the Office Plan application and for Visio.For example, when the user clicks a button control in the Office Plan application, there is a click event that is triggered. This click event instructs Visio to add the appropriate shape to the page. The action of adding the shape to the page causes Visio’s shape added event to fire. The shape added event is used to keep track of the number of shapes in the drawing and keep the product information up to date.Why bother listening for Visio’s shape added event when we know that a shape is going to be added when we click the furniture button? If everything works perfectly you might can assume that a shape will be added and go ahead and process it, but in reality something might go wrong. For example, the stencil that contains the shape’s master may not be accessible by Visio and an error condition may be raised. It is best not to add the product information for a new shape until you are sure that the new shape has finished being added to the drawing. That doesn’t happen until the Visio shape added event is fired.Respond to Visio events fired by user actions The procedure initializeEventSink sets up for listening for events from Visio. This procedure is in frmOfficePlanSample.cs. The following events are established in the event sink:Shape add: OnAddProductInformation will be called when a shape is addedShape delete: OnRemoveProductInformation will be called when a shape is deletedMarker events: Used to trap double clicks on a shape for those shapes whose double-click event runs the QueueMarkerEvent addon. OnShapeDoubleClick will be called.The VisEventProc method also listens for Visio’s NoEventsPending which occurs after Visio has finished flushing its events queue. When a shape is added or deleted they are simply added to a queue of shapes that need to be processed to update the product information. When the event NoEventsPending is fired, the added and deleted queues are processed.During processing of the shapes added and shapes deleted queues the totals for Retail price and Wholesale price are updated on the form and the data grid is updated to reflect additions and deletions from the drawing. Use events to keep track of the shapes within the drawing and to calculate total price information for these shapesIn the design view of the form select one of the furniture button controls. In the property window note its name.Scroll through the properties list and find the value in the Text property. This is the master name that is retrieved from the stencil when this button is clicked.Select the event procedures button in the properties window. Scroll through the list and find the click event procedure. The event procedure is onFurnitureButtonClicked.The onFurnitureButtonClicked method handles the event that is raised when one of the furniture buttons is clicked. The button text field contains the corresponding name of the master shape on the product stencil. The master is retrieved and dropped on the page.When the furniture shape is dropped on the page Visio’s ShapeAdded event is fired. We saw earlier how the event sink was established to listen for this event.Use mouse events to capture the right-click actions on a drawing shape In the design view of the form select the drawing control.In the properties window scroll through the event list and find the MouseUpEvent. Note that it is assigned to the procedure onDrawingControlMouseUp.The onDrawingControlMouseUp checks for different kinds of mouse up actions which can occur when a shape is right-clicked, such as when the user is using keyboard shortcuts to pan and zoom, or when a user is selecting a shape. The main body of the code for onDrawingControlMouseUp is below.// Check if the event was raised because of a right mouse button click,// and the user is not zooming (control+shift+right mouse click)// or selecting shapes (control+right mouse click).if ((eventData.button == (int)VisKeyButtonFlags.visMouseRight) &&((eventData.keyButtonState & (int)VisKeyButtonFlags.visKeyControl) ==0 )) {// Look for a shape on the drawing page at the click location.clickedShape = Utility.GetClickedShape(drawingControl, eventData.x, eventData.y);if (clickedShape != null) {// Cancel the default processing of this event since// it will be handled in this method.eventData.cancelDefault = true;// Show the shortcut menu at the click location. The// coordinates need to be converted from the Visio page// units that are in the event data to Windows pixel// coordinates.shapeShortcutMenu.Show(this,Utility.MapVisioToWindows(drawingControl, eventData.x, eventData.y));}}Finding the shape is done inside Utility.GetClickedShape. This uses Visio’s SpatialSearch method of the page to determine the closest shape to our mouse click location.Use the MarkerEvent event and the EventDblClick ShapeSheet cell to respond to when the user double-clicks shapes in the drawingThe detecting of when the user double clicks on a shape is handled with marker events. We saw earlier how the event sink was set up to listen to marker events. Now let’s look at how a marker event gets fired in the first place.In the design view of the form select the drawing control.In the properties window scroll through the event list and note that there is no double click event exposed for the drawing control. When you double-click on a shape within the control, the shape’s double click event fires which evaluates the EventDblClick cell in the shape’s ShapeSheet. The Events section for the Office Chair shape is shown below. Note that the formula calls RUNADDONWARGS and passes the string “QueueMarkerEvent”. This causes the MarkerEvent to fire. In addition the MarkerEvent is passed the string “/officeplan /cmd=1” which is used by the marker event listener to verify that the marker event was caused by double clicking a shape that it can recognize. Also, the RUNADDONWARGS functions appends the string “/doc=id /page=id /shape=sheet.id” to the string passed to the marker event. In our sample application this is used to get a reference to the specific shape that was double-clicked.The code trail starts with VisEventProc. This calls handleMarker, which gets a reference to the shape that was double clicked and then calls onShapeDoubleClick. onShapeDoubleClick displays the product detail form.Create a custom Windows form to display shape product information in an adjacent DataGrid control The information displayed in the datagrid is kept in the ProductData.xml file. The master shape has shape data fields defined, but contains no shape data except for the ProductID which is used to identify the corresponding ProductListItem in the xml file.The following code comes from the onAddProductInformation procedure which is called when a Visio shape added event is fired.// Update the total prices and the data grid // add the information from the new shape.TotalRetailPrice += productData.GetRetailPrice(productId);TotalWholesalePrice += productData.GetWholesalePrice(productId);productData.AddProduct(productId);Setting TotalRetailPrice updates the retail price on the form.Setting TotalWholesalePrice updates the wholesale price on the form.The variable productId contains the value in the shape data cell ProductID from the shape. This is used to associate the product id with the shape. The method productData.AddProduct updates the datagrid with the data for this productID when a shape is added. The method productData.RemoveProduct decrements the product information in the data grid with a shape is deleted.The actual product data is maintained in the ProductData object after being loaded from the xml file. The onShapeDoubleClick procedure and the onMenuProductInformationClicked procedure each display the Product Detail form.Save Visio drawings created by using the Drawing Control After constructing a Visio drawing using the drawing control the user can save the drawing using the File > Save command. This causes the click event for the menu item onMenuFileSaveClicked to execute. This event procedure calls Utility.SaveDrawing to save the Visio drawing.Open Visio drawings in the Drawing ControlVisio drawings can also be opened in the drawing control. This is done through the File > Open menu and the onMenuFileOpenClicked event procedure. This sets the drawingControl.Src property to the filename of the Visio drawing.Lesson 2: Creating an applicationThe Office Plan sample provides an example of using the drawing control in a Windows forms application. In this lesson we will explore more properties and features of the drawing control.Lesson ObjectivesAfter completing this lesson you will be able to:Identify the features of the Visio drawing control and example use scenarios. State best practices for using the Visio drawing control in Visio solutions. Embed the Visio drawing control in a variety of host applications, including Microsoft Windows? Forms, Microsoft Visual Basic? 6.0 forms, Microsoft Office documents, and Microsoft Internet Explorer. Use the properties of the Visio drawing control API. Load Visio documents into the drawing control window and save changes. Get a reference to the Visio Application object in order to work programmatically with the Visio document. Manage the display of the drawing surface. Integrate the control with your host application user interface. Deploy the Visio drawing control with your application. Best PracticesBecause the Visio drawing control is a programmable component, you can integrate your Visio solution code directly into the host container application. Prior to Visio 2003, a developer writing a solution for the Visio client application needed to package the solution code in a COM add-in, Visio solution library (VSL), out-of-process executable, or in a Visual Basic for Applications (VBA) project in a document. The Visio Drawing Control simplifies solution architecture and the development process by allowing programming of the Visio Application object from the hosting application. A developer using the control in a custom application (such as a C# application) or Internet Explorer should program against the Visio object model directly in the host application, without separating the Visio logic into a COM add-in, VSL, or executable. Calling a Visio COM add-in, VSL, or executable from the hosting application unnecessarily complicates the debugging of the Visio integration. However, if you would like to host the Visio control in a Microsoft Office System application other than Visio, you will have to use a COM add-in. In this case, create a COM add-in for your host application instead of for Visio. For example, if you plan to host your Visio control in a Microsoft Office Word 2003 document, create a Word COM add-in and access the Visio control through the Word add-in. Make sure your COM add-in is targeted at the host since an Office host application will not load a Visio COM add-in for the drawing control.Porting existing codeWhen you are porting your code from an existing Visio client application solution to the Visio control, include these design considerations in your planning. Port VBA code. You must port all existing VBA code into a COM add-in, or more preferably, your host application. You can keep most of your same algorithms and logic, as long as it makes sense working within the control's SDI architecture. Port an existing Visio solution COM add-in, executable, or VSL to the container application. While it might be initially easier to simply use an existing COM add-in, executable, or VSL with the host application, it is recommended that you integrate the Visio drawing control programming directly with the host application. By taking the time to port your code from your existing solution to your host application, you'll simplify deployment of your solution, and streamline the development, debugging, and maintenance process over time. You do not need to use a COM add-in unless you are working with the control in another Office container. Re-evaluate data storage in shapes. If your current Visio solution stores extensive data in shapes, consider re-architecting data storage out of Visio shapes and into data structures maintained or accessed by the host application. Visio can store as much data as you need, but it often makes more sense to keep Visio as a presentation layer component and use your host application as data storage or access to a data source. If the data is relatively static, though, and used heavily for modifying the appearance and layout of shapes, it makes more sense to store the information in the shape custom properties. Think about event integration with the host application. Unlike a Visio client application solution, the Visio drawing surface can respond to both user events and host application events. Consider how you want the drawing surface to respond to events fired by the host application, and how your host application needs to respond to events in the Visio drawing surface. Use marker events for COM add-ins. If you must use a COM add-in, you will need a way to notify your COM add-in to respond to a user action in your document. Use the QUEUEMARKER function in the ShapeSheet or a persistent event with the document to queue a marker event to which your COM add-in responds. The Controls SDI (single document interface)When designing an application that uses the Visio drawing control, it's important to understand that the Visio control supports a single document in a single window. The control's single document interface (SDI) architecture results in the following considerations when designing the Visio drawing control integration with your application: Use multiple instances of the Visio drawing control to display multiple Visio documents in your application. Unlike the Visio client application, which can display multiple documents and windows at a time, the Visio drawing control can only display a single document per instance of the control. If the developer wants to display multiple Visio documents, the developer can embed multiple instances of the control in the application, with each instance loading a separate Visio document. Do not depend on VBA for programming logic. VBA is not included with the Visio drawing control. As a result, documents loaded in the Visio drawing control do not execute any VBA code associated with the document. The control's lack of a VBA run-time environment prevents the distribution of legitimate code or malicious macros via documents loaded by the Visio control. It also means that the user of an application hosting the control will never see the Visio application's security dialog box warning about macros in the document. Use the Visio ShapeSheet? programmatically. The control does not provide access to the Visio ShapeSheet user interface, which is a separate window in the Visio application. However, the ShapeSheet itself still exists for the Visio shapes and pages in the document loaded in the Visio drawing control. You can still edit ShapeSheet cells for your Visio document in the control using Visio Automation. For example, you can use the Cell object's SRC property to add a double-click action for a Visio shape. Note: When programming the ShapeSheet for documents loaded in the control, you will not be able to use the CALLTHIS function, which calls a VBA macro in the document. The Visio drawing control does not execute VBA code, so any use of the CALLTHIS function will fail silently. Instead, use mouse events or QUEUEMARKEREVENT as was illustrated in the Office Plan sample program earlier.Getting a reference to the Visio Application ObjectYou can access the Visio object model through the Visio drawing control's API. To get a reference to the Visio Application object, use either the drawing control's Document or Window property.For example, the following C# code shows how to get a reference to the Visio Application object using the drawing control's Window property:using Microsoft.Office.Interop.Visio; private Microsoft.Office.Interop.Visio.Application application = null; application = (Microsoft.Office.Interop.Visio.Application) drawingControl.Window.Application; You can do the same thing using the following Visual Basic 6.0 code:Dim vsoApplication As Visio.Application Set vsoApplication = DrawingControl.Window.Application Loading a documentWhen the Visio drawing control is loaded, it displays a blank Visio drawing. If you want to display an existing Visio document, the drawing control exposes an Src property for loading a document into the control. You can then use the document's SaveAs method to save any changes.Use the Visio drawing control's Src property to load a document into the control. For example, the following C# example shows how to load a Visio drawing:drawingControl.Src = "C:\\Drawing.vsd"; You can load any Visio file type using the Src property (for example, .vsd, .vdx, .vst, or .svg). The file can be stored locally or on a remote file server. Note: To load a blank drawing into the drawing control when it initializes for the first time, set the Src property to an empty string, but setting the Src property to an empty string after a document has been loaded does not clear the contents of the current document. Instead assign a blank drawing to the Src property or SelectAll and delete to clear the contents from the current document.Saving a documentThe Visio control's Src property loads a copy of the file specified in the Src value. To persist the changes in the control's document, you must save the Visio document using the SaveAs method. Alternatively, you can persist changes in-stream. In both cases, however, you do not modify the original document loaded by the Src property.The control loads a copy of the file specified by the Src property. The file loaded through Src is not opened for read/write operations, and therefore cannot be saved using the Save method. To save changes to the document?loaded in the Visio drawing control, call the document's SaveAs method. The following C# example shows how you can use the drawing control Document property to call the SaveAs method:Visio.Document document = drawingControl.Document; document.SaveAs("C:\\Drawing.vsd"); You cannot use the SaveAsEx method to save Visio 2003 documents to Visio 2002 format in the Visio ActiveX control. To save a drawing loaded in the Visio drawing control to Visio 2002 format, launch an invisible instance of Visio and call the SaveAsEx method in your Visio application instance, as demonstrated in this Visual Basic 6.0 code that saves a Visio 2003 drawing into the Visio 2003 file format:Application.Documents(1).SaveAsEx("C:\Documents and Settings" & _ "\myusername\My Documents\Visio2002 file.vsd", visSaveAsWS + _ visSaveAsListInMRU) Saving a Visio Document in the Control to StreamDevelopers may want to persist changes to a drawing in the Visio drawing control without saving the drawing to disk. For example, if a user modifies a Visio document in an embedded control in a Word document, the changes are lost when the user forwards that Word document in an e-mail message. When another user opens the document, the control loads the file specified by the Src property, overwriting any modifications. To persist changes in-stream to a Visio document in the control Load the original document using the Visio control's Src property. After the document loads, set the Src property to an empty string. When the control is activated in its container document after the first initialization, the control displays the last in-stream image rather than the original document specified by the Src property. Note: Persisting changes in-stream is an unsupported feature of the drawing control, but the technique seems to work reliably.Integrating the control with the host containerYou can modify the appearance of the Visio drawing control in your application. By default, all Visio toolbars are turned off and the stencil pane is not displayed. You can choose how the drawing control surface appears by displaying scroll bars, rulers, or by changing the window background color. The drawing control exposes a PageSizingBehavior property that determines how the page is displayed within the drawing control window. You can choose to resize the page in relation to the drawing control's size, or provide a view similar to Visio, showing a portion of the drawing page. Because the control only supports a single window, you cannot access the ShapeSheet or windows such as icon editor and master and group editing. The page and shape right-click menus are enabled by default. The limited Visio UI for controlling shape behavior reflects the intent of the control to be tightly integrated with the container application. The best approach for allowing users to modify shapes on a document is to use a custom UI. However, if you want to use Visio menus and toolbars, the drawing control does support menu and toolbar merging with the host application. Most likely, your Visio drawing control application will be event-driven and respond to users clicking buttons or menu items contained in the application. The drawing control also exposes Visio events, so that you can respond to a user clicking within the control itself.Managing the Drawing Surface DisplayYou can modify the appearance of the Visio drawing control's surface through the control's Window property. For example, the following C# code hides the drawing control's scroll bars:drawingControl.Window.ShowScrollBars = (short) Visio.VisScrollbarStates.visScrollBarNeither; This example hides both the horizontal and vertical scroll bars. Other possible values for the VisScrollbarStates enumeration include visScrollBarBoth (display both scroll bars), visScrollBarHoriz (display horizontal scroll bar), and visScrollBarVert (display vertical scroll bar).By removing parts of the Visio UI, you can make the drawing control look more integrated within your application. The following C# code hides the rulers:drawingControl.Window.ShowRulers = 0; You can also change the color of the window background to suit the color scheme of your application. For example, the following C# code sets the window background color to solid red:drawingControl.Window.BackgroundColor = (uint) ColorTranslator.ToOle(Color.Red); drawingControl.Window.BackgroundColorGradient = (uint) ColorTranslator.ToOle(Color.Red); In this example, the ColorTranslator class is used to convert a .NET color type into OLE_COLOR type, which is how Visio Automation specifies colors. Page sizing and zoomUse the Visio drawing control's PageSizingBehavior property to resize the page with respect to the control window. The default setting of this property (visNeverResizePages) provides a view similar to that of Visio where a portion of the page is viewable within the window. The following C# code example resizes the page to fit the control:drawingControl.PageSizingBehavior = Visio.VisPageSizingBehaviors.visResizePages; When PageSizingBehavior is set to visResizePages, the page's shapes are not resized with respect to the page. Shapes remain located relative to the coordinate system of the Visio page, which has its origin in the lower left corner of the page. Sizing the page to fit within the control hides the page boundaries and is useful in situations where the control is sized to the maximum extent of the drawing surface.To rescale the entire page, including its shapes, within the drawing control window, set the Zoom property through the control's Window property, as shown in the following C# example:drawingControl.Window.Zoom = 2.0; This code magnifies the window's contents by 200%. To take effect, the zoom settings must be made after loading the document using the Src property.To prevent the user from changing the zoom setting, set the ZoomLock property as shown in the following C# example:drawingControl.Window.ZoomLock = true; You can set the extent to which Visio controls the zoom through the VisZoomBehavior property, which can be accessed through the drawing control's Window or Document property. By default, the control uses the current zoom setting for the document. If you want to be able to set the zoom to any level, not just discrete settings such as 50% or 100%, without making any adjustments for the appearance, set the VisZoomBehavior property to the VisZoomVisioExact value, as shown in the following C# example:drawingControl.Window.ZoomBehavior = Visio.VisZoomBehavior.visZoomVisioExact; Note: You cannot resize the Visio drawing control in a Word document. If you resize the drawing control and save the changes, the control will reset to its default size the next time the Word document is opened. Window managementYou can "turn off" the Visio Shape Search window in the document's stencil pane using the Visio ItemFromID property. To make the Shape Search window invisible in the stencil pane, set the property's Visible property to false, such as:Windows(1).ItemFromID(Visio.visWinIDShapeSearch).Visible = False To expose the Shape Search window in the stencil pane, set the same value to True.Each of the other View windows such as Size & Position Window and Shape Data Window are each controlled separately.Integrating menus and toolbarsThe best practice when building an application using the Visio drawing control is to implement a custom UI. If you want to display Visio menus and toolbars in your container application, set the drawing control's NegotatiateToolbars and NegotiateMenus properties. The following C# code enables both menu and toolbar merging:drawingControl.NegotiateMenus = True; drawingControl.NegotiateToolbars = True; The best practice is to set both of these properties to the same value. The control will not support independent negotiation of toolbars and menus. The container application must support OLE menu merging in order to display Visio menus or toolbars. For example, you can enable toolbar merging in a Word document. Within the Visual Basic project of the Word document you can programmatically display Visio toolbars. The following example displays the Layout & Routing toolbar.mandBars("Layout & Routing").Visible = True Important:Do not attempt menu and toolbar merging with multiple active instances of the ActiveX control. Multiple instances of the control share a single underlying Visio Application object. You may get unexpected results when trying to do menu merging with a single Application object and multiple active instances of the control. Important:Do not merge menus and toolbars with the Internet Explorer user interface. There are known issues with menu merging in Internet Explorer (see the Microsoft Knowledge Base article 193098, PRB: Unexpected Menu Merging Behavior in Internet Explorer).Handling eventsFor easier use of Visio events, the Visio drawing control object exposes all Visio Window and Document events. This allows developers to access the events directly from the control rather that going through the Visio Document object.Mouse and keyboard events are commonly used with Visio control programming. You can use mouse events on the Visio drawing control to display custom Windows Forms and update data in your host applications. If you would like to "lock down" the Visio control's drawing surface and prevent end users from modifying any content directly in the drawing, you can listen for all keyboard and mouse events and "throw them away." If the hosting application "swallows" the mouse and keyboard events, the Visio drawing surface won't respond to the user's typing and mouse-click actions.Mouse and Keyboard Event ObjectsEvent objects created by the Visio AddAdvise method offer the best performance. You can use the Visio mouse and keyboard events like any other Visio event with AddAdvise. The following code sample demonstrates how to capture a mouse event using an event sink in Visual Basic 6.0:Implements Visio.IVisEventProc Private Function IVisEventProc_VisEventProc( _ ByVal nEventCode As Integer, _ ByVal pSourceObj As Object, _ ByVal nEventID As Long, _ ByVal nEventSeqNum As Long, _ ByVal pSubjectObj As Object, _ ByVal vMoreInfo As Variant) As Variant Dim strMessage As String ' Determine if mouse up event fired. If nEventCode = visEvtCodeMouseUp Then MsgBox ("MouseUp coordinates (" & pSubjectObj.X & ", " _ & pSubjectObj.Y & ")") End If End Function The following code sample demonstrates how to create an event object for the mouse event using the AddAdvise method. Private mEventSink As clsEventSink Dim vsoMouseUpEvent As Visio.Event Dim vsoWindowEvents As Visio.EventList Set mEventSink = New clsEventSink Set vsoWindowEvents = DrawingControl1.Window.EventList Set vsoMouseUpEvent = vsoWindowEvents.AddAdvise( _ visEvtCodeMouseUp, mEventSink, "", "Mouse up...") Delegates for Mouse-Click EventsAlthough using event objects created with AddAdvise provides the best performance, you can also define a C# delegate in a Windows Form to handle mouse-click events within the drawing control window, as shown here:this.drawingControl.MouseUpEvent += new AxMicrosoft.Office.Interop.VisOcx.EVisOcx_MouseUpEventHandler( this.drawingControl_MouseUpEvent); The event handler would then have the following signature:private void drawingControl_MouseUpEvent( object sender, AxVisOcx.EVisOcx_MouseUpEvent eventData) Note: Examples of using delegates is illustrated in the Office Plan sample from the Visio 2010 SDK.Mouse Events for ShapesVisio mouse events are exposed on Page and Window objects. To locate a particular shape in a page or window on which a user clicks, developers must use the Visio SpatialSearch method. The following C# code passes in the x- and y- coordinates for the click event on the window, sets Visio constants that dictate how to set up the selection object, and defines a small tolerance in which to search around the x- and y- coordinates. MySelection = Window.SpatialSearch(x, y, visSpatialContainedIn, 0.001, visSpatialFrontToBack) If the tolerance is set to a very small unit relative to the size of the shape, the selection object returned by the SpatialSearch method will only contain one shape, the one that the end user clicked on in the window.Using the Visio Control with the Internet Explorer Browser ControlEven though you cannot embed the Visio drawing control directly into another ActiveX control, you can still use the Visio drawing control with applications that depend on the Internet Explorer browser control. Internet Explorer 5.0 or later provides an excellent host container for the Visio drawing control, allowing developers to write script against the Visio object model in Microsoft Visual Basic Scripting Edition (VBScript) or ECMAScript as defined by the specification of the European Computer Manufacturers Association, such as JScript or JavaScript. To integrate the Visio drawing control with an Internet Explorer browser control-based application, do the following: Add a link in your Internet Explorer browser control that launches a new Internet Explorer process with its own window. Embed the Visio drawing control in the new Internet Explorer window for the new Internet Explorer process. Program against the Visio drawing control using your preferred scripting language. Lab 3.8: Using the Visio Drawing ControlThe ScheduleBuilder solution from the previous labs has been ported to a Visual Studio 2005 application that uses the Visio 2010 Drawing Control.During this lab, you will make modifications to the application to enrich the functionality presented.Estimated time to complete this lab: 60 minutesBefore You BeginTo complete this lab, you will need:Participants should have completed the lessons within this module before completing this lab.Visio 2010 installed and configured.Visual Studio 2005 installed and configured.All files from folder Labs\Vol3\Schedule Builder StartThese files present the starting point for the labAll files from folder Labs\Vol3\Schedule Builder Finished These files present a completed solution for the labWhat You Will LearnAfter completing this lab, you will be able to:Set the document Src propertyControl windows in the Visio environment using the drawing control Add menus and call procedures in the container applicationSave the document to a Visio fileExercise 1: Set the Src property of the document and display the External Data windowScenarioDepending on where you placed the Lab files on your machine, you will likely get an error when you first start the application because the path to the Visio drawing being loaded is incorrect. You will fix that in this step.TasksOpen the Visual Studio 2005 project Labs\Schedule Builder Start\ScheduleBuilder.slnChoose Debug > Start Debugging. The program will stop with an error when trying to set the Src property of the document.Correct the path and continue.The External Data window is turned off. Find the code that keeps the window off and make it visible.Exercise 2: Add menus to place and delete SectionsScenarioAdd menus to access functions to Delete Selection Shapes, Drop Section Shapes, and Place Selected Shapes. These were all macros in the VBA version of this solution and have been ported to the Windows Form application containing the drawing control.TasksDisplay Form1.vb in design mode.Add a second top level menu item call ScheduleBuilderAdd 3 menu items under ScheduleBuilderDelete Section ShapesDrop Section ShapesPlace Selected ShapesDisplay Form1.vb (code view)In the objects drop down list at the top of the form choose DropSectionShapesToolStripMenuItemIn the events drop down choose the Click event. This will stub in the event procedure for this menuAdd the codeDocument.DropSectionShapes()This calls the DropSectionShapes procedure in the module ScheduleDocument.vbAdd the Click event procedures for the other two menus. The procedures to call are in ScheduleDocument.vbTry out the code. You will find that the Delete Section Shapes does not delete the shapes properly. Fix this error.Exercise 3: Add SaveAs menuScenarioTo save the drawing you will need to add a SaveAs menu.TasksDisplay Form1.vb in design mode.Under the File menu insert a new menu before Exit and name it SaveAsIn the code view of the form add the Click event for this menuAdd the code for the SaveAs. Look back at the sample code in this module for an example.Additional Resources – Drawing ControlProgramming with the Microsoft Office Visio 2003 ActiveX ControlLearn to integrate the Microsoft??Office Visio??2003 ActiveX??Control, also referred to as the Visio drawing control, into applications. Review best practices and how to use the Visio drawing control programmatically. (24 printed pages)(office.11).aspxDev Luv: Top Ten Things to Know When Using the Visio 2003 ActiveX ControlMai-lan's Visio BlogThis is a good summary blog on common things that can trip you up when using the drawing control. Visio Shapes in the Visio ActiveX Control using C# and .NETA sample program from Mike Gold to help you get started using the ActiveX Drawing Control. Using the Visio Drawing Control in Your Application [Visio 2003 SDK Documentation]Using this control, you can embed the full functionality of the Visio drawing surface into your applications. You can take advantage of the full Visio object model (API) and you can pick the aspects of the Visio user interface you want to expose to better integrate Visio seamlessly into the user interface of your application.(office.11).aspxIntegrating Menus and Toolbars in Visio 2003 Drawing Control ApplicationsYou can choose from several approaches when integrating Visio menus and toolbars in your applications that host the Visio drawing control. This article walks you through a sample application demonstrating these approaches, including the use of the IOleCommandTarget interface. (13 printed pages)(office.11).aspxVisio 2007: Bug in Drawing ControlBill Morein's WeblogThere is a bug in the Visio 2007 Drawing Control such that if you have the SRC property set and add a new page (either through the UI or through code), Visio crashes. an Interactive Visio Drawing Surface in .NET Custom ClientsMicrosoft Office Visio 2003 introduces a new drawing component that allows you to embed an interactive drawing surface into your application's user interface. You can drive the Visio drawing component from events in your host application or with data from a Web Service and an data adapter. The Visio drawing component supports the rich Visio application programming model, giving you control over how graphics are used and displayed on the drawing surface. This article explains how to embed the Visio drawing component into a C#-based Windows Forms client app that retrieves data from the Fabrikam 2.0 Web Service. – Visio Drawing ControlQuestionsTrue or False. You can embed the Visio drawing control into an Excel VBA form.What is the key difference in working with Visio embedded as an OLE object versus with the Visio drawing control embedded in a Windows form.True or False. The Visio control is installed with the Visio application setup program and requires the Visio client application to initialize. What are the steps required to upgrade an application currently using the Visio 2003 Drawing Control to use the Visio 2007 Drawing Control?When using a Visio 2010 Drawing Control in a Windows Forms application the developer should:Program directly against the Visio object modelCreate a COM add-in for the host application and have the COM add-in listen for Visio events and then react to these eventsHost the drawing control in Visio and use VBA to create any necessary forms so that you have access to the Visio user interfaceAny of these methods will workWhen using a Visio 2010 Drawing Control in a Windows Forms application, how can the Windows application be made to listen to events triggered in Visio?A Visio drawing can be displayed in the drawing control by assigning the Src property of the control. What happens to any VBA code that is a part of that document.True or False. Since the drawing control cannot display the ShapeSheet window, you cannot program against the ShapeSheet in application that use the drawing control.True or False. There can only be a single document displayed in an application using the drawing control.What two properties of the drawing control can be used to get a reference to the Visio Application object?What property of the drawing control must be set in order to display an existing Visio drawing in the drawing control?True or False. When editing a drawing in an application using the drawing control you are working directly on that document and can update the document with the Save method.True or False. The Shape Data window cannot be displayed in an application hosting the Visio drawing control.True or False. Any host application can display Visio menus and toolbars if the NegotiateMenus and NegotiateToolbars properties of the drawing control are set to True.What Visio method can be combined with mouse events by the host application to locate a shape on the drawing surface.AnswersTrue. You cannot embed the drawing control into a Visio VBA form, but you can embed into VBA forms of other applications.As an embedded OLE object you are working with Visio’s own user interface. In working with the drawing control on a form there is no Visio UI. The developer must build the interface that is presented to the user.TrueThe interfaces are the same so just rebuild the application.a.In the host application create an event sink and define the Visio events that are to be listened for.The drawing control does not support VBA. Any VBA code that is in the document cannot execute.False. Even though the ShapeSheet window cannot be displayed, you still have access to the Visio object model and therefore can get and set cells in the ShapeSheet.True. Only a single document can be displayed because of the drawing control’s single document interface.Document and Window properties.The Src property.False. You are always working on a copy of the document when using the drawing control and must use the SaveAs method to save changes to the drawing.False. The ShapeSheet an icon editing windows cannot be displayed, but the viewing windows can be controlled by the host application.False. The host application must also support OLE menu merging.SpatialSearch.Adding the Office Fluent UI to an existing Add-inMicrosoft Office 2007 introduced a new user interface called the Fluent UI or Ribbon interface; however this new interface was not adopted in all of the Office 2007 applications. Visio 2007 and other Office 2007 applications continued to use the older CommandBars interface. Now with the release of Microsoft Visio 2010, the Ribbon interface has been adopted allowing Visio solution developers to build rich Ribbon based interfaces for their Visio based solutions. This adoption does pose some issues for the Visio solution developer as this is yet another user interface technology that is available via the Visio API, giving the Visio solution developer three choices, 1) UIObject 2) CommandBars 3) Ribbon. The UIObject is still available however it is recommened that solution developer not use this API as it could be deprecated in future releases. This is also the case for CommandBars as future development investments will now be focused on the Ribbon interface. Visio solution developers that are creating new solutions specifically targeted for Visio 2010 should create their UI using the new Ribbon UI. Visio solution developers that currently maintain Visio 2003/2007 based solutions have a choice to make, migrate their solution to target Visio 2010 and create their UI using the Ribbons or upgrade their solution to target both Visio 2007 and Visio 2010 and manage both a CommandBars based UI and a new Ribbon based UI. Figure 1 – the Add-Ins tab is a catch all for UIObject and CommandBar based UIs This article will walk you thru the process of creating a Ribbon based interface for an existing Visio 2007 add-in, providing best practices for Ribbon item state management as well as best practices for supporting both CommandBar and Ribbon based UIs in one add-in.Getting started As shown in Figure 1, any UI modifications made using the UIObject APIs or the CommandBar APIs are aggregated within a new tab on the Visio 2010 ribbon named “Add-Ins”. Because both the UIObject and the CommandBars support the idea of Menus and Toolbars you see separate ribbon groups, one for each menu and toolbar created thru these legacy APIs. This is good news for both users and solution developers as existing add-ins are still compatible and accessible with the new Ribbon interface. The sample projects for this section are written in C# (Visual Studio 2008) for Visio 2007 using the Visual Studio Tools for Office (VSTO) 3.0 framework and runtime. The following software is required for this scenario: Visual Studio 2008 VSTO 3.0 (installed with Visual Studio 2008) Visio 2007 with .NET Programmability Support installed (PIA) VSTO is the preferred and supported framework for building add-ins for all Office applications. Prior to the release of VSTO, Office add-ins were developed as COM components implementing the IDExtensibility2 interface, commonly referred to as Shared Add-ins from the managed code world. Either framework supports Ribbon extensibility by simply implementing the IRibbonExtensibility interface. It is up to the host application to call the implemented interface in order to retrieve Ribbon customizations.Updating References For the purpose of this article it is not necessary to reference the Visio 2010 type library. Existing Visio 2007 add-ins can continue to reference the Visio 2007 type library in order to support both Visio 2007 and Visio 2010 as well as provide a rich Ribbon based interface when running in Visio 2010. Preparing the add-in for Ribbon support In order for your add-in to support the new Ribbon interface when loaded by Visio 2010, your add-in must be updated to support the IRibbonExtensibility interface. This interface is defined in the Office PIA. Add this reference to your project if it does not already exist. From the Add Reference menu select Office, 12.0.0.0 from the .NET tab. This is the Primary Interop Assembly for Office Core which provides the interfaces for IRibbonExtensibility as well as the APIs and interfaces for CommandBars, so if you are using CommandBars you probably already have this reference in your project. Figure 2 - Adding a reference to Office.dll After adding the reference you will need to implement the IRibbonExtensibility interface in order to provide the host application with an instance of an object that provides your ribbon implementation. For a VSTO based add-in start by creating a separate class that will implement the IRibbonExtensibility interface. I prefer to name this class Ribbon (in a separate file, Ribbon.cs). Here is a sample definition of this class: using Office = Microsoft.Office.Core; [ComVisible(true)] public class Ribbon : Office.IRibbonExtensibility {…} A single method needs to be implemented from the IRibbonExtensibility interface: #region IRibbonExtensibility Members public string GetCustomUI(string RibbonID) { return GetResourceText("DataLinkedOrgChart.Ribbon.xml"); } #endregion The GetCustomUI method is used to return the XML that defines your Ribbon to the host application. This xml is compiled into the add-in as a resource which is retrieved by the GetResourceText method. Using this XML the host application generates the Ribbon and displays it to the user. We will generate the XML for the ribbon later in this article. Application level Ribbon In order to create a single Application-Level Ribbon you need to override the CreateRibbonExtensibility method. This method is called by the VSTO runtime to retrieve an instance of your class that implements the IRibbonExtensibility interface, passing it to the host application which will then make the call to the GetRibbonUI method. protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject() { // create a new instance of our Ribbon this.ribbon = new Ribbon(); // return the ribbon to the VSTO runtime caller return this.ribbon; } As you can see this method simply creates a new instance of your Ribbon class and returns it to the caller. Document level Ribbon To implement a Document-Level Ribbon you do not override the CreateRibbonExtensibility method as described above as you will need to create an instance of your Ribbon for each document on an as needed basis. RegisterRibbonX and UnRegisterRibbonX are two new methods on the Visio.Application class that allow you to attach and detach a Ribbon to a specific open document. To create a Ribbon for a specific document you would create a new instance of the Ribbon class and pass that along with the Visio.Documentinstance that you want to attach it to as parameters to the RegisterRibbonXmethod. // add our UI for this document Globals.ThisAddIn.Application.RegisterRibbonX( ribbon, visioDocument,Visio.VisRibbonXModes.visRXModeDrawing, "My Ribbon"); It is important to perform cleanup operations as documents close so you should manage each instance of the Ribbon class that you create and as documents are closed you should call the UnRegisterRibbonX method. Globals.ThisAddIn.Application.UnregisterRibbonX( this.ribbon, this.visioDocument); Note for Shared add-ins If you are using the Shared add-in framework you simply implement the IRibbonExtensibility interface directly on the Connect class and provide the implementation for the GetCustomUI method as described above. public class Connect : Object, Extensibility.IDTExtensibility2, Microsoft.Office.Core.IRibbonExtensibilityCreating the Ribbon If you have created add-ins for Word or Excel you know that the add-in project template in Visual studio provides a very easy mechanism for creating a Ribbon using the Ribbon Designer. From the Add New Item dialog select the Ribbon Designer Figure 3 - Adding the Ribbon (Visual Designer) to your project And you will be able to visual design the layout of your ribbon using ribbon controls just as you would with a WinForm. Figure 4 - Using the Visual Designer for the Ribbon The problem is that the project template that is used to create add-ins for Visio 2007 knows that Visio does not support the Ribbon interface so this option is not available to you. You can skip the designer and just write the XML from scratch but it is much easier to work with the designer and then have the designer generate the XML when you have your ribbon laid out. To do this, create a new add-in project for Word 2007. Then from the Add New Item dialog choose the Ribbon Designer. Once the new Ribbon Designer is added to this temporary project you can copy the necessary files to your Visio add-in project and discard this temporary Word add-in project. To copy the ribbon designer files to your Visio add-in project:Close and save changes to the temporary Word add-in project/solution. From your Visio add-in project, choose the Add Existing Items menu and navigate to the temporary Word add-in project folder, selecting the following files: RibbonDesign.cs RibbonDesign.designer.cs RibbonDesign.resx This will copy the ribbon designer files to your Visio add-in project. Once these files are added to your Visio add-in project you can continue to the next step which would be to actually design the ribbon. Double-click the RibbonDesigner.cs item in the Project Explorer window. This will open the Visual Designer for the ribbon as shown in Figure 4Once you are happy with the design and layout of your ribbon it is time to generate the XML that will be embedded as a resource in your project. This is the XML that is passed to the host application from the GetCustomUI method described above. To generate the XML from the Visual Designer: Open the Visual Designer as shown in Figure 4 above. Right-click on the ribbon and from the context menu choose ?Export Ribbon to XML? Figure 5 - Export Ribbon to XML This will add a new file to your Visio add-in project named ?Ribbon.xml?. If you open this XML file in the editor you will see that it is a very simple schema.Figure 6 - View of XML generated by the Visual Designer After the Ribbon.xml file is generated and added to the project, verify that the Build Action for this file is set to Embedded Resource or the call to GetCustomUI will fail to return the XML. Figure 7 - Build Action set to Embedded Resource Tip:If you want to duplicate built in buttons on your Ribbon, such as the Refresh All button, you can use the idMso attribute in your XML.<button idMso="DataRefreshAllDialog" />Make sure to set the Build Actions for the Ribbon Designer files to None. It you compile these files into your project they could conflict with the Ribbon class. Make sure to set it for all three designer files: Tip:These files can be removed from your project once you are finished with the design of your Ribbon or they can be left for future design changes. Callbacks At this point you could actually compile and run your add-in and you should see your ribbon however the ribbon controls will not do anything (unless linked to build in commands). In order for the ribbon controls to perform custom actions you need to implement callback methods on the Ribbon class that can be called by the host application or the ribbon controls. These callbacks are assigned to ribbon controls using attributes in the ribbon xml. Figure 8 - Sample XML showing callback attributes The onAction callback should be defined as follows: public void OnAction( Office.IRibbonControl control) { switch (control.Id) { case "buttonCreate": { // do any work necessary for the selected control break; } // define a case for each button that needs a handler } } Manage Ribbon control state In addition to creating a Ribbon with controls that perform actions within your add-in, you will also want to manage the state of the controls on your Ribbon so that users have access to each control when appropriate. When the host application receives the XML from the GetCustomUI method it generates a new Ribbon tab. We can get a handle to this Ribbon when the host application creates it if we provide a callback to the onLoad attribute of the Ribbon XML. Callback defined in XML Figure 9 - Sample XML showing definition for onLoad callback Callback defined in the Ribbon class public void Ribbon_Load(Office.IRibbonUI ribbonUI) { // hold on to the instance of our ribbon this.ribbon = ribbonUI; if (Globals.ThisAddIn.Application != null){ VisioEvents_Connect(); } }Not only do we get the instance of the Ribbon that was created by the host application but in this callback we will connect to a few Visio events so that we can determine when Ribbon control states need to be updated. private void VisioEvents_Connect() { if (Globals.ThisAddIn.Application != null) { Globals.ThisAddIn.Application.AppObjActivated += new Microsoft.Office.Interop.Visio.EApplication_AppObjActivatedEventHandler(Application_AppObjActivated); Globals.ThisAddIn.Application.AfterModal += new Microsoft.Office.Interop.Visio.EApplication_AfterModalEventHandler(Application_AfterModal); Globals.ThisAddIn.Application.WindowOpened += new Microsoft.Office.Interop.Visio.EApplication_WindowOpenedEventHandler(Application_WindowOpened); Globals.ThisAddIn.Application.WindowActivated += new Microsoft.Office.Interop.Visio.EApplication_WindowActivatedEventHandler(Application_WindowActivated); Globals.ThisAddIn.Application.WindowChanged += new Microsoft.Office.Interop.Visio.EApplication_WindowChangedEventHandler(Application_WindowChanged); Globals.ThisAddIn.Application.BeforeWindowClosed += new Microsoft.Office.Interop.Visio.EApplication_BeforeWindowClosedEventHandler(Application_BeforeWindowClosed); } } Within each Visio event handler we can call the Invalidate method on our Ribbon to notify the Ribbon that it needs to get the state for each control. void Application_WindowChanged(Microsoft.Office.Interop.Visio.Window Window) { this.ribbon.Invalidate(); } However, for each control to update its new state each control must have a callback defined that returns true for Enabled or false for Disabled. Callback defined in XML Figure 10 - Sample XML showing getEnabled callback getEnabled defined in Ribbon class public bool GetEnabled( Microsoft.Office.Core.IRibbonControl control) { bool retVal = false; // default to false until we prove this enabled switch (control.Id) { case "buttonCreate": { // create is always available retVal = true; break; } case "buttonGenerate": {// only enabled if the active document is our document retVal = this.IsOurDocument(Globals.ThisAddIn.Application.ActiveDocument); break; } // additional cases for all controls that have state } return retVal; } After Invalidate is called, each Ribbon control that has its getEnabled attribute set will execute its callback and set its state based on the return value of the callback. At this point you can test the ActiveDocument or the Selection to see if the control should be enabled or disabled. Additional callbacks getImage If you do not find an image from Office (ex. imageMso="Refresh") to use on your control you can provide your own. The getImage attribute can be set on each control so that it will retrieve its own image from the specified callback in your add-in. As you can see in the sample below you can easily add your image to your add-in project as a resource and then return it to the caller based on the control.Id property. public System.Drawing.Bitmap GetImage( Microsoft.Office.Core.IRibbonControl control) { switch (control.Id) { case "buttonApplyDataGraphics": { return Properties.Resources.OperationsManagerProductIcon_32; } } // we should not get here for these buttons return null; }CommandBars and Ribbon After implementing the Ribbon as described above there is only one more step you should take, add a conditional statement around your existing UI code so that you do not build your legacy UI using CommandBars if the user is running Visio 2010. To do this add this simple check when initializing your add-in: if (this.Application.TypelibMinorVersion <= 12) { // code to provide CommandBars } else { // do nothing, VSTO will call into the defined // IRibbonExtensibility interface } With this check in place your add-in will now run in both Visio 2007 and Visio 2010, providing the user with the best UI experience available to each.Sample CodeThere are four Visual Studio projects included with this training which demonstrate the above concepts.Try it! Creating Office Fluent UI for Visio AddinsUsing Visual Studio 2008 open the project in <install>\Samples\Office Fluent UI\ Basic RibbonReview the exampleUsing Visual Studio 2008 open the project in <install>\Samples\Office Fluent UI\ Enhanced RibbonReview the exampleUsing Visual Studio 2008 open the project in <install>\Samples\Office Fluent UI\ Doc Level RibbonReview the exampleUsing Visual Studio 2008 open the project in <install>\Samples\Office Fluent UI\ Command Bars OnlyReview the example ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download