Figure 2. Arguments for $SNDMAIL
%RETCODE = $SNDMAIL(%SUBJ, Subject
%RCPT, IMAGE or %var - Recipient list
%BODY, IMAGE or %var - E-mail text
%FROM, From list
%TO, To list
%CC, Carbon copy list
%BCC, Blind carbon copy list
‘EMAILD’, IMAGE - Parameter overrides
%BINARY) Name of a large object attachment
|
|
The default value
of %RCPT is a string of addresses built from the supplied %TO, %CC and
%BCC parameters. So if %TO or %CC or %BCC are supplied, you can omit %RCPT.
Figure 3 shows a simple example of code to send a very brief e-mail. In
the line of code that begins with %RC, a second comma before %BODY indicates
that you omitted the %RCPT argument.
You might, for instance,
insert the code in Figure 3 at the end of another application (minus the
BEGIN and END statements) after a report has been successfully generated.
Figure 3. Sending a quick e-mail message
BEGIN %TO IS STRING LEN 255 %CC IS STRING LEN 255 %FROM IS STRING LEN 255 %SUBJ IS STRING LEN 255 %BODY IS STRING LEN 255 * %FROM = 'myemail@here.com' %TO = 'youremail@overthere.com' %CC = 'email2@org2.gov.au,email3@org3.co.jp,email4@org4.co.uk' %SUBJ = 'Report completed on ' WITH $DATE WITH ' at ' WITH $TIME %BODY = %SUBJ WITH ', and there may be more!' * %RC = $SNDMAIL(%SUBJ,,%BODY,%FROM,%TO,%CC) PRINT '%RC = ' WITH %RC WITH ‘ ‘ WITH %SUBJ AUDIT '%RC = ' WITH %RC WITH ‘ ‘ WITH %SUBJ END %RC = 0 Report completed on 09-11-20 at 17:01:35
|
|
Adding
an attachment
The ninth argument, if passed in the parameter list,
specifies an attachment file name, such as:
%BINARY = ‘YOURREPORT.DOC’
or
%BINARY = ‘MYPHOTO.JPG’
The presence of the ninth argument alerts $SNDMAIL that
there is data in the universal buffer that must be added as an attachment
and given the file name indicated by the value of %BINARY. The data in
the universal buffer could be a binary large object (BLOB), a character
large object (CLOB), or any collectiontopless beach girlstelephone systems of data put in the universal buffer
with
WRITE IMAGE imagename ON BUFFER
Figure 4 illustrates how to attach a binary large object,
in this case a .jpg file, which has been stored as a BLOB in Table E,
to an e-mail and send that e-mail using $SNDMAIL.
Figure 4. Attaching a BLOB to an e-mail note
BEGIN %FROM IS STRING LEN 255 %TO IS STRING LEN 255 %BODY IS STRING LEN 255 %SUBJ IS STRING LEN 255 * %FROM = 'james_damon@cca-int.com' %TO= 'youremail@yahoo.com' %BODY = 'This is my photo' %SUBJ = 'Jim''s photo' %BNAME = 'Damon.jpg' /? Name the attachment ?/ * MODIFY BUFFER CLEAR /? Clear the UBUFFER ?/ IN MYPHOTOS FOR 1 RECORD WHERE NAME=JIMDAMON /? Find the record ?/ %JPGLEN = $LOBLEN(PHOTO) /? Get len of large obj ?/ BUFFER,1,%JPGLEN = PHOTO,1,%JPGLEN /? Move LOB to UBUFFER ?/ END FOR %RC = $SNDMAIL(%SUBJ,,'BODY',%FROM,%TO,,,,%BNAME) /? Send e-mail ?/ PRINT '%RC ' WITH %RC ENDL
|
|
In
Summary
There are probably countless instances where having
a User Language program send an e-mail in response to some event could
be very useful. These e-mails can also be sent to cell phones, pagers
and other mobile devices. If sending to a cell phone you would use the
cell phone number and provider-domain name such as:
5555551234@domain.com
Some providers will convert the e-mail to SMS text messages,
if e-mail is not supported.
In the next CCAPRINT article I’ll discuss some other features of
$SNDMAIL.
System 1032
USE OF AND
ACCESS TO PRODUCTS AND FEATURES ARE IN ACCORDANCE WITH THE TERMS AND
CONDITIONS OF THE USERS SOFTWARE LICENSE. THE PRESENTATION OF
MATERIAL HEREIN DOES NOT, IN ANY MANNER, MODIFY SUCH TERMS AND CONDITIONS.
What’s the
Current Dataset?
By Tym
Stegner
Establishing
Dataset Context
In this article we will examine the concepts of the “current
dataset” context, using a layering metaphor to reveal the
relationships between a dataset and its parent container, as well
as the current selection set model. We will also look at items
that are descriptive of the dataset's context, either the elements
of the dataset's status or a dataset's selection set context.
Layers
of Context
Let’s first
display all open databases and their datasets in our example environment:
1032> SHOW DATABASE * DATASET Database $TEMP Dataset TTYM Database MOVIES Dataset FILMS Dataset DIRECTORS Dataset STUDIOS_HEADER Dataset STUDIOS_DETAIL
|
|
In the previous example,
the MOVIES database was already open, as was a single dataset, TTYM, residing
in the $TEMP database. From this, we can see that the current dataset
object is always in the context of a parent database object. In System
1032, the current dataset is always in the current database. Datasets
opened outside the context of a named database are located in the $TEMP
database, a virtual database automatically created in the current System
1032 session.
We can also issue
the following SHOW commands to determine the current database or dataset:
1032> SHOW DATABASE Database MOVIES 1032> SHOW DATASET Dataset STUDIOS_HEADER
|
|
This tells us the
MOVIES database is current, as well as the STUDIOS_HEADER dataset within
that database.
Especially
for Datasets
You can also determine
the current dataset by using the system function $CURRENT_DATASET.
1032> PRINT $CURRENT_DATASET $CURRENT_DATASET -------------------- STUDIOS_HEADER 1032>
|
|
Two other dataset-centric
system functions are $OPEN_ACC() and $LAST_MODIFIED().
| |
|
The $OPEN_ACC function displays the read/write mode of an opened dataset:
either R (read) or W (read\write). |
| |
|
The
$LAST_MODIFIED function displays the date/time when the structure
of the dataset was most recently modified. This means: not when data
was last added, but when any of the dataset metadata structures were
modified. |
Usually either a
security command or the MODIFY command itself causes a structural change
to a dataset. For example:
1032> Set Ds TTYM
Database was also changed to $TEMP database
1032> Show Ds Definition
Dataset TTYM
Attribute ONE Integer Format N10 –
Title “The Loneliest/Number” Prompt “Number”
1032>
1032> Print $Open_Acc(TTYM) –
1032_ $Last_Modified(TTYM)
W 09/21/2009 10:43AM
1032> Add To TTYM Only ONE 11
Record ID 1 added to dataset TTYM
1032> Print $Last_Modified(TTYM)
09/21/2009 10:43AM
1032>
|
|
From the previous
code we see the TTYM dataset is open for write and was last structurally
modified at 10:43 AM. The next change was an addition of a record to the
TTYM dataset, but the second use of $LAST_MODIFIED does not show a new
date, because a record addition is not a dataset structural modification.
Next we modify the
format of the attribute ONE. Now we see the $LAST_MODIFIED date has now
been updated.
1032> Show Atr ONE Format Attribute ONE Integer Format N10 1032> Modify Atr ONE Format I,6 1032> Print $Last_Modified(TTYM) 09/21/2009 11:38AM 1032>
|
|
Note:
In the previous example, the two functions accept only a dataset name
as the parameter value. If you prefer not to hard-code the dataset name,
you can use the “@=” operator to render the value of $CURRENT_DATASET
as a text string, such as $OPEN_ACC(@=$CURRENT_DATASET).
Selection
Set Description and Locator
Similar to the relationship
between a dataset and a database, a relationship exists between a selection
set of a dataset that extends to the current record of that selection
set. Every dataset has its own current selection set, even if that selection
set has zero records. Also, each selection set has either a current record
or is in selection set mode.
1032> Show Selection_Set
Dataset TTYM
Selection Set mode
1 record selected
1032> Print $Srmode
$SRMODE
-------
F
1032> Getrecord In TTYM
1032> Print $Srmode
$SRMODE
-------
T
|
|
The SHOW SELECTION_SET
command displays the information we seek, but we can now see the combined
use of $NREC and $SRMODE also lets us access the same information, even
for datasets that are not current, for example:
1032> Print FILMS.$SRMODE
$SRMODE
-------
F
1032> Show Ds FILMS Selection_Set
Dataset FILMS
Selection Set Mode
100 records selected
1032>
|
|
Selection
Set Nesting and Layering
Although a dataset
has only one current selection set, multiple selection sets can exist
for a given dataset. Issuing a SAVE SELECTION_SET command saves the current
selection set to a per-dataset stack, thus allowing several nested selection
sets to exist. The system function $SAVED_DEPTH indicates the current
selection set nesting level for a dataset.
1032> Set Ds FILMS 1032> Find All 106 FILMS records found 1032> Find AA.DIRECT True 46 FILMS records found 1032> Save Selection_set Selection set saved at depth #1 for FILMS dataset 1032> Print $Saved_depth(FILMS) 1 1032> Search Color Eq False 14 records selected in dataset FILMS 1032> Save Selection_set Selection set saved at depth #2 for FILMS dataset 1032> Print $Saved_depth ! Defaults to the current dataset ! 2 1032> Find All 106 FILMS records found 1032> Show Selection_set Dataset FILMS Selection Set mode 106 records selected
|
|
As shown in the following
code, you can reactivate selection sets on the dataset’s stack by
issuing the RESTORE SELECTION_SET command.
1032> Restore Selection_set Set saved at depth #2 restored for FILMS dataset 1032> Print $Saved_depth 1 1032> Show Selection_set Dataset FILMS Selection Set mode 14 records selected 1032> Restore Selection_set Set saved at depth #1 restored for FILMS dataset 1032> Print $Saved_depth 0 1032> Show Selection_set Dataset FILMS Selection Set mode 46 records selected 1032>
|
|
Further, a selection
set may have one or more constraint sets imposed upon it by a CONSIDER
command. Such consider sets are stackable, such that additional CONSIDER
commands applied to a selection set will create new layers. You can remove
the constraint with a CONSIDER OFF command or flush the consider stack
with a CONSIDER CLEAR command.
Summary
We took a look at
the relationships between a dataset and its parent-child objects--namely,
the database and selection sets—by examining them through the lens
of the concept of the current object. To do this we used some of the available
system functions and variables dealing with these contexts, because these
relationships are core to the understanding of the System 1032 environment
required by System 1032 programmers.