How do I migrate custom labels from Word 2003 to 2007?

G

Guest

I have a number of custom labels created with Word 2003. They are saved as
registry entries.
In 2007, custom labels are saved in an xml file.

Does anyone know of a way I can easily migrate my 2003 custom labels to 2007
fomat?
 
G

Graham Mayor

It was the same when Word 2002 replace 2000. You will have to rebuild your
custom label defintions.

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP

My web site www.gmayor.com

<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
 
P

Peter Jamieson

I threw together some Word macros that may help on this front, but whether
they are worth using depends on how many definitions you need to convert and
how much effort you are able/willing to put in to make the macro work. If
you are used to using VBA, it should be fairly straightforward. If not, it
is likely to be more trouble than it's worth.

One problem is that the existing label definitions are stored in a binary
format in the registry, and as far as I know the format is undocumented, so
a large amount of guesswork is involved as to what is in there, and what
/might/ be in there. For example, when I set up a label definition on my
current system, I get a choice of four stationery options - US Letter, US
Letter landscape, A4, A4 landscape, and I don't know if there are other
possibilities.

My guess is that the Word 2007 XML format is better documented, but I
haven't actually looked for the schema yet.

To use the macros, you will need to
a. use the Windows registry manually to export a .reg file containing the
layour definitions
b. install the macros in Word
c. if necessary, modify the pathname of the .reg file in the macro (I don't
prompt for it)
d. if necessary, modify the pathname of the output .xml file in the macro
(I don't prompt for it)
e. run the macro
f. (Probably) close Word
g. save a copy of your existing pg_custom.xml file
h. copy the newly created pg_custom.xml file into the correct location. In
other words, you will be replacing any existing definitions - if you need to
add to them, you will probably have to copy individual layout records from
the converted XML file to your pg_custom.xml file and perhaps modify one or
two IDs.
i. start Word and test the label layouts.

To do (a), start the WIndows registry program, locate the key containing the
custom definitions, which is probably

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels

then export the label data to a .reg file. I have used the following path in
my macro code

c:\a\mylabels.reg

For example, with some test data, I see

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels]
"a3"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,00,00,00,64,\
00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,03,00,00,00
"junelabel"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,6e,04,00,00,08,01,00,\
00,6e,04,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"xyz"=hex:4c,03,5c,00,00,00,6c,00,5d,00,10,0e,00,00,70,08,00,00,98,01,00,00,5d,\
03,00,00,a0,0e,00,00,70,08,00,00,03,00,07,00,01,00,02,00,00,00
"a4"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,b0,04,00,00,08,01,00,00,93,\
02,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"dotmat"=hex:4c,03,5c,00,01,00,6c,00,5d,00,81,0f,00,00,81,0f,00,00,fc,03,00,00,\
54,01,00,00,81,0f,00,00,d5,10,00,00,01,00,02,00,01,00,08,00,00,00
"rollborderless"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,\
00,00,00,64,00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,02,00,00,00

In other words, I do not have any subkeys under WordCustomLabels. There are
only values.

If you don't know how to do (b), and perhaps (e), visit

http://word.mvps.org/FAQs/MacrosVBA/CreateAMacro.htm

I provide the macros below. NB, there are some long lines in the code at
present.

If you need to do (c) or (d), either modify the macro code directly (each
pathname is only in one place in the code) or use the same paths as I have
used, which are as follows:
1. the registry file is at:
c:\a\mylabels.reg
2. The output .xml file is at
c:\a\pg_custom.xml

The macros (they are pretty crude!)

Sub ConvertWord2003LabelDefs()
'
' Macro to convert Word 2003 Custom label definitions
' exported from the registry to Word 2007 XML definitions
' Thrown together 11 Jun 2007 by Peter Jamieson
'
' This is based on numerous guesses about the format of the
' binary data that describes the labels in Word 2003.
' I would expect the XML schema for the Word 2007 file to
' be defined somewhere but have not yet looked
Dim objLabelDefDoc As Word.Document

' Open the exported .reg (it's a Unicode text file)
Set objLabelDefDoc = Documents.Open(FileName:="c:\a\mylabels.reg", _
ConfirmConversions:=False, _
Encoding:=1200)

' Delete the lines before the label entries
With Selection
.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
.Cut
End With

' Delete the lines after the label entries
With Selection
.EndKey Unit:=wdStory
' .MoveUp Unit:=wdLine, Count:=3, Extend:=wdExtend
' .Cut
.TypeBackspace
End With

' back to the beginning
Selection.HomeKey Unit:=wdStory

' replace the =hex: bits by commas
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "=hex:"
.Replacement.Text = ","
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the \ line ends
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "\^p "
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the " characters round the label names
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Chr(34)
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' Selec the whole document and convert it
' to a table
Selection.WholeStory
Selection.ConvertToTable _
Separator:=wdSeparateByCommas, _
AutoFitBehavior:=wdAutoFitContent
Call OutputWord2007LabelDefs
objLabelDefDoc.Close savechanges:=False
End Sub

