C5_ADEL

 ADEL()
 Delete an array element
------------------------------------------------------------------------------
 Syntax

     ADEL(<aTarget>, <nPosition>) --> aTarget

 Arguments

     <aTarget> is the array to delete an element from.

     <nPosition> is the position of the target array element to be
     deleted.

 Returns

     ADEL() returns a reference to the target array, <aTarget>.

 Description

     ADEL() is an array function that deletes an element from an array.  The
     contents of the specified array element is lost, and all elements from
     that position to the end of the array are shifted up one element.  The
     last element in the array becomes NIL.

     Warning!  Clipper implements multidimensional arrays by nesting
     arrays within other arrays.  If the <aTarget> array is a
     multidimensional array, ADEL() can delete an entire subarray specified
     by <nPosition>, causing <aTarget> to describe an array with a different
     structure than the original.

 Examples

     .  This example creates a constant array of three elements, and
        then deletes the second element.  The third element is moved up one
        position, and the new third element is assigned a NIL:

        LOCAL aArray
        aArray := { 1, 2, 3 }      // Result: aArray is
                                   // now { 1, 2, 3 }
        ADEL(aArray, 2)            // Result: aArray is
                                   // now { 1, 3, NIL }

 Files   Library is CLIPPER.LIB.


See Also: ACOPY() AFILL() AINS()

 

C5_ACOPY

 ACOPY()
 Copy elements from one array to another
------------------------------------------------------------------------------
 Syntax

     ACOPY(<aSource>, <aTarget>,
        [<nStart>], [<nCount>], [<nTargetPos>]) --> aTarget

 Arguments

     <aSource> is the array to copy elements from.

     <aTarget> is the array to copy elements to.

     <nStart> is the starting element position in the <aSource> array.
     If not specified, the default value is one.

     <nCount> is the number of elements to copy from the <aSource> array
     beginning at the <nStart> position.  If <nCount> is not specified, all
     elements in <aSource> beginning with the starting element are copied.

     <nTargetPos> is the starting element position in the <aTarget> array
     to receive elements from <aSource>.  If not specified, the default value
     is one.

 Returns

     ACOPY() returns a reference to the target array, <aTarget>.

 Description

     ACOPY() is an array function that copies elements from the <aSource>
     array to the <aTarget> array.  The <aTarget> array must already exist
     and be large enough to hold the copied elements.  If the <aSource> array
     has more elements, some elements will not be copied.

     ACOPY() copies values of all data types including NIL and code blocks.
     If an element of the <aSource> array is a subarray, the corresponding
     element in the <aTarget> array will contain a reference to the subarray.
     Thus, ACOPY() will not create a complete duplicate of a multidimensional
     array.  To do this, use the ACLONE() function.

 Examples

     .  This example creates two arrays, each filled with a value.
        The first two elements from the source array are then copied into the
        target array:

        LOCAL nCount := 2, nStart := 1, aOne, aTwo
        aOne := { 1, 1, 1 }
        aTwo := { 2, 2, 2 }
        ACOPY(aOne, aTwo, nStart, nCount)
        // Result: aTwo is now { 1, 1, 2 }

 Files   Library is CLIPPER.LIB.

See Also: ACLONE() ADEL() AEVAL() AFILL() AINS() ASORT()

 

C5_ACLONE

 ACLONE()
 Duplicate a nested or multidimensional array
------------------------------------------------------------------------------
 Syntax

     ACLONE(<aSource>) --> aDuplicate

 Arguments

     <aSource> is the array to be duplicated.

 Returns

     ACLONE() returns a duplicate of <aSource>.

 Description

     ACLONE() is an array function that creates a complete duplicate of the
     <aSource> array.  If <aSource> contains subarrays, ACLONE() creates
     matching subarrays and fills them with copies of the values in the
     <aSource> subarrays.  ACLONE() is similar to ACOPY(), but ACOPY() does
     not duplicate nested arrays.

 Examples

     .  This example creates an array then duplicates it using
        ACLONE().  The first array is then altered, but the duplicate copy is
        unaffected:

        LOCAL aOne, aTwo
        aOne := { 1, 2, 3 }         // Result: aOne is {1, 2, 3}
        aTwo := ACLONE(aOne)        // Result: aTwo is {1, 2, 3}
        aOne[1] := 99               // Result: aOne is {99, 2, 3}
                                   // aTwo is still {1, 2, 3}

 Files   Library is CLIPPER.LIB.

