'Which property does the visio.Masters.MatchByName method refer to?
The Master of vsoDoc can integrate Masters with the same name at drop time by using the MatchByName method.
However, it may not work well in some cases, and we are investigating the cause.
Which property does MatchByName refer to to integrate Master? Is it Master.Name? Or is it Master.NameU?
If you divide the case The copy destination is Master (vsoDoc.Masters) of the visio file (A.vsdx). There can be two cases for the copy source. One is to copy the Shapes of the visio file (B.vsdx) Or drop it from the vssx file (X.vssx) to A.vsdx.
When copying Shapes, do you refer to the Name or NameU of each Master?
Since the ReplaceShame method changes the name of Master, I am dealing with the new Master and the old Master by swapping the names with the following procedure.
First, in preparation for ReplaceShape, change the MatchByName of all vsoMasters to False.
Then "Replace Shape" all vsoShape
For Each vsoMaster in vsoMasters
vsoMaster.MatchByName = False
Next
Remove the replaced Master from Masters
For Each vsoPage In vsoDoc.Pages
For Each vsoShape in vsoPage.Shapes
If Not (vsoShape.Master is Nothing) then
vsoShape.Master.MatchByName = False
Set vsoShape = vsoShape.ReplaceShape(vssxMasters.ItemU(vsoShape.Master.NameU), 1)
end if
Next
Next
Remove the replaced Master from Masters
For Each vsoMaster in vsoMasters
If InStr(vsoMaster.Name, ".") == 0 then
vsoMasters.ItemU(vsoMaster.NameU).Delete
end if
Next
Change MatchByName of all vsoMasters to True
For Each vsoMaster In vsoMasters
vsoMaster.MatchByName = True
Next
For Each vsoPage In vsoDoc.Pages
For Each vsoShape in vsoPage.Shapes
vsoShape.Master.MatchByName = True
Next
Next
vsoDoc.SaveAs NewName
############################################################
I examined the phenomenon related to MatchByName in three cases. MatchByName = True in all of the following cases.
Case A-1 When using Master (NameU: "test") of the same stencil file (M.vssx)
Procedure
- Place the "test" stencil in the A.vsdx file.
- Copy the A.vsdx file and create the A-1_copy.vsdx file
- Copy the "test" stencil in which A_copy.vsdx, and pasting it into the A.vsdx file.
Result
- As expected, MatchByName works fine and the document stencil Masters doesn't increase.
Case B
- Create a Master (NameU: "test") in the stencil file (M-1.vssx)
- Create another Master (NameU: "test") in another stencil file (M-2.vssx)
In this case B, the Master Name U is same, but the Base ID and Unique ID are different. I think this is an important point.
Case B-1 Procedure
Place the "test" stencil of the M-1.vssx in the B.vsdx file.
Place the "test" stencil of the M-2.vssx in the C.vsdx file.
Copy the "test" stencil from the C.vsdx file and paste it into the B.vsdx file.
MatchByName doesn't work. "test.10" is added to the document stencil. I suspect that this is because the stencil's BaseID and UniqueID are different.
Case B-2 Procedure
Place the M-1.vssx "test" stencil in the B.vsdx file.
Launch another VISIO application and drop the "test" stencil of M-2.vssx into the B.vsdx file.
Result
- Unlike the B-1 result, MatchByName WORKS. I can not understand the cause.
The following code is the code to rewrite the XML file in the vsdx file. By rewriting the Unique ID of the Masters of the vsdx file and the vssx file, MatchByName can be operated as expected.
import zipfile
from pathlib import Path
import xml.etree.ElementTree as ET
import sys
import shutil
import os
# https://yuukou-exp.plus/handle-xlsx-with-python-intro/
# https://livingdead0812.hatenablog.com/entry/2019/07/18/183322
# https://pg-chain.com/python-xml-read-write
# https://note.com/you_memolog/n/ne7d9e8d8a0d3
# https://stackoverflow.com/questions/16721010/write-a-xssfworkbook-to-a-zip-file
#visiopath = Path(sys.argv[1])
visiopath = Path(r"Flowchart_v1.0.17.vssx")
folderpath = visiopath.parent
xml_path = None
with zipfile.ZipFile(visiopath) as zf:
for info in zf.infolist():
if "masters.xml" in info.filename:
xml_path = info.filename
archive = zipfile.ZipFile(visiopath)
#archive = zipfile.ZipFile(visiopath, "w")
print(f"xml_path {xml_path}")
NameU_UniqueID_dict = {'OPERATOR' : '{00FBF49C-0014-0000-8E40-00608CF305B2}',
'TERMINATOR' : '{00634DFF-0015-0000-8E40-00608CF305B2}',
'BRANCH' : '{07639B38-0034-0000-8E40-00608CF305B2}',
'SQUARE' : '{07622477-0012-0000-8E40-00608CF305B2}',
'STARTER' : '{00489A6D-0032-0000-8E40-00608CF305B2}',
'CONNECTOR' : '{006BE21A-0004-0000-8E40-00608CF305B2}',
}
if xml_path is not None:
tree = ET.parse(archive.open(xml_path))
root = tree.getroot()
for child in root:
if child.attrib['NameU'] in NameU_UniqueID_dict.keys():
UniqueID = NameU_UniqueID_dict[child.attrib['NameU']]
child.attrib['UniqueID'] = UniqueID
tree.write('masters.xml')
print('finished writing.')
with zipfile.ZipFile(visiopath, 'a') as zf:
zf.write('masters.xml', arcname='visio\masters\masters.xml')
del archive
zippath = visiopath.with_suffix('.zip')
print(zippath)
print(visiopath)
shutil.move(visiopath, zippath)
shutil.unpack_archive(zippath, 'dir_out')
os.remove(zippath)
shutil.make_archive(zippath.parent / zippath.stem, format='zip', root_dir='dir_out')
#shutil.make_archive(zippath, format='zip', root_dir='dir_out')
shutil.move(zippath, visiopath)
Solution 1:[1]
When copying Shapes, do you refer to the Name or NameU of each Master?
NameU
When working with Visio objects, developers should always use universal names to reference their objects. This advice applies to more than names. A number of properties and methods in the Visio API have universal syntax equivalents. If you find a property and notice the same property exists but ending in a āUā, use the universal property. A classic example is to use the FormulaU property to get and set formulas instead of Formula.
Read more about Name and NameU
when you use ReplaceShape method in Document stecnil created new master, this new master have different Name and NameU anyway !
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 |