Moves data previously placed in the screen buffer by a data input statement or moves data
specified within the ASSIGN statement by an expression to the corresponding fields and
variables in the record buffer.
Syntax
ASSIGN {
[ [ INPUT ] FRAME frame | BROWSE browse ]
{ field [ = expression] } [ WHEN expression ]
} ... [ NO-ERROR ]
|
ASSIGN { record [ EXCEPT field ... ] } [ NO-ERROR ]
|
- [ FRAME frame
| BROWSE browse
]
field
- The name of the field or variable (field) to be set from the
corresponding value found in the screen buffer or expression. The
field must be qualified by a frame name (frame)
or browse name (browse) if field is specified as
an input widget in more than one frame. If field is set from
expression, field can include all of the
elements that are defined for the left side of an Assignment (=) statement.
-
expression
- An expression with a data type that is consistent with the data type of
field. In this case, the AVM determines the
field value from the expression rather than from the screen buffer.
For more information on expression, see the Expression reference entry.
- WHEN expression
- Moves data to the record buffer only when expression has a value of
TRUE. Here, expression is a field name, variable name, or expression
whose value is logical. The AVM evaluates WHEN expressions at the beginning of the
assignment, before any assignments take place.
- NO-ERROR
- Suppresses ABL errors or error messages that would otherwise occur and diverts them to
the ERROR-STATUS system handle. If an error occurs, the
action of the statement is not done and execution continues with the next statement. If
the statement fails, any persistent side-effects of the statement are backed out. If the
statement includes an expression that contains other executable elements, like methods,
the work performed by these elements may or may not be done, depending on the order the
AVM resolves the expression elements and the occurrence of the error.
For the ASSIGN
statement with NO-ERROR, if an ERROR condition is raised, every instance of
field remains unchanged.
To check for errors after a
statement that uses the NO-ERROR option:
- Check the ERROR-STATUS:ERROR attribute to see if the AVM raised the ERROR
condition.
- Check if the ERROR-STATUS:NUM-MESSAGES attribute is greater than zero to see if
the AVM generated error messages. ABL handle methods used in a block without
a CATCH end block treat errors as warnings and do not raise ERROR, do not set the
ERROR-STATUS:ERROR attribute, but do add messages to the ERROR-STATUS system handle.
Therefore, this test is the better test for code using handle methods without CATCH
end blocks. ABL handle methods used in a block with a CATCH end block raise
ERROR and add messages to the error object generated by the AVM. In this case, the
AVM does not update the ERROR-STATUS system handle.
- Use ERROR-STATUS:GET-MESSAGE( message-num ) to retrieve a
particular message, where message-num is 1 for the first
message.
If the statement does not include the NO-ERROR option, you can use a CATCH end
block to handle errors raised by the statement.
Some other important usage notes
on the NO-ERROR option:
- NO-ERROR does not suppress errors that raise the STOP or QUIT condition.
- A CATCH statement, which introduces a CATCH end block, is analogous to a NO-ERROR
option in that it also suppresses errors, but it does so for an entire block of
code. It is different in that the error messages are contained in a class-based
error object (generated by the AVM or explicitly thrown), as opposed to the
ERROR-STATUS system handle. Also, if errors raised in the block are not handled by a
compatible CATCH block, ON ERROR phrase, or UNDO statement, then the error is not
suppressed, but handled with the default error processing for that block type.
- When a statement contains the NO-ERROR option and resides in a block with a CATCH
end block, the NO-ERROR option takes precedence over the CATCH block. That is, an
error raised on the statement with the NO-ERROR option will not be handled by a
compatible CATCH end block. The error is redirected to the ERROR-STATUS system
handle as normal.
- If an error object is thrown to a statement that includes the NO-ERROR option,
then the information and messages in the error object will be used to set the
ERROR-STATUS system handle. This interoperability feature is important for those
integrating code that uses the traditional NO-ERROR technique with the newer,
structured error handling that features error objects and CATCH end blocks.
-
record
- The record buffer name with the fields set, from the corresponding values in the
screen buffer. Naming a record is a shorthand way to list each field in that record
individually.
To use ASSIGN with a record in a table defined for multiple databases,
you might have to qualify the record's table name with the database name. See the
Record phrase reference entry for more information.
- EXCEPT field
- All fields in the record buffer are affected except for those listed. Separate field
names with a space.
Examples
The following procedure prompts you for a customer number and retrieves the customer record
if one exists, or creates a new one if it does not exist. If it creates a new record, the
value for the CustNum field is ASSIGNed from the value you entered in
response to the PROMPT-FOR statement.
r-asgn.p
REPEAT:
PROMPT-FOR Customer.CustNum.
FIND Customer USING Customer.CustNum NO-ERROR.
IF NOT AVAILABLE Customer THEN DO:
CREATE Customer.
ASSIGN Customer.CustNum. END.
UPDATE Customer WITH 2 COLUMNS.
END.
|
The next procedure changes the order number and line number of an order-line record. (It
copies an order-line from one order to another.) It sets the new values into variables and
modifies the record with a single ASSIGN statement that contains two assignment phrases in
the form field = expression. Thus, both fields are changed within a
single statement. Because the AVM re-indexes records at the end of any statement that
changes an index field value, and because OrderLine.OrderNum and
OrderLine.LineNum are used jointly in one index, this technique does not
generate an index until both values change.
r-asgn2.p
DEFINE VARIABLE neword LIKE order-line.order-num LABEL "New Order".
DEFINE VARIABLE newordli LIKE order-line.line-num LABEL "New Order Line".
REPEAT:
PROMPT-FOR OrderLine.OrderNum OrderLine.LineNum.
FIND OrderLine USING OrderLine.OrderNum AND OrderLine.LineNum.
SET neword newordli.
FIND Order WHERE Order.OrderNum = neword.
ASSIGN
OrderLine.OrderNum = neword
OrderLine.LineNum = newordli.
END.
|
Notes
- If field is an integer and expression is a
decimal, the AVM rounds the value of the expression before assigning it. If
field is a decimal and expression is a decimal,
the AVM rounds the value of the expression to the number of decimal places defined for the
field in the Data Dictionary, or defined or implied for a variable or temp-table
field.
- If field is an ABL array type (defined with EXTENT) and
expression is not an array, and you do not identify a particular
array element, the AVM stores expression in each element of the array.
If you identify a particular element, the AVM stores expression in the
specified array element.
- If both field and expression are ABL array types,
the AVM copies the data for all expression array elements into the
corresponding elements of the field array. This is known as a deep
copy.
- An indeterminate array is one where the size of the EXTENT is not yet
fixed. A determinate array is one where the EXTENT size is fixed. When deep
copying one array to another, the following rules apply:
- If both the array on the left-hand side and the right-hand side of the equation are
determinate arrays, the EXTENT size must match or the AVM raises an error.
- You cannot assign an indeterminate array to a determinate array.
- You can assign any array to an indeterminate array, but you cannot assign a scalar
value to an indeterminate array.
- ABL allows you to assign ABL arrays and .NET array objects to each other. How an array
assignment works between ABL and .NET arrays depends upon the array type of
field (the target of the assignment) and the array type of
expression (the source for the assignment). For more information, see
the Data types reference entry.
- If an assignment of one array to another encounters an error after some, but not all of
the source array's elements are retrieved, none of the target's elements are updated.
- If expression is an ABL handle-based object (for example, a
temp-table, ProDataSet, widget, or socket), field must be a temp-table
field, variable, or other ABL data element defined as a compatible handle. In this case,
the AVM assigns only the handle of the ABL handle-based object to
field, not the entire object and its contents.
- If any field is a field in a database record, the ASSIGN statement
upgrades the record lock condition to EXCLUSIVE-LOCK before updating the record.
- If any field is part of a record retrieved with a field list, the
ASSIGN statement rereads the complete record before updating it.
- If field is a handle, the expression on the
right-hand-side of the corresponding assignment must also evaluate to a handle value that
is specified using an appropriate reference to a handle-based object handle. For more
information on object handle references, see the Handle Attributes and Methods Reference.
- During data entry, a validation expression defined for the field in the database or in a
Format phrase executes only if the widget associated with the field receives input focus.
Use the VALIDATE( ) method to execute a validation expression defined for a field
regardless of whether it receives input focus or not.
- Use an ASSIGN statement after a PROMPT-FOR statement or to write changes from an enabled
field to the database. ASSIGN moves the value from the screen buffer into the field or
variable.
- Use the PROMPT-FOR statement to receive one or more index fields from the user, and you
use the FIND statement to find a record matching those index values. If no record is
found, use the CREATE statement to create a new record and use the ASSIGN statement to
assign the values the user supplied to the new record.
- You cannot use the SET statement in place of the PROMPT-FOR statement. The SET statement
prompts the user for input and then assigns that input to the record in the buffer.
However, if there is not a record available, SET cannot assign the values.
- ASSIGN does not move data into a field or variable if there is no data in the
corresponding screen field. There is data in a screen field if a DISPLAY of the field was
done or if data was entered into the field. If you PROMPT-FOR a field or variable that has
not been DISPLAYed in the frame and enter blanks, the AVM does not change the field or
variable because it considers the screen field changed only if the data differs from what
was in the field.
- If an ASSIGN statement references a field or variable that is used in more than one
frame, it uses the value in the frame most recently introduced in the procedure.
- If you type blanks into a field that has never displayed data, the ENTERED function
returns FALSE and the SET or ASSIGN statement does not update the underlying field or
variable. Also, if the AVM marks a field as entered, and the PROMPT-FOR statement prompts
for the field again and you do not enter any data, the AVM no longer considers the field
entered.
- If you use a single, qualified identifier with the ASSIGN statement, the Compiler
interprets the reference as dbname.filename. If the Compiler cannot
resolve the reference as dbname.filename, it tries to resolve it as
filename.fieldname.
- Many assignments within a single ASSIGN statement are more efficient than multiple
ASSIGN statements. It saves r-code size and improves performance.
- The ASSIGN statement, when used in database fields, causes all related database ASSIGN
triggers to execute in the order in which the fields were assigned. The ASSIGN triggers
execute after all the assignments have taken place. If an ASSIGN trigger fails (or
executes a RETURN statement with the ERROR option), all of the database changes are
undone. See OpenEdge Development: ABL Handbook for more information on
database triggers.
- You can assign large object data from one BLOB or MEMPTR to another, and from one CLOB,
LONGCHAR, or CHARACTER to another. You cannot assign large object data between BLOBs and
CLOBs or MEMPTRs and LONGCHARs. You can accomplish, indirectly, by using the COPY-LOB
statement. For more information, see the COPY-LOB statement
reference entry.
The following table lists the default character conversions that the
AVM performs when assigning CLOB, LONGCHAR, and CHARACTER data. References to CLOBCP and
CLOBDB represent CLOB data in either the CLOB's defined code page or the database's
defined code page, respectively. References to the "fixed code page" represent the code
page of a target LONGCHAR variable set using the FIX-CODEPAGE statement.
Default character conversions with the ASSIGN statement
When the target field is a . . . |
And the source expression results in a . . . |
The AVM converts the result of the source expression to . .
. |
LONGCHAR |
CLOBDB |
-cpinternal or the fixed code page |
LONGCHAR |
CLOBCP |
The CLOB's defined code page or the fixed code page |
LONGCHAR |
CHARACTER |
-cpinternal or the fixed code page |
CLOBDB |
CHARACTER |
The database's defined code page |
CLOBDB |
LONGCHAR |
The database's defined code page |
CLOBCP |
CHARACTER |
The CLOB's defined code page |
CLOBCP |
LONGCHAR |
The CLOB's defined code page |
CHARACTER |
CLOBDB |
-cpinternal code page |
CHARACTER |
CLOBCP |
-cpinternal code page |
CHARACTER |
LONGCHAR |
-cpinternal code page |
- When you assign the Unknown value (?) to a BLOB or CLOB field, the AVM
deletes any associated object data.
- You can assign DATE, DATETIME, and DATETIME-TZ data. When the data type
expression on the left side of the assignment statement contains more information than the
data type expression on the right side provides (for example, datetime-tz = date where a DATETIME-TZ value contains more information than a
DATE value), the time value defaults to midnight and the time zone is calculated using
SESSION:TIMEZONE when that attribute is in use. If the attribute is not in use, the value
defaults to the session's timezone. When the data type expression on the left side of the
assignment statement contains less information than the data type expression on the right
side provides (for example, date = datetime-tz where a
DATE value contains less information than a DATETIME-TZ value), the AVM converts the
DATETIME-TZ value to the local date and time of the session, then drops the time and time
zone.
Note: For releases 11.6.0 and earlier, assignments such as datetime-tz = date used the system's timezone, regardless
of whether or not SESSION:TIMEZONE was set. To revert to this earlier behavior, use the
Use SESSION:TIMEZONE (-useSessionTZ) startup
parameter. See OpenEdge Deployment: Startup Command and Parameter
Reference for more information.
- If expression is a solitary invocation of the NEW function, this
function behaves according to the rules specified for the NEW function (classes) when not operating in the context of a NEW statement.
- If expression evaluates to an object reference value,
field must also be a data element defined as a class or interface
type that is type-compatible with expression according to the rules for
assigning references to class instances defined for the NEW statement. For more
information, see the NEW statement reference entry. Thus, you can
assign one object reference variable to another object reference variable when the
destination object reference (on the left side of the assignment) is defined for the same
class, a super class, or an interface of the object reference being assigned (on the right
side of the assignment). The destination object reference retains its defined class or
interface type for compilation. However, following its assignment, at run time, the
destination represents the subclass of field (or the class that
implements the interface specified by field) that is defined by
expression.
If field has a class type that is a
subclass lower in the class hierarchy than the class type represented by
expression, you can cast expression to the type
of field using the CAST function, but only if
expression is a super class that actually contains an instance of
the field class type. If field has a class type
that implements an interface type represented by expression, you can
similarly cast expression using the CAST function, but only if
expression actually contains an instance of the
field class type. For more information about the CAST function, see
the CAST function reference
entry.
After the assignment, field contains a copy of the
object reference value returned by expression, which points to the
same object instance, not a copy of the object referenced by
expression.
- Although you can assign an object reference to a temp-table field defined as a Progress.Lang.Object class type, you cannot assign an object reference to a field in
a database table. For more information, see OpenEdge Development: Object-oriented
Programming.
See also
Assignment (=) statement, CAST function, Class-based object reference, COPY-DATASET( ) method, COPY-LOB statement,
COPY-TEMP-TABLE( ) method, Data types, Expression, FIX-CODEPAGE statement, INPUT function, PROMPT-FOR statement, SET statement, UPDATE statement