From: xlr82sas on
Hi SAS-Lers,

Suppose

%let wrds=The quick brown fox;

and you want
The following macro variables local to the calling macro (not
global)

wrds = The quick brown;
pop = fox;

For a cleaner version see

/* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
THE SHORTENED LIST
http://homepage.mac.com/magdelina/.Public/utl.html
utl_tipweb.txt

Here is the macro

%macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
& off - like superq - no macro triggers or quotes */
) / des="pop text from the end of a macro string containing
blank separated words";

/* There is not need for a push macro because %let stm=&stm &add;
will work */
/* this macro expects a clean string without macro triggers or
quotes */
/
*
*/
/*
Example
*/
/
*
*/
/* %let wrd=The quick brown
fox; */
/*
%utl_pop(wrd);
*/
/* results
in */
/* fox;%let wrd =The quick
brown; */
/
*
*/
/* after calling the macro the user
should */
/
*
*/
/* %let
lastword=&wrd; */
/
*
*/
/* This also updates the wrd (after
lastword) */
/
*
*/
/* this macro uses a datastep so you cannot use it in pure macro
code */

%local res b;

%put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
Provide macro var that holds list ****,));
%let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
1,0)));
%if &res = 0 %then %do;
%let b="/**/ /**/";
data _null_;
txt=strip("&&&txt");
popvar = scan(txt,-1);
pos = findc(txt,' ','b');
lst = substr(txt,1,pos);
popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
put popwrd=;
call symputx('wrd',popwrd);
run;
%end;
%mend utl_pop;

%let wrd=the quick brown fox;
%utl_pop(wrd);

%let popoff=&wrd;

%put popoff=&popoff; /* fox */
%put wrd=&wrd; /* the quick brown */
From: xlr82sas on
On Apr 13, 10:32 pm, xlr82sas <xlr82...(a)aol.com> wrote:
> Hi SAS-Lers,
>
>    Suppose
>
>       %let wrds=The quick brown fox;
>
>       and you want
>          The following macro variables local to the calling macro (not
> global)
>
>              wrds   =  The quick brown;
>              pop    =  fox;
>
> For a cleaner version see
>
> /* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
> THE SHORTENED LISThttp://homepage.mac.com/magdelina/.Public/utl.html
> utl_tipweb.txt
>
> Here is the macro
>
> %macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
> & off - like superq - no macro triggers or quotes */
>           ) / des="pop text from the end of a macro string containing
> blank separated words";
>
>    /* There is not need for a push macro because %let stm=&stm &add;
> will work */
>    /* this macro expects a clean string without macro triggers or
> quotes      */
>    /
> *
> */
>    /*
> Example
> */
>    /
> *
> */
>    /*  %let wrd=The quick brown
> fox;                                          */
>    /*
> %utl_pop(wrd);
> */
>    /*  results
> in                                                             */
>    /*  fox;%let wrd =The quick
> brown;                                        */
>    /
> *
> */
>    /*  after calling the macro the user
> should                                */
>    /
> *
> */
>    /*  %let
> lastword=&wrd;                                                 */
>    /
> *
> */
>    /*  This also updates the wrd  (after
> lastword)                                            */
>    /
> *
> */
>    /* this macro uses a datastep so you cannot use it in pure macro
> code      */
>
>    %local res b;
>
>    %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> Provide macro var that holds list        ****,));
>    %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> 1,0)));
>    %if &res = 0 %then %do;
>        %let b="/**/ /**/";
>        data _null_;
>          txt=strip("&&&txt");
>          popvar = scan(txt,-1);
>          pos    = findc(txt,' ','b');
>          lst    = substr(txt,1,pos);
>          popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
>          put popwrd=;
>          call symputx('wrd',popwrd);
>        run;
>    %end;
> %mend utl_pop;
>
> %let wrd=the quick brown fox;
> %utl_pop(wrd);
>
> %let popoff=&wrd;
>
> %put popoff=&popoff; /* fox             */
> %put wrd=&wrd;       /* the quick brown */

Correction

%macro
utl_pop(txt
) / des="pop text from the end of a macro string containing
blank separated words";
%local res
b;
%put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
Provide test stem ****,));
%let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
1,0)));
%if &res = 0 %then
%do;
%let b="/**/ /
**/";
data
_null_;

