How to insert Unicode text into Visio Shape?

Started by christianovitch, September 08, 2021, 08:38:09 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

christianovitch

I'm writing a VB.net routine to populate each shape in the second through last shapes of a selection of shapes with a single random character selected from the text in the first selected shape (the seed shape).  Thus, if the seed shape had characters "12345," each of the second through last shapes in the selection would have a random 1, 2, 3, 4, or 5 in it at the conclusion of the routine.  It works fine, but when my "seed" shape has Unicode characters in it, only some of the characters get populated correctly.

For example, the selected character from the seed shape has a character code (obtained via chrW) of 55356, it turns into 65533 ("replacement character") after setting the .text property of a shape to that selected character, indicating that character 55356 can't be found. 

I have no idea how to fix this.  Any suggestions are welcome.

The code is below.

Sub DistributeCharacters(sel As Visio.Selection)
        If sel.Count <= 1 Then Exit Sub
        Dim str As String
        Dim fnt As String
        str = sel.Item(1).Text
        fnt = Globals.ThisAddIn.Application.ActiveDocument.Fonts(CInt(sel.Item(1).Cells("Char.Font").Formula)).Name
        Dim c1, c2 As String
        If Len(str) = 0 Then Exit Sub
        For x = 2 To sel.Count
            With sel.Item(x)
                .Cells("Char.Font").Formula = sel.Item(1).Cells("Char.Font").Formula
                .Cells("Char.Size").Formula = sel.Item(1).Cells("Char.Size").Formula
                .Cells("Char.Style").Formula = sel.Item(1).Cells("Char.Style").Formula
                c1 = AscW(Mid(str, CInt(Rnd() * (Len(str) - 1)) + 1, 1))
                .Text = c1
                'c2 = AscW(.Text)
            End With
        Next
    End Sub

Paul Herber

I'm not sure whether you can work with Unicode in this manner. Characters have different lengths, depending on the encoding and the plane. You can't just replace one character with another.
Too late here now to think about a solution.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

christianovitch

You're likely right that this is part of the problem.  I broke out my string of characters into separate shapes, one character per shape, and then ran CharCount on the character of each shape--some were one character long, and others two characters long (despite only one character being visible in each shape).  I also ran AscW on the character of each shape, which I understand should kick back the Unicode code point of that character.  However, it kicked back negative numbers, including multiple duplicate values.  None of the characters repeat, so it seems like that shouldn't happen. 

Below is a list of the # of characters in each shape (1 or 2) and the AscW code for each shape's visible character.

1    9825
1    9826
1    9827
1    9828
1    9829
1    9830
1    9831
1    9752
2    -10180
1     11088
2    -10180
2    -10180
2    -10180
2    -10179
2    -10179

I'm utterly stumped.  Any help would be much appreciated.

Thanks
Christian

Surrogate

Hi, Christian!
Quote from: christianovitch on September 10, 2021, 06:49:26 AM
I broke out my string of characters into separate shapes, one character per shape, and then ran CharCount on the character of each shape--some were one character long, and others two characters long (despite only one character being visible in each shape).
You faced with this issue with non-latin unicode symbols?

christianovitch

Yes, correct--am using Segoe UI Emoji font, and the characters in question were:

