Extract Data From Forms

Home Up Search This Site What's New? Audio On CDR Favourites Downloadable files Photo Gallery 2002 Photo Gallery 2003 Photo Gallery 2004/5 Photo Gallery 2006/7 Photo Gallery 2008 Photo Gallery 2009/10 UK Photo Gallery Ireland Photo Gallery Cats Photo Gallery 

 

 

Google
 

 

Many people access the material from this web site daily. Most just take what they want and run. That's OK, provided they are not selling on the material as their own; however if your productivity gains from the material you have used, a donation from the money you have saved, however small, would help to ensure the continued availability of this resource.

Click the appropriate button above to access PayPal.

Extract data from protected forms

 

While Word 2007 introduced a new set of forms tools, the implementation for the moment leaves a lot to be desired, but there are still many users creating protected forms in Word 2002/3. Having prepared your forms and filled them, the next step is often to extract the completed data for use in a spreadsheet. Word provides the option (Tools > Options > Save) to save only the data from forms. This page extends that option to work on a folder full of similar forms to create a comma delimited text file that can be loaded into standard spreadsheet packages such as Excel.

Using the following simple form as an example:

Note:

The macros in the first part of this page are all concerned with legacy form fields, as used in Word 2002/3 and available from Word 2007/2010's Developer ribbon tab. However it is possible to extract the data from the new Word 2007/2010 content controls and I have included a macro to do that at the end of this page. The macro will work as a stand-alone macro on the currently active document, or will work in conjunction with the routine to extract data from e-mailed attachments, by changing the call to the macro where indicated.

 

the macro requires two empty text files - here DataDoc.txt  which is used as a temporary repository for the data from each form, and TargetDoc.txt which will be the completed comma delimited text file. No changes are made to the completed form documents.

To create the empty text files, Use Windows Explorer to navigate the the folder where the completed forms are filed. Right click in the right file window and select New > Text Document (see below).

 

This will produce a new filename similar to that above, already highlighted for renaming. Rename the file TargetDoc.txt. Repeat for DataDoc.txt.

Run the macro and each document will be opened in turn and the data saved to DataDoc.txt. This text file is then opened and the content copied and pasted to TargetDoc.txt. The result from the sample forms would be:

 

Sub ExtractDataFromForms()
Dim DocList As String
Dim DocDir As String
Dim DataDoc As Document
Dim TargetDoc As Document
Dim fDialog As FileDialog
Set fDialog = Application.FileDialog(msoFileDialogFolderPicker)
On Error GoTo err_FolderContents
With fDialog
     .Title = "Select Folder containing the completed form documents and click OK"
     .AllowMultiSelect = False
     .InitialView = msoFileDialogViewList
     If .Show <> -1 Then
          MsgBox "Cancelled By User"
          Exit Sub
     End If
     DocDir = fDialog.SelectedItems.Item(1)
     If Right(DocDir, 1) <> "\" Then DocDir = DocDir + "\"
End With
If Documents.Count > 0 Then
     Documents.Close SaveChanges:=wdPromptToSaveChanges
End If
Application.ScreenUpdating = False
DocList = Dir$(DocDir & "*.doc?")
Set TargetDoc = Documents.Open(DocDir & "TargetDoc.txt", False)
Do While DocList <> ""

     'The form may contain automacros, not required
     'by this macro, so disable them

     WordBasic.DisableAutoMacros 1
     Documents.Open DocDir & DocList

     'Save the form with the save only data option
     With ActiveDocument
          .SaveFormsData = True
          .SaveAs FileName:="DataDoc.txt", _
          FileFormat:=wdFormatText, _
          SaveFormsData:=True

          'Close the original form
          .Close SaveChanges:=wdDoNotSaveChanges
     End With

     'Now open the temporary saved text file containing the form data
     Set DataDoc = Documents.Open("DataDoc.txt", False)

     'And write its content into the data file
     TargetDoc.Range.InsertAfter DataDoc.Range.Text

     'Close the temporary file
     DataDoc.Close SaveChanges:=wdDoNotSaveChanges

     'Save the data file
     TargetDoc.Save
     DocList = Dir$()

     'Re-enable the automacros

     WordBasic.DisableAutoMacros 0
