Is there a way to make a (dynamic?) table of contents page in Visio?

When I knew very little about visio, in making network docs, I would jam way too much on 1 drawing, thinking I had to make an entire different file with a 2nd page.  DUH!

So I know a little more and love the seperate pages and being able to have a common background on all of them, etc.

Now, is there a way to make a table of contents page? A first page that lists the name of each page in the file?  Maybe updates automatically?  When you add another page / rearrange the order of pages, this page auto updates?
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
It is possible to create a TOC, but only by adding code to your diagram.

The code below creates a basic TOC that is sorted by page name. In addition, each TOC entry is hyperlinked to the corresponding page. I'ts not fancy but it gets the job done.

Creating a TOC that updates automatically is possible but requires more elaborate code. For that to work, the code needs to monitor page-related events as you work in the document, e.g., it needs to notice each time a page is created, deleted, moved, or a page name is changed.

Option Explicit

Sub GenerateTOC()
' generates an alphabetical list of page names and adds hyperlink to each page

    Const dLeftEdge     As Double = 0.5
    Const dWidth        As Double = 2
    Const dDeltaY       As Double = 0.15
    Const sTOCpagename  As String = "Table of Contents"

    Dim arrPages()      As String
    Dim arrNameNumber() As String
    Dim pg              As Visio.Page
    Dim shp             As Visio.Shape
    Dim iPageCount      As Integer
    Dim dX              As Double
    Dim dY              As Double
    Dim i               As Integer
    Dim HL              As Visio.Hyperlink
    ' create array of page names and numbers and `sort them
    iPageCount = 0
    ReDim arrPages(ActiveDocument.Pages.Count)
    For Each pg In ActiveDocument.Pages
        ' exclude background pages and existing TOC, if any
        If (Not pg.Background) And (pg.Name <> sTOCpagename) Then
            iPageCount = iPageCount + 1
            ' store page name and number separated by a pipe character (they will be split later)
            arrPages(iPageCount) = pg.Name & "|" & CStr(pg.Index)
        End If
    Call SortAscend_x1(arrPages, 1, iPageCount)

On Error Resume Next
    Set pg = ActiveDocument.Pages("Table of Contents")
    If pg Is Nothing Then                                       ' no existing page so create one
        ' create new page for TOC and make it the first page
        Set pg = ActiveDocument.Pages.Add
        pg.Name = "Table of Contents"
        'make this the first page
        pg.Index = 1
        ActiveWindow.Page = pg.Name
    Else                                                        ' page exists so delete everything on it
        With ActiveWindow
            .Page = pg.Name
        End With
    End If
    dX = dLeftEdge
    ' set vertical location for first TOC entry
    dY = pg.PageSheet.Cells("PageHeight").Result(visInches) - 0.25

    For i = 1 To iPageCount
        ' draw rectangle
        dY = dY - dDeltaY
        Set shp = pg.DrawRectangle(dX, dY, dX + dWidth, dY + dDeltaY * 0.9)
        With shp
            ' set right-aligned tab stop at right side of rectangle
            .RowType(visSectionTab, visRowTab) = Visio.VisRowTags.visTagTab2
            .CellsSRC(visSectionTab, 0, visTabStopCount).FormulaU = "1"
            .CellsSRC(visSectionTab, 0, visTabPos).FormulaU = "GUARD(Width-LeftMargin-RightMargin)"
            .CellsSRC(visSectionTab, 0, visTabAlign).FormulaU = Visio.visTabStopRight
            .CellsSRC(visSectionTab, 0, 3).FormulaU = "0"
            ' set font size and color, text alignment, border, fill and shadow
            .Cells("Char.Size").Formula = "10 pt"
            .Cells("Char.Color").Formula = 0     ' black
            .Cells("Para.HorzAlign") = 0         ' left justify
            .Cells("LinePattern").Formula = 0    ' none
            .Cells("FillPattern").Formula = 0    ' none
            .Cells("ShdwPattern").Formula = 0    ' none
            ' extract page name and number that are separated by a pipe character
            arrNameNumber = Split(arrPages(i), "|")
            .Text = arrNameNumber(0) & vbTab & arrNameNumber(1)
            Set HL = .Hyperlinks.Add                ' create hyperlink
            HL.SubAddress = arrNameNumber(0)        ' set hyperlink to page name
        End With
    Next i