♡♢♣♤♥♦♧☘🍒⭐🎁🏆🎲💎💰 (although I'd really like it to work with any characters--not necessarily limited to just these)

Best,
Christian


wapperdude

I looked at your code using VBA.  Not sure what exactly you were expecting, but with limited testing, this code did not barf.  However, I did not have the "font" to do the emoji's that you want to include.  Hopefully, those won't present a problem.  I broke the random number calculation into two statements, in order to track what they're doing and to easily adjust formulas if desired.


Sub myMac()
    Dim vSels As Visio.Selection
    Dim str As String
    Dim fnt As String
    Dim c1, c2 As String
   
   
    Set vSels = ActiveWindow.Selection
   
    If vSels.Count <= 1 Then Exit Sub
   
    str = vSels.Item(1).Text
'    fnt = Globals.ThisAddIn.Application.ActiveDocument.Fonts(CInt(sel.Item(1).Cells("Char.Font").Formula)).Name
   
    If Len(str) = 0 Then Exit Sub
    Debug.Print "rndNum", "rnum", "c1"
    strLen = Len(str)
    For x = 2 To vSels.Count
        With vSels.Item(x)
            .Cells("Char.Font").Formula = vSels.Item(1).Cells("Char.Font").Formula
            .Cells("Char.Size").Formula = vSels.Item(1).Cells("Char.Size").Formula
            .Cells("Char.Style").Formula = vSels.Item(1).Cells("Char.Style").Formula
            rndnum = Int((strLen - 1) * Rnd)
            rnum = rndnum + 1
            c1 = AscW(Mid(str, rnum, 1))
            .Text = c1
            Debug.Print rndnum, rnum, c1
        End With
    Next
    Debug.Print ""

End Sub
Visio 2019 Pro

christianovitch

Yes, it works fine with more limited character sets--it's when you get into symbols in larger character sets where it runs into problems...  :(  But glad to hear that my code is otherwise sound--am not a programmer by training, but a mech. engineer.

Christian

Surrogate

Offtopic
Quote from: christianovitch on September 13, 2021, 04:14:36 AM
but a mech. engineer
wow! just wondered 🙂
what kind of mechanical diagrams need symbols like?
♡♢♣♤♥♦♧☘🍒⭐🎁🏆🎲💎💰

christianovitch

I sometimes have to provide diagrams of slot machines.  But you likely guessed that.  Wanted a way to make them easily randomizable.

Cheers,
Christian

wapperdude

#9
Doh!  Of course.  But, that did not jump out at me.

Since the codes for each character have multi-digit designations, which aren't in a reasonable numerical order, thus complicating the randomization process, how about making a list which contains the actual numbers, and then just randomizing the selected index of the list.  The list wouldn't have to be too long.  In fact, that might be doable entirely within the shape sheet, no vba required.

Just a thought.

Ed.:  Check out this treatment on Unicodes and shapesheet functionality by David Parker:  https://bvisual.net/2020/03/31/using-code-and-unicode-functions-in-visio/?cn-reloaded=1
Visio 2019 Pro

christianovitch

It's an interesting thought, but what I really want is the ability to populate a single shape with a number of arbitrary "seed" characters and then have a routine that just selects any random single character from that set of seed characters and inserts it into each additional shape in the selection set.  If you take the raw string output of the see string, it fails due to the potential Unicode symbols not translating into a valid string.  I tried to be clever and use the Characters object to select random individual characters in the seed text and then copy and past them into the destination shapes, but then I found that the number of characters in the Characters object did not map to the number of displayed characters since some displayed characters were really two characters in length via the Characters object. 

I couldn't figure out a way to reliably parse the Characters object to identify single- and double-character characters, so couldn't correctly select the individual visible characters. 

I guess I could do something half-assed and insert a space between each visible character and try to use that as a delimiter to allow me to identify the start and end point of each visible character, but it seems so inelegant.

Christian

wapperdude

Take a look at what David Parker has done.  It may provide some insight. 

Your concept is quite clever, but it has two issues.  One, it uses code, and two, it doesn't work with some Unicode emoji's.  So rather than using code to go thru a set of characters to generate random subsets, just create a list and randomly select from the list.  That avoids the pitfalls of artificially creating random character codes.  It can all be done within the shapesheet, and that's better than using code. 

It's your decision, but do look at David Parker's post.  It might shed some light on those double character problems.
Visio 2019 Pro

christianovitch

OK, I'll take a look and see if David's material is of assistance.

Thanks for pointing me to it!

Best,
Christian

Paul Herber

As far as I know unicode characters can be multi-byte (up to 6?). Swapping one character for another may not be reliable but character concatenation in a string will always work.
Electronic and Electrical engineering, business and software stencils for Visio -

https://www.paulherber.co.uk/

wapperdude

Visio 2019 Pro