Loop
Application.ScreenUpdating = True

Exit Sub
err_FolderContents:
MsgBox Err.Description

WordBasic.DisableAutoMacros 0

End Sub

Note:

The above method uses Word's built-in option to save only the data from forms. This method works well but is slow thanks to the requirement to open and close a variety of files. At the end of this page there is an alternative method of writing the data to the text file directly from the source document. I have included both methods for the sake of completeness.

Create a report from protected form data

 

A variation on this approach could be used to create a report or letter using the data collected in a protected form. For multiple letters you would simply add a header row to the TargetDoc.txt file and run a mail merge, but you may wish to process forms individually. In order to do that, one way would be to create a document template containing docvariable fields that relate to some or all of the form fields in the form to be processed as shown in the simple report below:

 

When merged with the last line the above would produce the following. I only created one conditional field to illustrate the plurals. In practice you would need to create one for each field where it was relevant.

 

The macro below uses a similar process to that above to extract the data from the last entry of the text file and assigns the comma delimited items to the document variables used in the report. It then creates a new document from the report template (Report.dot) and updates the fields to display the current values of the fields.

 

Sub PrepareReport()
Dim DocDir As String
Dim
FormDoc As Document
Dim DataDoc As Document
Dim TargetDoc As Document
Dim NewDoc As Document
Dim fDialog As FileDialog
Dim oRng As Range
Dim sText As String
Dim
i As Long
Dim
sFormData() As String
Dim
oVars As Variables
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
On Error GoTo err_FolderContents
With fDialog 'Pick the form to process
     .Title = "Select the completed form document and click OK"
     .AllowMultiSelect = False
     .InitialView = msoFileDialogViewList
     If .Show <> -1 Then
          MsgBox "Cancelled By User"
          Exit Sub
     End If

     DocDir = fDialog.SelectedItems.Item(1)
End With
If
Documents.Count > 0 Then
     Documents.Close SaveChanges:=wdPromptToSaveChanges
End If
Application.ScreenUpdating = False

'The form may contain automacros, not required
'by this macro, so disable them

WordBasic.DisableAutoMacros 1

'Open the form for processing
Set FormDoc = Documents.Open(DocDir)
'The form is now open so re-enable the automacros

WordBasic.DisableAutoMacros 0
With FormDoc

     'Open the data file
     Set TargetDoc = Documents.Open("TargetDoc.txt", False)

     'Save the form with the save only data option
     .SaveAs FileName:="DataDoc.txt", _
     FileFormat:=wdFormatText, _
     SaveFormsData:=True

     'Close the original form without saving
     .Close SaveChanges:=wdDoNotSaveChanges

     'Now open the data file
     Set DataDoc = Documents.Open("DataDoc.txt", False)
End With

'Insert the content of the temporary file into the data file
TargetDoc.Range.InsertAfter DataDoc.Range

'Close the temporary file
DataDoc.Close SaveChanges:=wdDoNotSaveChanges

'Save the data file
TargetDoc.Save

'Locate the last written line of the data file.

'This will be the next to the last paragraph,

'as the last paragraph will always be empty.
Set oRng = TargetDoc.Paragraphs(TargetDoc.Paragraphs.Count - 1).Range

'Omit the final paragraph mark from the data paragraph
oRng.End = oRng.End - 1

'Divide the stored paragraph at the comma delimiting
sFormData = Split(oRng.Text, ",")

'Open a new document based on the report template stored in the

'User Templates folder. This template could be dotx format for Word 2007.
Set NewDoc = Documents.Add(Options.DefaultFilePath(wdUserTemplatesPath) & "\Report.dot")
Set oVars = NewDoc.Variables

