View Single Post
  #4   Report Post  
Posted to microsoft.public.word.mailmerge.fields
Peter Jamieson Peter Jamieson is offline
external usenet poster
 
Posts: 4,582
Default MailMergeDataSource iteration extremly slow

The code below should work after addresses were loaded.

Sorry, to look at the problem I would need a much simpler piece of code
that
a. I can get into operation without knowing a whole lot more about C#
than I do, and the specific interfaces you are using
b. defines stuff such as MailMergeDataFieldIndices, which is not
declared etc. etc.

If you have the inclination and can provide the code for a very small
Addin that would do that, perhaps fired from a single ribbon button, I
would be happy to give it a go.

Maybe it's a matter of interop.


That could be, but I can't say I have enough experience of working with
Mailmerge via Interop to have any idea how likely that would be.

I don't really know how this datasource
behaves or works under the hood.


Well, Word can connect to a datasource using 4 basic methods. I don't
know whether or not you know what type of data source will be used
(possibly "whatever the user throws at it?), but for test purposes you
would presumably have to set up a document with a suitable data source.
Word uses one of 4 "connection methods":
a. an internal/external text converter. It would do that if the data
source was another Word document containing a table with one row
forheaders and subsequent rows for data.
b. DDE (obsolescent, but users still sometimes use it to solve a few
formatting problems).
c. ODBC (obsolescent)
d. OLE DB. It would do that if, for example, you are using Word XP or
later and your data source is an Excel worksheet.

If you can set up some small data sources that you could open with each
method, you may find that the slowdown only occurs with some connection
types.

Peter Jamieson

http://tips.pjmsn.me.uk

On 05/03/2010 09:26, amr wrote:
Hi Peter,
thanks for your investigations.

I dont execute this code during a mailmerge event.
After the mailmerge addresses were selected, the user can open a dialog and
edit a product list. Each address has a product. At dialog initilisation i
load the addresses from the datasource. The source is an outlook addressbook
with two members.
When i try your example code during the mailmerge event , your right, its
pretty fast.

The code below should work after addresses were loaded.

using System.Windows.Data;

[ValueConversion(typeof(Word.MailMergeDataSource), typeof(ListAddress))]
public class MailMergeDataSourceConverter : IValueConverter {

private ListAddress addressList;

#region IValueConverter Member

public object Convert(object value, Type targetType, object parameter,
System.Globalization.CultureInfo culture) {
if (value != null) {
try {
Word.MailMergeDataSource dataSrc =
(Word.MailMergeDataSource)value;

int count = dataSrc.RecordCount;
Log.Info(string.Format("Converting MailMergeDataSource
(Count: {0})", count));

if (count 0) {
addressList = new ListAddress();

Word.MailMergeDataFields fields = dataSrc.DataFields;

object indexLastname = MailMergeDataFieldIndices.Lastname;
object indexFirstname =
MailMergeDataFieldIndices.Firstname;
object indexCompany = MailMergeDataFieldIndices.Company;
object indexStreet = MailMergeDataFieldIndices.Street;
object indexZip = MailMergeDataFieldIndices.Zip;
object indexCity = MailMergeDataFieldIndices.City;

object index = MailMergeDataFieldIndices.None;
for (int i = 0; i count; i++) {
int fieldCount = fields.Count;

// Crap
string name = (fieldCount= (int)indexFirstname) ?
fields.get_Item(ref indexFirstname).Value + " " + fields.get_Item(ref
indexLastname).Value : "";
string company = (fieldCount= (int)indexCompany) ?
fields.get_Item(ref indexCompany).Value : "";
string street = (fieldCount= (int)indexStreet) ?
fields.get_Item(ref indexStreet).Value : "";
string zip = (fieldCount= (int)indexZip) ?
fields.get_Item(ref indexZip).Value : "";
string city = (fieldCount= (int)indexCity) ?
fields.get_Item(ref indexCity).Value : "";

addressList.Add(new Address() {
Name = name,
Company = company,
Street = street,
Zip = zip,
City = city
});

dataSrc.ActiveRecord =
Word.WdMailMergeActiveRecord.wdNextDataSourceRecor d;
}
}
}
catch (Exception ex) {
Log.Error(ex);
}
}

return addressList;
}

public object ConvertBack(object value, Type targetType, object
parameter, System.Globalization.CultureInfo culture) {
throw new NotImplementedException();
}

#endregion
}

Maybe it's a matter of interop. I don't really know how this datasource
behaves or works under the hood.