如何使用VBA正确设置文档属性?

时间:2015-01-16 14:34:11

标签: vba word-vba word-2010

问题

我在使用Word 2010中的VBA设置文档属性时遇到了一些问题。

我有一个包含多个Heading 1部分的文档,我使用宏来提取所选部分(及其内容)并将其粘贴到新文档中。

这部分工作正常,但最后我需要设置几个文档属性,但都没有设置。

我正在尝试设置内置和自定义属性,但出于此问题的目的,我想设置标题主题和,类别即可。

我已经创建了一个函数来设置我想要的属性(如下所示),并且VBA没有抛出任何错误(即使我删除了函数中的错误处理)。

有人知道我做错了吗?


该功能应如何运作

以下是该功能应该做什么的简短摘要,但如果您发现更容易检查,则完整功能如下所示 -

  1. 检查该属性是否已存在
    • 确实如此,它是default属性
      • 设置默认属性
      • PropertyTypeUsed变量设置为default
    • 确实如此,它是custom属性
      • 设置自定义属性
      • PropertyTypeUsed变量设置为custom
    • 根本不存在
      • 创建新的自定义属性
      • 设置自定义属性
      • PropertyTypeUsed变量设置为custom
  2. 检查是否已成功设置值
    • 应该设置default属性
      • 该属性设置成功吗?
    • 应该设置custom属性
      • 该属性设置成功吗?
  3. 返回结果

  4. 我认为导致问题的功能

    Function UpdateDocumentProperty(ByRef doc As Document, _
                                    ByVal propertyName As String, _
                                    ByVal propertyValue As Variant, _
                                    Optional ByVal propertyType As Office.MsoDocProperties = 4)
    
        '** Set the result to 'False' by default '*
        Dim result As Boolean
        result = False
    
        '** A property to hold whether or not the property used is default or custom *'
        Dim propertyTypeUsed As String
    
        '** Check to see if the document property already exists *'
        If PropertyExists(doc, propertyName) Then                           ' A default property exists, so use that
            doc.BuiltInDocumentProperties(propertyName).value = propertyValue
            propertyTypeUsed = "default"
        ElseIf PropertyExists(doc, propertyName, "custom") Then             ' A custom property exists, so use that
            doc.CustomDocumentProperties(propertyName).value = propertyValue
            propertyTypeUsed = "custom"
        Else                                                                ' No property exists, so create a custom property
            doc.CustomDocumentProperties.Add _
                name:=propertyName, _
                LinkToContent:=False, _
                Type:=propertyType, _
                value:=propertyValue
            propertyTypeUsed = "custom"
        End If
    
        '** Check whether or not the value has actually been set *'
        On Error Resume Next
        If propertyTypeUsed = "default" Then
            result = (doc.BuiltInDocumentProperties(propertyName).value = propertyValue)
        ElseIf propertyTypeUsed = "custom" Then
            result = (doc.CustomDocumentProperties(propertyName).value = propertyValue)
        End If
        On Error GoTo 0
    
        UpdateDocumentProperty = result
    
    End Function
    

    完整项目代码

    此项目的完整代码可以在两个粘贴区中找到 -

    我不确定是否有可能获得实际创建表单的代码(不能导出它,但我无处可去),但无论如何它都非常简单 -

    1. 表单 - frmChooseDocument
    2. 标签 - lblChooseDocument(您要导出哪个新入门文档?)
    3. 组合框 - comChooseDocument
    4. 取消按钮 - btnCancel
    5. 确定按钮 - btnOK(最初禁用)
    6. 实际上,我正在使用包含此代码的文档作为新版本的“主”文档,其中包含有关如何使用variouse应用程序的详细说明。

      代码本身在文档中查找Heading 1格式的文本,并将它们添加到表单中的组合框中,允许用户选择要导出的部分。然后创建一个新文档并将其另存为PDF。


      更新

      正如评论中所建议的,我已经检查过所设置的值的类型是否与传递给函数的值的类型相匹配。

      在上述所有3个属性的情况下,我传递的值和针对文档存储的属性都是string类型。

      我添加了几行来输出我设置结果的类型和值,所有看起来都很好,但显然不是!

      Debug.Print "My value:        (" & TypeName(propertyValue) & ")" & propertyValue
      Debug.Print "Stored property: (" & TypeName(doc.BuiltInDocumentProperties(propertyName).value) & ")" & doc.BuiltInDocumentProperties(propertyName).value
      

      这是输出 -

      My value:        (String)New Starter Guide - Novell
      Stored property: (String)New Starter Guide - Novell
      My value:        (String)New starter guide
      Stored property: (String)New starter guide
      My value:        (String)new starters, guide, help
      Stored property: (String)new starters, guide, help
      

2 个答案:

答案 0 :(得分:2)

我设法通过在更改属性后保存文档来设置我的word文档标题。我设置了"已保存"首先将属性设置为false以确保Word注册状态更改。

Function ChangeDocumentProperty(doc As Document, sProperty As String, sNewValue As String)

    Debug.Print "Initial Property, Value: " & sProperty & ", " & doc.BuiltInDocumentProperties(sProperty)

    doc.BuiltInDocumentProperties(sProperty) = sNewValue

    doc.Saved = False
    doc.Save

    ChangeDocumentProperty = (doc.Saved = True And doc.BuiltInDocumentProperties(sProperty) = sNewValue)

    Debug.Print "Final Property, Value: " & sProperty & ", " & doc.BuiltInDocumentProperties(sProperty)

End Function

立即窗口:

? ThisDocument.ChangeDocumentProperty(ThisDocument, "Title", "Report Definitions")
Initial Property, Value: Title, Report Glossary
Final Property, Value: Title, Report Definitions
True

答案 1 :(得分:1)

函数无法设置永久对象属性。换句话说,VBA不允许函数具有在函数完成运行后持续存在的副作用。

将该函数重写为Sub,它应该可以工作。