I think Tom is on the right track. I somehow overlooked that you were trying to push &PAPA to the remote session.
&Papa is a local macro variable, because it is a parameter to %master_test. Which is why SAS complains when you tried to declare it as global.
When you code:
%NRSTR(%syslput _global_/like='papa' remote=EXTRCTN);
You are having to look for global macro var named PAPA, which doesnt exist. So I would try:
%NRSTR(%syslput _local_/like='papa' remote=EXTRCTN);
&e_construction type is also local, so would try making the change to _local_ on both %syslput statements.
HTH
In my testing it looks like it is the RSUBMIT and ENDRSUBMIT statements that SAS 9.3 is processing out of order.
It is executing the RSUBMIT statement while it is compiling the macro.
Here is the code.
signoff;
%let mvar=Before Compile ;
%macro test;
%syslput _global_ / like="mvar" ;
rsubmit;
%put mvar=|&mvar|;
%put mvar=|%nrstr(&mvar)|;
endrsubmit;
%mend test;
Here is the resulting LOG. Notice that even the line numbers for the lines of the macro code are counting wrong.
166 signoff;
NOTE: Remote signoff from PAL commencing.
NOTE: SAS Institute Inc., SAS Campus Drive, Cary, NC USA 27513-2414
NOTE: The SAS System used:
real time 1:45.26
cpu time 0.21 seconds
NOTE: Remote signoff from PAL complete.
167 %let mvar=Before Compile ;
168 %macro test;
169 %syslput _global_ / like="mvar" ;
170 rsubmit;
ERROR: A link must be established by executing the SIGNON command before you can communicate with PAL.
ERROR: Remote submit to PAL canceled.
171 %mend test;
172
Tom-
I think what you are seeing is the original problem that OP noted and linked to the ts note.
It's the %syslput that is trying to communicate with the remote session when the macro compiles.
If you wrap that in %nrstr() as in his first post, that error goes away. At least in my quick test.
I'm still thinking changing to _local_ will help. But I've been wrong before. And several times in this thread...
---Q.
It looks likes this new format of the %SYSLPUT command is causing the macro compiler to try and execute the RSUBMIT command while it is compiling the macro.
285 %let mvar=Before Compile ;
286 %macro test;
287 %syslput _global_ / like='mvar' remote=fred ;
288 rsubmit remote=pal;
ERROR: A link must be established by executing the SIGNON command before you can communicate with
PAL.
ERROR: Remote submit to PAL canceled.
289 %mend test;
290
291 %let mvar=After compile;
292 %test;
ERROR: A link must be established by executing the SIGNON command before you can communicate with
FRED.
The solution is to use the OLD style of %SYSLPUT. You might need to test to see if it will automatically start the remote session. But if not then just add the rsubmit code suggested by someone above to trigger the auto connect. Or explicitly connect before calling the macro.
%let mvar=Before Compile ;
**** Define the macro **** ;
%macro test;
%syslput mvar=%superq(mvar) /remote=pal ;
rsubmit remote=pal;
%put mvar=|&mvar|;
endrsubmit;
%mend test;
**** connect to remote ****;
%rsignon(pal);
%let mvar=After compile;
%test;
Hi Selcuk,
Wondering if you arrived at a satisfactory solution?
--Q.
Hi Quentin ,
unfortunately no...
Did you convert the code to use the original syntax for %SYSLPUT macro statement instead of the syntax with the /LIKE option?
Yes Tom , I tried it...
The problem is that every new attempt causes new error messages. Even some code blocks which worked fine in the past doesnt work right now , I am unable to understand...
Actually I gave up for a while , but if you have a certain solution of course I can try it.
regards
I think the solution as below...
%macro test(mvar);
options autosignon=yes sascmd='sas -nosyntaxcheck -autoexec "C:\............\autoexec_for_MASTER.sas"';
%syslput cici=&mvar/remote=koko;
rsubmit remote=koko wait=yes persist=no;
data x;
a=&cici;
run;
options autosignon=yes sascmd='sas -nosyntaxcheck -autoexec "C:\................\autoexec_for_MASTER.sas"';
%lput(tiki,&cici,remote=papa);
/* This macro takes place in autoexec file , it is included...
%macro lput(macvar,macval,remote=);
options nosource nonotes;
%let str=%str(rsubmit &remote;options nosource;)
%nrstr(%let) %str(&macvar = &macval;options source;endrsubmit;);
&str; options notes source;
%mend lput;
*/
%lput(kaka,&cici,remote=papa);
rsubmit remote=papa wait=yes persist=no;
data y;
a=&tiki;
b=&kaka;
run;
endrsubmit;
endrsubmit;
%mend test;
%test(5);
macro lput creates the macro variable in the desired session ("papa") , it is strange but it works : )
Your %LPUT macro is just a copy of the old sample macro %SYSLPUT that came with SAS/Connect that SAS broke when they introduced the %SYSLPUT macro statement.
[.../sas/sas612/samples/connect]->more syslput.sas
/*--------------------------------------------------------------
*
* SAS TEST LIBRARY
*
* NAME: SYSLPUT
* TITLE: MACRO FOR CREATING REMOTE MACRO VARIABLES
* INPUT:
* OUTPUT:
* SPEC.REQ:
* SYSTEMS: ALL
* PRODUCT: SAS/CONNECT
* KEYS:
* REF:
* COMMENTS:
* SUPPORT: LANGSTON, B.
* UPDATE: 01mar95.
*
*--------------------------------------------------------------*/
/****************************************************************/
/* SYSLPUT is the opposite of SYSRPUT. SYSLPUT creates a macro*/
/* variable in the remote environment. The user must specify */
/* the macro variable and its value. Optionally, the user */
/* may specify the remote session id; the default session is */
/* the current session. */
/****************************************************************/
%macro syslput(macvar,macval,remote=);
options nosource nonotes;
%let str=%str(rsubmit &remote;options nosource;)
%nrstr(%let) %str(&macvar = &macval;options source;endrsubmit;);
&str; options notes source;
%mend syslput;
/*----------------------------------------------------------------*
EXAMPLES:
(1) Macro variable to current (default) remote session:
%syslput(rc,&sysinfo)
(2) Macro variable to specified remote session:
%syslput(flag,1,remote=mvs)
*----------------------------------------------------------------*/
Yes exactly , but works : ))
Well, I'm confused.
So in that example, the %SYSLPUT on line two works or still fails?
Looks like %lput is doing a lot of quoting to make sure that the rsubmit does not execute when %test is compiled. And you end up executing a %LET statement on the remote server.
Thanks for sharing your results.
Yes it is strange that first rsubmit can use the macro variable produced by %syslput , but the same structure doesnt work in the nested rsubmit expressions , so I had to use %lput macro.
did something similar to what you are trying to do in a one of my codes. Getting it to work definitely required some creative thinking. I've tried this within a macro statement before, and it works:
%syslput _global_/like=%unquote(%bquote(')e_construction_type*%bquote(')) remote=EUSD;
I had to use a wildcard in the "like" clause for the code I run. The macromars wouldn't copy to the the remote server without the wildcard in the "like" clause. I don't know if that makes a difference for your code or not.
I have included an example of the code I use below in case any of it might be of help. In my code, I have to create some email distribution lists used later in the code, and then output them to the log for validation on a remote server to demonstrate that they copied over. I was to lazy to hard code each put statement for the long list of vendors. So i had to work some magic with nesting macrovars within macrovars within macrovars... to incorporate the macrovars i needed into a looped %put statement. The code looks a little insane, but it works. I put the relevant SYSLPUT section bold and in italics.
In the first section, I create a series of macro variables inside of a macro statement that I need to be global macro vars. So I make them global macro vars. In the second section I output them to the log locally. I didn't use the like clause in the SYSLPUT in my original code, but I tried incorporating it as demonstrated below, and the macrovars that met the criteria I specified still carried over to the remote session. Let me know if it works for you or if you have any other questions. I'll try to answer if I can.
/*
=======================================================================================================================
Create List of MacroVar Names
=======================================================================================================================
*/
proc sql noprint;
select distinct
DL
into :VNDLIST_ separated by " "
from EmailDG_1;
quit;
%PUT Vendor List = &VNDLIST_.;
/*
=======================================================================================================================
Create DG For Each Vendor Using MacroVar Names generated in previous step
=======================================================================================================================
*/
%MACRO CreateEmailDGs;
%let i=1;
%do %until (%scan(&VNDLIST_,&i)=);
%global %scan(&VNDLIST_,&i);
%let vl=%scan(&VNDLIST_,&i);
%global %scan(&VNDLIST_,&i);
proc sql noprint;
select distinct
Email
INTO :&VL Separated by " | "
From EmailDG_1
where Vendor=SUBSTR(%unquote(%quote("&VL.")),1,LENGTH(%unquote(%quote("&VL.")))-3); /*<<=The vendor names I need are included in the macrovar list here, i had to scan thru this macrovar list and extract the vendor names with a substring*/
quit;
%let i=%eval(&i+1);
%end;
%Mend CreateEmailDGs;
%CreateEmailDGs;
/*
=======================================================================================================================
Output DG Lists to Log for Validation
=======================================================================================================================
*/
options nosymbolgen;
/* MACRO LOOP - OUTPUT Values of MacroVars TO LOG */
%macro MVar2Log;
%let i=1;
%do %until (%scan(&VNDLIST_,&i)=);
%let vl=%scan(&VNDLIST_,&i);
data _null_;
mac='&';
vl="&vl";
value&i=compress(mac||vl);
Call Symput("value&i",value&i);
run;
%put "**** &vl = &&value&i." ;
%let i=%eval(&i+1);
%end;
%syslput _global_/like=%unquote(%bquote(')*DL%bquote(')) remote=rhost;
%mend MVar2Log;
%MVar2Log;
rsubmit rhost;
put "**** VendorName1_DL = &VendorName1_DL." ;
put "**** VendorName2_DL = &VendorName2_DL." ;
put "**** VendorName3_DL = &VendorName3_DL." ;
put "**** VendorName4_DL = &VendorName4_DL." ;
put "**** VendorName5_DL = &VendorName5_DL." ;
put "**** VendorName6_DL = &VendorName6_DL." ;
endrsubmit;
The content of the output to the log from the final loop with the %put statement is similar to what i have posted below. Instead of VendorName#, of course, is the name of the vendor. And the email distribution lists are longer and contain valid email addresses. And it generates a lot more put statements than what you see below.... But you get the idea.
"**** VendorName1_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
"**** VendorName2_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
"**** VendorName3_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
"**** VendorName14_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
"**** VendorName5_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
cpu time 0.00 seconds
"**** VendorName6_DL = recipient1@emaildomain.com | recipient2@emaildomain.com"
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Ready to level-up your skills? Choose your own adventure.