views:

1511

answers:

1

I want to iterate over all rows of a MS-Word mail merge data source and extract the relevant data into an XML.

I'm currently using this code:

Imports Microsoft.Office.Interop
Do
  objXW.WriteStartElement("Recipient")
  Dim objDataFields As Word.MailMergeDataFields = DataSource.DataFields
  For Each FieldIndex As Integer In mdictMergeFields.Keys
    strValue = objDataFields.Item(FieldIndex).Value
    If Not String.IsNullOrEmpty(strValue) Then
      strName = mdictMergeFields(FieldIndex)
      objXW.WriteElementString(strName, strValue)
    End If
  Next
  objXW.WriteEndElement()
  If DataSource.ActiveRecord = LastRecord Then
    Exit Do
  Else
    DataSource.ActiveRecord = Word.WdMailMergeActiveRecord.wdNextDataSourceRecord
  End If
Loop

And it turns out to be a little sluggish (About 1 second for each row). Is there any way to do it faster?

My fantasy is finding a function like MailMergeDataSource.ToDatatable and then inspecting the datatable.

A: 

Hi Guy,

Any time you're iterating through something row by row, and then doing some kind of processing on each row, is going to get a little slow.

I would be inclined to approach this problem by having a step before this which prepared the mdictMergeFields collection so that it only contained elements that were not 'null or empty', this will mean you won't have to check for that on each iteration. You could do this in process, or 'sneakily' in the background while the user is doing something else.

The other thing to try (might help!) is to change the "Do... Loop" block so that you're not checking at the end of each imported row whether or the record is the 'last record'. Instead, get a count of the records, and then compare the current index to the knowm maximum (which might be quicker)

I.E.:

Dim i, x as Integer
i = ActiveDocument.MailMerge.DataSource.RecordCount

Do While x < i
objXW.WriteStartElement("Recipient")  
Dim objDataFields As Word.MailMergeDataFields = DataSource.DataFields  
For Each FieldIndex As Integer In mdictMergeFields.Keys    
 strValue = objDataFields.Item(FieldIndex).Value    
 If Not String.IsNullOrEmpty(strValue) Then      
  strName = mdictMergeFields(FieldIndex)      
  objXW.WriteElementString(strName, strValue)    
 End If  
Next  
objXW.WriteEndElement()
x += 1
Loop

I don't really work with the Office Interop much, but hopefully this might offer some assistance! Post back, let me know how it goes.

/Richard.

Richard
Thank you but this doesn't help. I added a comment above about the problematic line.
Guy Marom
If you are manually going to set strValue = "" each time, you don't even need the .IsNullOrEmpty check. Just remove strValue = "", then get rid of the If/End If below it... Make sense?
Richard