'Assign the comma delimited items, from the last line of the text file

'to variables. Note that numbering starts at 0 for the first item in

'the string. The replace function removes the quotes applied by the

'process of saving forms data to a text file.
oVars("varFirstName").Value = Replace(sFormData(0), Chr(34), "")
oVars("varLastName").Value = Replace(sFormData(1), Chr(34), "")
oVars("varDate").Value = Replace(sFormData(2), Chr(34), "")
oVars("varWidget").Value = Replace(sFormData(3), Chr(34), "")
oVars("varWhatsit").Value = Replace(sFormData(4), Chr(34), "")
oVars("varThingummy").Value = Replace(sFormData(5), Chr(34), "")

' see note below
For i = NewDoc.Fields.Count To 1 Step -1
     With NewDoc.Fields(i)

          'Update only the docvariable fields
          If .Type = wdFieldDocVariable Then .Update
     End With
Next
i

'Close the data file
TargetDoc.Close wdDoNotSaveChanges
Application.ScreenUpdating = True
'NewDoc.Save 'Remove the apostrophe at the start of this line to force a save.
Exit Sub
err_FolderContents:
MsgBox Err.Description

WordBasic.DisableAutoMacros 0
End Sub

Create a report from protected form data (an alternative method)

 

If you had no reason to retain the results from the forms in a data file for re-use (e.g. in a mail merge or to process in Excel), the macro could be simplified, as you could read the data directly from the form and create the report.

In the following example I have used the similar form data. However whereas the previous method works regardless of the field names, this method requires the fields to be addressed by name. We will assume that they have the default names "Text1" to "Text6". On this occasion I have added two more fields to the original form  - a check box and a dropdown field to demonstrate how to handle the results of those types of form fields They too use the default names of "Check1" and "Dropdown1".

Note:

The above macro will resolve the result of a CheckBox as 1 (checked) or 0 (unchecked), so if you wished to add the additional fields into that macro, you could use the following

oVars("varCheck1").Value = Replace(sFormData(6), Chr(34), "")
If oVars("varCheck1").Value = 1 Then
     oVars("varCheck1").Value = "YES"
Else
     oVars("varCheck1").Value = "NO"
End If
oVars("varPrivacy").Value = Replace(sFormData(7), Chr(34), "")

 

The following macro opens the form document and creates a new report from the Report.dot template and writes the formfield results directly to the report.

Two docvariable fields corresponding to the additional form fields have been included in the Report.dot template as shown below:

 

Sub PrepareReport2()

Dim DocDir As String
Dim
FormDoc As Document
Dim NewDoc As Document
Dim fDialog As FileDialog
Dim i As Long
Dim
oVars As Variables
Set fDialog = Application.FileDialog(msoFileDialogFilePicker)
On Error GoTo err_FolderContents
With fDialog
     .Title = "Select the completed form document and click OK"
     .AllowMultiSelect = False
     .InitialView = msoFileDialogViewList
     If .Show <> -1 Then
          MsgBox "Cancelled By User"
     Exit Sub
     End If

     DocDir = fDialog.SelectedItems.Item(1)
End With
If
Documents.Count > 0 Then
     Documents.Close SaveChanges:=wdPromptToSaveChanges
End If
Application.ScreenUpdating = False

'The form may contain automacros, not required
'by this macro, so disable them

WordBasic.DisableAutoMacros 1

'Open the form containing the data to be used in the report
Set FormDoc = Documents.Open(DocDir)

'The form is now open so re-enable the automacros

WordBasic.DisableAutoMacros 0

'Open a new document based on the report template stored in the

'User Templates folder. This template could be dotx format for Word 2007.

Set NewDoc = Documents.Add(Options.DefaultFilePath(wdUserTemplatesPath) & "\Report.dot")
Set oVars = NewDoc.Variables
'Assign the form field results to variables.