See Also: ACOPY() ADEL() AINS() ASIZE()

 

C5_ACHOICE

 ACHOICE()
 Execute a pop-up menu
------------------------------------------------------------------------------
 Syntax

     ACHOICE(<nTop>, <nLeft>, <nBottom>, <nRight>,
        <acMenuItems>,
        [<alSelectableItems> | <lSelectableItems>],
        [<cUserFunction>],
        [<nInitialItem>],
        [<nWindowRow>]) --> nPosition

 Arguments

     <nTop>, <nLeft> and <nBottom>, <nRight> are the upper-
     left and lower-right window coordinates.  Row values can range from zero
     to MAXROW() and column values can range from zero to MAXCOL().

     <acMenuItems> is an array of character strings to display as the
     menu items.  The individual menu items are later identified by their
     numeric positions in this array.

     <alSelectableItems> is a parallel array of logical values--one
     element for each item in <acMenuItems>--that specify the selectable menu
     items.  Elements can be logical values or character strings.  ACHOICE()
     will not permit a null string and stops displaying if it encounters one.
     If the element is a character string, it is evaluated as a macro
     expression which should evaluate to a logical data type.  In either
     case, a value of false (.F.) means that the corresponding menu item is
     not available, and a value of true (.T.) means that it is available.  If
     you specify <lSelectableItems> instead of an array, false (.F.) makes
     all menu items unavailable and true (.T.) makes all menu items
     available.  By default, all menu items are available for selection.

     <cUserFunction> is the name of a user-defined function that executes
     when an unrecognizable key is pressed.  Specify the function name as a
     character expression without parentheses or arguments.  Note that the
     behavior of ACHOICE() is affected by the presence of this argument.
     Refer to the discussion below for further information.

     <nInitialItem> is the position in the <acMenuItems> array of the
     item that will be highlighted when the menu is initially displayed.  If
     you specify an unavailable menu item or no argument at all, the initial
     menu item is the first selectable item in the array.

     <nWindowRow> is the number of the window row on which the initial
     menu item will appear.  Row numbering begins with zero.  By default, the
     initial menu item appears as close to the top of the window as possible,
     without leaving any empty rows at the bottom.  Thus, if there are enough
     menu items following the initial one to fill up the window, the initial
     form will appear on the first row (row zero) of the menu.  This function
     argument is used to control the initial menu appearance when there are
     more menu items than will fit in the window.

     As with all functions, optional arguments are omitted by using a comma
     instead of the actual argument.

 Returns

     ACHOICE() returns the numeric position in the <acMenuItems> array of the
     menu item selected.  If the selection process is aborted, ACHOICE()
     returns zero.

 Description

     ACHOICE() is a user interface function that can create various kinds of
     pop-up menus.  Each menu uses an array of character strings as menu
     items and a parallel array of logical values to determine whether items
     are selectable.  When you invoke ACHOICE(), the list of menu items is
     displayed within the specified window coordinates.  When the user
     presses Return, the current item is selected, and ACHOICE() returns the
     position of the menu item in <acMenuItems>.  When the user presses Esc,
     ACHOICE() aborts and returns zero.

     The menu items scroll if the number of items in <acMenuItems> exceeds
     the number of rows in the menu window, and the user attempts to move the
     highlight beyond the top or bottom of the menu window.  Note that the
     highlight does not wrap when you reach the top or bottom of the list of
     items.  Pressing the first letter does, however, wrap the highlight
     within the set of items whose first letter matches the key you press.

     .  Navigating the menu:  ACHOICE() has two modes depending on
        whether the <cUserFunction> argument is specified.  If it is not
        specified the following navigation keys are active:

        ACHOICE() Keys (No User Function)
        ---------------------------------------------------------------------
        Key            Action
        ---------------------------------------------------------------------
        Up arrow       Go to previous item
        Down arrow     Go to next item
        Home           Go to first item in menu
        End            Go to last item in menu
        Ctrl+Home      Go to first item in window
        Ctrl+End       Go to last item in window
        PgUp           Go to previous page
        PgDn           Go to next page
        Ctrl+PgUp      Go to the first item in menu
        Ctrl+PgDn      Go to last item in menu
        Return         Select current item
        Esc            Abort selection
        Left arrow     Abort selection
        Right arrow    Abort selection
        First Letter   Go to next item beginning with first letter
        ---------------------------------------------------------------------

     .  Color:  Menu items are displayed in standard color, the
        highlight in enhanced color, and the unavailable items in the
        unselected color.  For example, the following color statement

        SETCOLOR("W+/N, BG+/B, , , W/N")

        displays a menu that is bright white on black, the highlight is
        bright cyan on blue, and the unavailable menu items are dim white on
        black.

     .  User function: Like the other user interface functions,
        ACHOICE() supports a user function.  The user function is specified
        when you want to nest ACHOICE() invocations to create hierarchical
        menus or to redefine keys.

        When a user function is specified, ACHOICE() processes only a limited
        set of keys automatically.  These are listed in the following table.
        All other keys generate a key exception which passes control to the
        user function for handling.  Control is also passed to the user
        function when ACHOICE() goes idle (i.e., when there are no more keys
        to process).

        ACHOICE() Keys (User Function Specified)
        ---------------------------------------------------------------------
        Key          Action
        ---------------------------------------------------------------------
        Uparrow      Go to previous item
        Dnarrow      Go to next item
        Ctrl+Home    Go to first item in window
        Ctrl+End     Go to last item in window
        PgUp         Go to previous page
        PgDn         Go to next page
        Ctrl+PgUp    Go to the first item in menu
        Ctrl+PgDn    Go to last item in menu
        ---------------------------------------------------------------------

        When ACHOICE() executes the user function, it automatically passes
        the following three parameters:

        -  The current ACHOICE() mode

        -  The current element in the array of items

        -  The relative row position within the menu window

        The mode indicates the current state of ACHOICE() depending on the
        key pressed and the action taken by ACHOICE() prior to executing the
        user function.  The mode parameter has the following possible values:

        ACHOICE() Modes
        ---------------------------------------------------------------------
        Mode    Achoice.ch     Description
        ---------------------------------------------------------------------
        0       AC_IDLE        Idle
        1       AC_HITTOP      Attempt to cursor past top of list
        2       AC_HITBOTTOM   Attempt to cursor past bottom of list
        3       AC_EXCEPT      Keystroke exceptions
        4       AC_NOITEM      No selectable items
        ---------------------------------------------------------------------

        After the user function has performed whatever operations are
        appropriate to the ACHOICE() mode or LASTKEY(), it must RETURN a
        value requesting ACHOICE() to perform an operation from the following
        set of actions:

        ACHOICE() User Function Return Values
        ---------------------------------------------------------------------
        Value   Achoice.ch     Action
        ---------------------------------------------------------------------
        0       AC_ABORT       Abort selection
        1       AC_SELECT      Make selection
        2       AC_CONT        Continue ACHOICE()
        3       AC_GOTO        Go to the next item whose first character
                               matches the key pressed
        ---------------------------------------------------------------------

 Examples

     .  This example uses two literal arrays to specify the menu items
        and selection criteria.  After the menu is displayed and the user
        makes a selection, the name of the selected menu item is displayed:

        acMenuItems := {"One", "Two", "-------", "Three"}
        alSelectableItems := {.T., .T., .F., .T.}
        nPosition := ACHOICE(10, 10, 12, 15, acMenuItems,;
                                 alSelectableItems)
        ? acMenuItems[nPosition]

     .  This example declares an array of menu items and supplies a
        user-defined function which displays a message with each highlighted
        choice:

        #include "achoice.ch"
        #include "inkey.ch"

        PROCEDURE Main()

           LOCAL acMenuItems[4], cUserFunction, nRetVal
           LOCAL nKey, nPos

           acMenuItems[1] := "Add"
           acMenuItems[2] := "Edit"
           acMenuItems[3] := "Delete"
           acMenuItems[4] := "Update"

           CLS

           nPos := ACHOICE( 10, 10, 13, 15, acMenuItems,;
                          .T., "cUserFunction" )
           DO CASE
           CASE nPos == 1
              //  Put ADD routine here
           CASE nPos == 2
              //  Put EDIT routine here
           CASE nPos == 3
              //  Put DELETE routine here
           CASE nPos ==4
              //  Put UPDATE routine here
           ENDCASE

        RETURN

        FUNCTION cUserFunction( nMode, nCurElement, nRowPos )

           LOCAL nRetVal := AC_CONT     // Default, Continue
           LOCAL nKey := LASTKEY()

           DO CASE
        // After all pending keys are processed, display message
           CASE nMode == AC_IDLE
           DO CASE
              CASE nCurElement == 1
                 @ 22, 5 SAY " Adding   "
              CASE nCurElement == 2
                 @ 22, 5 SAY " Editing  "
              CASE nCurElement ==  3
                 @ 22, 5 SAY " Deleting "
              CASE nCurElement ==  4
                 @ 22, 5 SAY " Updating "
           ENDCASE

              nRetVal := AC_CONT            // Continue ACHOICE()

           CASE nMode == AC_HITTOP          // Attempt to go past Top
              TONE( 100, 3 )
           CASE nMode == AC_HITBOTTOM       // Attempt to go past
                                            // Bottom
              TONE( 100, 3 )

           CASE nMode == AC_EXCEPT          // Key Exception
              DO CASE
              CASE nKey == K_RETURN         // If RETURN key, select
                 nRetVal := AC_SELECT
              CASE nKey == K_ESC            // If ESCAPE key, abort
                 nRetVal := AC_ABORT
              OTHERWISE
                    nRetVal := AC_GOTO      // Otherwise, go to item
              ENDCASE
           ENDCASE

        RETURN nRetVal

     .  The next example declares the arrays, specifies a selection
        condition for one of the menu items, and supplies a user function:

        EXTERNAL UPDATED
        //
        FUNCTION MyMenu
           LOCAL acMenuItems[4], alSelectableItems[4],;
                  cUserFunction := "DoIt"
           //
           acMenuItems[1] := "Add Record"
           acMenuItems[2] := "Edit Record"
           acMenuItems[3] := "Delete Record"
           acMenuItems[4] := "Update Record"
           //
           alSelectableItems[1] := .T.
           alSelectableItems[2] := .T.
           alSelectableItems[3] := .T.
           alSelectableItems[4] := "!UPDATED()"
           // Selection condition

           RETURN ACHOICE(10, 10, 12, 15, acMenuItems,;
              alSelectableItems, cUserFunction)

     .  This example uses two arrays to specify menu items and
        corresponding action blocks.  After the menu is displayed and the
        user makes a selection, the ACHOICE() return value is used to
        determine which action block of the aActionItems array is evaluated:

        PROCEDURE Main()
           LOCAL nChoice
           LOCAL aMenuItems := { "Add Record   ", ;
                                    "Edit Record  ", ;
                                    "Delete Record", ;
                                    "Update Record"   }

           LOCAL aActionItems := { {|| AddFunc()  }, ;
                                    {|| EditFunc() }, ;
                                    {|| DelFunc()  }, ;
                                    {|| UpdFunc()  }  }

           nChoice := ACHOICE( 10, 10, 13, 22, aMenuItems )

           IF nChoice == 0
              QUIT      // ESCAPE was pressed
           ENDIF

           EVAL( aActionItems[nChoice] )

        RETURN

 Files   Library is EXTEND.LIB, header files are Achoice.ch and Inkey.ch.

