Jump to content

A few problems with Delphi involving Mail Merge, SQL + Databases.

- - - - -

This topic has been archived. This means that you cannot reply to this topic.
11 replies to this topic

#1
Ilikestring

Ilikestring

    Newbie

  • Members
  • PipPip
  • 17 posts
My first problem is with mail merge. I have created a a Data File and a table, yet I am not able to fill my table with information from my Data File. The <<Info>> just seems to be inserted after wherever the cursor is on the page, which is not where the table is. All that is entered into the actual table is a '59'. Therefore I think I either need to to change the code or be able to move the cursor. Here is the code I am currently using, the code in bold is where I believe the problem lies:

    wrdDoc.Tables.Add(wrdSelection.Range, ADOTable1.FieldCount, 3);
  wrdDoc.Tables.Item(1).Columns.Item(1).SetWidth(51,wdAdjustNone);
  wrdDoc.Tables.Item(1).Columns.Item(2).SetWidth(20,wdAdjustNone);
  wrdDoc.Tables.Item(1).Columns.Item(3).SetWidth(100,wdAdjustNone);
  // Set the shading on the first row to light gray

  wrdDoc.Tables.Item(1).Rows.Item(1).Cells
      .Shading.BackgroundPatternColorIndex := wdGray25;
  // BOLD the first row
  wrdDoc.Tables.Item(1).Rows.Item(1).Range.Bold := True;
  // Center the text in Cell (1,1)
  wrdDoc.Tables.Item(1).Cell(1,1).Range.Paragraphs.Alignment :=
        wdAlignParagraphCenter;

  // Fill each row of the table with data
  wrdDoc.Tables.Item(1).Cell(1, 1).Range.InsertAfter('Time');
  wrdDoc.Tables.Item(1).Cell(1, 2).Range.InsertAfter('');
  wrdDoc.Tables.Item(1).Cell(1, 3).Range.InsertAfter('Teacher');
[B]
  For Count := 1 to (ADOTable1.FieldCount - 1) do
    begin
      wrdDoc.Tables.Item(1).Cell((Count + 1), 1).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'Time' + IntToStr(Count)));
      wrdDoc.Tables.Item(1).Cell((Count + 1), 2).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'THonorific' + IntToStr(Count)));
      wrdDoc.Tables.Item(1).Cell((Count + 1), 3).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'TSurname' + IntToStr(Count)));
    end; [/B]

My second problem is that I do not know what the correct SQL syntax is for editing the name of a column in the database (I am using Delphi 7 and Microsoft Jet Engine if that makes a difference).

The third problem is that when I add a new column to my database manually (which I need to do) I get a 'violation' error in one of my units when I activate an ADOTable. This only happens on one unit and it happens when I add a column with any name anywhere in the table. I know that is vague but I can't seem to narrow down the problem any further than that.

If you could help with me with any of those it would be great. Thanks.

#2
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
I don't use the word interface thingy, so I can't be very specific. One thing that I think could help is to select. Your selection can then be replaced. I bet. Agian, I don't know.

Something like:
doc.tables.item(1).cell(12,1275).select;
doc.replaceselection('whatever I want in the table');

I'm pretty sure word only allows "typing", whether through keyboard or through interface api. So, position the cursor by selecting a range, then type, or replace or whatever method it needs. I bet you can find the right methods, I just wanted to point out that you'll probably want to select to position the cursor, then replace to enter text. You can have an empty selection, which is just a cursor position. When you replace that, you just insert.

As for the database problem, read the manual. Search for "violation" errors. Probably something to do with access rights if you ask me.

#3
Ilikestring

Ilikestring

    Newbie

  • Members
  • PipPip
  • 17 posts
Thank you for your reply.
I tried the selecting and replacing like you said and I got an error when executing the replace line. Something about 'cannot use automation with replacing', and so I tried just placing a select before each line with my original code:

  For Count := 1 to (ADOTable1.FieldCount - 1) do
    begin
      wrdDoc.Tables.Item(1).Cell(Count + 1,1).select;
      wrdDoc.Tables.Item(1).Cell((Count + 1), 1).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'Time' + IntToStr(Count)));
      wrdDoc.Tables.Item(1).Cell(Count + 1,2).select;
      wrdDoc.Tables.Item(1).Cell((Count + 1), 2).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'THonorific' + IntToStr(Count)));
      wrdDoc.Tables.Item(1).Cell(Count + 1,3).select;
      wrdDoc.Tables.Item(1).Cell((Count + 1), 3).Range.InsertAfter(wrdMergeFields.Add(wrdSelection.Range,'TSurname' + IntToStr(Count)));
    end;

Now, it works perfectly! :) Eexxcccepppttt for I have some rather peculiar looking '59's added onto every entry I make into the table, like so:

Posted Image

I also clearly need to make the second column bigger, but that's no trouble. The '59's on the other hand are probably going to be a bit of nuisance :(
I have done a CTRL+F for the entire unit and no instances of '59' are found.

EDIT: An important update is that the '59's occur before the mail merge executes, which means the problem does not lie within the data file, but with the above code:

Posted Image

#4
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Well... To fix this, you need to figure out if it's Word doing it, or you.