With FormDoc
     oVars("varFirstName").Value = .FormFields("Text1").Result
     oVars("varLastName").Value = .FormFields("Text2").Result
     oVars("varDate").Value = .FormFields("Text3").Result
     oVars("varWidget").Value = .FormFields("Text4").Result
     oVars("varWhatsit").Value = .FormFields("Text5").Result
     oVars("varThingummy").Value = .FormFields("Text6").Result
     If .FormFields("Check1").CheckBox.Value = True Then
          oVars("varCheck1").Value = "YES"
     Else
          oVars("varCheck1").Value = "NO"
     End If
     oVars("varPrivacy").Value = .FormFields("DropDown1").Result
End With

'Update the docvariable fields in the document

For i = NewDoc.Fields.Count To 1 Step -1
     With NewDoc.Fields(i)
          If .Type = wdFieldDocVariable Then .Update
     End With
Next
i

'Close the original form without saving changes
FormDoc.Close wdDoNotSaveChanges
Application.ScreenUpdating = True
'NewDoc.Save 'Remove the apostrophe at the start of this line to force a save.

Exit Sub
err_FolderContents:
MsgBox Err.Description

WordBasic.DisableAutoMacros 0
End Sub
 

 

The end result is similar to that below:

   
   

Note:

The macros will also run in Word 2007 using forms in Word "*.doc" and "*.docx" formats. Similarly the Report.dot template could be a Report.dotx template for Word 2007 if preferred.

Processing Forms Received by E-Mail

 

The above processes assume that you have stored a collection of forms locally, however, it is likely that the completed forms will be submitted by e-mail. It is possible to process the forms directly from the e-mail message attachments. To facilitate that, it is necessary to set up a number of folders in Outlook to handle the forms at the various stage of the process, and an Outlook Rule to direct all messages containing the forms to one of the folders, automatically.

The folders used for the purpose of this illustration are a sub folder of Outlook's Inbox - called Forms_In and three sub folders of that folder called Forms_Completed, Forms_Incomplete & Forms_Wrong

There are two paths used in the macros defined:

sPath = "D:\My Documents\Test\Temp\"

and

fName = "D:\My Documents\FormData.doc"

The latter, which is the document used to store the form data as a table, can be either doc or docx format depending on Word version. If the document doesn't exist, the macro will create it, but the folder used to store it must exist, as must the former path used as a temporary store for the documents being processed, which are likely all to have the same name and thus can only exist one at a time in the folder.

If preferred you can change the routine to extract data from the correctly submitted forms to save the data as a comma delimited file. Here I have shown an alternative method of creating the text file from that shown in the previous ExtractDataFromForms macro. The method shown below uses less processing and is thus faster.

Where that method is used, the data document path is instead

fName = "D:\My Documents\FormData.txt"

 

The macro opens Outlook and examines each message in the 'Forms_In' folder, in turn, starting at the bottom of the list (to avoid the count getting screwed up later). If the message doesn't have an attachment, or has more than one attachment, it is moved to the folder 'Forms_Wrong' for later manual examination. If the message has the required single form attached, that attachment is opened in Word and docvariables containing the message subject and the sender's e-mail address are added.

The macro then checks that all the fields contain data. Obviously the macro has no way of knowing whether the data submitted is wrong, or what the correct state of check boxes or selection from drop down fields should be. It only checks to ensure that all the fields have been filled.

Note:

The macros work only with legacy form fields when used in Word 2007

 

If any of the form fields is incomplete, the message is moved to the 'Forms_Incomplete' folder and the incomplete form is returned by e-mail to the address whence it came.

If the form fields are completed, the data is extracted to the document/text file defined at

fName =

and the message is moved to the 'Forms_Completed' folder.

 

Private oVars As Variables
Private vVar As Variant
'This macro requires a reference to the Microsoft Outlook Object Library
Sub ProcessFormAttachments()
Dim i As Long
Dim olApp As Outlook.Application
Dim olNs As Outlook.Namespace
Dim olFolder As Outlook.Folder
Dim olItem As Outlook.MailItem
Dim olMailItem As Outlook.MailItem
Dim oNewMailItem As Outlook.MailItem
Dim olAttachments As Outlook.Attachments
Dim sFname As String
Dim sPath As String
Dim iMessages As Long
Dim TempDoc As Document
 

