Visio2000: Cross-Functional Flowchart Shapes Incorrectly Aligned When You Open Drawing
This article was previously published under Q289815
This article has been archived. It is offered "as is" and will no longer be updated.
When you change the measurement units in Page Setup, or the routing style, and then save the drawing, the drawing's flowchart shapes are incorrectly aligned the next time you open the drawing.
NOTE: If Automation events are not enabled (on the Tools menu, click Options, and then click the Advanced tab), or you open the drawing in read-only mode, this problem does not occur.
This problem occurs when there is a difference between the measurement units for page width/height, and the page and drawing scales. The problem typically occurs when the page width/height settings are set to inches, and the page/drawing scales are set to millimeters.
This difference in measurement units causes Visio to view the flowchart shape values for PinX/PinY, and either User.xRight/User.xLeft or User.yTop/User.yBottom, as the same measurement units as the page scale, which is typically in millimeters. Therefore, the shapes shift towards the zero axis.
A supported hotfix is now available from Microsoft, but it is only intended to correct the problem that this article describes. Apply it only to systems that are experiencing this specific problem.
To resolve this problem, contact Microsoft Product Support Services to obtain the hotfix. For a complete list of Microsoft Product Support Services telephone numbers and information about support costs, visit the following Microsoft Web site:Note In special cases, charges that are ordinarily incurred for support calls may be canceled if a Microsoft Support Professional determines that a specific update will resolve your problem. The usual support costs will apply to additional support questions and issues that do not qualify for the specific update in question.
The English version of this fix should have the following file attributes or later:
Date Time Version Size File name --------------------------------------------------------- 4/18/2001 12:17:12 PM 5.0.2920.0 2,207,504 q289815.exeAfter the hotfix is installed, the following files will have the listed attributes or later:
Date Time Version Size File name ---------------------------------------------------------- 4/16/2001 5:41:02 PM 126.96.36.1996 5,107,712 VISLIB32.DLL 4/16/2001 4:59:02 PM 188.8.131.526 540,672 crosfunc.vsl
Microsoft has confirmed that this is a problem in the Microsoft products that are listed at the beginning of this article.
Microsoft provides programming examples for illustration only, without warranty either expressed or implied. This includes, but is not limited to, the implied warranties of merchantability or fitness for a particular purpose. This article assumes that you are familiar with the programming language that is being demonstrated and with the tools that are used to create and to debug procedures. Microsoft support engineers can help explain the functionality of a particular procedure, but they will not modify these examples to provide added functionality or construct procedures to meet your specific requirements.
Although the hotfix prevents further occurrences of the problem, it does not correct drawings already saved in the "shifted" state.
To reset or fix some the drawing's flowchart shapes' positions and sizes, you can use the following Microsoft Visual Basic for Applications (VBA) macro. The following macro is intended to reset enough of the drawing's shapes so that only some further editing is required.
The following macro assumes that the shapes are grouped together by being associated to a layer in Visio. The following macro will not touch or adjust any shapes that are not associated to a layer. Microsoft recommends that you only apply this macro to a copy of each original drawing.
NOTE: You must install the hotfix to use the following macro.
Steps to Take Prior to Running ResetFlowChartShapes() Macro
- Close all instances of Visio and apply the hotfix described in the "Resolution" section of this article. Make sure that the Crosfunc.vsl and Vislib32.dll files are updated.
- Start Visio. On the Tools menu, click Options. On the Advanced tab, click to clear the Enable Automation Events check box, and then click OK.
- Open each of the cross-functional flowchart drawings that were saved in the shifted state, and press ALT+F11 to switch to the VBA Editor.
- On the Insert menu, click Module. In the Code window, paste the following code:
'Global Structures for shape processingDim iPageWidth As IntegerDim iPageHeight As IntegerDim iPageScale As IntegerDim iDrawingScale As IntegerDim intShapesBaseCount As IntegerDim szFlowChtOrientation As String' Global ConstantsConst szVertFlwCht = "Vertical holder"Const szHorzFlwCht = "Horizontal holder"Const szSpanVertFlwCht = "Banda functional"Const szSpanHorzFlwCht = ""Const NOT_FLWCHT_ERR_DESC = "Not a Functional Flowchart"'=============================================================' GetPageMMUnits - Routine to obtain the Page's Units'Function GetPageMMUnits(pageObj As Visio.Page) As Long Dim cellObj As Visio.Cell Set cellObj = pageObj.PageSheet.Cells("DrawingScale") iDrawingScale = cellObj.Units Set cellObj = pageObj.PageSheet.Cells("PageScale") iPageScale = cellObj.Units Set cellObj = pageObj.PageSheet.Cells("PageHeight") iPageHeight = cellObj.Units Set cellObj = pageObj.PageSheet.Cells("PageWidth") iPageWidth = cellObj.UnitsEnd Function'=============================================================' AdjustFlowchartShapes() - Routine that performs fix up to' flowchart shapes.'Function AdjustFlowchartShapes(shpObj As Visio.Shape) As Long Dim cellPinXObj As Visio.Cell Dim cellPinYObj As Visio.Cell Dim cellUsrXLeft As Visio.Cell Dim cellUsrXRight As Visio.Cell Dim cellUsrYBtm As Visio.Cell Dim cellUsrYTop As Visio.Cell Dim cellWidthObj As Visio.Cell Dim cellHgtObj As Visio.Cell Dim dwPinXVal As Double Dim dwPinYVal As Double Dim dwxLeft As Double Dim dwxRight As Double Dim dwyTop As Double Dim dwyBottom As Double Dim dwHeight As Double Dim dwWidth As Double Dim dwTmpWidth As Double Dim dwTmpHeight As Double Set cellPinXObj = shpObj.Cells("PinX") Set cellPinYObj = shpObj.Cells("PinY") Set cellWidthObj = shpObj.Cells("Width") Set cellHgtObj = shpObj.Cells("Height") dwPinXVal = cellPinXObj.Result(cellPinXObj.Units) dwPinYVal = cellPinYObj.Result(cellPinYObj.Units) 'If Vertical Flowchart If szFlowChtOrientation = szVertFlwCht Then Set cellUsrXLeft = shpObj.Cells("User.xLeft") Set cellUsrXRight = shpObj.Cells("User.xRight") dwxRight = cellUsrXRight.Result(cellUsrXRight.Units) dwxLeft = cellUsrXLeft.Result(cellUsrXLeft.Units) dwWidth = cellWidthObj.Result(cellWidthObj.Units) dwTmpWidth = dwxRight - dwxLeft ' Adjust the X Axis values cellPinXObj.Result(iPageScale) = Application.ConvertResult(dwPinXVal, iPageHeight, iPageScale) cellUsrXRight.Result(iPageScale) = Application.ConvertResult(dwxRight, iPageHeight, iPageScale) cellUsrXLeft.Result(iPageScale) = Application.ConvertResult(dwxLeft, iPageHeight, iPageScale) cellWidthObj.Result(iPageScale) = Application.ConvertResult(dwWidth, iPageHeight, iPageScale) End If 'If Horizontal Flowchart If szFlowChtOrientation = szHorzFlwCht Then Set cellUsrYTop = shpObj.Cells("User.yTop") Set cellUsrYBtm = shpObj.Cells("User.yBottom") dwyTop = cellUsrYTop.Result(cellUsrYTop.Units) dwyBottom = cellUsrYBtm.Result(cellUsrYBtm.Units) dwHeight = cellHgtObj.Result(cellHgtObj.Units) dwTmpHeight = dwyTop - dwyBottom cellPinYObj.Result(iPageScale) = Application.ConvertResult(dwPinYVal, iPageWidth, iPageScale) cellUsrYTop.Result(iPageScale) = Application.ConvertResult(dwyTop, iPageWidth, iPageScale) cellUsrYBtm.Result(iPageScale) = Application.ConvertResult(dwyBottom, iPageWidth, iPageScale) cellHgtObj.Result(iPageScale) = Application.ConvertResult(dwHeight, iPageWidth, iPageScale) End If End Function'===============================================================' ResetFlowChartShapes() Main driver program' - Calls VerifyFunctionalFlowchart to verifies the drawing' is a Cross Functional Flowchart an orientation.' - Builds an array of shapes in the Layer "Flowchart".' - Submits each shape in array to AdjustFlowchartShapes' to fix up shapes PinX or PinY positions.'' This routine requires the drawing window to be the ActiveWindow,' and also that the drawing page that needs the shapes reset be' the ActivePage when the code is run.' Additionally, this routine prompts for the layer' the shapes are on (typically called "FlowChart") that ' needs to be reset. If the shapes are on no layer, type ' nothing into the input box when you are prompted.'' This is sample code meant for demonstration purposes only.' Run the code only on a copy of your drawing documents, and never' on the originals.'Sub ResetFlowChartShapes()Dim docsObj As Visio.DocumentsDim docObj As Visio.DocumentDim mastsObj As Visio.MastersDim mastObj As Visio.MasterDim pagesObj As Visio.PagesDim pageObj As Visio.PageDim layersObj As Visio.LayersDim layerObj As Visio.LayerDim shpsObj As Visio.ShapesDim shpObj As Visio.ShapeDim shpary() As Visio.ShapeDim szObjName As StringDim szLayerName As StringDim rst As LongDim intMastsBaseCount As IntegerDim intMastsCount As IntegerDim intPagesBaseCount As IntegerDim intPagesCount As IntegerDim intShapesCount As IntegerDim iShpCounter As IntegerDim UBnd As Integer, LBnd As IntegerOn Error GoTo ErrhdliShpCounter = 0Set docsObj = Visio.DocumentsintDocsCounter = docsObj.Count' VerificationVerifyFunctionalFlowchartSet docObj = ActiveDocumentSet pageObj = ActivePageSet pagesObj = docObj.PagesintPagesCount = docObj.Pages.Count ' Iterate through the pages collection intPagesBaseCount = 1 GetPageMMUnits pageObj Set shpsObj = pageObj.Shapes If pagesObj(intPagesBaseCount).Layers.Count > 0 Then Set layersObj = pagesObj(intPagesBaseCount).Layers ' Get the Layer name szLayerName = "" szLayerName = InputBox("Input the exact name of the Layer that contains the affected shapes:", _ "Input Layer Name") Set layerObj = layersObj.Item(intPagesBaseCount) ' Iterate through the Shapes collection intShapesCount = shpsObj.Count For intShapesBaseCount = 1 To intShapesCount DoEvents Set shpObj = shpsObj(intShapesBaseCount) If shpObj.Type = 3 And (-1 <> shpObj.CellExists("BeginX", 0)) Then If shpObj.LayerCount > 0 Then If shpObj.Layer(1).Name = szLayerName Then iShpCounter = iShpCounter + 1 ReDim Preserve shpary(iShpCounter) Set shpary(iShpCounter) = shpObj End If ElseIf shpObj.LayerCount = 0 And szLayerName = "" Then iShpCounter = iShpCounter + 1 ReDim Preserve shpary(iShpCounter) Set shpary(iShpCounter) = shpObj End If End If DoEvents Next intShapesBaseCount End If 'Check for empty array If iShpCounter = 0 Then MsgBox "No shapes found in specified Layer Name." Exit Sub End If UBnd = UBound(shpary) LBnd = LBound(shpary) LBnd = 1 'Fix up each shape in specified layer While LBnd <= UBnd AdjustFlowchartShapes shpary(LBnd) LBnd = LBnd + 1 Wend MsgBox "ResetFlowChartShapes reset " & UBnd & " shape positions without errors." _ & vbCrLf & vbCrLf & "Inspect drawing before saving changes."Exit Sub'==============' Error handler'Errhdl: MsgBox "Error: " & Err.Number & vbLf & Err.Description, _ vbCritical + vbOKOnly, "Error Encountered"End Sub'=============================================================' VerifyFunctionalFlowchart - Verify flowchart is functional' by inspecting the master shapes, and determine orientation.'Function VerifyFunctionalFlowchart() ' Get the names of all masters in the active ' document and display the names in the Immediate window. Dim masnames() As String ActiveDocument.Masters.GetNames masnames Dim iIsFuncFlwCht As Integer Dim lb As Integer, ub As Integer 'Get the upper and lower bounds of the array lb = LBound(masnames) ub = UBound(masnames) iIsFuncFlwCht = 0 While lb <= ub If masnames(lb) = szHorzFlwCht Then szFlowChtOrientation = szHorzFlwCht iIsFuncFlwCht = 1 ElseIf masnames(lb) = szVertFlwCht Or masnames(lb) = szSpanVertFlwCht Then szFlowChtOrientation = szVertFlwCht iIsFuncFlwCht = 1 End If lb = lb + 1 Wend If iIsFuncFlwCht = 0 Then MsgBox "This routine is to be run only against a Functional Flowchart", vbCritical _ + vbOKOnly, "Not a Functional Flowchart" Err.Raise Number:=vbObjectError + 512 + 1, Description:=NOT_FLWCHT_ERR_DESC, _ Source:="VerifyFunctionalFlowchart()" End IfEnd Function
- Switch back to the affected drawing and make the page that contains the affected flowchart shapes active.
- Using the Drawing Explorer, (on the View menu, click Windows), inspect the Layers under the Foreground Pages folder, and note the name of the layer that the affected shapes are associated with, or if they are not associated with any layer. You may even want to create a layer temporarily and associate the affected shapes with that layer for this purpose.
- On the Tools menu, point to Macro, and then click Macros (or press ALT+F8). In the drop-down list, click the Module name that you added in the VBA Editor (typically Module(n)), and click Run.
- You are prompted to type the name of the layer that contains the flowchart shapes. Make sure to type the name exactly as it is spelled and capitalized. If the shapes are not associated with any layer, type nothing. Click OK.
- You can run the ResetFlowChartShapes macro multiple times if you have multiple layers.
NOTE: You can undo any changes from the Edit menu. Also, the changes are not final unless you save the drawing document.
squashed skewed compress left bottom
Article ID: 289815 - Last Review: 11/02/2013 05:30:00 - Revision: 3.0
- kbnosurvey kbarchive kbhotfixserver kbqfe kbbug kbfix KB289815