BookmarkSubscribeRSS Feed
Jumboshrimps
Quartz | Level 8

Have several programs that have the same date variable changing each quarter..

Wrote the code at the start of the program to change the one date variable each quarter - code runs once a quarter.

 


data null;
%global qstart ;
%global qtr_numb;          
 qstart = intnx('quarter',date(),-0);                         */first day of quarter.
qtr_numb =compress("QTR" || qtr(intnx('quarter',date(),-0))); */ this quarter
format qstart date9.;
 put qstart;
put qtr_numb;
 run;


01JUL2025    */correct result.
QTR3              */correct result

 

All good.  First variable is date, second variable is a concatenation of the string "QTR" and the numeric value of the quarter.  No thought at all went into the design of the data sets, instead of one variable with the results for eacg quarter, they of course, made four distinct variables = QTR1, QTR2, QTR3, QTR4.  That's not too bad, but there are data sets with 40 variables, 20 of them are one variable repeated 20 times.  Data sets are unnaturally long.

 
data BASE  (keep = GROUP accountID  &QTR_numb. );
    set based;
Run;

 

When I place the variable &qtr_numb in a KEEP statement as above I get the following error:

 

 

compress("QTR" || qtr(intnx('quarter',date(),-0)))
ERROR 214-322: Variable name ( is not valid.

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, /, ;, _DATA_,
_LAST_, _NULL_.

ERROR 23-7: Invalid value for the KEEP option.

ERROR 200-322: The symbol is not recognized and will be ignored.

----- --------- -
23 23 22
ERROR 22-7: Invalid option name ,.

1 ! compress("QTR" || qtr(intnx('quarter',date(),-0)))
-----
214
ERROR 214-322: Variable name "QTR" is not valid.

 

Why is SAS interpreting the variable assignment as a literal string?

 

The first variable above - an actual day, DID originally work in a simple data step like below, but no longer works:

 

data SAMP ;
set VAMP;
where sampdate ge &Qstart. ;
run;

 

 LOG:

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string,
a numeric constant, a datetime constant, a missing value, INPUT, PUT.
ERROR 76-322: Syntax error, statement will be ignored.
ERROR: Syntax error while parsing WHERE clause.
43 where sampdate ge &Qstart. ;
-
22
76

 

Are there supposed to be double ampersands, triple?   I will need to use one or more of the two variables in

  1. Where clause in data steps.
  2. Keep/Drop  statements
  3. PROC SQL.

Thanks.

5 REPLIES 5
PaigeMiller
Diamond | Level 26
compress("QTR" || qtr(intnx('quarter',date(),-0)))
ERROR 214-322: Variable name ( is not valid.

 

You need to show us the entire log, not a partial log. The command on the first line I pasted above will always fail as it is only a partial command. So we cannot tell what you did wrong. Show us the entire log so we can see the full commands used and the errors and warnings interspersed. Also, nothing you have shown uses macro variables, but you ask questions about macro variables and about double or triple ampersands, how can we answer that?

 

Please copy the log as text and paste it into the window that appears when you click on the </> icon. DO NOT SKIP THIS STEP.

PaigeMiller_0-1715196634946.png

--
Paige Miller
Kathryn_SAS
SAS Employee

You have not created macro variables in the DATA step that you show. You need to add CALL SYMPUTX as shown:

data null;
qstart = intnx('quarter',date(),-0);                         
qtr_numb =compress("QTR" || qtr(intnx('quarter',date(),-0))); 
format qstart date9.;
put qstart;
put qtr_numb;
call symputx('qtr_numb',qtr_numb);
call symputx('qstart',qstart);
run;

%put &qtr_numb;
%put &qstart;
Tom
Super User Tom
Super User

Do not place macro code like those %GLOBAL statements  in the middle of a data step.  It just confuses the poor humans trying to read it.  The macro processor will deal with all of the macro code before the resulting strings are passed on to SAS to actually interpret the generated code.  So the macro statements will end up executing before the data step.  So place them there to begin with.

%global qstart ;
%global qtr_numb;   

data null;
...

 

But also you never assigned any values to those two macro variables.

 

Instead you created two actual variables in a dataset named WORK.NULL.    Notice the difference between using NULL as the dataset name the special keyword _NULL_.  If you use DATA _NULL_ then SAS does not generate any dataset at all.

 

To create a macro variable with SAS code (as opposed the MACRO code) use the CALL SYMPUTX() statement.  You can use the optional third argument to force the macro variables to be GLOBAL.  Note I do not see any reason why either of these macro variables need to be made global.  If you are running this data step in open code they will already be created in the GLOBAL symbol table since that is the only symbol table available at that time.  

 

Example:

1    data _null_;
2     qstart = intnx('qtr',date(),0) ;
3     put 'The date ' qstart date9.
4         ' is the first day of QTR' qstart qtr1.
5         '.'
6     ;
7     call symputx('qstart',put(qstart,date9.));
8     call symputx('qtr_numb',cats('QTR',qtr(qstart)));
9    run;

The date 01JUL2025 is the first day of QTR3.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


10
11   %put The date &qstart is the first day of &qtr_numb.. ;
The date 01JUL2025 is the first day of QTR3.

If you want to try to do some of this in pure macro code then you will need to use the %SYSFUNC() macro function to allow you to call those data step functions like DATE(), INTNX() or QTR().

12
13   %let qstart=%sysfunc(intnx(qtr,%sysfunc(date()),0),date9.);
14   %let qtr_numb=QTR%sysfunc(qtr("&qstart"d));
15
16   %put The date &qstart is the first day of &qtr_numb.. ;
The date 01JUL2025 is the first day of QTR3.

 

 

 

 

 

ballardw
Super User

The minus sign in this

qstart = intnx('quarter',date(),-0);

does nothing.

I would suggest using the proper basis options of 'B' or 'E' for beginning and end of the interval instead of relying on the automatic advance to start of interval default behavior so you others can tell clearly the intent.

Tom
Super User Tom
Super User

Before starting on using the macro processor to generate some SAS code you need to be clear about what SAS you need to generate.

 

Can you explain a little more about what code you are trying to create?

 

For example you mentioned that you were able to get this code fragment to work.

data SAMP ;
  set VAMP;
  where sampdate ge &Qstart. ;
run;

That will work when value of the macro variable QSTART is text that will make the syntax of the WHERE statement valid.  So if SAMPDATE is numeric variable with DATE values then any text that looks to the SAS compiler like a valid date value should work.  So you could have QSTART set to things like:

%let qstart="01JUL2025"d;
%let qstart='01-jul-2025'd;
%let qstart=mdy(7,1,2025);
%let qstart=intnx('qtr',date(),0,'b');
%let qstart=23923;

The first two are date literals.  The next two are expression that SAS will evaluate to a date value. The last one is the actual number that SAS uses to represent the first of July in the year 2025.

 

Note that to the macro processor all of them are just text strings.

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 5 replies
  • 521 views
  • 0 likes
  • 5 in conversation