Sub OutputWord2007LabelDefs()
Dim objRow As Word.Row
Dim lngLabelWidth As Long
Dim lngLabelHeight As Long
Dim lngHorizontalPitch As Long
Dim lngVerticalPitch As Long
Dim strAcross As Long
Dim strDown As Long
Dim strSideMargin As String
Dim strTopMargin As String
Dim strHorizGap As String
Dim strVertGap As String
Dim strLabelName As String
Dim strDotMatrixLabel As String
Dim strLocDesc As String
Open "c:\a\pg_custom.xml" For Output As #1
Print #1, "<?xml version=""1.0""?>"
Print #1, "<vps>"
Print #1, " <vendorProductSets>"
Print #1, " <vendorProductSet vendorID=""0"" vendor=""Custom""
copyright="""" version=""1"" schemaVersion=""1"">"
For Each objRow In ActiveDocument.Tables(1).Rows
strLabelName = Left(objRow.Cells(1).Range.Text,
Len(objRow.Cells(1).Range.Text) - 2)
If CInt(Left(objRow.Cells(6).Range.Text, 2)) = 1 Then
strDotMatrixLabel = "true"
strLocDesc = "Custom dot matrix"
Else
strDotMatrixLabel = "false"
strLocDesc = "Custom laser"
End If
lngLabelWidth = emu(objRow, 12)
lngLabelHeight = emu(objRow, 16)
strSideMargin = Trim(CStr(emu(objRow, 20)))
strTopMargin = Trim(CStr(emu(objRow, 24)))
lngHorizontalPitch = emu(objRow, 28)
lngVerticalPitch = emu(objRow, 32)
strHorizGap = Trim(CStr(lngHorizontalPitch - lngLabelWidth))
strVertGap = Trim(CStr(lngVerticalPitch - lngLabelHeight))
strAcross = Trim(CStr(wrd(objRow, 36)))
strDown = Trim(CStr(wrd(objRow, 38)))
Select Case wrd(objRow, 42)
Case 0 ' US Letter portrait
strSheetHeight = "10058400"
strSheetWidth = "7772400"
Case 1 ' US Letter landscape
strSheetHeight = "7772400"
strSheetWidth = "10058400"
Case 2 ' A4 portrait
strSheetHeight = "10692130"
strSheetWidth = "7560310"
Case 3 ' A4 landscape
strSheetHeight = "7560310"
strSheetWidth = "10692130"

Case Else ' set to US letter portrait for now
strSheetHeight = "10058400"
strSheetWidth = "7772400"

End Select
Print #1, " <product units=""emu"" productID=""" & Trim(objRow.Index)
& """ layoutGroup=""all"" bindingEdge=""none"" dotMatrixLabel=""" &
strDotMatrixLabel & """ fold=""none"">"
Print #1, " <prodName nameGroup=""custom"">"
Print #1, " <locName locale=""all"">" & strLabelName &
"</locName>"
Print #1, " </prodName>"
Print #1, " <desc descGroup=""custom"">"
Print #1, " <locDesc locale=""all"">" & strLocDesc & "</locDesc>"
Print #1, " </desc>"
Print #1, " <masterPanel masterID=""0"" height=""" &
Trim(CStr(lngLabelHeight)) & """ width=""" & Trim(CStr(lngLabelWidth)) & """
shape=""rect"" cornerRadius=""0"" topMargin=""0"" leftMargin=""0""
bottomMargin=""0"" rightMargin=""0"" centerContent=""false"">"
Print #1, " </masterPanel>"
Print #1, " <sheet height=""" & strSheetHeight & """ width=""" &
strSheetWidth & """ allowPartialSheet=""false"" bgColor=""""
isTwoSided=""false"" printMirrored=""false"">"
Print #1, " <sheetGrid numAcross=""" & strAcross & """
numDown=""" & strDown & """ horizGap=""" & strHorizGap & """ vertGap=""" &
strVertGap & """ posX=""" & strSideMargin & """ posY=""" & strTopMargin &
""" cellWidth=""0"" cellHeight=""0"">"
Print #1, " </sheetGrid>"
Print #1, " </sheet>"
Print #1, " </product>"
Next
Print #1, " </vendorProductSet>"
Print #1, " </vendorProductSets>"
Print #1, "</vps>"

Close #1
End Sub

Function emu(objRow As Row, intColumn As Integer) As Long
' Get a measurement in ems (12700ems/pt, 36000ems/cm I think)
emu = wrd(objRow, intColumn) * 635
End Function

Function wrd(objRow As Row, intColumn As Integer) As Long
' Get a measurement in twips (20twips/pt I think)
wrd = (256 * hex2tolng(objRow.Cells(intColumn + 1).Range.Text) + _
hex2tolng(objRow.Cells(intColumn).Range.Text))
End Function

Function hex2tolng(strHex As String) As Long
' Convert 2-digit hex value to number
hex2tolng = (16 * (InStr(1, "0123456789ABCDEF", UCase(Left(strHex, 1))) -
1)) + _
InStr(1, "0123456789ABCDEF", UCase(Mid(strHex, 2, 1))) - 1
End Function

Peter Jamieson
 
G

Guest

Thanks Graham for your answer and thanks Peter for all that effort in trying
to get around the problem of no available tools!

Peter Jamieson said:
I threw together some Word macros that may help on this front, but whether
they are worth using depends on how many definitions you need to convert and
how much effort you are able/willing to put in to make the macro work. If
you are used to using VBA, it should be fairly straightforward. If not, it
is likely to be more trouble than it's worth.

