Search code examples
vbaexcelms-wordactivexobject

transfer data from word to excel via vba


I have a form in ms word with some of the fields are content control and some (which are the radio buttons) are ActiveX control. I want to automatically transfer hundred word forms to an excel file. I use the following vba code:

Sub getWordFormData()
Dim wdApp As New Word.Application
Dim myDoc As Word.Document
Dim CCtl As Word.ContentControl
Dim myFolder As String, strFile As String
Dim myWkSht As Worksheet, i As Long, j As Long

myFolder = "C:\Users\alarfajal\Desktop\myform"
Application.ScreenUpdating = False

If myFolder = "" Then Exit Sub
Set myWkSht = ActiveSheet
ActiveSheet.Cells.Clear
Range("A1") = "name"
Range("a1").Font.Bold = True
Range("B1") = "age"
Range("B1").Font.Bold = True
Range("C1") = "gender"
Range("C1").Font.Bold = True
Range("D1") = "checkbox1"
Range("D1").Font.Bold = True
Range("E1") = "checkbox2"
Range("E1").Font.Bold = True
Range("F1") = "singlechoice1"
Range("F1").Font.Bold = True
Range("G1") = "singlechoice2"
Range("G1").Font.Bold = True



i = myWkSht.Cells(myWkSht.Rows.Count, 1).End(xlUp).Row
strFile = Dir(myFolder & "\*.docx", vbNormal)

While strFile <> ""
    i = i + 1

    Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, AddToRecentFiles:=False, Visible:=False)

    With myDoc
        j = 0
        For Each CCtl In .ContentControls
            j = j + 1
            myWkSht.Cells(i, j) = CCtl.Range.Text
        Next
        myWkSht.Columns.AutoFit
    End With
    myDoc.Close SaveChanges:=False
    strFile = Dir()
Wend
wdApp.Quit
Set myDoc = Nothing: Set wdApp = Nothing: Set myWkSht = Nothing
Application.ScreenUpdating = True

End Sub

all the data (text fields, checkbox) are transferred successfully but, the radio button (which is ActiveX) is not transferred.

This is the word doc:

enter image description here

This is the excel result:

enter image description here

How can I solve this problem?


Solution

  • You can refer to an ActiveX control on a Word document by it's name

    myDoc.singlechoice1.Value

    It is better to refer to the ContentControls by their tag names.

    myDoc.SelectContentControlsByTag("name").Item(1).Range.Text

    Refactored Code

    Sub getWordFormData()
        Dim wdApp As Object, myDoc As Object
    
        Dim myFolder As String, strFile As String
        Dim i As Long, j As Long
    
        myFolder = "C:\Users\alarfajal\Desktop\myform"
    
        If Len(Dir(myFolder)) = 0 Then
            MsgBox myFolder & vbCrLf & "Not Found", vbInformation, "Cancelled - getWordFormData"
            Exit Sub
        End If
    
        Application.ScreenUpdating = False
        Set wdApp = CreateObject("Word.Application")
    
        With ActiveSheet
            .Cells.Clear
            With .Range("A1:G1")
                .Value = Array("name", "age", "gender", "checkbox1", "checkbox2", "singlechoice1", "singlechoice2")
                .Font.Bold = True
            End With
    
            strFile = Dir(myFolder & "\*.docx", vbNormal)
    
            i = 1
            While strFile <> ""
                i = i + 1
    
                Set myDoc = wdApp.Documents.Open(Filename:=myFolder & "\" & strFile, ReadOnly:=True, AddToRecentFiles:=False, Visible:=False)
    
                .Cells(i, 1).Value = myDoc.SelectContentControlsByTag("name").Item(1).Range.Text
                .Cells(i, 2).Value = myDoc.SelectContentControlsByTag("age").Item(1).Range.Text
                .Cells(i, 3).Value = myDoc.SelectContentControlsByTag("gender").Item(1).Range.Text
                .Cells(i, 4).Value = myDoc.SelectContentControlsByTag("checkbox1").Item(1).Checked
                .Cells(i, 5).Value = myDoc.SelectContentControlsByTag("checkbox2").Item(1).Checked
                .Cells(i, 6).Value = myDoc.singlechoice1.Value
                .Cells(i, 7).Value = myDoc.singlechoice2.Value
    
                myDoc.Close SaveChanges:=False
                strFile = Dir()
            Wend
            wdApp.Quit
    
            Application.ScreenUpdating = True
        End With
    
    End Sub