VARSCAN – Search a sequential object variable
Use the VARSCAN
command to locate the position of specified
strings or words within a sequential Workload Automation Programming Language object, or to filter rows
within a Workload Automation Programming Language
object.
VARSCAN <object> TARGET(<target1>[, <targetn>)]
[ACTION(ITERATIVE|LEAVE|RC)]
[CASE(Y|N)]
[COLS(<from>,<to>)]
[CURSOR(<rowvar>,<colvar>)]
[DISTINCT(Y|N,[<separators>])]
[FILTER(EQ|NE|GT|LT|LE|GE|CO|NC)]
[FOUND(<foundvar>)]
[INSTANCE(<n>|1)]
[ROWS(CURRENT|FIRST|LAST|<start>,<end>)]
<object>
- Name of the object to search. You can omit the at sign (@), because this is a known object.
The object must be a sequential object, such as one created by the
READ
command. Complex objects, like those created byLIST
orSELECT
cannot be read by this command. ACTION(ITERATE|LEAVE|RC)
- Determines the action to take if no match is found:
ITERATE
- Continues to the next iteration of the loop. Typically performed in a
FILTER
loop. LEAVE
- Leaves the current loop. Typically performed in a
SCAN
loop. - RC
- Sets return code 4 if the the
FOUND
keyword is not specified. This is the default.
CASE(Y|N)
- Determines whether the target must be an exact match, including the case. If you specify
N
, differences in the case are tolerated. For example,Help
would match withhelp
. If you specifyY
(default), the case must match exactly. COLS(1|<left>,0|<right>)
- Limits the columns across which the search is performed. For example,
COLS(20,30)
searches from column 20 to 30 included. You can use the value0
for the right column, which allows searching to the end of the row. If a target starts within the column limits but finishes outside of the limits, it is not considered a match. The default isCOLS(1,0)
. CURSOR(<rowvar>,<colvar>)
- Names a pair of variables within which to store a cursor position. Searching starts from
the row named in the row name variable, and the column after the col name variable. This
allows subsequent use of the same
CURSOR
to find the next occurrence of the target. If the named variables do not exist or do not contain whole numbers, they are initialized to the default start position, otherwise the current values is used. If no match is found, the row variable is set to the number of rows +1 and the column variable set to 0. The default cursor starting position is row 1, column 0, meaning that searching starts from row 1, column 1.You can set the cursor position by setting each variable with the
VARSET
command (for example,VARSET MYROW=2
). If you set the column variable, the search will start from the following column.If the
CURSOR
position falls outside the limits ofCOLS
orROWS
, the starting point is adjusted to fit within those limits. If it is already within those limits, the search starts from theCURSOR
position.If
CURSOR
is not specified, the search starts from the beginning of the object. DISTINCT(Y|N,[delimiters])
- Determines whether the target is found as a character match, or as a distinct word or
label. If you select
Y
, a match occurs only if the preceding and following characters are not alphanumeric. Alternatively, you can specify as delimiters a list of characters, instead of the alphanumeric distinction. If the text is found at position 1, it is considered to have a preceding delimiter. The default isN
, meaning that a match occurs by finding the specified set of characters, regardless of whether it is a distinct word. For example, if you setDISTINCT(N)
, the keywordTARGET(one)
will match withgone
,bone
andone
. If you setDISTINCT(Y)
, the keywordTARGET(one)
will match only withone
. FILTER(EQ|NE|GT|LT|LE|GE|CO|NC)
- Puts the scan command into
FILTER
mode. InFILTER
mode the command compares only the current cursor row, or the nearest within the row limits, with the comparator specified and each or the targets. The comparison is done with the contents of the row between the column limits. For most comparators, only 1 needs to be matched for the row to be selected, with the exception of NE and NC where all must be true to be successful.The following comparator values are allowed:EQ
- The column range must match a target string.
NE
- The column range must not match all target strings.
GT
- The column range must be greater than a target string.
LT
- The column range must be less than a target string.
GE
- The column range must be greater than or equal to a target string.
LE
- The column range must be less than or equal to a target string.
CO
- The column range must contain a target string.
NC
- The column range must not contain a target string.
FOUND(<foundvar>)
- Names a variable to store the number of the
TARGET
value that is found. If the firstTARGET
is found, 1 is stored in the named variable; if the secondTARGET
is found, 2 is stored and so on. If noTARGET
is found, 0 is stored.If you specify
FOUND
, theVARSCAN
command issues a return code of 0 regardless of whether aTARGET
is found, checking theFOUND
variable be necessary to determine success or failure. IfFOUND
is not specified, the return code 4 is issued in the event of no match being found andACTION(RC)
being specified. INSTANCE(<n>|1)
- Specifies the instance of a potentially repeating match, for example
TARGET(Thunderbird) INSTANCE(4)
returns the fourth occurrence of Thunderbird found in the text. If you specify multipleTARGET
values, it will count the overall matches regardless of theTARGET
. For example,TARGET(Scott,Virgil,Gordon,Alan,John) INSTANCE(4)
returns a pointer toVirgil
from the string“John, Alan, Gordon, Virgil, Scott”
. To find the fourth instance of Virgil, you need to specifyVARSCAN
with a singleTARGET
. ROWS(CURRENT|FIRST|LAST|<n>,[endrow])
- Sets the limit of the rows to search. The
CURRENT
keyword represents the current cursor position,FIRST
is the first row of the object andLAST
is the last row of the object. SpecifyingFIRST
allows the search to start from row 1 regardless ofCURSOR
position. Specifying 1 as the starting row will honor theCURSOR
position. SpecifyingCURRENT
,FIRST
orLAST
alone will restrict the search to only that row, while combinations will search a range. For example,ROWS(FIRST,CURRENT)
searches from the first row to the current cursor row. TARGET(<target1>,[targetn])
- Specifies the string or strings for which to search. You can specify a list of strings
separated by a comma or a single string. For example,
TARGET(alpha,beta)
searches for either alpha or beta in the object.TARGET(alpha)
searches only for alpha.To search for a target containing commas specify 2 commas, where one is needed in the target. For example,
TARGET(alpha,,beta,gamma)
searches for “alpha,beta” and “gamma” as two separate target strings.
Use the VARSCAN
command to search an OBJECT
variable containing file type of data. You can use the command to simply detect whether a
single string occurs anywhere within the object, or perform more complex multi-pass,
multi-target searches. You can limit the search to a specific set of ROWS and COLS, and use
CURSOR
positioning for subsequent searches.
If you do not set the FILTER
keyword, the search operates in scan
mode, meaning that using CURSOR
variables enables the command to
be called repeatedly and to find each successive occurrence of the
TARGET
. If you set the FILTER
keyword, the
search operates in filter mode, meaning that each row is compared with the
FILTER
criteria to be processed or not.
In scan mode the VARSCAN
command would typically be in a
DO FOREVER
loop, with an ACTION(LEAVE)
keyword. This means that the majority of the loop is processed only for matching rows, and the
loop ends when no match is found.
In filter mode the VARSCAN
command would typically be in an
iterative DO FOREVER
loop that processes every row of the object (for
example, the command DO row = 1 TO !@MYOBJ
). The
ACTION
would be ITERATE
, meaning that the
main loop does not process any rows that does not match the
FILTER
.
Examples
Wally
within object
MYOBJ
:VARSCAN MYOBJ TARGET(Wally) CASE(N)
Wally
within object
MYOBJ
. If Wally
is found as an exact
match, the return code 0 is issued; otherwise the return code 4 is issued (for example, if
WALLY
is
found):VARSCAN MYOBJ TARGET(Wally) CASE(N)
Wally
or
Gromit
within object MYOBJ
and sets
variable RESULT
to show which is found, if any. If
Wally
is found, RESULT
shows 1; if
Gromit
is round RESULT
shows 2; if
neither is found RESULT
sows 0. Return code 4 is not issued because
you specified
FOUND
:VARSCAN MYOBJ TARGET(Wally,Gromit) CASE(N) FOUND(RESULT)
Wally
on every row
between columns 10 and 30. The TARGET
string must be contained
entirely within those columns, therefore if Wally
starts in column
26 the match is found, if it starts in column 27 the match is not
found:VARSCAN MYOBJ TARGET(Wally) COLS(10,30)
Wally
only from the
second to fifth row of the
file:VARSCAN MYOBJ TARGET(Wally) CASE(N) ROW(2,5)
Wally
and sets the
variables WALROW
and WALCOL
with the row and
column where the string was found, respectively. If no occurrences are found,
RESULT
shows 0, WALROW
is set to the
number of records in MYOBJ + 1
, and WALCOL
is set 0. If the same command is repeated, WALROW
and
WALCOL
are set to the second occurrence of the found
string.VARSCAN MYOBJ TARGET(Wally) CASE(N)
CURSOR(WALROW,WALCOL) FOUND(RESULT)
Wally
, then checks if
Gromit
exists in the same row as Wally
.
To do this, the second command must either use the same CURSOR
variables as the first, or use variables that have been copied from the first
command.VARSCAN MYOBJ TARGET(Wally) CASE(N)
CURSOR(WALROW,WALCOL) FOUND(RESULT)
VARSCAN MYOBJ TARGET(Gromit) CASE(N) ROWS(CURRENT)
CURSOR(WALROW,WALCOL) FOUND(RESULT)
one
within the
object, meaning that would also match with stone, bone, bones, tones, and
similar:VARSCAN MYOBJ TARGET(one) CASE(N)
To search only for
the characters one
, use the following
command:VARSCAN MYOBJ TARGET(one) CASE(N) DISTINCT(Y)
oh
in
any case combination. The LEAVE
action ensures that the loop stops
when all the occurrences are
found:DO FOREVER
VARSCAN MYOBJ TARGET(Oh) CURSOR(RX,CX) DISTINCT(Y)
CASE(N) COLS(001,080) ACTION(LEAVE)
WRITE OUTDATA "@V(@MYOBJ-!RX)"
END
oh
is not found in the
row:DO FOREVER
VARSCAN MYOBJ TARGET(Oh) CURSOR(RX,CX) DISTINCT(Y)
CASE(N) COLS(001,080) ACTION(LEAVE)
WRITE OUTDATA "@V(@MYOBJ-!RX)"
END
F
,
A
, or
B
:DO RX = 1 TO !@MYOBJ
VARSCAN MYOBJ TARGET(F,A,B) CURSOR(RX,CX) FILTER(EQ)
CASE(N) COLS(001,001) ACTION(ITERATE)
WRITE OUTDATA "@V(@MYOBJ-!RX)"
END
S
,
I
, nor
G
:DO RX = 1 TO !@MYOBJ
VARSCAN MYOBJ TARGET(S,I,G) CURSOR(RX,CX) FILTER(NE)
CASE(N) COLS(001,001) ACTION(ITERATE)
WRITE OUTDATA "@V(@MYOBJ-!RX)"
END
Troubleshooting scanning
VARSCAN
cannot find what you are searching for, use the
OPTIONS TRACE(1)
command as in the following
example:EQQI200I VARSCAN MYOBJ TARGET(Is it far,high noon) CURSOR(RX,CX)
EQQI200I FOUND(RESULT) CASE(N) INSTANCE(7)
- The row and column limits used (EQQI953A).
- The cursor starting position (EQQI954A).
- Because you used
INSTANCE
, you are shown the instance number, target number, row and column of each instance found before the requested instance is reached (EQQI954A). - The full text of the row on which the target was found (EQQ951A).
EQQI952A >>Row range 1 to 101
EQQI952A >>Column range 1 to unlimited
EQQI953A >>Cursor position Row=1, Column=0
EQQI954A >>Instance=1 Target=2 Row=1 Column=1
EQQI954A >>Instance=2 Target=1 Row=8 Column=1
EQQI954A >>Instance=3 Target=1 Row=8 Column=12
EQQI954A >>Instance=4 Target=1 Row=8 Column=23
EQQI954A >>Instance=5 Target=1 Row=29 Column=1
EQQI954A >>Instance=6 Target=1 Row=29 Column=12
EQQI064A Target "Is it far" found on row 29 column 23
EQQI951A >>Is it far, is it far, is it far?
EQQI033A Variable RESULT set to "1"
EQQI033A Variable RX set to "29"
EQQI033A Variable CX set to "23"
EQQI908I >>LAST_RC=0 LAST_XRC=0 MAX_RC=0 MAX_RESP=0
EQQI909I >>LEVEL=1 NUM=14 PARENT=SYSIN REF=SYSIN.7
EQQI299I Statement completed - RC=0