identifying most recently used symbol (via VBA) in MSO2003, as shown in the insert symbol dialogue b

K

KR

Does anyone know where the information for the most recently used symbol can
be accessed via VBA? It must be stored somewhere, because it is the leftmost
symbol of the recently used symbols in the insert symbol dialogue box.

I often use the same symbol lots of times in a single document, so I want to
assign a macro to a custom button that simply inserts whatever the last
symbol was that was inserted in the document. It'll still be better than
using the keyboard shortcut, for example [<alt>+0176], assuming I could even
remember the keyboard shortcut... :-/

Thanks!
Keith
 
J

Jay Freedman

Hi Keith,

I can tell you the information, but I don't think it's going to be a big
help in creating the function you want.

The list of recently used symbols is in the registry in the binary value
SymbolMRU under the key (adjust for your Office version)
HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Common\General.

The hex code for the most recently used symbol is in bytes 0008 and 0009 in
byte-reversed order (for example, if the hex code is 2526, the two bytes
contain 26 25). The name of the font is in double-byte characters starting
at byte 0032 (hex), with 00 byte padding out to byte 0071 (hex).

VBA doesn't have proper functions for dealing with non-string registry data,
but there are Win32 APIs you can use -- see Karl Peterson's site at
http://mvps.org/vb/apixref.htm and look at the samples for the functions
that start with 'Reg', especially RegQueryValueEx.
 
K

KR

Gack. <cough>

I'm not a programmer by training or trade, so my eyes glaze over anytime I
think stuff outside of VBA will be involved. ;-)

Of course, on the document I'm working on today, I've had to insert the same
symbol a bajillion times, so maybe I'll get motivated and take a harder look
this time. I appreciate your very complete information about where the data
is stored!

Thanks,
Keith

Jay Freedman said:
Hi Keith,

I can tell you the information, but I don't think it's going to be a big
help in creating the function you want.

The list of recently used symbols is in the registry in the binary value
SymbolMRU under the key (adjust for your Office version)
HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Common\General.

The hex code for the most recently used symbol is in bytes 0008 and 0009 in
byte-reversed order (for example, if the hex code is 2526, the two bytes
contain 26 25). The name of the font is in double-byte characters starting
at byte 0032 (hex), with 00 byte padding out to byte 0071 (hex).

VBA doesn't have proper functions for dealing with non-string registry data,
but there are Win32 APIs you can use -- see Karl Peterson's site at
http://mvps.org/vb/apixref.htm and look at the samples for the functions
that start with 'Reg', especially RegQueryValueEx.

--
Regards,
Jay Freedman
Microsoft Word MVP
Does anyone know where the information for the most recently used
symbol can be accessed via VBA? It must be stored somewhere, because
it is the leftmost symbol of the recently used symbols in the insert
symbol dialogue box.

I often use the same symbol lots of times in a single document, so I
want to assign a macro to a custom button that simply inserts
whatever the last symbol was that was inserted in the document. It'll
still be better than using the keyboard shortcut, for example
[<alt>+0176], assuming I could even remember the keyboard shortcut...
:-/

Thanks!
Keith
 
J

Jay Freedman

Hi Keith,

Now that I've scared you sufficiently <eg>... A better idea is to
assign an easier shortcut to each symbol you use frequently. Just
select the symbol in the Insert Symbol dialog and click the Shortcut
button. Then you can assign a letter with some combination of Ctrl,
Alt, and Shift. If need be, you can reassign the shortcut to a
different symbol later.

BTW, I *am* a professional programmer, but grabbing data out of the
registry and turning it into a symbol isn't something I ever looked at
before, and it would probably take me a couple of hours of
head-scratching to get it right. It isn't worth the effort.

--
Regards,
Jay Freedman
Microsoft Word MVP

Gack. <cough>

I'm not a programmer by training or trade, so my eyes glaze over anytime I
think stuff outside of VBA will be involved. ;-)

