SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
awais
Obsidian | Level 7

Hi,

 

I am struggling to pass a numeric value through a sas macro.  Program1 generates two macros, prodname and prodcost. Program2 filters the data by using the character value that we have stored through program1- this program is working fine. Program3 is intended to filter the data by using the numeric value that we have stores through program2- this program is not working. details of the programs are provided below.

 

Program1

 

proc sql;
 select prodname, prodcost
 into: prodname, : prodcost
 from procsql.products;
quit;

%put &prodname and &prodcost;

 

When I want to use the macro (prodname) that recalls the character value, works perfectly fine. the following program runs perfectly fine:

 

Program2

 

proc sql;
 select prodname, prodcost
 from procsql.products
 where prodname = "&prodname";
quit;

 

 

Program3

 

However, when I use the same program to recall the macro that holds the numeric values, it throws me an error.

 

proc sql;
 select prodname, prodcost
 from procsql.products
 where prodcost > &prodcost;
quit;

 

the log shows the following error:

 

ERROR 22-322: Syntax error, expecting one of the following: a name, a quoted string, a numeric constant, a datetime constant,
a missing value, BTRIM, INPUT, PUT, SUBSTRING, USER.
 
Any help would be appreciated.
 

 

 

 

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
awais
Obsidian | Level 7

Hi Patric,

 

yeey. I got it working. you were right it had to do something with format of the macro variable. I modified the code as below and it is working:

 

 

proc sql;
 select prodname, prodcost format 32.
 into: prodname,
  : prodcost trimmed
 from procsql.products;
quit;
%put &prodname and &prodcost;

proc sql;
 select prodname, prodcost
 from procsql.products
 where prodname = "&prodname";
quit;


/* Resolved now */
proc sql;
 select prodname, prodcost
 from procsql.products
 where prodcost > &prodcost;
quit;

View solution in original post

9 REPLIES 9
ed_sas_member
Meteorite | Level 14

Hi @awais ,

 

Could you please specify what does the macro variable &prodcost look like when you run:  %put &prodcost;

For example, are there some leading / trailing blanks in addition to the stored number?

If so, I would suggest to use the a function like trim(&prodcost) to help SAS convert automatically the character value to a numeric one.

 

Hope this help!

andreas_lds
Jade | Level 19

@ed_sas_member wrote:

Hi @awais ,

 

Could you please specify what does the macro variable &prodcost look like when you run:  %put &prodcost;

For example, are there some leading / trailing blanks in addition to the stored number?

If so, I would suggest to use the a function like trim(&prodcost) to help SAS convert automatically the character value to a numeric one.

 

Hope this help!


The function trim removes trailing whitspace only, all macro variables are always character, but because sas-macros exist to create sas-code, which is text, this is hardly a problem at all.

 

I fully support your request that @awais needs to show the result of the %put-statement. And, @awais, please use the {i}-button and paste the excerpt of the sas log in that window, so that formatting is preserved.

awais
Obsidian | Level 7

Hi,

 

thank you for replying. here is what I am seeing in the log

 

%put &prodname and &prodcost;
Dream Machine and $3,200.00
Patrick
Opal | Level 21

@awais wrote:

Hi,

 

thank you for replying. here is what I am seeing in the log

 

%put &prodname and &prodcost;
Dream Machine and $3,200.00

It looks like SAS variable prodcost from your table procsql.products has a permanent format of DOLLARw.d attached.

When creating macro variable &prodcost the formatted value gets used (which dollar sign, comma thousand separator). This then causes the error when you try to pass in this string as a numerical value to SAS (as there you can't use a dollar sign and comma separator unless you use such a string in an input function).

May be just set an explicit format of 32. when creating the macro variable as done in below code sample for macro variable &PROD_COST2

 

data sample;
  format prod_cost dollar16.2;
  prod_cost=320000;
  output;
  stop;
run;

proc sql;
  select 
    prod_cost, 
    prod_cost format=32.
      into 
        :prod_cost1 trimmed, 
        :prod_cost2 trimmed
  from sample
  ;
quit;

%put &=prod_cost1 &=prod_cost2;

PROD_COST1=$320,000.00 PROD_COST2=320000

awais
Obsidian | Level 7

Hi Patric,

 

yeey. I got it working. you were right it had to do something with format of the macro variable. I modified the code as below and it is working:

 

 

proc sql;
 select prodname, prodcost format 32.
 into: prodname,
  : prodcost trimmed
 from procsql.products;
quit;
%put &prodname and &prodcost;

proc sql;
 select prodname, prodcost
 from procsql.products
 where prodname = "&prodname";
quit;


/* Resolved now */
proc sql;
 select prodname, prodcost
 from procsql.products
 where prodcost > &prodcost;
quit;

awais
Obsidian | Level 7

Hi thank you for replying. Here is the snapshot from log:

 

 
%put &prodname and &prodcost;
Dream Machine and $3,200.00
PaigeMiller
Diamond | Level 26

In addition the what @ed_sas_member said, &prodcost may have many values, such as 2.79 0.66 14.08, since PROCSQL.PRODUCTS probably contains many records, so its not really clear what you are trying to do in the case of many records. So, yes, I agree we need to see the contents of &prodcost.

--
Paige Miller
Tom
Super User Tom
Super User

First check that the dataset variable PRODCOST is actually numeric.  Then check whether PRODCOST has any FORMAT attached to it.

 

You can change the SELECT statement to remove the format (or convert to a better format) so that the generated macro variable is in a form that is valid in SAS code.  You can change the %PUT statement to make it clearer if there are any leading/trailing spaces in the macro variable's value.

proc sql noprint;
select prodname
     , prodcost format=best32.
 into :prodname trimmed
    , :prodcost trimmed
 from procsql.products
;
quit;

%put prodname=|&prodname| and prodcost=|&prodcost|;

For you character variable you might want to use the QUOTE() function to add the surrounding quotes into the macro variable and then you can remove them from your query that references to macro variable.

proc sql noprint;
select quote(trim(prodname))
     , prodcost format=best32.
 into :prodname trimmed
    , :prodcost trimmed
 from procsql.products
;
quit;
FreelanceReinh
Jade | Level 19

Hi @awais,

 

I suspect that there's a format associated with variable prodcost in dataset procsql.products and that you expect SAS to use the internal numeric value in your WHERE statement. But macro variables contain only text, in this case the formatted value of prodcost and there is no way to reconstruct the unformatted value from the macro variable alone. So, the solution would be to use a format (temporarily, in the PROC SQL step populating the macro variable) such that the formatted value is valid as a numeric literal (and, of course, is appropriate in terms of precision).

 

Example:

data products;
prodname='ABC';
prodcost=123.45;
format prodcost dollar8.2;
run;

proc sql noprint;
select prodname, prodcost format=best12.
into :prodname, :prodcost
from products;
quit;

sas-innovate-white.png

Special offer for SAS Communities members

Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.

 

View the full agenda.

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 9 replies
  • 3864 views
  • 2 likes
  • 7 in conversation