Hope this is the correct location for this question. It appears that I cannot run macros in Jupyter:
https://blogs.sas.com/content/sasdummy/2016/04/24/how-to-run-sas-programs-in-jupyter-notebook
Code used:
%macro SomeExcitingMacro(OriginName);
PROC SGPLOT DATA=SASHELP.cars(where=(Origin = "&OriginName."));
VBOX Invoice
/ category = DriveTrain nooutliers;
yaxis min=0 max=100000;
RUN;
%mend SomeExcitingMacro;
proc sql;
create table LoopData as
select
distinct Origin
from SASHELP.cars
;
quit;
data _null_;
set LoopData;
call execute('%nrstr(%SomeExcitingMacro('||Origin||'))');
run;
PS:
Log:
6 The SAS System 16:14 Thursday, April 26, 2018
39 ods listing close;ods html5 (id=saspy_internal) file=_tomods1 options(bitmap_mode='inline') device=svg; ods graphics on /
39 ! outputfmt=png;
NOTE: Writing HTML5(SASPY_INTERNAL) Body file: _TOMODS1
40
41 PROC SGPLOT DATA=SASHELP.cars(where=(Origin = "&OriginName."));
WARNING: Apparent symbolic reference ORIGINNAME not resolved.
42 VBOX Invoice
43 / category = DriveTrain nooutliers;
44 yaxis min=0 max=100000;
45 RUN;
NOTE: There were 0 observations read from the data set SASHELP.CARS.
WHERE 0 /* an obviously FALSE WHERE clause */ ;
NOTE: PROCEDURE SGPLOT used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 243.46k
OS Memory 19864.00k
Timestamp 26/04/2018 04:14:56 PM
Step Count 6 Switch Count 40
Page Faults 0
Page Reclaims 99
Page Swaps 0
Voluntary Context Switches 105
Involuntary Context Switches 2
Block Input Operations 0
Block Output Operations 0
ERROR: No matching %MACRO statement for this %MEND statement.
46 %mend SomeExcitingMacro;
47
48 proc sql;
49 create table LoopData as
50 select
51 distinct Origin
52 from SASHELP.cars
53 ;
NOTE: Compression was disabled for data set WORK.LOOPDATA because compression overhead would increase the size of the data set.
NOTE: Table WORK.LOOPDATA created, with 3 rows and 1 columns.
54 quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
user cpu time 0.01 seconds
system cpu time 0.01 seconds
memory 5328.46k
OS Memory 24988.00k
Timestamp 26/04/2018 04:14:56 PM
Step Count 7 Switch Count 48
Page Faults 0
Page Reclaims 431
Page Swaps 0
Voluntary Context Switches 136
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 136
55
56 data _null_;
57 set LoopData;
58 call execute('%nrstr(%SomeExcitingMacro('||Origin||'))');
59 run;
NOTE: There were 3 observations read from the data set WORK.LOOPDATA.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.01 seconds
memory 921.87k
OS Memory 21144.00k
Timestamp 26/04/2018 04:14:56 PM
Step Count 8 Switch Count 32
Page Faults 0
Page Reclaims 314
Page Swaps 0
Voluntary Context Switches 73
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
NOTE: CALL EXECUTE generated line.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
NOTE: Line generated by the CALL EXECUTE routine.
1 + %SomeExcitingMacro(Asia )
_
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
2 + %SomeExcitingMacro(Europe)
3 + %SomeExcitingMacro(USA )
60
61 ;
61 ! *';*";*/;ods html5 (id=saspy_internal) close;ods listing;
62
The coloring might be coming from settings for the editor.
See the capture from my editor. The pink background is for macro code, the dark pink with white background is for the macro language keywords.
If you copy code directly from some sources you sometimes get non-displayed characters that interfere with the SAS language interpreter. Sometimes the results are pretty bizarre depending on which code locations they occur. So did any of those %macro statements originate as copy and paste or did you type them directly?
Something else to try might be to put some code before the macro definition that doesn't really do anything and see if the same issue repeats. Something like
data _null_;
run;
You can use this extension to get the SAS log:
https://github.com/sassoftware/sas_kernel/tree/master/sas_kernel/nbextensions
First off, you really need to understand what macros, and commands are used for an when to use them as %nrstr is really not needed here.
%macro someexcitingmacro(originname);
proc sgplot data=sashelp.cars;
where origin="&originname.";
vbox invoice / category=drivetrain nooutliers;
yaxis min=0 max=100000;
run;
%mend someexcitingmacro;
proc sql;
create table loopdata as
select distinct origin
from sashelp.cars;
quit;
data _null_;
set loopdata;
call execute('%SomeExcitingMacro('||origin||');');
run;
Now this program should work. However that being said there is no need to utilise macro at all. SAS provides the structure to loop over variables within a procedure itself. It is called by grouping and is very powerful:
proc sgplot data=sashelp.cars;
by origin;
title "By group=#byval1";
vbox invoice / category=drivetrain nooutliers;
yaxis min=0 max=100000;
run;
This will create one vbox output for each distinct origin in the dataset cars. If you only need specific ones add a where clause. This type of code is far simpler to write and maintain.
Still error in Jupyter Notebook:
No such macro: 'someexcitingmacro(originname);'
Available macros:
System:
renumber-cells
Learned:
Please post your full code and/or log.
You do not have the code as I present it, you are missing:
%macro someexcitingmacro(originname);
At least. This is what the log is telling you, there is no macro variable called originname, and there is no macro definition for someexcitingmacro, as you do not have the above line. Please use my code in full.
As I said I submitted your code as well. The screenshot is below. I get similar error logs:
6 The SAS System 18:24 Thursday, April 26, 2018
39 ods listing close;ods html5 (id=saspy_internal) file=_tomods1 options(bitmap_mode='inline') device=svg; ods graphics on /
39 ! outputfmt=png;
NOTE: Writing HTML5(SASPY_INTERNAL) Body file: _TOMODS1
40
41 proc sgplot data=sashelp.cars; where origin="&originname."; vbox invoice / category=drivetrain nooutliers;
WARNING: Apparent symbolic reference ORIGINNAME not resolved.
42 yaxis min=0 max=100000;
43 run;
NOTE: There were 0 observations read from the data set SASHELP.CARS.
WHERE 0 /* an obviously FALSE WHERE clause */ ;
NOTE: PROCEDURE SGPLOT used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 242.03k
OS Memory 19864.00k
Timestamp 26/04/2018 06:24:26 PM
Step Count 6 Switch Count 32
Page Faults 0
Page Reclaims 104
Page Swaps 0
Voluntary Context Switches 72
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
ERROR: No matching %MACRO statement for this %MEND statement.
44 %mend someexcitingmacro;
45
46 proc sql;
47 create table loopdata as
48 select distinct origin
49 from sashelp.cars;
NOTE: Compression was disabled for data set WORK.LOOPDATA because compression overhead would increase the size of the data set.
NOTE: Table WORK.LOOPDATA created, with 3 rows and 1 columns.
50 quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.01 seconds
memory 5328.46k
OS Memory 24988.00k
Timestamp 26/04/2018 06:24:26 PM
Step Count 7 Switch Count 40
Page Faults 0
Page Reclaims 424
Page Swaps 0
Voluntary Context Switches 104
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 144
51
52 data _null_;
53 set loopdata;
54 call execute('%SomeExcitingMacro('||origin||');');
55 run;
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
NOTE: There were 3 observations read from the data set WORK.LOOPDATA.
NOTE: DATA statement used (Total process time):
real time 0.00 seconds
user cpu time 0.01 seconds
system cpu time 0.00 seconds
memory 925.21k
OS Memory 21144.00k
Timestamp 26/04/2018 06:24:26 PM
Step Count 8 Switch Count 38
Page Faults 0
Page Reclaims 313
Page Swaps 0
Voluntary Context Switches 96
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
NOTE: CALL EXECUTE generated line.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
NOTE: Line generated by the CALL EXECUTE routine.
1 + %SomeExcitingMacro(Asia );
_
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
NOTE: Line generated by the CALL EXECUTE routine.
2 + %SomeExcitingMacro(Europe);
_
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
NOTE: Line generated by the CALL EXECUTE routine.
3 + %SomeExcitingMacro(USA );
_
180
ERROR 180-322: Statement is not valid or it is used out of proper order.
56
57 ods html5 (id=saspy_internal) close;ods listing;
58
My current conclusion is that Jupyter does not work with macros or maybe I am missing something.
Sorry, the log you post is not of the code I provided. Please point me to exactly where in the log:
39 ods listing close;ods html5 (id=saspy_internal) file=_tomods1 options(bitmap_mode='inline') device=svg; ods graphics on /
39 ! outputfmt=png;
NOTE: Writing HTML5(SASPY_INTERNAL) Body file: _TOMODS1
40
41 proc sgplot data=sashelp.cars; where origin="&originname."; vbox invoice / category=drivetrain nooutliers;
WARNING: Apparent symbolic reference ORIGINNAME not resolved.
42 yaxis min=0 max=100000;
43 run;
Where I can find the string:
%macro someexcitingmacro(originname);
That is missing from the run, hence originname is not defined, and there is not macro start, so medn calls and error.
It doesn't make sense to have ODS statements in Jupyter because output goes into the notebook. If hte purpase is to generate external fiels, I'd say that Jupyter is not the method you'd likely want to use. Or at least it makes it harder than it needs to be.
PS. Personally, I like Notebooks for presenting work, but for development it's hell.
Are you ready for the spotlight? We're accepting content ideas for SAS Innovate 2025 to be held May 6-9 in Orlando, FL. The call is open until September 25. Read more here about why you should contribute and what is in it for you!
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.