Word- VBA- 为什么我会收到 运行 时间错误 451 "Property Let Procedure Not Defined And Property Get Procedure Did Not Return Object"?

Word- VBA- Why do I get a Run Time Error 451 "Property Let Procedure Not Defined And Property Get Procedure Did Not Return Object"?

尽管给我一个 运行 时间错误 451“属性 Let Procedure Not Defined And 属性 Get Procedure Did Not Return Object”,但以下代码成功运行。

调试器将 With oCC.Range.Style("Placeholder Text").Font 标记为罪魁祸首。

我需要对占位符文本应用样式,以便在输入或删除值时它不会重置。

缺少什么?

Dim oTable As Table
Dim ocell As Cell
Dim oCC As ContentControl
Dim oNewRow As Row
    Set oTable = ActiveDocument.Tables(1)
    Set oNewRow = oTable.Rows.Add
    Set ocell = oNewRow.Cells(1)
    Set oCC = ActiveDocument.ContentControls.Add(wdContentControlRichText, ocell.Range)
    With oCC
        .DefaultTextStyle = "Style1"
        .Tag = "Test1"
        .Setplaceholdertext , , "test1"
        If oCC.ShowingPlaceholderText Then
             With oCC.Range.Style("Placeholder Text").Font
                                    
                   .Name = "Arial"
                   .Size = 8
                   .ColorIndex = wdRed
                   .Italic = True
            End With
        End If
    End With

“我需要对占位符文本应用样式,以便在输入或删除值时它不会重置。”

ContentControl 不是这样工作的。正如之前向您解释的那样,占位符文本在设计上是临时的。您可以在它存在时对其应用格式,但是一旦文本消失,您应用到它的格式也会消失。

如果替换占位符文本的文本被删除默认格式,样式 'Placeholder Text' 将应用于内容控件随后显示的任何占位符文本。

如果使用不同的格式对您的项目至关重要,您唯一的选择是在 ThisDocument 模块中创建一个 ContentControlOnExit 事件,该事件需要检查退出的内容控件是否显示占位符文本然后应用适当的格式。这将要求您找到一些方法来确定应将哪种格式应用于内容控件。

抱歉,VBA 无法做到这一点。对象模型不包含设置占位符样式的方法。这是未修改的富文本内容控件的 XML:

<w:sdtContent>
    <w:p w14:paraId="13211677" w14:textId="4A21E55A" w:rsidR="00A934F5" w:rsidRDefault="00EB0426" w:rsidP="00857546">
        <w:r w:rsidRPr="00FD3EE5">
            <w:rPr>
                <w:rStyle w:val="PlaceholderText"/>
            </w:rPr>
            <w:t>Click or tap here to enter text.</w:t>
        </w:r>
    </w:p>
</w:sdtContent>

起初我以为您可以创建自定义样式,然后将其应用 VBA:

oCC.Range.Style = "PlaceholderText1"

但这只会改变输入文本的外观,不会改变占位符文本。这与在内容控件属性对话框中设置样式相同。这是 运行 之后的 XML:

<w:sdtContent>
    <w:p w14:paraId="0686A900" w14:textId="2CAB6B2E" w:rsidR="00A934F5" w:rsidRPr="00332D6D" w:rsidRDefault="00332D6D" w:rsidP="00332D6D">
        <w:pPr>
            <w:pStyle w:val="PlaceholderText1"/>
        </w:pPr>
        <w:r w:rsidRPr="00D90D77">
            <w:rPr>
                <w:rStyle w:val="PlaceholderText"/>
            </w:rPr>
            <w:t>Click or tap here to enter text.</w:t>
        </w:r>
    </w:p>
</w:sdtContent>

样式已添加,但占位符样式未更改。当您键入文本时,文本会以宏设置的样式显示。

要解决此问题,请创建多个替代占位符文本样式。 (提示:不要在这些样式名称中使用空格)。然后创建相同数量的内容控件。打开文件以编辑 XML 并将“PlaceHolderText”名称替换为每个内容控件中的新样式名称。

然后打开文档并将每个内容控件保存为 AutoText/Building 块。然后使用 VBA 插入那些样式化的内容控件:

ActiveDocument.AttachedTemplate.AutoTextEntries("CCStyle1").Insert Where:=oCell.Range, RichText:=True

这是我关于编辑 OOXML 的文章:OOXML Hacking: An Introduction

所以我想通了。

使用下面的 With ActiveDocument.Styles("Placeholder Text").Font 为整个文档设置占位符文本框架并防止重置。

Dim oTable As Table
Dim ocell As Cell
Dim oCC As ContentControl
Dim oNewRow As Row
    Set oTable = ActiveDocument.Tables(1)
    Set oNewRow = oTable.Rows.Add
    Set ocell = oNewRow.Cells(1)
    Set oCC = ActiveDocument.ContentControls.Add(wdContentControlRichText, ocell.Range)
    With oCC
        .DefaultTextStyle = "Style1"
        .Tag = "Test1"
        .Setplaceholdertext , , "test1"
        If oCC.ShowingPlaceholderText Then
             **With ActiveDocument.Styles("Placeholder Text").Font**       
                   .Name = "Arial"
                   .Size = 8
                   .ColorIndex = wdRed
                   .Italic = True
            End With
        End If
    End With

然后,在我的例子中,对于文档中的每个后续占位符文本,我可以分别使用 With oCC.Range.Font 修改它们的格式,如下所示。

    Set ocell = oNewRow.Cells(2)
    Set oCC = ActiveDocument.ContentControls.Add(wdContentControlRichText, ocell.Range)
    With oCC
        .DefaultTextStyle = "Style2"
        .Tag = "test2"
        .SetPlaceholderText , , "test2"
        If oCC.ShowingPlaceholderText Then
            **With oCC.Range.Font**
                .Name = "Arial"
                .Size = 12
                .ColorIndex = wdBlack
                .Italic = True
            End With
        End If
    End With