'Set the temporary document path
sPath = "D:\My Documents\Test\Temp\"

On Error Resume Next
'Open Outlook

Set olApp = GetObject(, "Outlook.Application")

If Err = 429 Then
    
'Outlook is closed so start Outlook

     Set olApp = CreateObject("Outlook.Application")
End If
Set olNs = olApp.GetNamespace("MAPI")

'Locate the folder containing the unprocessed e-mail messages
Set olFolder = olNs.GetDefaultFolder(olFolderInbox).Folders("Forms_In")

'Examine each message starting from the bottom of the list
For i = olFolder.Items.Count To 1 Step -1
     Set olItem = olFolder.Items(i)

     'Mark the message as read
     olItem.UnRead = False
     Set olAttachments = olItem.Attachments

     'Count the attachments attached to the message
     If olAttachments.Count = 1 Then

     'There is one attachment so note its filename
          sFname = olAttachments.Item(1).DisplayName
          On Error Resume Next
         
'If the filename already exists in the temporary folder, remove it.

          Kill sPath & sFname
          On Error GoTo 0

          'Save the attachment to the temporary folder
          olAttachments.Item(1).SaveAsFile _
          sPath & sFname
     Else 'The message has the wrong number of attachments

          'Mark it as unread
          olItem.UnRead = True

          'and move it to the Forms_Wrong folder
          olItem.Move olFolder.Folders("Forms_Wrong")

          'and move on to the next message

          GoTo ProcessNext
     End If

     'Open the temporary document from its folder

     'The form may contain automacros, not required
     'by this macro, so first disable them

     WordBasic.DisableAutoMacros 1

     Set TempDoc = Documents.Open(sPath & sFname)
     Set oVars = TempDoc.Variables

     'Store the sender's e-mail address and message subject in the document
     oVars("varSender").Value = olItem.SenderEmailAddress
     oVars("varSubject").Value = olItem.Subject

     'Word 2007 has a habit of switching to draft view so select PrintView
     ActiveWindow.View.Type = wdPrintView

     'Check all the form fields in the temporary document
     For j = 1 To TempDoc.FormFields.Count

          'If any are incomplete
          If TempDoc.FormFields(j).Result = "" Then

               'Call the routine to return the unaltered form to the sender
               Call ReturnForm

               'close the temporary document
               TempDoc.Close wdDoNotSaveChanges

               'and move it to the Forms_Incomplete folder
               olItem.Move olFolder.Folders("Forms_Incomplete")

               'and quit the loop

               Exit For
          Else
'The form is correctly filled, so call the routine

               'to extract the data to a table.
               Call ExtractDataFromForm

               'Alternatively call the routine to save to a comma delimited text file

               'Call ExtractDataFromForm2

               'Or if the form contains content controls rather than legacy form fields

               'Call ExtractFataFromForm3

               'Close the temporary document
               TempDoc.Close wdDoNotSaveChanges

               'and move the message to the Forms_Complete folder
               olItem.Move olFolder.Folders("Forms_Completed")

               Exit For
          End If
     Next
j
ProcessNext:
Next i

'Re-enable automacros

WordBasic.DisableAutoMacros 0
'Clean up

Set olItem = Nothing
Set olFolder = Nothing
Set olAttachments = Nothing
Set olNs = Nothing
Set
olApp = Nothing
End Sub

 

'Routine to return the incorrectly filled form to the sender
Sub ReturnForm()
'This macro requires a reference to the Microsoft Outlook Object Library

Dim oOutlookApp As Outlook.Application
Dim oItem As Outlook.MailItem
On Error Resume Next
Set
oVars = ActiveDocument.Variables

'Outlook is already running so open it.
Set oOutlookApp = GetObject(, "Outlook.Application")

