Site icon bVisual

Formatting Shape Data in Visio

One of the best aspects of Visio is the ability of shapes to hold data, and the easiest way to do this is to define rows of Shape Data. Each row can be defined as holding one of eight different types, and most of these can have their values formatted for display. In this article I discuss the formatting of these values, using either ShapeSheet functions or automation methods. The driver for this is my on-going frustration with the Microsoft provided standard Shape Data window because of its shortcomings … for example, its lack of multi-line support even though it can hold 64k characters in each row, and its lack of a time control, even though it can store dates and time.

I created a simple shape which has at least one example of each type of Shape Data, and applied some sample formatting using the Define Shape Data dialog.

I then inserted a table of each row into the shape, and displayed the Type, Label, actual Value, the Format string, and the formatted value (if applicable).

My intention was to understand if the ShapeSheet FORMAT(…) function could be applied in all cases, and it turns out that t can’t. So, I had to test if a Format actually existed before applying it. Therefore, I inserted a custom formula similar to the following in the fifth column of the table:

=IF(FORMULAEXISTS(Prop.FString.Format),FORMAT(Prop.FString,Prop.FString.Format),Prop.FString)

If I look at the values in the ShapeSheet of my sample shape, then it is clear that the display in the Shape Data window is slightly different in some cases. Look at the Formatted String and Time rows, for example.

So, now if I switch the view the formulas in the ShapeSheet, I can see how the values are represented as formulas:

Thus, it is apparent that the Shape Data window value display is not exactly available from the ShapeSheet direct, so I wrote a VBA method to display the data values exactly how they appear in the Shape Data window:

Type

Label

Format

Value

0

String

 

This is a normal case sentence

0

Formatted String

@

THIS IS A NORMAL CASE SENTENCE

2

Number

 

123.45

2

Formatted Number with units

#.#### u

123.45 cm

2

Number fraction with units

# ##/## u

123 9/20 cm

1

Fixed list

;A;B;C;D;E;F

A

4

Variable List

;A;B;C;D;X

X

3

Boolean

 

TRUE

7

Currency

 

£123.45

7

Currency System

@

£123.45

7

Currency with unit

U 0.00

£ 123.45

5

Date

 

24/07/2015

5

Date formatted

{{dd MMM. yy}}

24 Jul. 15

5

Time

{{h:mm:ss am
/pm}}

1:21:00 PM

6

Duration       

 

123.4500 ed.

6

Formatted Duration

[h]

:[mm]

123:27

The code to produce the display above (without the tabular grid) is:

Public Sub DisplayData() 
    If Application.ActiveWindow.Selection.Count = 0 Then
        Exit Sub
    End If
Dim shp As Visio.Shape
    Set shp = Application.ActiveWindow.Selection.PrimaryItem
   
Dim sect As Integer
    sect = Visio.VisSectionIndices.visSectionProp
Dim iRow As Integer
Dim format As String
Dim value As String
Dim dataType As Integer
Dim toUpper As Boolean
Dim toLower As Boolean
Dim label As String
Dim units As Integer
Dim txt As String
    txt = "Type" & vbTab & "Label" & vbTab & "Format" & vbTab & "Value" 
    For iRow = 0 To shp.RowCount(sect) - 1
        If shp.CellsSRC(sect, iRow, _
            Visio.VisCellIndices.visCustPropsInvis).ResultIU = 0 Then
           
            dataType = shp.CellsSRC(sect, iRow, _
                Visio.VisCellIndices.visCustPropsType).ResultIU
            format = shp.CellsSRC(sect, iRow, _
                Visio.VisCellIndices.visCustPropsFormat).ResultStr("")
            label = shp.CellsSRC(sect, iRow, _
                Visio.VisCellIndices.visCustPropsLabel).ResultStr("")
            units = shp.CellsSRC(sect, iRow, _
                Visio.VisCellIndices.visCustPropsValue).units
               
            If Len(format) > 0 Then
                If dataType = 1 Or dataType = 4 Then
                    value = shp.CellsSRC(sect, iRow, _
                        Visio.VisCellIndices.visCustPropsValue).ResultStr("")
                ElseIf dataType > 0 Then
                    value = Application.FormatResult(shp.CellsSRC(sect, iRow, _
                            Visio.VisCellIndices.visCustPropsValue).ResultIU, _
                        "", units, format)
                Else
                    If InStr(format, "+") > 0 Then
                        toUpper = True
                    ElseIf InStr(format, "-") > 0 Then
                        toLower = True
                    End If
                    format = Replace(Replace(format, "+", ""), "-", "")
                    value = Replace(format, "@", _
                        shp.CellsSRC(sect, iRow, _
                            Visio.VisCellIndices.visCustPropsValue).ResultStr(""))
                    If toUpper Then
                        value = UCase(value)
                    End If
                    If toLower Then
                        value = LCase(value)
                    End If
                End If
            Else
                If dataType = 2 Then
                    value = CStr(shp.CellsSRC(sect, iRow, _
                            Visio.VisCellIndices.visCustPropsValue).ResultIU)
                Else
         
;           value = shp.CellsSRC(sect, iRow, _
                        Visio.VisCellIndices.visCustPropsValue).ResultStr("")
                End If
            End If
            txt = txt & vbCrLf & dataType & vbTab & label & vbTab & format & vbTab & value
        End If
    Next iRow
   
    Debug.Print txt
   
End Sub

So, I had to make special consideration for lists and text formatting, and for displaying numbers if there is no formatting.

Armed with this knowledge, I can continue to create a replacement Shape Data window add-in in C# and WPF.

Visio Format(…) function : https://msdn.microsoft.com/EN-US/library/office/ff766359.aspx

About Format Pictures : https://msdn.microsoft.com/EN-US/library/office/ff768634.aspx

Application.FormatResult Method : https://msdn.microsoft.com/EN-US/library/office/ff765455.aspx

Exit mobile version