vbams-worddocvariable

vba word variables value delete


There is a MS Word 2016 document with DOCVARIABLES set in it. For example:

{ DOCVARIABLE "SerialNumber" \* MERGEFORMAT }

I need to have this DOCVARIABLE filled in via VBA with InputBox. The VBA code:

Sub Document_Open()

Dim sNumber, mNumber, iDate As String

sNumber = InputBox("Please enter the Serial Number", "Serial number", "Enter 
the Serial Number here")

mNumber = InputBox("Please enter the Model Number", "Model number", "Enter 
the Model Number here")

iDate = InputBox("Please enter the Date of Issue, dd.mm.yyyy", "Date of 
Issue", "Enter the Date of Issue here")

With ActiveDocument

  .Variables.Add Name:="SerialNumber", Value:=sNumber

  .Variables.Add Name:="ModelNumber", Value:=mNumber

  .Variables.Add Name:="IssueDate", Value:=iDate

  .Fields.Update

End With

End Sub

When the document opens up, it automatically prompts for user data. When the data is entered it then gets populated into DOCVARIABLES within the document. But if I run the code again (when the DOCVARIABLES are storing the data already) it gives me an error: Run-Time Error "5903": The Variable name already exists.
The question is how to fix it and make the DOCVARIABLES updatable.

Here is a solution Cindy Meister provided, but with introduction of array:

Sub Document_Open()
  Dim sNumber As String, mNumber As String, iDate As String, i As Integer

  Dim varData(1 To 3) As String
    varData(1) = "SerialNumber"
    varData(2) = "ModelNumber"
    varData(3) = "IssueDate"

  Dim varInput(1 To 3) As String
    varInput(1) = InputBox("Please enter the Serial Number", "Serial number", "Enter the Serial Number here")
    varInput(2) = InputBox("Please enter the Model Number", "Model number", "Enter the Model Number here")
    varInput(3) = InputBox("Please enter the Date of Issue, dd.mm.yyyy", "Date of Issue", "Enter the Date of Issue here")


  For i = 1 To 3
  With ActiveDocument
    If DocVarExists(varData(i), ActiveDocument) Then
       .Variables(varData(i)).Value = varInput(i)
    Else
       .Variables.Add Name:=varData(i), Value:=varInput(i)
    End If
   .Fields.Update
  End With
  Next i


End Sub

Function DocVarExists(sVarName As String, doc As Word.Document) As Boolean
    Dim var As Word.Variable, bExists As Boolean
    bExists = False
    For Each var In doc.Variables
        If var.Name = sVarName Then
            bExists = True
            Exit For
        End If
    Next
    DocVarExists = bExists
End Function

Solution

  • With document Variables you have two possibilities.

    The "simple" one is to simply assign the value. There's no need to use the Add method at all. So you need only one line of code, whether the Variable already exists in the document or not:

    ActiveDocument.Variables("name").Value = "new value"
    

    (Note: Variables originate from the old, Word Basic days, where things were much less formal than they've become. A CustomDocumentProperty, in contrast, requires an Add method - the object was introduced in the VBA days.)

    If you want things to be very correct, then you'd need to loop through the Variables collection to find out if it already exists and only add it if it does. I have a little function for this which I've pasted below and put a call to it in your code. (Which I've edited for only one Variable to make it easier to follow the function call.)

    Sub Document_Open()
      Dim sNumber as String, mNumber As String, iDate As String
    
      sNumber = InputBox("Please enter the Serial Number", "Serial number", _
        "Enter the Serial Number here")
    
      With ActiveDocument
        If DocVarExists("SerialNumber", ActiveDocument) Then
           .Variables("SerialNumber").Value = sNumber
        Else
           .Variables.Add Name:="SerialNumber", Value:=sNumber
        End If
       .Fields.Update   
      End With   
    End Sub
    
    Function DocVarExists(sVarName As String, doc As Word.Document) As Boolean
        Dim var As Word.Variable, bExists As Boolean
        bExists = False
        For Each var In doc.Variables
            If var.Name = sVarName Then
                bExists = True
                Exit For
            End If
        Next
        DocVarExists = bExists
    End Function
    

    (Note: This is the approach required for CustomDocumentProperties.)

    Just a remark about Variable objects for anyone reading this that's not familiar with them: As soon as an emtpy (zero-length) string is assigned the Variable object is deleted and no longer available in the document.