One problem is that the existing label definitions are stored in a binary
format in the registry, and as far as I know the format is undocumented, so
a large amount of guesswork is involved as to what is in there, and what
/might/ be in there. For example, when I set up a label definition on my
current system, I get a choice of four stationery options - US Letter, US
Letter landscape, A4, A4 landscape, and I don't know if there are other
possibilities.

My guess is that the Word 2007 XML format is better documented, but I
haven't actually looked for the schema yet.

To use the macros, you will need to
a. use the Windows registry manually to export a .reg file containing the
layour definitions
b. install the macros in Word
c. if necessary, modify the pathname of the .reg file in the macro (I don't
prompt for it)
d. if necessary, modify the pathname of the output .xml file in the macro
(I don't prompt for it)
e. run the macro
f. (Probably) close Word
g. save a copy of your existing pg_custom.xml file
h. copy the newly created pg_custom.xml file into the correct location. In
other words, you will be replacing any existing definitions - if you need to
add to them, you will probably have to copy individual layout records from
the converted XML file to your pg_custom.xml file and perhaps modify one or
two IDs.
i. start Word and test the label layouts.

To do (a), start the WIndows registry program, locate the key containing the
custom definitions, which is probably

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels

then export the label data to a .reg file. I have used the following path in
my macro code

c:\a\mylabels.reg

For example, with some test data, I see

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels]
"a3"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,00,00,00,64,\
00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,03,00,00,00
"junelabel"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,6e,04,00,00,08,01,00,\
00,6e,04,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"xyz"=hex:4c,03,5c,00,00,00,6c,00,5d,00,10,0e,00,00,70,08,00,00,98,01,00,00,5d,\
03,00,00,a0,0e,00,00,70,08,00,00,03,00,07,00,01,00,02,00,00,00
"a4"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,b0,04,00,00,08,01,00,00,93,\
02,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"dotmat"=hex:4c,03,5c,00,01,00,6c,00,5d,00,81,0f,00,00,81,0f,00,00,fc,03,00,00,\
54,01,00,00,81,0f,00,00,d5,10,00,00,01,00,02,00,01,00,08,00,00,00
"rollborderless"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,\
00,00,00,64,00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,02,00,00,00

In other words, I do not have any subkeys under WordCustomLabels. There are
only values.

If you don't know how to do (b), and perhaps (e), visit

http://word.mvps.org/FAQs/MacrosVBA/CreateAMacro.htm

I provide the macros below. NB, there are some long lines in the code at
present.

If you need to do (c) or (d), either modify the macro code directly (each
pathname is only in one place in the code) or use the same paths as I have
used, which are as follows:
1. the registry file is at:
c:\a\mylabels.reg
2. The output .xml file is at
c:\a\pg_custom.xml

The macros (they are pretty crude!)

Sub ConvertWord2003LabelDefs()
'
' Macro to convert Word 2003 Custom label definitions
' exported from the registry to Word 2007 XML definitions
' Thrown together 11 Jun 2007 by Peter Jamieson
'
' This is based on numerous guesses about the format of the
' binary data that describes the labels in Word 2003.
' I would expect the XML schema for the Word 2007 file to
' be defined somewhere but have not yet looked
Dim objLabelDefDoc As Word.Document

' Open the exported .reg (it's a Unicode text file)
Set objLabelDefDoc = Documents.Open(FileName:="c:\a\mylabels.reg", _
ConfirmConversions:=False, _
Encoding:=1200)

' Delete the lines before the label entries
With Selection
.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
.Cut
End With

' Delete the lines after the label entries
With Selection
.EndKey Unit:=wdStory
' .MoveUp Unit:=wdLine, Count:=3, Extend:=wdExtend
' .Cut
.TypeBackspace
End With

' back to the beginning
Selection.HomeKey Unit:=wdStory

' replace the =hex: bits by commas
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "=hex:"
.Replacement.Text = ","
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the \ line ends
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "\^p "
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the " characters round the label names
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Chr(34)
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' Selec the whole document and convert it
' to a table
Selection.WholeStory
Selection.ConvertToTable _
Separator:=wdSeparateByCommas, _
AutoFitBehavior:=wdAutoFitContent
Call OutputWord2007LabelDefs
objLabelDefDoc.Close savechanges:=False
End Sub