Instead of calling:

... .InsertAfter(...,'MyText'+IntToStr(MyNum),...);

You need to precompute the whole string as you're sending it to word and put it in a var:

var sendthis:string;

begin
...
sendthis:='MyText'+IntToStr(MyNum);
... .InsertAfter(...,sendthis,...); //then place a breakpoint on this line. Hover your mouse over 'sendthis' and see what you're acetually sending.

if this has '59' at the end, it's your fault somewhere earlier. If not, word is doing something weird. You may want to work around this by backspacing twice or something like that. You may be able to simply do something like

doc.select(,-2);
doc.insert(''); //kill it

which would select from the cursor 2 back and then delete it.

Phabulous.

#5
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Ps, in your case:

sendthis:=wrdMergeFields.Add(wrdSelection.Range,'Time' + IntToStr(Count));

Then inspect your sendthis var. Set a brakpoint on the line after the above one to stop the running.

If it has a 59 at the end, just go ahead and after the above line simply add:

sendthis:=copy(sendthis,1,length(sendthis)-2);

Which chops the last 2 chars off, no matter what they are.

Then go ahead and InsertAfter this thing.

#6
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Ow, and by the way, I have no clue what the actual name of the replace function would be, so if you're going to use "replaceselection", that may very well make your computer puke at runtime (because it can't know it's wrong at compile time when using variants). You'd have to check the interface.

#7
Ilikestring

Ilikestring

    Newbie

  • Members
  • PipPip
  • 17 posts
I went straight away and just tried to delete the '59's, I think that'll be the easiest route to take.
However when the program runs the line:
wrdDoc.select(,-2);
I get 'invalid number of parameters'
Any idea why?
I also tried wrdDoc.select(-2); and wrdDoc.select(0,-2); and neither play ball.

#8
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Well, then you're screwed. If I recall, you can use the (,-2) syntax with variant calls, but I may be very wrong. Probably am. Again, I don't have it in front of me.

But forget about deleting the 59s. They ain't supposed to be there. You're sending them. You need to not send them. Unless word has gone bonkers and wants to let you know you're getting really old, you are sending it. So don't.

And also, the function name may very well be "selectrange", I wouldn't know. I don't have word, it costs more than I'm willing to pay. Plus, it's from MS and MS isn't... well, let's just say I don't like to use MS stuff.

#9
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
You really, really, really need to do debugging. That means setting a breakpoint. This takes 1 click in the margin. Then run. Then Delphi will stop your program. Then you inspect what's up. Hover the mouse over the word. That's it. To find out what's wrong, you need to know what you're sending. And the nice thing is: That is possible, you can peek in there and see it. But you have to shove it in its own variable first, so that when your program is stopped it's all ready to go, but hasn't gone yet. Then you can take a look-see at it and see that, yes, indeed, you're sending a 59. Apparently wrdMergeFieldMaker.AddANewMergeField() or whatever it's called adds your 59. Bad baby, bad baby! So chop it off before you send it. Go ahead and chop chop it off and you'll be okay! But first, debug, debug, debug. The debugger is your best friend to figure out what the hell is going on. Really, it sounds complex, but you'll just be playing voyeur to your program, something which I'm sure you have experience in. You already know how to do this! lol.

Anyway, good luck.

#10
Ilikestring

Ilikestring

    Newbie

  • Members
  • PipPip
  • 17 posts
Sorry, I went for my lunch break.
Okay, I'll have a little play around with it and see if it goes anywhere. I'll let you know how it goes.
Thanks for your help!

#11
Ilikestring

Ilikestring

    Newbie

  • Members
  • PipPip
  • 17 posts
After some fiddling around I have found something that works perfectly:

  For Count := 1 to (ADOTable1.FieldCount - 1) do
    begin
      wrdDoc.Tables.Item(1).Cell(Count + 1, 1).select;
      SendThis := wrdMergeFields.Add(wrdSelection.Range,'Time' + IntToStr(Count));
      wrdDoc.Tables.Item(1).Cell(Count + 1, 2).select;
      SendThis := wrdMergeFields.Add(wrdSelection.Range,'THonorific' + IntToStr(Count));
      wrdDoc.Tables.Item(1).Cell(Count + 1, 3).select;
      SendThis := wrdMergeFields.Add(wrdSelection.Range,'TSurname' + IntToStr(Count));
    end;

Strangely enough just writing "SendThis := wrdMergeFields.Add(wrdSelection.Range,'Time' + IntToStr(Count));" puts the 'Time' into the table perfectly with no rogue 59's. The SendThis variable just becomes '59'. How strange. I have no idea how it works, and I'm not particularly bothered so long as it does!
Thank you for your help Firebird_38. I appreciate it.
Now it's just to try and fix those SQL and database problems! The end of my system is in sight :)

#12
Firebird_38

Firebird_38

    Programmer

  • Members
  • PipPipPipPip
  • 126 posts
Well, forget storing your result into "sendthis", because wrdMergeFields.Add already adds the actual field code, and returns a field number or something like that, or a field code 59 for mail-merge field. So, you don't add it, it's already added. That's the reason.

Posted Image