See Also: MENU TO,  SET COLOR*

 

C5_ABS

 ABS()
 Return the absolute value of a numeric expression
------------------------------------------------------------------------------
 Syntax

     ABS(<nExp>) --> nPositive

 Arguments

     <nExp> is the numeric expression to be evaluated.

 Returns

     ABS() returns a number representing the absolute value of its argument.
     The return value is a positive number or zero.

 Description

     ABS() is a numeric function that determines the magnitude of a numeric
     value independent of its sign.  It lets you, for example, obtain the
     difference between two numbers as a positive value without knowing in
     advance which of the two is larger.

     As a formalism, ABS(x) is defined in terms of its argument, x, as
     follows: if x >= 0, ABS(x) returns x; otherwise, ABS(x) returns the
     negation of x.

 Examples

     .  These examples show typical results from ABS():

        nNum1 := 100
        nNum2 := 150
        ? nNum1 - nNum2                  // Result: -50
        ? ABS(nNum1 - nNum2)             // Result: 50
        ? ABS(nNum2 - nNum1)             // Result: 50
        ? ABS(-12)                       // Result: 12
        ? ABS(0)                         // Result: 0

 Files   Library is CLIPPER.LIB.

 

C5_AADD

 AADD()
 Add a new element to the end of an array
------------------------------------------------------------------------------
 Syntax

     AADD(<aTarget>, <expValue>) --> Value

 Arguments

     <aTarget> is the array to which a new element is to be added.

     <expValue> is the value assigned to the new element.

 Returns

     AADD() evaluates <expValue> and returns its value.  If <expValue> is not
     specified, AADD() returns NIL.

 Description

     AADD() is an array function that increases the actual length of the
     target array by one.  The newly created array element is assigned the
     value specified by <expValue>.

     AADD() is used to dynamically grow an array.  It is useful for building
     dynamic lists or queues.  A good example of this is the GetList array
     used by the Get system to hold Get objects.  After a READ or CLEAR GETS,
     GetList becomes an empty array.  Each time you execute an @...GET
     command, the Get system uses AADD() to add a new element to the end of
     the GetList array, and then assigns a new Get object to the new element.

     AADD() is similar to ASIZE() but only adds one element at a time;
     ASIZE() can grow or shrink an array to a specified size.  AADD(),
     however, has the advantage that it can assign a value to the new
     element, while ASIZE() cannot.  AADD() may also seem similar to AINS(),
     but they are different:  AINS() moves elements within an array, but it
     does not change the array's length.

     Note:  If <expValue> is another array, the new element in the target
     array will contain a reference to the array specified by <expValue>.

 Examples

     .  These examples demonstrate the effects of multiple invocations
        of AADD() to an array:

        aArray := {}                  // Result: aArray is an empty array
        AADD(aArray, 5)               // Result: aArray is { 5 }
        AADD(aArray, 10)              // Result: aArray is { 5, 10 }
        AADD(aArray, { 12, 10 })      // Result: aArray is
                                      // { 5, 10, { 12, 10 } }

 Files   Library is CLIPPER.LIB.