Sub OutputWord2007LabelDefs()
Dim objRow As Word.Row
Dim lngLabelWidth As Long
Dim lngLabelHeight As Long
Dim lngHorizontalPitch As Long
Dim lngVerticalPitch As Long
Dim strAcross As Long
Dim strDown As Long
Dim strSideMargin As String
Dim strTopMargin As String
Dim strHorizGap As String
Dim strVertGap As String
Dim strLabelName As String
Dim strDotMatrixLabel As String
Dim strLocDesc As String
Open "c:\a\pg_custom.xml" For Output As #1
Print #1, "<?xml version=""1.0""?>"
Print #1, "<vps>"
Print #1, " <vendorProductSets>"
Print #1, " <vendorProductSet vendorID=""0"" vendor=""Custom""
copyright="""" version=""1"" schemaVersion=""1"">"
For Each objRow In ActiveDocument.Tables(1).Rows
strLabelName = Left(objRow.Cells(1).Range.Text,
Len(objRow.Cells(1).Range.Text) - 2)
If CInt(Left(objRow.Cells(6).Range.Text, 2)) = 1 Then
strDotMatrixLabel = "true"
strLocDesc = "Custom dot matrix"
Else
strDotMatrixLabel = "false"
strLocDesc = "Custom laser"
End If
lngLabelWidth = emu(objRow, 12)
lngLabelHeight = emu(objRow, 16)
strSideMargin = Trim(CStr(emu(objRow, 20)))
strTopMargin = Trim(CStr(emu(objRow, 24)))
lngHorizontalPitch = emu(objRow, 28)
lngVerticalPitch = emu(objRow, 32)
strHorizGap = Trim(CStr(lngHorizontalPitch - lngLabelWidth))
strVertGap = Trim(CStr(lngVerticalPitch - lngLabelHeight))
strAcross = Trim(CStr(wrd(objRow, 36)))
strDown = Trim(CStr(wrd(objRow, 38)))
Select Case wrd(objRow, 42)
Case 0 ' US Letter portrait
strSheetHeight = "10058400"
strSheetWidth = "7772400"
Case 1 ' US Letter landscape
strSheetHeight = "7772400"
strSheetWidth = "10058400"
Case 2 ' A4 portrait
strSheetHeight = "10692130"
strSheetWidth = "7560310"
Case 3 ' A4 landscape
strSheetHeight = "7560310"
strSheetWidth = "10692130"

Case Else ' set to US letter portrait for now
strSheetHeight = "10058400"
strSheetWidth = "7772400"

End Select
Print #1, " <product units=""emu"" productID=""" & Trim(objRow.Index)
& """ layoutGroup=""all"" bindingEdge=""none"" dotMatrixLabel=""" &
strDotMatrixLabel & """ fold=""none"">"
Print #1, " <prodName nameGroup=""custom"">"
Print #1, " <locName locale=""all"">" & strLabelName &
"</locName>"
Print #1, " </prodName>"
Print #1, " <desc descGroup=""custom"">"
Print #1, " <locDesc locale=""all"">" & strLocDesc & "</locDesc>"
Print #1, " </desc>"
Print #1, " <masterPanel masterID=""0"" height=""" &
Trim(CStr(lngLabelHeight)) & """ width=""" & Trim(CStr(lngLabelWidth)) & """
shape=""rect"" cornerRadius=""0"" topMargin=""0"" leftMargin=""0""
bottomMargin=""0"" rightMargin=""0"" centerContent=""false"">"
Print #1, " </masterPanel>"
Print #1, " <sheet height=""" & strSheetHeight & """ width=""" &
strSheetWidth & """ allowPartialSheet=""false"" bgColor=""""
isTwoSided=""false"" printMirrored=""false"">"
Print #1, " <sheetGrid numAcross=""" & strAcross & """
numDown=""" & strDown & """ horizGap=""" & strHorizGap & """ vertGap=""" &
strVertGap & """ posX=""" & strSideMargin & """ posY=""" & strTopMargin &
""" cellWidth=""0"" cellHeight=""0"">"
Print #1, " </sheetGrid>"
Print #1, " </sheet>"
Print #1, " </product>"
Next
Print #1, " </vendorProductSet>"
Print #1, " </vendorProductSets>"
Print #1, "</vps>"

Close #1
End Sub

Function emu(objRow As Row, intColumn As Integer) As Long
' Get a measurement in ems (12700ems/pt, 36000ems/cm I think)
emu = wrd(objRow, intColumn) * 635
End Function

Function wrd(objRow As Row, intColumn As Integer) As Long
' Get a measurement in twips (20twips/pt I think)
wrd = (256 * hex2tolng(objRow.Cells(intColumn + 1).Range.Text) + _
hex2tolng(objRow.Cells(intColumn).Range.Text))
End Function

Function hex2tolng(strHex As String) As Long
' Convert 2-digit hex value to number
hex2tolng = (16 * (InStr(1, "0123456789ABCDEF", UCase(Left(strHex, 1))) -
1)) + _
InStr(1, "0123456789ABCDEF", UCase(Mid(strHex, 2, 1))) - 1
End Function

Peter Jamieson

Alice Graham said:
I have a number of custom labels created with Word 2003. They are saved as
 
P

Peter Jamieson

Hi Alice,

I would be interested to know if you tried the code I wrote - perhaps not
worth your while but since other people are likely to encounter this problem
the code may be worth a bit more work.

Peter Jamieson


Alice Graham said:
Thanks Graham for your answer and thanks Peter for all that effort in
trying
to get around the problem of no available tools!

Peter Jamieson said:
I threw together some Word macros that may help on this front, but
whether
they are worth using depends on how many definitions you need to convert
and
how much effort you are able/willing to put in to make the macro work. If
you are used to using VBA, it should be fairly straightforward. If not,
it
is likely to be more trouble than it's worth.

One problem is that the existing label definitions are stored in a binary
format in the registry, and as far as I know the format is undocumented,
so
a large amount of guesswork is involved as to what is in there, and what
/might/ be in there. For example, when I set up a label definition on my
current system, I get a choice of four stationery options - US Letter, US
Letter landscape, A4, A4 landscape, and I don't know if there are other
possibilities.