Of course, on the document I'm working on today, I've had to insert the same
symbol a bajillion times, so maybe I'll get motivated and take a harder look
this time. I appreciate your very complete information about where the data
is stored!

Thanks,
Keith

Jay Freedman said:
Hi Keith,

I can tell you the information, but I don't think it's going to be a big
help in creating the function you want.

The list of recently used symbols is in the registry in the binary value
SymbolMRU under the key (adjust for your Office version)
HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Common\General.

The hex code for the most recently used symbol is in bytes 0008 and 0009 in
byte-reversed order (for example, if the hex code is 2526, the two bytes
contain 26 25). The name of the font is in double-byte characters starting
at byte 0032 (hex), with 00 byte padding out to byte 0071 (hex).

VBA doesn't have proper functions for dealing with non-string registry data,
but there are Win32 APIs you can use -- see Karl Peterson's site at
http://mvps.org/vb/apixref.htm and look at the samples for the functions
that start with 'Reg', especially RegQueryValueEx.

--
Regards,
Jay Freedman
Microsoft Word MVP
Does anyone know where the information for the most recently used
symbol can be accessed via VBA? It must be stored somewhere, because
it is the leftmost symbol of the recently used symbols in the insert
symbol dialogue box.

I often use the same symbol lots of times in a single document, so I
want to assign a macro to a custom button that simply inserts
whatever the last symbol was that was inserted in the document. It'll
still be better than using the keyboard shortcut, for example
[<alt>+0176], assuming I could even remember the keyboard shortcut...
:-/

Thanks!
Keith
 
S

Sabaka

Here is a thought.

If the special symbol is stored in a place that isn't readily accessible,
why not store it yourself in a location of your choosing? The code which
follows stores it at the start of the document. It would require that you
remember to manually delete the symbol at the end of your session (though I
suppose you could intercept a close event and do it with code then).

It's not a partiuclarly elegant solution. I would like to know how one can
save a variable after it goes out of scope when the Macro finishes so that it
could be used by another module (and so you don't have store it in the
document.)

Sub InsertSymbol()
'
'Intercepts Word Command for Inserting a symbol,
'proceeds with the insert symbol command, then
'places copy of the symbol inserted at start of
'document for later reuse
'
Dim symb As String
Dim MyRange As Range
' Insert a special character
Dialogs(wdDialogInsertSymbol).Show
' Assign the special char to the variable symb
Set MyRange = ActiveDocument.Range(Start:=Selection.End - 1,
End:=Selection.End)
symb = MyRange.Text
' Place a copy of the symbol at the start of the document
' where it can be read by another Macro that needs to know
' the value of the most recently used symbol
With ActiveDocument.Content
.InsertParagraphBefore
.InsertBefore symb
End With
End Sub
 
J

Jay Freedman

Hi Sabaka,

I don't mind solutions that aren't particularly elegant -- I use 'em
all the time <g> -- but unfortunately this one doesn't work in all
situations.

The problem is that Word doesn't treat "decorative fonts" -- Symbol,
the Wingdings family, and a number of others -- the same way it treats
"normal" fonts when you use the Insert > Symbol dialog. There's a good
discussion of this at
http://word.mvps.org/faqs/macrosvba/FindReplaceSymbols.htm. The bottom
line is that if you run your macro and insert something from a
decorative font, the character it places at the beginning of the
document is always a left parenthesis regardless of what character you
selected in the dialog.

To work around this, you need to use the technique indicated in the
FAQ article: capture the character number and font name from the
dialog and store them separately. The demo macros below show how to do
that.

As for where to store the info, there are several possibilities, and
the choice depends on what functionality you want to provide.

- Storing them in the body of the document is generally not good for
the reasons you've already given.
- You can store them in document variables, as the demo below does.
That way they're "invisible" except to macros. Doc variables are
stored in the file when you save the document. This choice means that
each document has its own "most recent symbol", which could be useful
in some scenarios (e.g., if you send the document to someone else) but
probably isn't what you want.
- You could instead use the System.PrivateProfileString property to
store the info either in the registry or in a separate text file. This
makes the "most recent symbol" available system-wide (but it doesn't
travel with a document that you send to someone). This is probably the
best choice.