'Create a new e-mail message
Set oItem = oOutlookApp.CreateItem(olMailItem)
With oItem

     'Read the sender and subject from the document variables
     .To = oVars("varSender")
     .Subject = "Re: " & oVars("varSubject")

     'Add a suitable message c/w your contact details
     .Body = "The form you have submitted is incomplete." & vbCr & _
             "Please complete the form and return it." & vbCr & vbCr & _
             oOutlookApp.Session.CurrentUser.name & vbCr & _
             oOutlookApp.Session.CurrentUser.Address
     .Attachments.Add Source:=ActiveDocument.FullName, _
      Type:=olByValue, DisplayName:="Document as attachment"
     .Send 'Send the message (It might be better to ensure that Outlook

           'does not send the messages immediately while testing).
End With

'Clean up
Set oItem = Nothing
Set
oOutlookApp = Nothing
End Sub

 

'Routine to extract data from the correctly submitted forms to a Word table
Sub ExtractDataFromForm()
Dim oDoc As Word.Document
Dim oTarget As Word.Document
Dim oTable As Table
Dim iCol As Integer
Dim
i As Long
Dim
sText As String
Dim
sName As String
Dim
fName As String
 

'Define the name and path of the document to hold the data

'This can be Word 2007 docx format if preferred.
fName = "D:\My Documents\FormData.doc"

Set oDoc = ActiveDocument
On Error Resume Next

'Open the data document to receive input
Set
oTarget = Documents.Open(fName)

If Err.Number = 5174 Then
     'The data document doesn't exist so create a new one
     Set oTarget = Documents.Add
     oTarget.SaveAs fName
End If
Set oFld = oDoc.FormFields

'Count the form fields in the document
iCol = oFld.Count
If oTarget.Tables.Count = 0 Then

     'It's a new data document so if there are more than 10 fields,

     'set the new layout in landscape mode, and add a 2 row table.
     If
iCol > 10 Then
          oTarget.PageSetup.Orientation = _
          wdOrientLandscape
     End If
     oTarget.Tables.Add oTarget.Range, 2, iCol
Else 'It's an existing table so add a single row
     oTarget.Tables(1).Rows.Add
End If
Set oTable = oTarget.Tables(1)

'If an incorrect form has slipped through with the wrong number of

'form fields, the routine quits with an error message
If iCol <> oTable.Columns.Count Then
     MsgBox "The form and data table do not have the same number of fields", _
     vbCritical, "Error!"
     Exit Sub
End If

'Read the form data
For
i = 1 To iCol
     sName = oFld(i).name
     Select Case oFld(i).Type
          Case Is = wdFieldFormDropDown, wdFieldFormTextInput
               sText = oFld(i).Result
          Case Is = wdFieldFormCheckBox
               sText = oFld(i).CheckBox.Value
     End Select

     'If it is a new table add the field names to the header row
     If
oTable.Rows.Count = 2 Then
          With oTable.Cell(1, i).Range
               .Text = sName
               .Font.Bold = True
               .Collapse wdCollapseEnd
          End With
     End If

     'Write the form data to the table
     With oTable.Cell(oTable.Rows.Count, i).Range
          .Text = sText
          .Collapse wdCollapseEnd
     End With
Next
i
End Sub

 

 

'Alternative routine to save the form data as a comma delimited file

Sub ExtractDataFromForm2()
Dim oTarget As Document
Dim oDoc As Document
Dim fName As String
Se
t oDoc = ActiveDocument
'Define the name and path of the text file to hold the data

fName = "D:\My Documents\FormData.txt"
'Turn off screen updating to reduce flicker whilst opening/closing files
Application.ScreenUpdating = False
On Error Resume Next
Set oTarget = Documents.Open(fName, False)