My guess is that the Word 2007 XML format is better documented, but I
haven't actually looked for the schema yet.

To use the macros, you will need to
a. use the Windows registry manually to export a .reg file containing
the
layour definitions
b. install the macros in Word
c. if necessary, modify the pathname of the .reg file in the macro (I
don't
prompt for it)
d. if necessary, modify the pathname of the output .xml file in the
macro
(I don't prompt for it)
e. run the macro
f. (Probably) close Word
g. save a copy of your existing pg_custom.xml file
h. copy the newly created pg_custom.xml file into the correct location.
In
other words, you will be replacing any existing definitions - if you need
to
add to them, you will probably have to copy individual layout records
from
the converted XML file to your pg_custom.xml file and perhaps modify one
or
two IDs.
i. start Word and test the label layouts.

To do (a), start the WIndows registry program, locate the key containing
the
custom definitions, which is probably

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels

then export the label data to a .reg file. I have used the following path
in
my macro code

c:\a\mylabels.reg

For example, with some test data, I see

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels]
"a3"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,00,00,00,64,\
00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,03,00,00,00
"junelabel"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,6e,04,00,00,08,01,00,\
00,6e,04,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"xyz"=hex:4c,03,5c,00,00,00,6c,00,5d,00,10,0e,00,00,70,08,00,00,98,01,00,00,5d,\
03,00,00,a0,0e,00,00,70,08,00,00,03,00,07,00,01,00,02,00,00,00
"a4"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,b0,04,00,00,08,01,00,00,93,\
02,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"dotmat"=hex:4c,03,5c,00,01,00,6c,00,5d,00,81,0f,00,00,81,0f,00,00,fc,03,00,00,\
54,01,00,00,81,0f,00,00,d5,10,00,00,01,00,02,00,01,00,08,00,00,00
"rollborderless"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,\

00,00,00,64,00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,02,00,00,00

In other words, I do not have any subkeys under WordCustomLabels. There
are
only values.

If you don't know how to do (b), and perhaps (e), visit

http://word.mvps.org/FAQs/MacrosVBA/CreateAMacro.htm

I provide the macros below. NB, there are some long lines in the code at
present.

If you need to do (c) or (d), either modify the macro code directly (each
pathname is only in one place in the code) or use the same paths as I
have
used, which are as follows:
1. the registry file is at:
c:\a\mylabels.reg
2. The output .xml file is at
c:\a\pg_custom.xml

The macros (they are pretty crude!)

Sub ConvertWord2003LabelDefs()
'
' Macro to convert Word 2003 Custom label definitions
' exported from the registry to Word 2007 XML definitions
' Thrown together 11 Jun 2007 by Peter Jamieson
'
' This is based on numerous guesses about the format of the
' binary data that describes the labels in Word 2003.
' I would expect the XML schema for the Word 2007 file to
' be defined somewhere but have not yet looked
Dim objLabelDefDoc As Word.Document

' Open the exported .reg (it's a Unicode text file)
Set objLabelDefDoc = Documents.Open(FileName:="c:\a\mylabels.reg", _
ConfirmConversions:=False, _
Encoding:=1200)

' Delete the lines before the label entries
With Selection
.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
.Cut
End With

' Delete the lines after the label entries
With Selection
.EndKey Unit:=wdStory
' .MoveUp Unit:=wdLine, Count:=3, Extend:=wdExtend
' .Cut
.TypeBackspace
End With

' back to the beginning
Selection.HomeKey Unit:=wdStory

' replace the =hex: bits by commas
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "=hex:"
.Replacement.Text = ","
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the \ line ends
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "\^p "
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the " characters round the label names
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Chr(34)
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' Selec the whole document and convert it
' to a table
Selection.WholeStory
Selection.ConvertToTable _
Separator:=wdSeparateByCommas, _
AutoFitBehavior:=wdAutoFitContent
Call OutputWord2007LabelDefs
objLabelDefDoc.Close savechanges:=False
End Sub

