-1

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)

1 Answers1

0

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 ! enter image description here

Surrogate
  • 1,466
  • 2
  • 11
  • 13
  • Thanks. I read the https://books.google.co.jp/books?id=8q5RG2CwF5wC&pg=PA94 – user18616709 Apr 20 '22 at 01:15
  • Additional question. After the replaeshape method, even if NameU is the same, match by name does not work well. I suspect this is a bug in visio, but I would like to hear your opinion – user18616709 Apr 20 '22 at 01:17
  • when you use ReplaceShape method in Document stecnil created new master, this new master have different Name and NameU anyway ! – Surrogate Apr 20 '22 at 10:00
  • I add my previous comment and gif in my answer – Surrogate Apr 21 '22 at 05:51
  • After "ReplaceShape" method, I change the NameU (& Name) of Masters. Even though, Match By Name doesen't work.. – user18616709 Apr 25 '22 at 05:12
  • You mean rename masters (old and new editions) into Document stencil? – Surrogate Apr 25 '22 at 06:22
  • May be russian article translated via any Translate Service can helps? https://visioport.ru/blog/index.php/33-matchondrop – Surrogate Apr 25 '22 at 06:38
  • Большое тебе спасибо. I read the material you taught me. I've sorted out the questions and specifications about MatchByName. Added to the question text – user18616709 Apr 26 '22 at 01:34
  • I gave up thinking that it was impossible to use the replaceshape method and MatchByName together. The reason is that MatchByName probably matches not only NameU but also ID. – user18616709 Apr 27 '22 at 01:07
  • **IMHO** it is not good idea use both these methods, with rename masters – Surrogate Apr 27 '22 at 04:17
  • Eventually I used a python program to rewrite the uniqueID in the masters.xml of the VISIO file. As a result, the replaceshape method and MatchByName can be used together. – user18616709 May 10 '22 at 09:46
  • WOW!!! Great, can you share how you change xml via python? – Surrogate May 10 '22 at 13:44
  • 1
    Thanks. I add the python code in the question. – user18616709 May 12 '22 at 00:43
  • It turns out that simply rewriting the xml file will corrupt the file. Therefore, the operation to decompress and compress the file is performed at the end. – user18616709 May 12 '22 at 00:45
  • I dont know how change xml without corruption with code. Even if i unpack/repack archive manually it corrupted :( – Surrogate May 12 '22 at 06:41
  • 1
    I'm not sure how file corruption happens. It may work if you add the following code to prevent the ns0 prefix from being automatically added. ET.register_namespace ('','test.xml') – user18616709 May 13 '22 at 00:09