See Also: AINS() ASIZE()



CT_POKEWORD

 POKEWORD()
 Writes a 16-bit word to memory
------------------------------------------------------------------------------
 Syntax

     POKEWORD(<nSegment|cHexSegment>,<nOffset|cHexOffset>,
        <nWord|cHexWord>) --> lSuccessful

 Arguments

     <nSegment|cHex>  Designates the segment address where a word is
     stored.  This value can be a decimal integer or hexadecimal string.  The
     maximum is 65520 ("FFF0").

     <nOffset|cHexOffset>  Designates the offset address within the
     segment specified by <nSegment|cHexSegment>.  This value can be a
     decimal integer or hexadecimal string.  The maximum is 65534 ("FFFE").

     <nWord|cHexWord>  Designates the word to be stored in memory.  This
     value can be a decimal integer or  hexadecimal string.  The maximum is
     65535 ("FFFF").

 Returns

     POKEWORD() returns .T. when the operation is successfully completed.  A
     return value of .F. indicates an error.

 Description

     POKEWORD() writes a word to a desired memory area within the
     conventional memory.  The segment address and offset are required.

     Warning!  Be aware that this is not always safe.  If you
     inadvertently manipulate the wrong memory location, there may be serious
     consequences.  Use POKEWORD() ONLY when you have a thorough knowledge of
     the system environment and there is no other solution than to directly
     alter a memory location.

 Notes

     .  The function does not test whether the word is stored in
        memory.

     .  POKEWORD() stores the <nWord|cHexWord> word in memory in the
        low-byte/high-byte sequence.

 Examples

     .  Poke a word using decimal parameters:

        ? POKEWORD(32768, 1000, 65535)          // Can be dangerous!

     .  Poke a word using hexadecimal parameters:

        ? POKEWORD("F000", "8000", "FFFF")      // Impossible, ROM area