Sub OutputWord2007LabelDefs()
Dim objRow As Word.Row
Dim lngLabelWidth As Long
Dim lngLabelHeight As Long
Dim lngHorizontalPitch As Long
Dim lngVerticalPitch As Long
Dim strAcross As Long
Dim strDown As Long
Dim strSideMargin As String
Dim strTopMargin As String
Dim strHorizGap As String
Dim strVertGap As String
Dim strLabelName As String
Dim strDotMatrixLabel As String
Dim strLocDesc As String
Open "c:\a\pg_custom.xml" For Output As #1
Print #1, "<?xml version=""1.0""?>"
Print #1, "<vps>"
Print #1, " <vendorProductSets>"
Print #1, " <vendorProductSet vendorID=""0"" vendor=""Custom""
copyright="""" version=""1"" schemaVersion=""1"">"
For Each objRow In ActiveDocument.Tables(1).Rows
strLabelName = Left(objRow.Cells(1).Range.Text,
Len(objRow.Cells(1).Range.Text) - 2)
If CInt(Left(objRow.Cells(6).Range.Text, 2)) = 1 Then
strDotMatrixLabel = "true"
strLocDesc = "Custom dot matrix"
Else
strDotMatrixLabel = "false"
strLocDesc = "Custom laser"
End If
lngLabelWidth = emu(objRow, 12)
lngLabelHeight = emu(objRow, 16)
strSideMargin = Trim(CStr(emu(objRow, 20)))
strTopMargin = Trim(CStr(emu(objRow, 24)))
lngHorizontalPitch = emu(objRow, 28)
lngVerticalPitch = emu(objRow, 32)
strHorizGap = Trim(CStr(lngHorizontalPitch - lngLabelWidth))
strVertGap = Trim(CStr(lngVerticalPitch - lngLabelHeight))
strAcross = Trim(CStr(wrd(objRow, 36)))
strDown = Trim(CStr(wrd(objRow, 38)))
Select Case wrd(objRow, 42)
Case 0 ' US Letter portrait
strSheetHeight = "10058400"
strSheetWidth = "7772400"
Case 1 ' US Letter landscape
strSheetHeight = "7772400"
strSheetWidth = "10058400"
Case 2 ' A4 portrait
strSheetHeight = "10692130"
strSheetWidth = "7560310"
Case 3 ' A4 landscape
strSheetHeight = "7560310"
strSheetWidth = "10692130"

Case Else ' set to US letter portrait for now
strSheetHeight = "10058400"
strSheetWidth = "7772400"

End Select
Print #1, " <product units=""emu"" productID=""" &
Trim(objRow.Index)
& """ layoutGroup=""all"" bindingEdge=""none"" dotMatrixLabel=""" &
strDotMatrixLabel & """ fold=""none"">"
Print #1, " <prodName nameGroup=""custom"">"
Print #1, " <locName locale=""all"">" & strLabelName &
"</locName>"
Print #1, " </prodName>"
Print #1, " <desc descGroup=""custom"">"
Print #1, " <locDesc locale=""all"">" & strLocDesc &
"</locDesc>"
Print #1, " </desc>"
Print #1, " <masterPanel masterID=""0"" height=""" &
Trim(CStr(lngLabelHeight)) & """ width=""" & Trim(CStr(lngLabelWidth)) &
"""
shape=""rect"" cornerRadius=""0"" topMargin=""0"" leftMargin=""0""
bottomMargin=""0"" rightMargin=""0"" centerContent=""false"">"
Print #1, " </masterPanel>"
Print #1, " <sheet height=""" & strSheetHeight & """ width=""" &
strSheetWidth & """ allowPartialSheet=""false"" bgColor=""""
isTwoSided=""false"" printMirrored=""false"">"
Print #1, " <sheetGrid numAcross=""" & strAcross & """
numDown=""" & strDown & """ horizGap=""" & strHorizGap & """ vertGap="""
&
strVertGap & """ posX=""" & strSideMargin & """ posY=""" & strTopMargin &
""" cellWidth=""0"" cellHeight=""0"">"
Print #1, " </sheetGrid>"
Print #1, " </sheet>"
Print #1, " </product>"
Next
Print #1, " </vendorProductSet>"
Print #1, " </vendorProductSets>"
Print #1, "</vps>"

Close #1
End Sub

Function emu(objRow As Row, intColumn As Integer) As Long
' Get a measurement in ems (12700ems/pt, 36000ems/cm I think)
emu = wrd(objRow, intColumn) * 635
End Function

Function wrd(objRow As Row, intColumn As Integer) As Long
' Get a measurement in twips (20twips/pt I think)
wrd = (256 * hex2tolng(objRow.Cells(intColumn + 1).Range.Text) + _
hex2tolng(objRow.Cells(intColumn).Range.Text))
End Function

Function hex2tolng(strHex As String) As Long
' Convert 2-digit hex value to number
hex2tolng = (16 * (InStr(1, "0123456789ABCDEF", UCase(Left(strHex, 1))) -
1)) + _
InStr(1, "0123456789ABCDEF", UCase(Mid(strHex, 2, 1))) - 1
End Function

Peter Jamieson

Alice Graham said:
I have a number of custom labels created with Word 2003. They are saved
as
 
G

Guest

Peter,
You seem to be very knowledgable about labels. Would you have any clue why
our labels, which printed fine in Office 03, are no longer printing correctly
in Office 07? We have many offices across the country, and each office is
experiencing the same problems as they are upgraded. The label looks perfect
on the screen, but when it is printed it does not print out correctly. And
each printer presents a different type of error - sometimes the border is
off, sometimes nothing prints, sometimes the last line is cut off, etc. Any
help would be greatly appreciated.


Peter Jamieson said:
I threw together some Word macros that may help on this front, but whether
they are worth using depends on how many definitions you need to convert and
how much effort you are able/willing to put in to make the macro work. If
you are used to using VBA, it should be fairly straightforward. If not, it
is likely to be more trouble than it's worth.

One problem is that the existing label definitions are stored in a binary
format in the registry, and as far as I know the format is undocumented, so
a large amount of guesswork is involved as to what is in there, and what
/might/ be in there. For example, when I set up a label definition on my
current system, I get a choice of four stationery options - US Letter, US
Letter landscape, A4, A4 landscape, and I don't know if there are other
possibilities.

My guess is that the Word 2007 XML format is better documented, but I
haven't actually looked for the schema yet.

