Page.GetResults for batch reading and too high ID numbers

Started by Yacine, July 22, 2023, 08:06:43 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Yacine

Hello guys,
you may remember that I wanted to import the shapes' data from big drawings in an Access database.
Several problems made the task difficult:
- the drawings are quite big (up to 1000 shapes)
- up to 30 custom fields per shape to read out
- shapes not consistent (legacy). The prop section rows are not all in the same order.

At the time you guys recommended that I collect all the rows including their name and that I identify the rows after the import into Access by means of the row name. I tested it and it ran well, but at the end I came up with a solution even more elegant.

Batch reading of props
----------------------
The idea behind batch reading is the use of the getResults function of the page.
You set up an array of groups of 4 integer values: the shape ID, the section number, the row number and the column number (SRC address).
Plus some extra data like the formats and so on. (https://learn.microsoft.com/en-us/office/vba/api/visio.page.getresults)

Now if your field "prop.foo" happens to have a different row number in different shapes, addressing it by the SRC method would fail.

And now the trick: write in an immutable and not used field of the shapesheet a formula that collects all the necessary data and read only this field out.
I chose the prompt field of the first row of the user section. That is SRC 242,0,1. (All my shapes have a user section, otherwise I could have created one.)
The formula could then be something like: =ID()&"|"&prop.foo&"|"&prop.bar&"|"&prop.beacon&"|"&prop.eggs&"|"&pinX&"|"&pinY
Resulting in a value like "123|apples|green|Heinz|Rudolf|12|24"
Which - after import - can then be split by the VBA command split(tVar,"|")

Why is this more efficient? The mapping of the rows to their names is made by Visio in the background and only when necessary.
For about 500 shapes and 30 prop fields, I get a processing time of less than a second.

Too high shape IDs
------------------
So fine so good. Now if you happen to re-use, your drawings, copying and pasting big chunks of groups you can easily pass the boundary of the 2 byte integer limit of 32 thousand (and some crumbs) of the shape IDs. This results in not being able to populate the getresults array, which requires integers.
Solution (tedious, but working):
Set up a fresh drawing from your template and paste in the whole old drawing. Visio will renumber the shape IDs. 32 thousand is big enough in my case.
Cutting and pasting in the same drawing does not work.

Additional tip to position correctly the drawing when pasting:
Prior to copying the drawing, draw a small rectangle, set its origin to left bottom, move it to 0,0.
Select everything, copy and paste in the new drawing.
Group everything, set the origin of the group to left bottom and position the group at 0,0. Ungroup, done.

These issues have kept me busy several weeks. Thought I'd share my experiences for whomever may stumble in a similar situation.
Yacine