See Also: PEEKWORD() POKEBYTE()



CT_POKEBYTE

 POKEBYTE()
 Writes a byte to memory
------------------------------------------------------------------------------
 Syntax

     POKEBYTE(<nSegment|cHexSegment>,<nOffset|cHexOffset>,
         <nByte|cHexByte>) --> lSuccessful

 Arguments

     <nSegment|cHexSegment>  Designates the segment address in which a
     byte is stored.  This value can be a decimal integer or hexadecimal
     string.  The maximum is 65520 ("FFF0").

     <nOffset|cHexOffset>  Designates the offset address within the
     segment specified by <nSegment|cHexSegment>.  This value can be a
     decimal integer or hexadecimal string.  The maximum is 65535 ("FFFF").

     <nByte|cHexByte>  Designates the byte to store in memory.  This
     value can be a decimal integer or hexadecimal string.  The maximum is
     255 ("FF").

 Returns

     POKEBYTE() returns .T., if the operation is successfully completed.  A
     return value of .F. indicates a parameter error.

 Description

     POKEBYTE() writes a byte to a desired memory area within conventional
     memory.  The segment address and offset are required.

     Warning!  Be aware that this is not always safe.  If you
     inadvertently manipulate the wrong memory location, there may be serious
     consequences.  Use POKEBYTE() ONLY when you have a thorough knowledge of
     the system environment and there is no other solution than to directly
     alter a memory location.

 Note

     .  The function does not check if you can store the byte in
        memory.

 Examples

     .  Poke a byte using decimal parameters:

        ? POKEBYTE(32768, 1000, 65)           // Can be dangerous!

     .  Poke a byte using hexadecimal parameters:

        ? POKEBYTE("F000", "8000", "41")      // Impossible, ROM area