To use the macros, you will need to
a. use the Windows registry manually to export a .reg file containing the
layour definitions
b. install the macros in Word
c. if necessary, modify the pathname of the .reg file in the macro (I don't
prompt for it)
d. if necessary, modify the pathname of the output .xml file in the macro
(I don't prompt for it)
e. run the macro
f. (Probably) close Word
g. save a copy of your existing pg_custom.xml file
h. copy the newly created pg_custom.xml file into the correct location. In
other words, you will be replacing any existing definitions - if you need to
add to them, you will probably have to copy individual layout records from
the converted XML file to your pg_custom.xml file and perhaps modify one or
two IDs.
i. start Word and test the label layouts.

To do (a), start the WIndows registry program, locate the key containing the
custom definitions, which is probably

HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels

then export the label data to a .reg file. I have used the following path in
my macro code

c:\a\mylabels.reg

For example, with some test data, I see

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Word\Custom Labels]
"a3"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,00,00,00,64,\
00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,03,00,00,00
"junelabel"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,6e,04,00,00,08,01,00,\
00,6e,04,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"xyz"=hex:4c,03,5c,00,00,00,6c,00,5d,00,10,0e,00,00,70,08,00,00,98,01,00,00,5d,\
03,00,00,a0,0e,00,00,70,08,00,00,03,00,07,00,01,00,02,00,00,00
"a4"=hex:4c,03,5c,00,00,00,6c,00,5d,00,70,08,00,00,b0,04,00,00,08,01,00,00,93,\
02,00,00,00,09,00,00,b0,04,00,00,05,00,0d,00,01,00,02,00,00,00
"dotmat"=hex:4c,03,5c,00,01,00,6c,00,5d,00,81,0f,00,00,81,0f,00,00,fc,03,00,00,\
54,01,00,00,81,0f,00,00,d5,10,00,00,01,00,02,00,01,00,08,00,00,00
"rollborderless"=hex:4c,03,5c,00,00,00,6c,00,5d,00,20,03,00,00,90,01,00,00,c8,\
00,00,00,64,00,00,00,a0,0f,00,00,d0,07,00,00,02,00,03,00,01,00,02,00,00,00

In other words, I do not have any subkeys under WordCustomLabels. There are
only values.

If you don't know how to do (b), and perhaps (e), visit

http://word.mvps.org/FAQs/MacrosVBA/CreateAMacro.htm

I provide the macros below. NB, there are some long lines in the code at
present.

If you need to do (c) or (d), either modify the macro code directly (each
pathname is only in one place in the code) or use the same paths as I have
used, which are as follows:
1. the registry file is at:
c:\a\mylabels.reg
2. The output .xml file is at
c:\a\pg_custom.xml

The macros (they are pretty crude!)

Sub ConvertWord2003LabelDefs()
'
' Macro to convert Word 2003 Custom label definitions
' exported from the registry to Word 2007 XML definitions
' Thrown together 11 Jun 2007 by Peter Jamieson
'
' This is based on numerous guesses about the format of the
' binary data that describes the labels in Word 2003.
' I would expect the XML schema for the Word 2007 file to
' be defined somewhere but have not yet looked
Dim objLabelDefDoc As Word.Document

' Open the exported .reg (it's a Unicode text file)
Set objLabelDefDoc = Documents.Open(FileName:="c:\a\mylabels.reg", _
ConfirmConversions:=False, _
Encoding:=1200)

' Delete the lines before the label entries
With Selection
.MoveDown Unit:=wdLine, Count:=3, Extend:=wdExtend
.Cut
End With

' Delete the lines after the label entries
With Selection
.EndKey Unit:=wdStory
' .MoveUp Unit:=wdLine, Count:=3, Extend:=wdExtend
' .Cut
.TypeBackspace
End With

' back to the beginning
Selection.HomeKey Unit:=wdStory

' replace the =hex: bits by commas
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "=hex:"
.Replacement.Text = ","
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the \ line ends
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = "\^p "
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' remove the " characters round the label names
With Selection.Find
.ClearFormatting
.Replacement.ClearFormatting
.Text = Chr(34)
.Replacement.Text = ""
.Forward = True
.Wrap = wdFindContinue
.Format = False
.MatchCase = False
.MatchWholeWord = False
.MatchByte = False
.CorrectHangulEndings = False
.MatchWildcards = False
.MatchSoundsLike = False
.MatchAllWordForms = False
.Execute Replace:=wdReplaceAll
End With

' Selec the whole document and convert it
' to a table
Selection.WholeStory
Selection.ConvertToTable _
Separator:=wdSeparateByCommas, _
AutoFitBehavior:=wdAutoFitContent
Call OutputWord2007LabelDefs
objLabelDefDoc.Close savechanges:=False
End Sub

