After successfully developing the letter, my next task was to write a procedure that would be executed as a direct activation from the orders screen and would send the letter via email. My original code was something like this
LINK ORDERS TO :$.PAR; ERRMSG 1 WHERE :RETVAL <= 0; :FNAME = 'X:/1/TEST_SENDORDLETTER.pdf'; EXECUTE WINHTML '-d', 'TEST_ORDLETTER', 'ORDERS', :$.PAR, '-pdf', :FNAME; :EMAIL = '....'; MAILMSG 10 TO EMAIL :EMAIL DATA :FNAME;
I'm leaving out all the changes that were added later - I ended up using the interface for mail messages instead of MAILMSG and that's not really relevant.
Every time that I tried this, the procedure worked fine and sent the mail containing the letter. Every time the user wanted to run it, the letter was created but contained only with the logo and signature: the important part of the letter was missing.
It took some time to figure out what was missing: I had originally run the mail merge program and had defined what the format was to be. Someone running the 'envelope' procedure as a direct activation would not get the chance to define the format of the mail merge. OK: there is a paragraph in the SDK that shows how to overcome this -
/* Set print format */ :EXEC = 0; SELECT EXEC INTO :EXEC FROM EXEC WHERE TYPE = 'P' AND ENAME = 'TEST_ORDLETTER'; UPDATE PRINTFORMAT SET VALUE = -102 /* required format */ WHERE EXEC = :EXEC AND USER = SQL.USER;
I've used the same code (albeit with a different ENAME and format) for a similar program and there this code worked fine. But the print format was still not being set for the user. At first, I thought that the user would have to run the mail merge procedure once from the menu in order to set the print format, which is when the light finally went on in my head. The above code will fail because there is no record in the PRINTFORMAT to update! So I added the code to insert the necessary values into that table; if the insert succeeds, the code jumps over the 'update' statement. Looking at this again, the 'update' statement should come first, and only if this fails should there be the 'insert'.
The above is not written in the SDK!
There are two pitfalls here: (1) The inner procedure has to appear in a menu that the user has permission for; (2) The format has to be set.