See Also: PEEKBYTE() POKEWORD()



CT_PEEKWORD

 PEEKWORD()
 Reads a 16-bit word from memory
------------------------------------------------------------------------------
 Syntax

     PEEKWORD(<nSegment|cHexSegment>,<nOffset|cHexOffset>)
         --> nWord

 Arguments

     <nSegment|cHex>  Designates the segment address from which a word is
     read.  This value can be a decimal integer or a hexadecimal string.

     <nOffset|cHexOffset>  Designates the offset address within the
     segment specified by <nSegment|cHexSegment>.  This value can be a
     decimal integer or hexadecimal string.  The maximum is ("FFFE").

 Returns

     PEEKWORD() returns the word that is read in or a value of -1, if an
     error occurs.

 Description

     In contrast to PEEKBYTE(), this function reads 16 bits from memory.  In
     this way, WORDS (16-bit integers) are read directly out of two memory
     regions within conventional memory.  Therefore, you must specify a value
     for the segment address and offset.

 Note

     .  PEEKWORD() assumes that a 16-bit value is presented in the low-
        byte/high-byte sequence.

 Examples

     .  Peek a word using a hexadecimal parameters:

        ? PEEKWORD("F000", "8000")      // The WORD at address F8000h

     .  Store a value in memory and then retrieve it:

        POKEBYTE("9000", "F000", 1)     // 1 stored-9F000h (low byte)
        POKEBYTE("9000", "F001", 2)     // 2 stored-9F001h (high byte)
        ? PEEKWORD("9000", "F000")      // Word at 9F000h  513

See Also: PEEKBYTE() POKEBYTE() POKEWORD() NUMHIGH() NUMLOW()

 

CT_PEEKSTR

 PEEKSTR()
 Reads a byte sequence from memory
------------------------------------------------------------------------------
 Syntax

     PEEKSTR(<nSegment|cHexSegment>, <nOffset|cHexOffset>,
        [<nLength|cHexLength>]) --> cCharacterString

 Arguments

     <nSegment|cHex>  Designates the segment address from which the
     character sequence string is read.  This value can be a decimal integer
     or hexadecimal string.

     <nOffset|cHexOffset>  Designates the offset address within the
     segment specified by <nSegment|cHexSegment>.  This value can be a
     decimal integer or hexadecimal string.

     <nLength|cHexLength>   Designates the string length to read, up to a
     maximum of 65520.  This value can be a decimal integer or a hexadecimal
     string.  The default, PEEKSTR(), reads to the first CHR(0).

 Returns

     PEEKSTR() returns the character string read from memory.

 Description

     PEEKSTR() reads an area of memory and returns it as a string.  The
     function reads to the first CHR(0) or the length specified through
     <nLength|cHexLength>.

 Example

     The AT BIOS copyright is found at the F000:0h address.  Therefore, each
     byte is repeated and CHARODD() is used to display it.  It reads to the
     first CHR(0):

     ? CHARODD(PEEKSTR("F000", 0))      // "19xx, 19xx Copyright...."

See Also: PEEKBYTE() PEEKWORD()