BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
imdickson
Quartz | Level 8

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.

Reeza
Super User

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.

Patrick
Opal | Level 21

@imdickson

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.

Tom
Super User Tom
Super User

@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-2024.png

Don't miss out on SAS Innovate - Register now for the FREE Livestream!

Can't make it to Vegas? No problem! Watch our general sessions LIVE or on-demand starting April 17th. Hear from SAS execs, best-selling author Adam Grant, Hot Ones host Sean Evans, top tech journalist Kara Swisher, AI expert Cassie Kozyrkov, and the mind-blowing dance crew iLuminate! Plus, get access to over 20 breakout sessions.

 

Register now!

How to Concatenate Values

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 18 replies
  • 2191 views
  • 2 likes
  • 4 in conversation