Hi Guys. Thanks for all the advices. I truly understand about the learn from basics part. Currently i will have to settle my works on my hand first. I talked to my senior and just like what some of you all mentioned, SAS can execute the code straight after removing %put.
I tried to put double quote wrapping like :
"&comma. &&cwcolumn&k.."
(previously i never wrap it with double quote)
However, I am getting error for all the resolved variable:
May i know if there is any special handling when it is actually resolving a proc sql statement?
proc sql; create table CDSSTG.CSTG_ACTIVITY_CONCERN_AREA as( select NOTE: Line generated by the macro variable "CWCOLUMN1". 386 " ACTION_DATE ______________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN2". 386 ", ACTION_PARTY ________________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN3". 11 The SAS System 15:40 Tuesday, July 11, 2017 386 ", ACTION_REQUIRED ___________________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN4". 386 ", ACTIVITIES ______________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN5". 386 ", OFFLINE_DATE ________________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN6". 386 ", PLATFORM_CD _______________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN7". 386 ", REMARKS ___________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN8". 386 ", REPORT_DT _____________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN9". 386 ", STATUS __________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN10". 386 ", TARGET_DATE _______________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN11". 386 ", WF_COACT ____________ 12 The SAS System 15:40 Tuesday, July 11, 2017 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN12". 386 ", WF_DEL_DATE _______________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN13". 386 ", WF_PHASE ____________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN14". 386 ", WF_STATUS _____________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN15". 386 ", WF_TXNID ____________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN16". 386 ", WF_USERID _____________ 180 ERROR 180-322: Statement is not valid or it is used out of proper order. NOTE: Line generated by the macro variable "CWCOLUMN17". 386 ", WF_USERMODDATE __________________ 180 from CDSSTG.CSTGT_ACTIVITY_CONCERN_AREA); ERROR 180-322: Statement is not valid or it is used out of proper order.
May i know if the double quote wrap here is wrongly used or there is something missing from it.
You need to post your actual code in addition to your log. We see the generated errors but not the code.
Did you do a mock example like we suggested? It will help you figure out how to build this process.
I truly understand about the learn from basics part. Currently i will have to settle my works on my hand first.
Actually, I believe you haven't understood what we're trying to tell you. If you got lost in your code then DO NOT TRY TO FIX EVERYTHING AT ONCE. Take a step back!
You've got now a macro with lots of code in it and it's not working. One way to go:
1. Create a backup of your current code.
2. Start a new code (a brand new .sas file or EG/Studio code node).
3. Copy the macro "shell" to your new code: %macro blah(...); %mend; %blah(...) - run it. If no error then proceed else debug and fix.
4. Copy the very first run group from your backed up code into the new code (ie. the first proc sql, data step etc.). If you've got already macro syntax in this first step: Remove it as far as possible - run it. If no error then proceed else debug and fix.
5. If there had been macro syntax/logic: add it back - run it. If no error then proceed else debug and fix.
6. Now add the next logical unit ....and so on and so on, step by step
For your latest question: I don't believe you need these quotes.
The way SAS Macro code interacts with "normal" SAS code:
First comes the SAS Macro guy (could also be a girl of course). This one looks all the code and searches for % and & - these are the tokens for the SAS Macro guy telling him that this is his job and he needs to do something with it. The SAS macro guy consumes everything macro and once he's done only non macro stuff remains.
Now comes the SAS girl. She picks up the "left overs" and does then does her thing with it, i.e. executes the "left over" Proc SQL syntax.
If you're using options mprint and mlogic for the code I've posted earlier then the log shows you what the macro guy does and what the SAS girl has to do.
options mprint mlogic;
/* macro definition */
%macro test(selected_var);
proc sql feedback;
select
name,
age,
case
%if %upcase(&selected_var) = USE_HEIGHT %then
%do;
WHEN height<60 THEN 'Height <60'
ELSE 'Height >=60'
%end;
%else %if %upcase(&selected_var) = USE_WEIGHT %then
%do;
WHEN weight<90 THEN 'Weight <90'
ELSE 'Weight >=90'
%end;
end as
my_selected_var length=20
from sashelp.class
;
quit;
%mend;
/* macro call */
%test(use_weight)
The macro call generates the following log:
54 /* macro call */ 55 %test(use_weight) MLOGIC(TEST): Beginning execution. MLOGIC(TEST): Parameter SELECTED_VAR has value use_weight 2 The SAS System 16:02 Wednesday, July 19, 2017 MPRINT(TEST): proc sql feedback; MLOGIC(TEST): %IF condition %upcase(&selected_var) = USE_HEIGHT is FALSE MLOGIC(TEST): %IF condition %upcase(&selected_var) = USE_WEIGHT is TRUE MPRINT(TEST): select name, age, case WHEN weight<90 THEN 'Weight <90' ELSE 'Weight >=90' end as my_selected_var length=20 from sashelp.class ; NOTE: Statement transforms to: select CLASS.Name, CLASS.Age, case when CLASS.Weight < 90 then 'Weight <90' else 'Weight >=90' end as my_selected_var length=20 from SASHELP.CLASS; MPRINT(TEST): quit; NOTE: The PROCEDURE SQL printed page 1. NOTE: PROCEDURE SQL used (Total process time): real time 0.01 seconds cpu time 0.03 seconds MLOGIC(TEST): Ending execution.
What's shown in lines starting with MLOGIC is what the Macro guy has been doing, what's shown in lines starting with MPRINT is what the macro guy left over for the SAS girl to do; and the rest of the log shows you what the SAS girl has been doing.
And the sometimes a bit fiddely thing with macro coding: You must code carefully so that the macro guy only leaves stuff behind for the SAS girl which is really hers to deal with - this one is not very generous in this regards and throws errors if not treated with respect.
@imdickson wrote:
Hi Guys. Thanks for all the advices. I truly understand about the learn from basics part. Currently i will have to settle my works on my hand first. I talked to my senior and just like what some of you all mentioned, SAS can execute the code straight after removing %put.
I tried to put double quote wrapping like :"&comma. &&cwcolumn&k.."
(previously i never wrap it with double quote)
.
I seriously doubt if you want the double quotes in that situation. In SAS code you use quotes around string literals. NOT around pieces of code. From your macro variable names it looks like COMMA will have a comma in it and &&cwcolumn&k.. should resolve to a variable name. So it looks like you are trying to build part of the variable list in an SQL SELECT statement. Or perhaps part of the variable list in an ORDER BY or GROUP BY clause in an SQL SELECT statement.
So if you ran this code:
%macro gen;
%local comma k ;
%do k=1 %to &n ;
&comma. &&cwcolumn&k..
%let comma=,;
%end;
%mend gen;
%let n=2 ;
%let cwcolumn1=FIRST ;
%let cwcolumn2=SECOND ;
%put %gen;
The last line will cause FIRST , SECOND to be written to the SAS log.
Now if call %gen in the middle of an SQL statement then you could use it to conditionally generate a list of variable names to use in the select statement.
proc sql ;
select %gen
from mydata
;
quit;
So it is the same as if I had just hard coded the list of variable names in the SELECT statement.
proc sql ;
select FIRST , SECOND
from mydata
;
quit;
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.