txt=strip("&&&txt");
popvar =
scan(txt,-1);
pos = findc(txt,'
','b');
lst = substr(txt,
1,pos);
popwrd = cats(popvar,';','%let',&b,"&txt
=",lst,';');
put
popwrd=;
call
symputx("&txt",popwrd);

run;

%end;
%mend
utl_pop;

%let key=a b c
g;
%utl_pop(key);
%let
pop=&key;
%put
pop=&pop;
%put
key=&key;

SYMBOLGEN: Macro variable KEY resolves to g;%let/**/ /**/key =a b c;
2114 %let pop=&key;
2115 %put pop=&pop;
SYMBOLGEN: Macro variable POP resolves to g
pop=g
2116 %put key=&key;
SYMBOLGEN: Macro variable KEY resolves to a b c
key=a b c
From: RolandRB on
On Apr 14, 7:32 am, xlr82sas <xlr82...(a)aol.com> wrote:
> Hi SAS-Lers,
>
>    Suppose
>
>       %let wrds=The quick brown fox;
>
>       and you want
>          The following macro variables local to the calling macro (not
> global)
>
>              wrds   =  The quick brown;
>              pop    =  fox;
>
> For a cleaner version see
>
> /* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
> THE SHORTENED LISThttp://homepage.mac.com/magdelina/.Public/utl.html
> utl_tipweb.txt
>
> Here is the macro
>
> %macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
> & off - like superq - no macro triggers or quotes */
>           ) / des="pop text from the end of a macro string containing
> blank separated words";
>
>    /* There is not need for a push macro because %let stm=&stm &add;
> will work */
>    /* this macro expects a clean string without macro triggers or
> quotes      */
>    /
> *
> */
>    /*
> Example
> */
>    /
> *
> */
>    /*  %let wrd=The quick brown
> fox;                                          */
>    /*
> %utl_pop(wrd);
> */
>    /*  results
> in                                                             */
>    /*  fox;%let wrd =The quick
> brown;                                        */
>    /
> *
> */
>    /*  after calling the macro the user
> should                                */
>    /
> *
> */
>    /*  %let
> lastword=&wrd;                                                 */
>    /
> *
> */
>    /*  This also updates the wrd  (after
> lastword)                                            */
>    /
> *
> */
>    /* this macro uses a datastep so you cannot use it in pure macro
> code      */
>
>    %local res b;
>
>    %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> Provide macro var that holds list        ****,));
>    %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> 1,0)));
>    %if &res = 0 %then %do;
>        %let b="/**/ /**/";
>        data _null_;
>          txt=strip("&&&txt");
>          popvar = scan(txt,-1);
>          pos    = findc(txt,' ','b');
>          lst    = substr(txt,1,pos);
>          popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
>          put popwrd=;
>          call symputx('wrd',popwrd);
>        run;
>    %end;
> %mend utl_pop;
>
> %let wrd=the quick brown fox;
> %utl_pop(wrd);
>
> %let popoff=&wrd;
>
> %put popoff=&popoff; /* fox             */
> %put wrd=&wrd;       /* the quick brown */

Use my %verifyb macro searching for a space as shown in the header
then use %substr with a length that is what %verifyb returns minus
one.

Something like %let str2=%scan(&str,1,%verifyb(&str,%str( ))-1);

