David J Parker MVP (Visio) bVisual ltd Microsoft MVP (Visio) Microsoft MCP (Visio, SQL) Pre-Microsoft acquisition Post-Microsoft acquisition http://www.visiotoolbox.com/productdetail.aspx?productid=9 WBS Modeler for Visio and Project McGraw-Hill, 2007 http://www.visualizinginformation.com DataLegends – Visio add-in to add Data Graphic legends • Microsoft Visio Solution Provider since 1999 Speaker at Microsoft Office Visio Conferences 2006 & 2008 Visio Solution Provider Training for Microsoft EMEA Visualizing Information with Microsoft Office Visio 2007 • Visio Business Partner, 1996-8 Speaker at Visio Conferences 1997 &1998 Started bVisual in 1998 www.wbsmodeler.com Visio Blog • http://bvisual.spaces.live.com/ On-line Shape Graphics Data Source Prints odc Data Visio Drawing Import > Link > Display Reports > Communicate Microsoft Office Visio 2007 Standard Database Wizard Microsoft Office Visio 2007 Professional Database Wizard Database reverse engineering UML models Link Data To Shapes * PivotDiagrams * Data Graphics * Shape Data Link Data to Shapes Renamed from Custom Properties Multiple data sources per shape Read only Uses Office Data Connections (*.odc files) PivotDiagrams Diagrammatic version of PivotTables Uses Office Data Connections (*.odc files) Data Graphics Data sensitive text and graphics on shapes COM Add-in Add-ons Full Visio Client App Visio Drawing Control (ActiveX) ShapeSheet, Smart Shapes Visio Engine Visio Viewer VSTO Add-in Data Diagramming ML Extensibility Support Save As Web Visio Drawings Sample code Tools & Wizards Visio Object Model (COM) VBA ShapeStudio Visio SDK .NET Primary Interoperability Assemblies (PIAs) DataConnection and DataRecordsets UI and code links to: Visio 12.0 Type Lib Add, AddFromConnectionFile, AddFromXML Microsoft Office Excel & Access SharePoint Services Lists SQL Server Tables and Views OLEDB & ODBC Can also create link in code to : SQL Server stored procedures XML files Declarations & Connection String Dim Dim Dim Dim Dim dds As Visio.DataRecordset 'The data recordset ary() As String ‘Array to hold the p key columns SQLConnStr As String 'The connection string SQLCommStr As String 'The Command string datasetName As String 'The dataset name SQLConnStr = "Provider=SQLOLEDB.1;" & _ "Integrated Security=SSPI;" & _ "Persist Security Info=True;" & _ "Data Source=.;" & _ "Initial Catalog=AdventureWorks;" & _ "Use Procedure for Prepare=1“ Command String & Adding DataRecordset SQLCommStr = "EXEC uspGetEmployees 1" ary() = Split("EmployeeID", ";") datasetName = "Employees“ Set dds = Visio.ActiveDocument.DataRecordsets.Add( _ SQLConnStr, SQLCommStr, _ VisDataRecordsetAddOptions.visDataRecordsetDelayQuery, _ datasetName) dds.SetPrimaryKey VisPrimaryKeySettings.visKeySingle, ary() dds.Refresh Visio.ActiveWindow.Windows.ItemFromID( _ visWinIDExternalData).Visible = True Connection String Dim Dim Dim Dim Dim doc As Visio.Document dst As Visio.DataRecordset xmlFile As String dom As New MSXML2.DOMDocument OK As Boolean Set doc = Visio.ActiveDocument xmlFile = “MyXMLFile.xml" OK = dom.Load(xmlFile) Set dst = doc.DataRecordsets.AddFromXML( _ dom.XML, 0, “Any Name") UI and code refreshing of DataRecordset .Refresh .GetAllRefreshConflicts .GetMatchingRowsForRefreshConflict .RemoveRefreshConflict XML files can only be refreshed in code .RefreshUsingXML Automation requires assigned name and file Refreshing Dim Dim Dim Dim Dim doc As Visio.Document dst As Visio.DataRecordset xmlFile As String dom As New MSXML2.DOMDocument OK As Boolean Set doc = Visio.ActiveDocument xmlFile = “MyXMLFile.xml" OK = dom.Load(xmlFile) For Each dst In Visio.ActiveDocument.DataRecordsets If dst.Name = “Any Name" Then dst.RefreshUsingXML dom.XML Exit For End If Next Select a Master – Drag data row(s) Drag a data row onto any shape Shape Data key field(s) contain values AutoLink Shape Data automatically added to shapes Basic Data Graphics usually added by default User-defined Cells Shape Data _VisDM_ prefixes column names Unless already exist! DropManyLinkedU ObjectsToInstance() array of variants XYs() array of doubles DataRecordsetID long DataRowIDs() array of longs ApplyDataGraphicAfterLink boolean ShapeIDs() out array of longs Example 'Retrieve the row ids from the datarecordset Dim aryRowIDs() As Long aryRowIDs = drs.GetDataRowIDs("") 'Drop the master in random co-ords, and linked to the datarecordset, applying a DataGraphic Dim aryShapeIDs() As Long Dim applyDataGraphics As Boolean Visio.ActiveDocument.DocumentSheet.Cells( _ "User.msvLastAppliedDataGraphic").FormulaU = _ "=""Data - Employees""" applyDataGraphics = True Visio.ActivePage.DropManyLinkedU _ aryMsts, aryXYs, drs.ID, aryRowIDs, _ applyDataGraphics , aryShapeIDs Drop Many... Many types of diagrams require shapes to be connected Connecting shapes example code Organization Charts, Network diagrams, Process ConnectSubordinates ConnectDottedLineManagers Can then use different layouts for display LayoutPage... example code LayoutSelection... example code Code excerpt For iEmp = 0 To UBound(aryShapeIDs) 'Get the potential manager row Set shpEmp = Visio.ActivePage.Shapes.ItemFromID(aryShapeIDs(iEmp)) rowID = shpEmp.GetLinkedDataRow(drs.ID) varRowData = drs.GetRowData(rowID) 'Arrays are zero based empID = CLng(varRowData(empColumn - 1)) 'Filter the rows to get sub-ordinates of the current employee aryRowIDs = drs.GetDataRowIDs("ManagerID = " & CStr(empID)) 'Iterate thru the subordinate datarecordset rows For iSub = 0 To UBound(aryRowIDs) v = drs.GetRowData(aryRowIDs(iSub)) 'Get the subordinate shapes Visio.ActivePage.GetShapesLinkedToDataRow drs.ID, aryRowIDs(iSub), arySubShapeIDs 'Check that there is actually something in the array If IsArrayAllocated(arySubShapeIDs) = True Then 'Iterate thru the subordinate shapes For iSubShape = 0 To UBound(arySubShapeIDs) Set shpSub = Visio.ActivePage.Shapes.ItemFromID(arySubShapeIDs(iSubShape)) 'Create a dynamic connection from manager to subordinate shpEmp.AutoConnect shpSub, visAutoConnectDirUp Next iSubShape End If Next iSub Next iEmp Standard Hierachy Org Chart Page Layout Modified with Selection Layout cf Org Chart Wizard Other Page Layouts may also be suitable Compact Tree Radial Circular Reading Data and Layouts 'Get the DataRecordset Dim drs As DataRecordset Set drs = Visio.ActiveWindow.Windows.ItemFromID( _ Visio.visWinIDExternalData).SelectedDataRecordset ... ‘Get the connection string Dim conStr As String conStr = drs.DataConnection.ConnectionString ‘Use the connection string to create a connection Dim dbCnxn As New ADODB.Connection dbCnxn.ConnectionString = conStr dbCnxn.Open dbCnxn.BeginTrans ... Color By Value Text Data Bar Icon Set Document stencil only shows visible masters Drawing Explorer displays all (but not type) Behind the scenes Public Sub EnumMasters() Dim mst As Visio.Master Debug.Print "ID", "Hidden", "Type", "IsDGCallout", "Name" For Each mst In Visio.ActiveDocument.Masters Debug.Print mst.ID, mst.Hidden, mst.Type, _ mst.Shapes(1).IsDataGraphicCallout, mst.name Next mst End Sub Normal Master GraphicItem Master Master instance with DataGraphic DataGraphic Master Document Stencil Document Page Create a new DataGraphic master Open the new Master .GraphicItems.AddCopy(existingGI) Amend GraphicItems Master.Open Copy an existing GraphicItem to it Document.Masters.AddEx(visTypeDataGraphic) .HorizontalPosition & .VerticalPosition .SetExpression VisGraphicField, string Close Master A Data Bar graphic item can be Min and max values read from shape instances Multiple times in same Data Graphic In multiple Data Graphics Each instance has different value ranges Prop. msvCalloutField Data Bar can have multiple fields E.g. Multi-bar graph Prop. msvCalloutPropFieldn where n=2 to 5 Update master using .Open 5. Update DataGraphic Master Data Bar GraphicItem Min/Max Values 4. Read Min/Max of Data Bar Graphic Items 2. Collect Data Bar GraphicItems 1. Get Active DataGraphic Master Document Stencil 3. Create Selection Document Page Start Part Const Const Const Const UserType As String = "User.msvCalloutType“ UserDGID As String = "User.visDGItemID " PropMax As String = "Prop.msvCalloutPropMax" PropMin As String = "Prop.msvCalloutPropMin“ 'Get the active Data Graphic Dim mstDG As Master Set mstDG = GetActiveDataGraphic im dicDataBarShapes As New Dictionary Dim gi As Visio.GraphicItem 'Create a dictionary of data bars For Each gi In mstDG.GraphicItems If gi.Type = visTypeDataBar Then dicDataBarShapes.Add CStr(gi.ID), 0 End If Next gi Middle Part Dim colDataBarShapes As New Collection Dim itmGraphic As Visio.shape Dim gID As String 'Update the data bars dictionary with shape pseudo-index For Each itmGraphic In mstDG.Shapes(1).Shapes If itmGraphic.IsDataGraphicCallout = True Then If itmGraphic.Cells(UserType).ResultStr("") = "Data Bar" Then gID = CStr(itmGraphic.Cells(UserDGID).ResultInt("", 0)) dicDataBarShapes.Item(gID) = itmGraphic.NameU colDataBarShapes.Add gID End If End If Next itmGraphic 'Iterate thru each page to collect min/max values For Each pag In Visio.ActiveDocument.Pages 'Get all shapes that use this data graphic master Set sel = pag.CreateSelection(visSelTypeByDataGraphic, 0, mstDG) ... Next shp Next pag End Part ... 'Finally - update the ItemGraphic in the DataGraphic Master Dim mstCopy As Visio.Master Set mstCopy = mstDG.Open For Each itmGraphic In mstCopy.Shapes(1).Shapes If itmGraphic.IsDataGraphicCallout = True Then If itmGraphic.Cells(UserType).ResultStr("") = "Data Bar" Then gID = CStr(itmGraphic.Cells(UserDGID).ResultInt("", 0)) itmGraphic.Cells(PropMax).FormulaU = "=" & dicMaxVal.Item(gID) itmGraphic.Cells(PropMin).FormulaU = "=" & dicMinVal.Item(gID) End If End If Next itmGraphic 'Close the copy to update all instances mstCopy.Close Updating DataBar Minimum and Maximum Values automatically Breakdown data into Categories Sort Merge Promote Collapse PivotDiagram is an add-on Not an API extension Only launched in code from SharePoint Services List (soon to be published MSDN article) Use code to select in various ways Aids in applying DataGraphics and extra DataRecordsets E.g. SelectSameBreakdownName sample ... Set vsoWindow = Visio.Application.ActiveWindow If vsoWindow.Selection.Count > 0 Then Set shp = vsoWindow.Selection.PrimaryItem If IsPivotNode(shp) = True Then breakdownName = _ GetGroupNameByID(GetBreakdownID(shp)) SelectByBreakdownName breakdownName End If End If IsPivotNode = isPivotShapeType(shape, ePivotShapeType.Node) Private Function isPivotShapeType(ByVal shape As Visio.shape, _ ByVal pivotShapeType As ePivotShapeType) As Boolean If Not shape.CellExists(UserDDShapeType, _ Visio.VisExistsFlags.visExistsAnywhere) = 0 Then If shape.Cells(UserDDShapeType).ResultIU = pivotShapeType Then isPivotShapeType = True Else isPivotShapeType = False End If Else isPivotShapeType = False End If End Function Custom Selections Legends for Icon Sets & Color By Value TS Exam 70-545 Microsoft Office Visio 2007, Application Development http://www.microsoft.com/learning/exams/70545.mspx Deploying Visio Solutions Working with External Data Developing Visio Libraries Automating Visio Diagrams Publishing and Viewing Visio Diagrams New Microsoft Certified Partner Specialization Information Worker Competency Data Visualization Specialization https://partner.microsoft.com/40039095 Need 2 individuals that have passed Visio TS exam Visio 2007 SDK Visio 2007 Solution Development Workshop http://blogs.msdn.com/visio/ Visio MVP web site http://msdn2.microsoft.com/en-us/office/aa905478.aspx Visio Insight blog http://www.microsoft.com/downloads/details.aspx?FamilyID=332c21 1e-581e-4029-9839-8f45de10b4c2&DisplayLang=en Visio Developer Portal http://msdn2.microsoft.com/en-us/library/ms409183.aspx http://visio.mvps.org/ My Visio Blog http://bvisual.spaces.live.com/ David J Parker Microsoft MVP (Visio) http://www.bVisual.net Book http://www.visualizinginformation.com davidp@bvisual.net