End Sub
Private Sub SortAscend_x1(ByRef arr, SortStart, SortEnd)
' SortKey identifies column in array by which to sort
' SortStart and SortEnd allow flexibility to sort only selected rows within the array

    Dim i, j As Integer
    Dim Temp1
    If SortEnd - SortStart <= 0 Then Exit Sub

    ' bubble sort
    For i = SortEnd - 1 To SortStart Step -1
        For j = SortStart To i
            If LCase(arr(j)) > LCase(arr(j + 1)) Then ' Compare neighboring elements
               Temp1 = arr(j)
               arr(j) = arr(j + 1)
               arr(j + 1) = Temp1
            End If
        Next j
    Next i

End Sub

Open in new window


Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
BeGentleWithMe-INeedHelpAuthor Commented:
Scott, first, thanks!!  Did you write that? Not just for me I hope : )

Since posting this question, I had found this:

I knew enough how to use that (OK, he had pretty good directions). I emailed the author about it / looking at the code - He wrote it for Visio 2003.  I'm on Visio 2013 and it still works. He got a kick out of someone writing after all this time : )

I was asking if he made a sequel script.. I was envisioning something that checks to see if a ToC page existed, if not, it makes the ToC page at the front, then puts a text box on that page and fills it with the ToC.

If the ToC page exists already, then just update the contents of the text box...  I was envisioning it auto run on saves, etc.  (rather than it having to monitor what you are  doing as you mention).  But then I just realized... you have to save the drawing  (to get the script to auto run) or manually trigger the script before printing to have the most accurate ToC

Anyway.... as I mentioned to the author... funny that something he did for visio 2003 isn't in the 2013 version... even though they do have something like this built into word, right?  And I'm not the only one that was looking for something like this.. but hey, it's microsoft.

Anyway, I gave it a shot figuring out how to run your script. I think I got it to work! (I know just enough to be dangerous).  

Correct me if I'm wrong about my observations?

It makes a ToC page if it doesn't exist (Where did I hear that before : )
You don't have to be on the ToC page when running your script (nice)
I have a frame on a background page that the other pages use as a background.  Your ToC picked up that setting!! (REALLY nice!)
I'd have to fiddle with things to change the font / placement of the ToC text on the page... that's about the limit of my skills - vaguely understanding a script and changing variables.  Could never write from scratch and get the syntax correct

As the other script I found talked about, I put your script in a separate template (I put his and yours into my favorites stencil). I guess that's good if I make changes, it'd be in that 1 place rather than in each file... and the visio drawing file is a tad smaller without that script in each one of them?

Other than your thoughts about my ramblings... would you know how to set up a script like yours to run with a shortcut / F key / something else??  Right now, I go to view -> macros, choose favorites.vss, choose the macro, then click run.  Or does visio have a way to set up a command to 'run on save' / back to my automating it a little?
BeGentleWithMe-INeedHelpAuthor Commented:
I'm closing this but still eager to hear if you have any thoughts!  Have a great weekend!
Scott HelmersVisio Consultant, Trainer, Author, and DeveloperCommented:
I did write the code, but not just for you. ;-)  I actually wrote most of it for several previous questions on the same topic here at EE, including this one. However, I spent some time modifying it this morning to add some error checking and also to add the display of page numbers.

I tried to leave lots of comments in the code so that someone like you who wants to move things around, change font sizes, etc. would be able to do so. I'm glad to know you've had some success doing just that sort of thing. Don't hesitate to ask questions if there are things you can't figure out how to change.

You can assign shortcut keys to macro in Visio: open the Macros dialog box, select a macro, and then click the Options button.

Putting macro code in a central location is definitely a good idea -- good thinking about that.

Finally, yes, it is possible to run a command each time a document is saved but the programming to do so is a bit trickier. If you'd like to explore that idea I would suggest you ask about that in a separate question. There used to be an "Ask a related question" link or button in each question. But if you don't find such a thing for this question, you can just start a new one.
BeGentleWithMe-INeedHelpAuthor Commented:
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Visio

From novice to tech pro — start learning today.