Sub InsertSymbol()
'
'Intercepts Word Command for Inserting a symbol,
'proceeds with the insert symbol command, then
'stores info about the symbol in doc variables
'for later use

Dim symb As String, fnt As String
Dim MyRange As Range

' Insert a special character
With Dialogs(wdDialogInsertSymbol)
.Show
Selection.MoveStart unit:=wdCharacter, Count:=-1
symb = CStr(.Charnum)
fnt = .Font
Selection.Collapse wdCollapseEnd
End With
' Place the symbol's charnum & font in document variables
' where they can be read by another macro that needs to know
' the value of the most recently used symbol
ActiveDocument.Variables("SymbolMRU").Value = symb
ActiveDocument.Variables("SymbolMRUfont").Value = fnt
End Sub

' the "other macro", for example...
Sub InsertRecentSymbol()
On Error GoTo bye
Selection.Collapse wdCollapseEnd
Selection.InsertSymbol _
CharacterNumber:=CLng( _
ActiveDocument.Variables("SymbolMRU").Value), _
Font:=ActiveDocument.Variables("SymbolMRUfont").Value, _
Unicode:=True
Selection.Collapse wdCollapseEnd
bye:
End Sub

--
Regards,
Jay Freedman
Microsoft Word MVP

Here is a thought.

If the special symbol is stored in a place that isn't readily accessible,
why not store it yourself in a location of your choosing? The code which
follows stores it at the start of the document. It would require that you
remember to manually delete the symbol at the end of your session (though I
suppose you could intercept a close event and do it with code then).

It's not a partiuclarly elegant solution. I would like to know how one can
save a variable after it goes out of scope when the Macro finishes so that it
could be used by another module (and so you don't have store it in the
document.)

Sub InsertSymbol()
'
'Intercepts Word Command for Inserting a symbol,
'proceeds with the insert symbol command, then
'places copy of the symbol inserted at start of
'document for later reuse
'
Dim symb As String
Dim MyRange As Range
' Insert a special character
Dialogs(wdDialogInsertSymbol).Show
' Assign the special char to the variable symb
Set MyRange = ActiveDocument.Range(Start:=Selection.End - 1,
End:=Selection.End)
symb = MyRange.Text
' Place a copy of the symbol at the start of the document
' where it can be read by another Macro that needs to know
' the value of the most recently used symbol
With ActiveDocument.Content
.InsertParagraphBefore
.InsertBefore symb
End With
End Sub


KR said:
Does anyone know where the information for the most recently used symbol can
be accessed via VBA? It must be stored somewhere, because it is the leftmost
symbol of the recently used symbols in the insert symbol dialogue box.

I often use the same symbol lots of times in a single document, so I want to
assign a macro to a custom button that simply inserts whatever the last
symbol was that was inserted in the document. It'll still be better than
using the keyboard shortcut, for example [<alt>+0176], assuming I could even
remember the keyboard shortcut... :-/

Thanks!
Keith
 
S

Sabaka

Hi Jay,

Thank you! I cut and pasted your code - it's pretty cool!

Thanks for answering my question about storing info. I'm teaching this to
myself and it seems like something that could come up in a variety of
contexts.

Thanks also for the code and the link. Working through the details of the
syntax and the link will keep me busy for a little while.


Jay Freedman said:
Hi Sabaka,

I don't mind solutions that aren't particularly elegant -- I use 'em
all the time <g> -- but unfortunately this one doesn't work in all
situations.

The problem is that Word doesn't treat "decorative fonts" -- Symbol,
the Wingdings family, and a number of others -- the same way it treats
"normal" fonts when you use the Insert > Symbol dialog. There's a good
discussion of this at
http://word.mvps.org/faqs/macrosvba/FindReplaceSymbols.htm. The bottom
line is that if you run your macro and insert something from a
decorative font, the character it places at the beginning of the
document is always a left parenthesis regardless of what character you
selected in the dialog.

