Hi All
I have one requirement of migration activity where I need to store this code in a macro variables.
ods noproctitle; ods graphics / imagemap=on; libname _tmpcas_ cas caslib="CASUSER"; proc cas; session %sysfunc(getlsessref(MYCAS)); loadactionset "timeData"; action runTimeCode / table={caslib="%sysfunc(getlcaslib( MYCAS))", name="PRICEDATA"} objOut={{table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outStatTemp" , replace="true"}, objRef='outStat'} , {table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outFcastTemp" , replace="true"}, objRef='outFcast'} } seasonality=12 timeId={name='date', FORMAT="_DATA_"} interval="Month" nlFormat=true series={'sale'} require={{pkg='TSM'}} code=' array diff[1]/nosymbols; declare object myModel(TSM); declare object mySpec(ARIMASpec); rc = mySpec.Open( ); /* Specify differencing orders */ diff[1] = 1; rc = mySpec.SetDiff(diff); rc = mySpec.SetOption(''noint'',1); rc = mySpec.SetOption(''method'',''CLS''); rc = mySpec.Close( ); /* Setup and run the TSM model object */ rc = myModel.Initialize(mySpec); rc = myModel.SetY(sale); rc = myModel.SetOption(''lead'',12); rc = myModel.SetOption(''alpha'',0.05); rc = myModel.Run( ); /* Output model forecasts and estimates */ declare object outFcast(TSMFor); rc = outFcast.Collect(myModel); declare object outStat(TSMSTAT); rc = outStat.Collect(myModel); '; run; proc print data=_tmpcas_.outStatTemp label contents="Fit statistics"; title 'Fit statistics'; run; ods exclude all; proc sql; select max(date) into :maxTimeID from MYCAS.PRICEDATA; quit; ods exclude none; proc sgplot data=_tmpcas_.outFcastTemp noautolegend description="Predicted and actual values of sale"; title 'Predicted and actual values of sale'; xaxis label='date'; yaxis label='sale'; series x=date y=ACTUAL /lineattrs=(color=black) name="actual" legendlabel="Actual"; series x=date y=PREDICT /name="predict" legendlabel="Predicted"; band x=date lower=LOWER upper=UPPER / transparency=0.5 name="pband" legendlabel="95% Confidence Limits"; refline &maxTimeID /axis=x label="Forecast Start"; keylegend "actual" "predict" "pband" / across=4 noborder position=TopLeft location=inside; run; proc delete data=_tmpcas_.outFcastTemp _tmpcas_.outStatTemp; run; libname _tmpcas_;
We are using these macro call to print exact same program as part of migration
for e.g
%__code(libname _tmpcas_ cas caslib="CASUSER") %__code(proc cas) %__code(session %sysfunc(getlsessref(MYCAS))) %__code(loadactionset "timeData") %__code( action runTimeCode / table={caslib="%sysfunc(getlcaslib( MYCAS))", name="PRICEDATA"} objOut={{table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name='outStatTemp' , replace='true'}, objRef='outStat'} , {table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outFcastTemp" , replace="true"}, objRef='outFcast'} } seasonality=12 timeId={name='date', FORMAT="_DATA_"} interval="Month" nlFormat=true series={'sale'} require={{pkg='TSM'}} code=' array diff[1]/nosymbols; declare object myModel(TSM); declare object mySpec(ARIMASpec); rc = mySpec.Open( ); /* Specify differencing orders */ diff[1] = 1; rc = mySpec.SetDiff(diff); rc = mySpec.SetOption(''noint'',1); rc = mySpec.SetOption(''method'',''CLS''); rc = mySpec.Close( ); /* Setup and run the TSM model object */ rc = myModel.Initialize(mySpec); rc = myModel.SetY(sale); rc = myModel.SetOption(''lead'',12); rc = myModel.SetOption(''alpha'',0.05); rc = myModel.Run( ); /* Output model forecasts and estimates */ declare object outFcast(TSMFor); rc = outFcast.Collect(myModel); declare object outStat(TSMSTAT); rc = outStat.Collect(myModel);%nrstr(%')) %__code( &_procStatementVar4)
I am facing issue while storing and calling %__code( action runTimeCode .......... macro . I have use %let of each and every line too but same isue. can anyone pls suggest any wayout..
the errors I got
a. bad listing
b. open code recursion , this is because of single(') . Please help me in resolving this issue. Thanks!
@Aexor wrote:
I have one requirement of migration activity where I need to store this code in a macro variables.
I don't even understand the requirement of storing a program in a macro variable. Programs can be stored as simple text files, why can't you just do that?
It sounds like someone has invented a very complicated way of doing something very simple.
@Aexor wrote:
this is a part of migration activity . I cant give much detail .. i tried using %let to store lines as text , but due to single ' getting issue
Define what you mean be "line of code"? Give concrete examples. They can be fake as long as they are similar in terms of their usage of characters like ; ' " & % ( ) that are important to parsing macro code and regular SAS code.
Where are some examples of how to store SAS statements in a macro variable.
You could use %NRSTR().
%let mycode=%nrstr(proc print data=sashelp.class; where sex='M'; run;) ;
&mycode.
Results
1 %let mycode=%nrstr(proc print data=sashelp.class; where sex='M'; run;) ; 2 &mycode. NOTE: There were 10 observations read from the data set SASHELP.CLASS. WHERE sex='M'; NOTE: PROCEDURE PRINT used (Total process time): real time 0.03 seconds cpu time 0.03 seconds
You could use data step code. Perhaps storing a string literal into the macro variable.
data _null_;
call symputx('mycode',"proc print data=sashelp.class; where sex='M'; run;");
run;
Or by reading from a file. Say for example by storing each line into a different macro variable.
data _null_;
infile mycode ;
input;
call symputx(cats('mycode',_n_),_infile_);
run;
I do not see any %LET statements in the code you posted. Can you show us what you actually tried to do?
If you want to see an example of storing code in macro variable look at this macro:
https://github.com/sasutils/macros/blob/master/subnet.sas
Migration from what to what?
Without really understanding what this is about it feels to me like a bad re-design done by someone with likely an object oriented background who doesn't know much about SAS and what SAS macros are. If I'm right then this will not only lead to a very significant increase in migration effort (with a risk of failure) but also to way more complicated code and a maintenance nightmare later on.
@Aexor wrote:
Hi All
I have one requirement of migration activity where I need to store this code in a macro variables.
SpoilerWe are using these macro call to print exact same program as part of migrationods noproctitle; ods graphics / imagemap=on; libname _tmpcas_ cas caslib="CASUSER"; proc cas; session %sysfunc(getlsessref(MYCAS)); loadactionset "timeData"; action runTimeCode / table={caslib="%sysfunc(getlcaslib( MYCAS))", name="PRICEDATA"} objOut={{table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outStatTemp" , replace="true"}, objRef='outStat'} , {table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outFcastTemp" , replace="true"}, objRef='outFcast'} } seasonality=12 timeId={name='date', FORMAT="_DATA_"} interval="Month" nlFormat=true series={'sale'} require={{pkg='TSM'}} code=' array diff[1]/nosymbols; declare object myModel(TSM); declare object mySpec(ARIMASpec); rc = mySpec.Open( ); /* Specify differencing orders */ diff[1] = 1; rc = mySpec.SetDiff(diff); rc = mySpec.SetOption(''noint'',1); rc = mySpec.SetOption(''method'',''CLS''); rc = mySpec.Close( ); /* Setup and run the TSM model object */ rc = myModel.Initialize(mySpec); rc = myModel.SetY(sale); rc = myModel.SetOption(''lead'',12); rc = myModel.SetOption(''alpha'',0.05); rc = myModel.Run( ); /* Output model forecasts and estimates */ declare object outFcast(TSMFor); rc = outFcast.Collect(myModel); declare object outStat(TSMSTAT); rc = outStat.Collect(myModel); '; run; proc print data=_tmpcas_.outStatTemp label contents="Fit statistics"; title 'Fit statistics'; run; ods exclude all; proc sql; select max(date) into :maxTimeID from MYCAS.PRICEDATA; quit; ods exclude none; proc sgplot data=_tmpcas_.outFcastTemp noautolegend description="Predicted and actual values of sale"; title 'Predicted and actual values of sale'; xaxis label='date'; yaxis label='sale'; series x=date y=ACTUAL /lineattrs=(color=black) name="actual" legendlabel="Actual"; series x=date y=PREDICT /name="predict" legendlabel="Predicted"; band x=date lower=LOWER upper=UPPER / transparency=0.5 name="pband" legendlabel="95% Confidence Limits"; refline &maxTimeID /axis=x label="Forecast Start"; keylegend "actual" "predict" "pband" / across=4 noborder position=TopLeft location=inside; run; proc delete data=_tmpcas_.outFcastTemp _tmpcas_.outStatTemp; run; libname _tmpcas_;
for e.g
Spoiler%__code(libname _tmpcas_ cas caslib="CASUSER") %__code(proc cas) %__code(session %sysfunc(getlsessref(MYCAS))) %__code(loadactionset "timeData") %__code( action runTimeCode / table={caslib="%sysfunc(getlcaslib( MYCAS))", name="PRICEDATA"} objOut={{table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name='outStatTemp' , replace='true'}, objRef='outStat'} , {table={caslib="%sysfunc(getlcaslib(_tmpcas_))", name="outFcastTemp" , replace="true"}, objRef='outFcast'} } seasonality=12 timeId={name='date', FORMAT="_DATA_"} interval="Month" nlFormat=true series={'sale'} require={{pkg='TSM'}} code=' array diff[1]/nosymbols; declare object myModel(TSM); declare object mySpec(ARIMASpec); rc = mySpec.Open( ); /* Specify differencing orders */ diff[1] = 1; rc = mySpec.SetDiff(diff); rc = mySpec.SetOption(''noint'',1); rc = mySpec.SetOption(''method'',''CLS''); rc = mySpec.Close( ); /* Setup and run the TSM model object */ rc = myModel.Initialize(mySpec); rc = myModel.SetY(sale); rc = myModel.SetOption(''lead'',12); rc = myModel.SetOption(''alpha'',0.05); rc = myModel.Run( ); /* Output model forecasts and estimates */ declare object outFcast(TSMFor); rc = outFcast.Collect(myModel); declare object outStat(TSMSTAT); rc = outStat.Collect(myModel);%nrstr(%')) %__code( &_procStatementVar4)
I am facing issue while storing and calling %__code( action runTimeCode .......... macro . I have use %let of each and every line too but same isue. can anyone pls suggest any wayout..
the errors I got
a. bad listing
b. open code recursion , this is because of single(') . Please help me in resolving this issue. Thanks!
Please explain what you are doing.
Where do you have the original program stored?
Why do you want to pass pieces of the program to the macro _CODE?
Show the definition of your __CODE macro.
What is is supposed to do?
What parameters does it take as INPUT?
I suspect that there is another way to perform your migration, but you will need explain what you are doing in more detail to get useful help. For example if you want to copy a file from one machine to another you could use sftp or if you have SAS/Connect licenses on both machines PROC UPLOAD (or PROC DOWNLOAD depending on the direction.)
If you want to pass lines of text into a macro it is best to design to macro to expect the lines to be quoted. That way you can use a string literal quoted with single quotes to hide any macro triggers (& and % characters) in the text and get the actual text into the macro. The macro could then use the DEQUOTE() function to remove the quotes.
Then you could easily use a data step to generate one call to the macro for each line of text in a file.
data _null_;
infile codefile ;
input;
call execute(cats('%nrstr(%__code)(',quote(trim(_infile_),"'"),')'));
run;
Would generate and run code lines like:
%__code('ods noproctitle;')
%__code('ods graphics / imagemap=on;')
%__code('libname _tmpcas_ cas caslib="CASUSER";')
%__code(' ')
%__code('proc cas;')
%__code(' session %sysfunc(getlsessref(MYCAS));')
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.