2

I'm wanting to create a mail marge for a letter inputting different names and address on each. I've used Microsoft example as a base point http://support.microsoft.com/kb/229310 and i've customized it to how i like. But my problem arises when trying to get the data for either selected rows of the dbgrid or just the whole thing. I have no idea how to do it. My first thought was do 1 to the amount of rows, then put some tedit boxes down and put them equal to mailmerged data but that still only does it one at a time. The dbgrid is linked up to a ms outlook. This is how they fill the data..

// Open the file to insert data
wrdDataDoc := wrdApp.Documents.Open('E:\Temp.doc');
 for iCount := 1 to (DBGrid1.DataSource.DataSet.RecordCount) do
wrdDataDoc.Tables.Item(1).Rows.Add;
FillRow(wrdDataDoc, 2, 'Steve', 'DeBroux',
    '4567 Main Street', 'Buffalo, NY  98052');
// Fill in the data
FillRow(wrdDataDoc, 3, 'Jan', 'Miksovsky',
    '1234 5th Street', 'Charlotte, NC  98765');
FillRow(wrdDataDoc, 4, 'Brian', 'Valentine',
    '12348 78th Street  Apt. 214', 'Lubbock, TX  25874');

So how would I grab the data from the dbgrid and fill the file with that information?

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
captiv
  • 107
  • 2
  • 9
  • 1
    DBGrid1.DataSource.DataSet.FieldByName('name').AsString ? – Sertac Akyuz Apr 29 '12 at 14:05
  • Thanks for the reply, i'm getting the error "not enough actual parameters" now. Also the size is subject to change, so is there away to do this for multiple rows then? Would I do loop from 1 to however many records, fill row with data and add one to the number each time? – captiv Apr 29 '12 at 14:14
  • 1
    Have a look at the answer I posted. – Sertac Akyuz Apr 29 '12 at 14:16

2 Answers2

5
var
  i: Integer;
  bm: TBookmark;
begin
  DBGrid1.DataSource.DataSet.DisableControls;
  try
    bm := DBGrid1.DataSource.DataSet.GetBookmark;
    try
      i := 0;
      DBGrid1.DataSource.DataSet.First;
      while not DBGrid1.DataSource.DataSet.Eof do begin
        Inc(i);
        FillRow(wrdDataDoc, i,
          DBGrid1.DataSource.DataSet.FieldByName('Name').AsString,
          DBGrid1.DataSource.DataSet.FieldByName('Address1').AsString,
          ..
          );
        DBGrid1.DataSource.DataSet.Next;
      end;
      if Assigned(bm) then
        DBGrid1.DataSource.DataSet.GotoBookmark(bm);
    finally
      DBGrid1.DataSource.DataSet.FreeBookmark(bm);
    end;
  finally
    DBGrid1.DataSource.DataSet.EnableControls;
  end;
end;
Sertac Akyuz
  • 54,131
  • 4
  • 102
  • 169
  • Wow thanks a bunch! 2 Small errors now though, 'END' expected but 'FINALLY' found, that's on the last finally, and EXCEPT or FINALLY expected and that's on the second to last end. – captiv Apr 29 '12 at 14:29
  • I'm really sorry to bother you again but i'm having another error now. "invalid variant operation" and this is at the line `Doc.Tables.Item(1).Cell(Row,1).Range.InsertAfter(Text1);` And this is in the fill row procedure provided by ms. I know it's not part of the code you gave me but im unsure on whats causing it. – captiv Apr 29 '12 at 15:02
  • 1
    @captiv - I had to use ';' instead of ',' while calling `CreateDataSource` to make the sample work. That's the 'list separator' from 'regional settings'. You would use 'sysutils.ListSeparator' to have it working on any system (`wrdDoc.MailMerge.CreateDataSource('..\DataDoc.doc',,,'FirstName+ListSeparator+LastName'+..`). – Sertac Akyuz Apr 29 '12 at 15:46
  • 1
    +1, just a side note: I've been using `TBookmarkStr` for ages but now I've read that it's [deprecated](http://docwiki.embarcadero.com/Libraries/XE2/en/Data.DB.TBookmarkStr). but on the other hand ["TBookmark does not need to free memory"](http://docwiki.embarcadero.com/Libraries/XE2/en/Data.DB.TDataSet.FreeBookmark), so go figure... :/ – kobik Oct 22 '12 at 13:22
  • @kobik - Thanks for that. I didn't know what was happening to TBookmark. I was using D2007 then, and it was a Pointer which needed to be freed. – Sertac Akyuz Oct 22 '12 at 18:05
1

Hmm, this gives me a bit of a clue on how to use Bookmarks to manage selectedrows in DBGrid. My problem is being able to read through certain fields of selectedRows, such as extract the email addresses (or record ID No) of selected contacts(records) to,perhaps, send email to. Any further info on using TBookmarkList and TBookmark would be helpful :) Too Easy... it seems the only way to loop through a TBookmarkLIst is using its Count property, and using its Item[index] as a TBookmark. Which is then used to dataset.gotBookMark and then access the required fieldByName('Fieldname').

I would have liked...

For bmBookmark in bmlBookmarkList do

but this works...

  var bmlGridSelectedRows: TBookmarkList;
      bmRecord: TBookmark;
      I: Integer;
begin
   JvdbUltimGridContacts.DataSource.DataSet.DisableControls;
   bmlGridSelectedRows := JvdbUltimGridContacts.SelectedRows;

   for I := 0 to bmlGridSelectedRows.Count - 1 do
     begin
       bmRecord := bmlGridSelectedRows.Items[I];
       ABSTableContacts.GotoBookmark(bmRecord);
       MessageDlg(ABSTableContacts.FieldByName('DisplayName').AsString,mtInformation,[mbOK],0); //this is just to show that you are accessing the correct record you expect, replace with your own code of course
     end;
  JvdbUltimGridContacts.DataSource.DataSet.EnableControls;

Nice tip about the Dataset.DisableControls / EnableControls properties,:)

Of course you do not need to declare the variables for TbookmarkList and TBookmark as they can be accessed directly, I am just in the habit of doing that as I think it is cleaner code. i.e.

 DBGrid.DataSource.DataSet.DisableControls;

   for I := 0 to DBGrid.SelectedRows.Count - 1 do
     begin
       ABSTableContacts.GotoBookmark(DBGrid.SelectedRows.Items[I]);
       MessageDlg(ABSTableContacts.FieldByName('DisplayName').AsString,mtInformation,[mbOK],0);
     end;
  DBGrid.DataSource.DataSet.EnableControls;
Darren
  • 225
  • 3
  • 8