I don't have Jupyter at the moment, but see no reason they wouldn't work. I would test it first...here's a very simple one you can test if desired.
%macro sample_print(dsn=);
proc print data=&dsn; run;
%mend ;
%sample_print(dsn=sashelp.class);
Thanks Reeza
Again Jupyter marks macro code red (see screenshot below). Errors in log:
SAS Connection established. Subprocess id is 8964
6 The SAS System 20:53 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
42 proc print data=&dsn; run;
_
22
200
WARNING: Apparent symbolic reference DSN not resolved.
ERROR: File WORK.DSN.DATA does not exist.
ERROR 22-322: Expecting a name.
ERROR 200-322: The symbol is not recognized and will be ignored.
NOTE: The SAS System stopped processing this step because of errors.
NOTE: PROCEDURE PRINT used (Total process time):
real time 0.00 seconds
user cpu time 0.00 seconds
system cpu time 0.00 seconds
memory 72.71k
OS Memory 19608.00k
Timestamp 26/04/2018 08:53:52 PM
Step Count 6 Switch Count 38
Page Faults 0
Page Reclaims 84
Page Swaps 0
Voluntary Context Switches 96
Involuntary Context Switches 0
Block Input Operations 0
Block Output Operations 0
ERROR: No matching %MACRO statement for this %MEND statement.
WARNING: Apparent invocation of macro SAMPLE_PRINT not resolved.
43
44 %mend ;
45
46 %sample_print(dsn=sashelp.class);
47
48 ods html5 (id=saspy_internal) close;ods listing;
49
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;
This works:
data _null_;
run;
%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;
The first lines of code seem to be necessary to get the macro to work.
@csetzkorn wrote:
This works:
The first lines of code seem to be necessary to get the macro to work.
I am glad we got something to work. I guessed about the Data _null_ as the code generated by Jupyter for the ODS stuff at the top may have been using the first lines to trigger some internal macro-like code that was trying to use your macro definition as part of the instruction and there by eating it.
It might be worth bringing this to the attention of Tech Support.
Not to make this a big issue, but I cannot replicate your issue in a Jupyter notebook with the latest updated version of SAS UE.
It works fine for me, including your original code, though I changed your macro code slightly to add in the missing semicolon to the macro call.
I tried this code (adopted according to your suggestions):
%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;
str = catt('%SomeExcitingMacro(', Origin, ');');
call execute(str);
run;
Unfortunately, I am still getting and error, if I do not use:
data _null_;
run;
at the beginning. I have installed the latest saspy but maybe my server version is not the latest (e.g. we do not have M5).
Hey, I'm just starting to look through all of these threads and I saw this one.
I assume you are running the SAS_kernel in Jupyter. Jupyter itself has a special kind of 'macro' called a Magic. It is designated by a percent sign; '%some_magic'. It has special meaning in a jupyter cell. It's unfortunate for coding SAS Macros in a cell like this. But, you can work around this easily; it you know what to do. Here's an excerpt from the SAS_Kernel documentation that addresses this specific problem. The doc is at https://sassoftware.github.io/sas_kernel/overview.html:
The %%prompt4var magic is written specifically for the SAS kernel. The purpose of the magic is to prompt for sensitive information such as a password and store the value in a SAS macro variable.
Seasoned SAS programmers might notice that Python magics begin with a percent sign (%) and that SAS macro variables also begin with a percent sign. To ensure that magics are interpreted by Python, they must be specified in the first line of a notebook cell. Otherwise, the magic (%xxxxx) is submitted to SAS.
If you need to run a SAS macro as the first statement, then insert a blank line as the first line in the notebook cell and the macro on the second line. The blank line prevents Python from intrepreting the macro variable as a magic.
So, you should be able to run that code simply by adding a blank line as the first line in that cell, before your macro definition.
Hope this helps!
Tom
@csetzkorn wrote:
added log (?) to original code. the suggested alternative code produces the same ...
Note sure of timing on when posted but in the posted log
Your "code used" does not show the ODS Listing; Ods html5 ... that appears in the log.
The LOG does NOT show the
%macro SomeExcitingMacro(OriginName);
And the error about the not matching %macro is likely the result of no such line submitted.
So the macro did not compile . Then when call execute creates the call you get all those
WARNING: Apparent invocation of macro SOMEEXCITINGMACRO not resolved.
because the macro doesn't exist.
Generic hint: move as much code outside of ODS destination/ ods destination close statements as practical. That way only the actual output generation is involved. Test the macros and data generation separately.
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.