Database table names in mail merge fields

Hi,

Is it possible to put table names in a merge field? I have a large DataReader that contains columns from many tables - some of these columns have the same name - therefore the logical way to get the correct data into the correct merge fields would be to name the merge fields as follows:

{MERGEFIELD table1.column \* MERGEFORMAT}
{MERGEFIELD table2.column \* MERGEFORMAT}

So far the I cannot get the merge to work. Is there a way to get this to work?

Greg Pakes

Hey Greg,

Interesting question. Are you sure there are the same column names held by DataReader? Could you please check it, for example by executing the following code:

for (int i = 0; i < reader.FieldCount; i++)

Debug.WriteLine(reader.GetName(i));

Thanks,

It appears the table names are being omitted from the name of the columns (despite the fact there are duplicates). I wonder if i can use a datatable instead??? Do you know of anyway i can do this?

Is there a possibility of reading your data into several data tables to avoid duplicate names in one place?

Well yes there is - but that would involve doing multiple mail merges from different sources on one document. Is this supported?? Will this not just exponentially increase the document length?

25 records in first merge --> turns 1 page into 25 pages

25 records in second merge --> turns 25 pages into 625 pages etc etc.

Thanks again,

You have been very helpful in all my posts.

I have run a test and have found that it does indeed convert it to 625 pages.

Maybe a find and replace might be a better option. Or is there a way I can acheive this?

Indeed, this would not work because when doing a simple mail merge, the document will be duplicated per each record. Why I asked you about the possibility of having the data in separate tables is because I thought that it would be possible to merge them into a single table where column names are prefixed with some unique identifier such as the name of the table they originate from. Then you could prepare merge fields in the template in a way like "TableName1_ColumnName1", "TableName1_Column2" and thus avoid the ambiguity.

I realize this approach is a bit clumsy and there is definitely a neater way to resolve; but I have tested it and it worked. I used code like the following:

[Test]

public void TestMailMerge()

{

Document doc = new Document("D:\\TestTableMerge.doc");

DataTable table1 = GetSampleDataTable("Table1");

DataTable table2 = GetSampleDataTable("Table2");

DataTable tableToMerge = new DataTable();

MergeTable(table1, tableToMerge);

MergeTable(table2, tableToMerge);

doc.MailMerge.Execute(tableToMerge);

doc.Save("D:\\TestTableMerge Out.doc");

}

private void MergeTable(DataTable srcTable, DataTable dstTable)

{

for (int i = 0; i < srcTable.Columns.Count; i++)

dstTable.Columns.Add(string.Format("{0}_{1}", srcTable.TableName, srcTable.ColumnsIdea [I].ColumnName));

for (int i = 0; i < srcTable.Rows.Count; i++)

{

DataRow row = GetOrAddRow(dstTable, i);

for (int j = 0; j < srcTable.Columns.Count; j++)

{

string dstColumnName = string.Format("{0}_{1}", srcTable.TableName, srcTable.Columns[j].ColumnName);

row[dstColumnName] = srcTable.RowsIdea [I][j];

}

}

}

private DataRow GetOrAddRow(DataTable table, int rowIndex)

{

if (rowIndex >= table.Rows.Count)

{

DataRow row = table.NewRow();

table.Rows.Add(row);

return row;

}

else

{

return table.Rows[rowIndex];

}

}

Let me know if you need any additional assistance on this inquiry.

Dmitry,

Thank you very much for your help. This is definitely a solution to my issue. Thank you very much.

I was thinking of basically writing my own mailmerge procedure which takes a dataset as an argument (with the appropriate tables and relations between the tables). It would detect the merge fields and then apply the field from the appropriate datatable in the dataset. do you think this is a better solution, or would you stick with your solution above?

Thanks again

I believe they are just equipollent alternative solutions, yours one even sounds neater so it’s up to you which one to choose Smile [:)] I also think that the resulting performance will be more or less equal in both approaches so basically this is just a matter of implementation.