If Err.Number = 5174 Then

     'The file does not exist, so create a new one
     Set oTarget = Documents.Add

     'and add the header row comprising the form field names
     For i = 1 To oDoc.FormFields.Count
          oTarget.Range.InsertAfter Chr(34) & _
          oDoc.FormFields(i).name & Chr(34)
          If i < oDoc.FormFields.Count Then
               oTarget.Range.InsertAfter Chr(44)
          End If
          If
i = oDoc.FormFields.Count Then
               oTarget.Range.InsertAfter vbCr
          End If
     Next
i

     'and save it as a text file
     oTarget.SaveAs fName, wdFormatText
End If

'Add the form field content to the text file

For i = 1 To oDoc.FormFields.Count
     oTarget.Range.InsertAfter Chr(34) & _
     oDoc.FormFields(i).Result & Chr(34)
     If i < oDoc.FormFields.Count Then
          oTarget.Range.InsertAfter Chr(44) & Chr(32)
     End If
     If
i = oDoc.FormFields.Count Then
          oTarget.Range.InsertAfter vbCr
     End If
Next
i

'Save the data file
oTarget.Save
'Restore screen updating

Application.ScreenUpdating = True
End Sub

 

Extract data from Word 2007/2010 content controls

 

The above methods are all aimed at legacy form fields as used by Word 2002 and 2003 versions. A similar procedure can be used with Word 2007/2010 content controls and that is achieved by using the following version of the ExtractDataFromForm macro. Word 2007 content controls are incompatible with earlier Word versions - even with when the compatibility pack is installed in those earlier versions. This macro will therefore will only work in Word 2007/2010 and the macro error traps Word versions before 2007.

This macro does not extract images from picture content controls, but records such data as a simple forward slash character "/". For any content control that doesn't have a title, the content is recorded under the heading name CControln where n is the sequential number of the content control in the form.

 

'Extract data from Word 2007/2010 content control fields
Sub ExtractDataFromForm3()
Dim oTarget As Document
Dim oDoc As Document
Dim fName As String
Dim
sCCName as String
Dim
i As Long
If Application.Version < 12 Then
'The Word version is not 2007/2010

     'So show a message
     MsgBox "This function only works with Word versions after Word 2003", _
     vbCritical, "Word version error"
    
'and quit

     Exit Sub
End If
Set
oDoc = ActiveDocument
'Define the name and path of the text file to hold the data

fName = "D:\My Documents\FormData.txt"
'Turn off screen updating to reduce flicker whilst opening/closing files
Application.ScreenUpdating = False
On Error Resume Next
Set oTarget = Documents.Open(fName, False)
If Err.Number = 5174 Then

     'The file does not exist, so create a new one
     Set oTarget = Documents.Add
     'and add the header row comprising the content control names
     For i = 1 To oDoc.ContentControls.Count
          sCCName = oDoc.ContentControls(i).Title

          'If the content control has no name, create one
          If sCCName = "" Then
               sCCName = "CControl" & i
          End If
          oTarget.Range.InsertAfter Chr(34) & _
          sCCName & Chr(34)
          If i < oDoc.ContentControls.Count Then
               oTarget.Range.InsertAfter Chr(44) & Chr(32)
          End If
          If
i = oDoc.ContentControls.Count Then
               oTarget.Range.InsertAfter vbCr
          End If
     Next
i
     'and save it as a text file
     oTarget.SaveAs fName, wdFormatText
End If
For
i = 1 To oDoc.ContentControls.Count
     'Add the content control content to the text file

     oTarget.Range.InsertAfter Chr(34) & _
     oDoc.ContentControls(i).Range & Chr(34)
     If i < oDoc.ContentControls.Count Then
          oTarget.Range.InsertAfter Chr(44) & Chr(32)
     End If
     If
i = oDoc.ContentControls.Count Then
          oTarget.Range.InsertAfter vbCr
     End If
Next
i
'Save the data file
oTarget.Save
'Restore screen updating

Application.ScreenUpdating = True
End Sub

Note:

A vba module containing the code used in this section is available for download. ExtractDataFromEmailedForms.zip