I recently started to work with C# and I have to import a Visio file that is including a flow-chart with different path.
I load the file with this code.
public Container loadFile(string fileName)
{
Microsoft.Office.Interop.Visio.Application app = new Microsoft.Office.Interop.Visio.Application();
app.Visible = false;
Documents docs = app.Documents;
Document doc = docs.Open(fileName);
Microsoft.Office.Interop.Visio.Page page = doc.Pages[1];
Container container = printProperties(page.Shapes);
return container;
}
public Container printProperties(Microsoft.Office.Interop.Visio.Shapes shapes)
{
Container container = new Container("Visio Import");
container.setParent(null);
// Look at each shape in the collection.
foreach (Microsoft.Office.Interop.Visio.Shape shape in shapes)
{
// traverse
}
return container;
}
I want to traverse through every possible (!) path of the flow-chart and print the process names. E.g.
Path 1:
- Enter PIN
- Select Account
- Select Amount
- Print Receipt
- Take Money
Path 2:
- Enter PIN
- Select Account
- Check Money
- Abort
Can you tell me how to check the connections between the single processes and traverse it? Thank you very much for your help!
I have code that does this, but I cannot share it, since it's part of a commercial product.
However, I can tell you that the way I coped with doing this within Visio was, I first wrote a set of very generic directed graph classes in VBA: one for nodes, one for edges, and one for the graph as a whole. I built circular path checks into the graph class, as well as the code for finding all paths in the graph.
Then I had some code that would read the Visio page and populate this simple graph representation, and call the appropriate code.
I think this would probably be good for you to do, too, since the Visio side of things will inevitably be messier than a simple directed graph implementation. I didn't use the ConnectedShapes part of the API since I have to support down to Visio 2003, so I actually look at the Connects and FromConnects objects on my shapes to see what OneD connectors are attached to a shape, and determine whether a shape is at the head or tail of an arrow. This is another reason to break the graph part away from the Visio part, since the way we read the Visio page is subject to change over time, but the graph theory will stay the same.
The path-finding algorithm works by first finding all the terminal nodes in the graph, and I mean those nodes with no Downstream nodes. For each of these I add a list called DownstreamPaths, which is just empty since there is nothing downstream. Then for each node in the graph I call a recursive function that populates all the downstream paths for the current node, and basically all it does is builds a DownstreamPaths list on each node. This list is a list of lists, so you just look at each downstream node, and append that node on the head of its own DownstreamPaths list, and add that into the current node's path list. When that's all done, you find all the starting nodes, with nothing upstream, and collate all the downstream paths lists on those, and you get your list of paths.
You could use shape.ConnectedShapes (Visio 2010+) to find which shapes are connected to the current one. Thus, you will be able to build a graph (model) out of the flowchart.
Check out also this article which explains things about Visio connectivity: http://blogs.msdn.com/b/visio/archive/2009/09/22/the-visio-2010-connectivity-api.aspx
Finding all paths in that graph is a different story though, the solution may depend of what kind of flowchart you analyze; for example, if the flowchart has a cycle, there will be infinite number of paths in fact... Also, the number of possible paths may grow exponentially for relatively simple acyclic graphs. You could try "finding all paths in directed graph" search.