Can't test this where I currently am.
From: data _null_; on
On Apr 14, 1:51 am, xlr82sas <xlr82...(a)aol.com> wrote:
> On Apr 13, 10:32 pm, xlr82sas <xlr82...(a)aol.com> wrote:
>
>
>
>
>
> > Hi SAS-Lers,
>
> >    Suppose
>
> >       %let wrds=The quick brown fox;
>
> >       and you want
> >          The following macro variables local to the calling macro (not
> > global)
>
> >              wrds   =  The quick brown;
> >              pop    =  fox;
>
> > For a cleaner version see
>
> > /* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
> > THE SHORTENED LISThttp://homepage.mac.com/magdelina/.Public/utl.html
> > utl_tipweb.txt
>
> > Here is the macro
>
> > %macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
> > & off - like superq - no macro triggers or quotes */
> >           ) / des="pop text from the end of a macro string containing
> > blank separated words";
>
> >    /* There is not need for a push macro because %let stm=&stm &add;
> > will work */
> >    /* this macro expects a clean string without macro triggers or
> > quotes      */
> >    /
> > *
> > */
> >    /*
> > Example
> > */
> >    /
> > *
> > */
> >    /*  %let wrd=The quick brown
> > fox;                                          */
> >    /*
> > %utl_pop(wrd);
> > */
> >    /*  results
> > in                                                             */
> >    /*  fox;%let wrd =The quick
> > brown;                                        */
> >    /
> > *
> > */
> >    /*  after calling the macro the user
> > should                                */
> >    /
> > *
> > */
> >    /*  %let
> > lastword=&wrd;                                                 */
> >    /
> > *
> > */
> >    /*  This also updates the wrd  (after
> > lastword)                                            */
> >    /
> > *
> > */
> >    /* this macro uses a datastep so you cannot use it in pure macro
> > code      */
>
> >    %local res b;
>
> >    %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> > Provide macro var that holds list        ****,));
> >    %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> > 1,0)));
> >    %if &res = 0 %then %do;
> >        %let b="/**/ /**/";
> >        data _null_;
> >          txt=strip("&&&txt");
> >          popvar = scan(txt,-1);
> >          pos    = findc(txt,' ','b');
> >          lst    = substr(txt,1,pos);
> >          popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
> >          put popwrd=;
> >          call symputx('wrd',popwrd);
> >        run;
> >    %end;
> > %mend utl_pop;
>
> > %let wrd=the quick brown fox;
> > %utl_pop(wrd);
>
> > %let popoff=&wrd;
>
> > %put popoff=&popoff; /* fox             */
> > %put wrd=&wrd;       /* the quick brown */
>
> Correction
>
> %macro
> utl_pop(txt
>         ) / des="pop text from the end of a macro string containing
> blank separated words";
>  %local res
> b;
>  %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> Provide test stem        ****,));
>  %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> 1,0)));
>  %if &res = 0 %then
> %do;
>      %let b="/**/ /
> **/";
>      data
> _null_;
>
> txt=strip("&&&txt");
>        popvar =
> scan(txt,-1);
>        pos    = findc(txt,'
> ','b');
>        lst    = substr(txt,
> 1,pos);
>        popwrd = cats(popvar,';','%let',&b,"&txt
> =",lst,';');
>        put
> popwrd=;
>        call
> symputx("&txt",popwrd);
>
> run;
>
> %end;
> %mend
> utl_pop;
>
> %let key=a b c
> g;
> %utl_pop(key);
> %let
> pop=&key;
> %put
> pop=&pop;
> %put
> key=&key;
>
> SYMBOLGEN:  Macro variable KEY resolves to g;%let/**/ /**/key =a b c;
> 2114   %let pop=&key;
> 2115   %put pop=&pop;
> SYMBOLGEN:  Macro variable POP resolves to g
> pop=g
> 2116   %put key=&key;
> SYMBOLGEN:  Macro variable KEY resolves to a b c
> key=a b c- Hide quoted text -
>
> - Show quoted text -

CALL SCAN offers a fairly concise solution, via a call routine style
macro.

I did not address the left over delimiters, but I suppose you could.

3823 %macro pop(arg1,arg2,arg3);
3824 %local position length;
3825 %let position=0;
3826 %let length=0;
3827 /* *CALL SCAN(string, n, position, length <,delimiters>); */
3828 %sysCALL SCAN(&arg1,%bquote(arg3),position,length);
3829 %let &arg2 = %sysfunc(substrN(&&&arg1,&position,&length));
3830 %let &arg1 = %sysfunc(substrN(&&&arg1,1,&position-1))
%sysfunc(substrN(&&&arg1,&position+&length));
3831 %put NOTE: %qupcase(&arg1)=&&&arg1 %qupcase(&arg2)=&&&arg2;
3832 %mend pop;
3833
3834 %let wrds=The quick brown fox;
3835 %let pop=;
3836 %pop(wrds,pop,-1);
NOTE: WRDS=The quick brown POP=fox
3837
3838 %let wrds=The quick brown fox;
3839 %let pop=;
3840 %pop(wrds,pop,-2);
NOTE: WRDS=The quick fox POP=brown
3841
3842 %let wrds=The quick brown fox;
3843 %let pop=;
3844 %pop(wrds,pop,2);
NOTE: WRDS=The brown fox POP=quick
From: xlr82sas on
On Apr 14, 5:07 am, "data _null_;" <datan...(a)gmail.com> wrote:
> On Apr 14, 1:51 am, xlr82sas <xlr82...(a)aol.com> wrote:
>
>
>
> > On Apr 13, 10:32 pm, xlr82sas <xlr82...(a)aol.com> wrote:
>
> > > Hi SAS-Lers,
>
> > >    Suppose
>
> > >       %let wrds=The quick brown fox;
>
> > >       and you want
> > >          The following macro variables local to the calling macro (not
> > > global)
>
> > >              wrds   =  The quick brown;
> > >              pop    =  fox;
>
> > > For a cleaner version see
>
> > > /* T005790 POP THE LAST WORD OFF A LIST AND RETURN THE LAST WORD AND
> > > THE SHORTENED LISThttp://homepage.mac.com/magdelina/.Public/utl.html
> > > utl_tipweb.txt
>
> > > Here is the macro
>
> > > %macro utl_pop(txt /* must be a macro variable cannot be a list. Leave
> > > & off - like superq - no macro triggers or quotes */
> > >           ) / des="pop text from the end of a macro string containing
> > > blank separated words";
>
> > >    /* There is not need for a push macro because %let stm=&stm &add;
> > > will work */
> > >    /* this macro expects a clean string without macro triggers or
> > > quotes      */
> > >    /
> > > *
> > > */
> > >    /*
> > > Example
> > > */
> > >    /
> > > *
> > > */
> > >    /*  %let wrd=The quick brown
> > > fox;                                          */
> > >    /*
> > > %utl_pop(wrd);
> > > */
> > >    /*  results
> > > in                                                             */
> > >    /*  fox;%let wrd =The quick
> > > brown;                                        */
> > >    /
> > > *
> > > */
> > >    /*  after calling the macro the user
> > > should                                */
> > >    /
> > > *
> > > */
> > >    /*  %let
> > > lastword=&wrd;                                                 */
> > >    /
> > > *
> > > */
> > >    /*  This also updates the wrd  (after
> > > lastword)                                            */
> > >    /
> > > *
> > > */
> > >    /* this macro uses a datastep so you cannot use it in pure macro
> > > code      */
>
> > >    %local res b;
>
> > >    %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> > > Provide macro var that holds list        ****,));
> > >    %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> > > 1,0)));
> > >    %if &res = 0 %then %do;
> > >        %let b="/**/ /**/";
> > >        data _null_;
> > >          txt=strip("&&&txt");
> > >          popvar = scan(txt,-1);
> > >          pos    = findc(txt,' ','b');
> > >          lst    = substr(txt,1,pos);
> > >          popwrd = cats(popvar,';','%let',&b,"&txt =",lst,';');
> > >          put popwrd=;
> > >          call symputx('wrd',popwrd);
> > >        run;
> > >    %end;
> > > %mend utl_pop;
>
> > > %let wrd=the quick brown fox;
> > > %utl_pop(wrd);
>
> > > %let popoff=&wrd;
>
> > > %put popoff=&popoff; /* fox             */
> > > %put wrd=&wrd;       /* the quick brown */
>
> > Correction
>
> > %macro
> > utl_pop(txt
> >         ) / des="pop text from the end of a macro string containing
> > blank separated words";
> >  %local res
> > b;
> >  %put %sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),**** Please
> > Provide test stem        ****,));
> >  %let res= %eval(%sysfunc(ifc(%sysevalf(%superq(txt)=,boolean),
> > 1,0)));
> >  %if &res = 0 %then
> > %do;
> >      %let b="/**/ /
> > **/";
> >      data
> > _null_;
>
> > txt=strip("&&&txt");
> >        popvar =
> > scan(txt,-1);
> >        pos    = findc(txt,'
> > ','b');
> >        lst    = substr(txt,
> > 1,pos);
> >        popwrd = cats(popvar,';','%let',&b,"&txt
> > =",lst,';');
> >        put
> > popwrd=;
> >        call
> > symputx("&txt",popwrd);
>
> > run;
>
> > %end;
> > %mend
> > utl_pop;
>
> > %let key=a b c
> > g;
> > %utl_pop(key);
> > %let
> > pop=&key;
> > %put
> > pop=&pop;
> > %put
> > key=&key;
>
> > SYMBOLGEN:  Macro variable KEY resolves to g;%let/**/ /**/key =a b c;
> > 2114   %let pop=&key;
> > 2115   %put pop=&pop;
> > SYMBOLGEN:  Macro variable POP resolves to g
> > pop=g
> > 2116   %put key=&key;
> > SYMBOLGEN:  Macro variable KEY resolves to a b c
> > key=a b c- Hide quoted text -
>
> > - Show quoted text -
>
> CALL SCAN offers a fairly concise solution, via a call routine style
> macro.
>
> I did not address the left over delimiters, but I suppose you could.
>
> 3823  %macro pop(arg1,arg2,arg3);
> 3824     %local position length;
> 3825     %let position=0;
> 3826     %let length=0;
> 3827  /*   *CALL SCAN(string, n, position, length <,delimiters>);  */
> 3828     %sysCALL SCAN(&arg1,%bquote(arg3),position,length);
> 3829     %let &arg2 = %sysfunc(substrN(&&&arg1,&position,&length));
> 3830     %let &arg1 = %sysfunc(substrN(&&&arg1,1,&position-1))
> %sysfunc(substrN(&&&arg1,&position+&length));
> 3831     %put NOTE: %qupcase(&arg1)=&&&arg1 %qupcase(&arg2)=&&&arg2;
> 3832     %mend pop;
> 3833
> 3834  %let wrds=The quick brown fox;
> 3835  %let pop=;
> 3836  %pop(wrds,pop,-1);
> NOTE: WRDS=The quick brown POP=fox
> 3837
> 3838  %let wrds=The quick brown fox;
> 3839  %let pop=;
> 3840  %pop(wrds,pop,-2);
> NOTE: WRDS=The quick  fox POP=brown
> 3841
> 3842  %let wrds=The quick brown fox;
> 3843  %let pop=;
> 3844  %pop(wrds,pop,2);
> NOTE: WRDS=The  brown fox POP=quick

Nice solutions

Better than the datastep, thanks

Regards