To work around this, you need to use the technique indicated in the
FAQ article: capture the character number and font name from the
dialog and store them separately. The demo macros below show how to do
that.

As for where to store the info, there are several possibilities, and
the choice depends on what functionality you want to provide.

- Storing them in the body of the document is generally not good for
the reasons you've already given.
- You can store them in document variables, as the demo below does.
That way they're "invisible" except to macros. Doc variables are
stored in the file when you save the document. This choice means that
each document has its own "most recent symbol", which could be useful
in some scenarios (e.g., if you send the document to someone else) but
probably isn't what you want.
- You could instead use the System.PrivateProfileString property to
store the info either in the registry or in a separate text file. This
makes the "most recent symbol" available system-wide (but it doesn't
travel with a document that you send to someone). This is probably the
best choice.

Sub InsertSymbol()
'
'Intercepts Word Command for Inserting a symbol,
'proceeds with the insert symbol command, then
'stores info about the symbol in doc variables
'for later use

Dim symb As String, fnt As String
Dim MyRange As Range

' Insert a special character
With Dialogs(wdDialogInsertSymbol)
.Show
Selection.MoveStart unit:=wdCharacter, Count:=-1
symb = CStr(.Charnum)
fnt = .Font
Selection.Collapse wdCollapseEnd
End With
' Place the symbol's charnum & font in document variables
' where they can be read by another macro that needs to know
' the value of the most recently used symbol
ActiveDocument.Variables("SymbolMRU").Value = symb
ActiveDocument.Variables("SymbolMRUfont").Value = fnt
End Sub

' the "other macro", for example...
Sub InsertRecentSymbol()
On Error GoTo bye
Selection.Collapse wdCollapseEnd
Selection.InsertSymbol _
CharacterNumber:=CLng( _
ActiveDocument.Variables("SymbolMRU").Value), _
Font:=ActiveDocument.Variables("SymbolMRUfont").Value, _
Unicode:=True
Selection.Collapse wdCollapseEnd
bye:
End Sub

--
Regards,
Jay Freedman
Microsoft Word MVP

Here is a thought.

If the special symbol is stored in a place that isn't readily accessible,
why not store it yourself in a location of your choosing? The code which
follows stores it at the start of the document. It would require that you
remember to manually delete the symbol at the end of your session (though I
suppose you could intercept a close event and do it with code then).

It's not a partiuclarly elegant solution. I would like to know how one can
save a variable after it goes out of scope when the Macro finishes so that it
could be used by another module (and so you don't have store it in the
document.)

Sub InsertSymbol()
'
'Intercepts Word Command for Inserting a symbol,
'proceeds with the insert symbol command, then
'places copy of the symbol inserted at start of
'document for later reuse
'
Dim symb As String
Dim MyRange As Range
' Insert a special character
Dialogs(wdDialogInsertSymbol).Show
' Assign the special char to the variable symb
Set MyRange = ActiveDocument.Range(Start:=Selection.End - 1,
End:=Selection.End)
symb = MyRange.Text
' Place a copy of the symbol at the start of the document
' where it can be read by another Macro that needs to know
' the value of the most recently used symbol
With ActiveDocument.Content
.InsertParagraphBefore
.InsertBefore symb
End With
End Sub


KR said:
Does anyone know where the information for the most recently used symbol can
be accessed via VBA? It must be stored somewhere, because it is the leftmost
symbol of the recently used symbols in the insert symbol dialogue box.

I often use the same symbol lots of times in a single document, so I want to
assign a macro to a custom button that simply inserts whatever the last
symbol was that was inserted in the document. It'll still be better than
using the keyboard shortcut, for example [<alt>+0176], assuming I could even
remember the keyboard shortcut... :-/

Thanks!
Keith
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top