Sub OutputWord2007LabelDefs()
Dim objRow As Word.Row
Dim lngLabelWidth As Long
Dim lngLabelHeight As Long
Dim lngHorizontalPitch As Long
Dim lngVerticalPitch As Long
Dim strAcross As Long
Dim strDown As Long
Dim strSideMargin As String
Dim strTopMargin As String
Dim strHorizGap As String
Dim strVertGap As String
Dim strLabelName As String
Dim strDotMatrixLabel As String
Dim strLocDesc As String
Open "c:\a\pg_custom.xml" For Output As #1
Print #1, "<?xml version=""1.0""?>"
Print #1, "<vps>"
Print #1, " <vendorProductSets>"
Print #1, " <vendorProductSet vendorID=""0"" vendor=""Custom""
copyright="""" version=""1"" schemaVersion=""1"">"
For Each objRow In ActiveDocument.Tables(1).Rows
strLabelName = Left(objRow.Cells(1).Range.Text,
Len(objRow.Cells(1).Range.Text) - 2)
If CInt(Left(objRow.Cells(6).Range.Text, 2)) = 1 Then
strDotMatrixLabel = "true"
strLocDesc = "Custom dot matrix"
Else
strDotMatrixLabel = "false"
strLocDesc = "Custom laser"
End If
lngLabelWidth = emu(objRow, 12)
lngLabelHeight = emu(objRow, 16)
strSideMargin = Trim(CStr(emu(objRow, 20)))
strTopMargin = Trim(CStr(emu(objRow, 24)))
lngHorizontalPitch = emu(objRow, 28)
lngVerticalPitch = emu(objRow, 32)
strHorizGap = Trim(CStr(lngHorizontalPitch - lngLabelWidth))
strVertGap = Trim(CStr(lngVerticalPitch - lngLabelHeight))
strAcross = Trim(CStr(wrd(objRow, 36)))
strDown = Trim(CStr(wrd(objRow, 38)))
Select Case wrd(objRow, 42)
Case 0 ' US Letter portrait
strSheetHeight = "10058400"
strSheetWidth = "7772400"
Case 1 ' US Letter landscape
strSheetHeight = "7772400"
strSheetWidth = "10058400"
Case 2 ' A4 portrait
strSheetHeight = "10692130"
strSheetWidth = "7560310"
Case 3 ' A4 landscape
strSheetHeight = "7560310"
strSheetWidth = "10692130"

Case Else ' set to US letter portrait for now
strSheetHeight = "10058400"
strSheetWidth = "7772400"

End Select
Print #1, " <product units=""emu"" productID=""" & Trim(objRow.Index)
& """ layoutGroup=""all"" bindingEdge=""none"" dotMatrixLabel=""" &
strDotMatrixLabel & """ fold=""none"">"
Print #1, " <prodName nameGroup=""custom"">"
Print #1, " <locName locale=""all"">" & strLabelName &
"</locName>"
Print #1, " </prodName>"
Print #1, " <desc descGroup=""custom"">"
Print #1, " <locDesc locale=""all"">" & strLocDesc & "</locDesc>"
Print #1, " </desc>"
Print #1, " <masterPanel masterID=""0"" height=""" &
Trim(CStr(lngLabelHeight)) & """ width=""" & Trim(CStr(lngLabelWidth)) & """
shape=""rect"" cornerRadius=""0"" topMargin=""0"" leftMargin=""0""
bottomMargin=""0"" rightMargin=""0"" centerContent=""false"">"
Print #1, " </masterPanel>"
Print #1, " <sheet height=""" & strSheetHeight & """ width=""" &
strSheetWidth & """ allowPartialSheet=""false"" bgColor=""""
isTwoSided=""false"" printMirrored=""false"">"
Print #1, " <sheetGrid numAcross=""" & strAcross & """
numDown=""" & strDown & """ horizGap=""" & strHorizGap & """ vertGap=""" &
strVertGap & """ posX=""" & strSideMargin & """ posY=""" & strTopMargin &
""" cellWidth=""0"" cellHeight=""0"">"
Print #1, " </sheetGrid>"
Print #1, " </sheet>"
Print #1, " </product>"
Next
Print #1, " </vendorProductSet>"
Print #1, " </vendorProductSets>"
Print #1, "</vps>"

Close #1
End Sub

Function emu(objRow As Row, intColumn As Integer) As Long
' Get a measurement in ems (12700ems/pt, 36000ems/cm I think)
emu = wrd(objRow, intColumn) * 635
End Function

Function wrd(objRow As Row, intColumn As Integer) As Long
' Get a measurement in twips (20twips/pt I think)
wrd = (256 * hex2tolng(objRow.Cells(intColumn + 1).Range.Text) + _
hex2tolng(objRow.Cells(intColumn).Range.Text))
End Function

Function hex2tolng(strHex As String) As Long
' Convert 2-digit hex value to number
hex2tolng = (16 * (InStr(1, "0123456789ABCDEF", UCase(Left(strHex, 1))) -
1)) + _
InStr(1, "0123456789ABCDEF", UCase(Mid(strHex, 2, 1))) - 1
End Function

Peter Jamieson

Alice Graham said:
I have a number of custom labels created with Word 2003. They are saved as
 
G

Graham Mayor

Word 2007, as you acknowledge, uses a different method of storing custom
labels. I know of no automatic conversion process. Your best bet is to note
the settings (using a Word 2003 equipped PC) and recreate them in 2007. 2007
does, however have a wider range of labels than earlier versions and you may
find a standard label that fits the bill.

--
<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
Graham Mayor - Word MVP

My web site www.gmayor.com

<>>< ><<> ><<> <>>< ><<> <>>< <>><<>
 

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