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
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.
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
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?
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
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
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
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?
♡♢♣♤♥♦♧☘🍒⭐🎁🏆🎲💎💰
I sometimes have to provide diagrams of slot machines. But you likely guessed that. Wanted a way to make them easily randomizable.
Cheers,
Christian
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 (https://bvisual.net/2020/03/31/using-code-and-unicode-functions-in-visio/?cn-reloaded=1)
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
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.
OK, I'll take a look and see if David's material is of assistance.
Thanks for pointing me to it!
Best,
Christian
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.
In a related topic, by David Parker, regarding use of emoticons in Visio: https://bvisual.net/2020/05/18/using-emojis-in-visio/?cn-reloaded=1 (https://bvisual.net/2020/05/18/using-emojis-in-visio/?cn-reloaded=1)
This is not an endorsement. But, I discovered this site which might be useful for your effort: https://perchance.org/emoji (https://perchance.org/emoji)