You need to communicate between the exec and the macro as they don't inherit each other's variable pool.
Using the VPUT/VGET service allows this but you have to pass anything needed back and forth.
This example below is simplistic and will only work properly when executed as TSO Command.
If executed as a MACRO it will CANCEL the member being executed.
Beware, untested so may contain the odd typo!?/*REXX*/
PARSE ARG parms
PARSE VALUE TRANSLATE(parms,","," ")",,,,,," ,
WITH dsn","string","scol","ecol"," .
ADDRESS ISPEXEC "CONTROL ERRORS RETURN"
ADDRESS ISREDIT
"MACRO (STRING) NOPROCESS"
IF( RC=0) THEN
CALL ASMACRO
ELSE
CALL ASEXEC
EXIT
ASEXEC:
ADDRESS ISPEXEC
"VPUT(SCOL,ECOL) SHARED "
"VIEW DATASET ('USER.XYZ') MACRO(CNTSTRGS)"
"VGET(FC,SCOL,ECOL) SHARED "
zedsmsg = fc "OCCURENCES"
zedlmsg = "String '"string"' was found" fc "times between columns" scol"-"ecol"."
"SETMSG MSG(ISRZ000)"
RETURN
ASMACRO:
ADDRESS ISREDIT
ADDRESS ISPEXEC "VGET (STRING,SCOL,ECOL) SHARED "
"(DW) = DATA_WIDTH "
IF( DATATYPE(scol)<>"NUM" )THEN scol=1
IF( DATATYPE(ecol)<>"NUM" )THEN ecol=dw
"F ALL '"string'"" scol ecol
"(FC) = FIND_COUNTS "
ADDRESS ISPEXEC "VPUT(FC,SCOL,ECOL) SHARED "
"CANCEL "
RETURN
Another technique is to VPUT/VGET as a vector - like this...
PARSE VALUE dsn","string","fcol","ecol","fc"," WITH cntparms
VPUT (CNTPARMS) SHARED
then reading
VGET (CNTPARMS) SHARED
PARSE VALUE cntparms",,,,," WITH dsn","string","fcol","ecol","fc"," .