BookmarkSubscribeRSS Feed
David_Billa
Rhodochrosite | Level 12

I've written a macro program as follows. First program to create a dataset named 'protocol' and the second macro program is to check for the count in 'dups' dataset.

 

If the count is greater than 0 in 'dups' dataset then I would like to call the first macro program with some values. In the list of Parameter macro variables there is a macro variable called 'flt_rec_txt'. In this variable (don't worrry about length) I want to feed the values by populating all the observations from 'dups' dataset seperated by space. However I'm not certain how to achieve it in my apporach  and I got error as below. Also I was asked not to change the apporach in order to resolve the error.

 

%macro IFR_WRITE_ERROR(
			error_code =
			, error_text =
			, flt_id =
			,flt_rec_txt =		
			);

	data protocol;
		ERROR_CODE = &error_code.;
		TEXT = "&error_text.";
		flt_id=&flt_id.;
		flt_rec_txt="&flt_rec_txt.";
	run;

%mend IFR_WRITE_ERROR;

 

%macro IFR_CHECK_KEYS;

	proc sql noprint;
		select count(*)
			into :dup_columns
				from dups
		;
	quit;

	%if &dup_columns. > 0 %then
		%do;
			%IFR_WRITE_ERROR(
				error_code = 100
				, error_text = Validation key - unique key violated
				,flt_id = 128
				flt_rec_txt=dups
				);
			%let processing_code = 1;
		%end;
%end;
%mend IFR_CHECK_KEYS;

%IFR_CHECK_KEYS;

Error message in the log:

 

MPRINT(IFR_WRITE_ERROR):   TEXT = "Validation key - unique key violated";
SYMBOLGEN:  Macro variable FLT_ID resolves to 128     flt_rec_txt=dups
NOTE: Line generated by the macro variable "FLT_ID".
2433       128     flt_rec_txt=dups
                   ___________ ____________
                   22          557
ERROR: DATA STEP Component Object failure.  Aborted during the COMPILATION phase.
ERROR 22-322: Syntax error, expecting one of the following: !, !!, &, *, **, +, -, /, ;, <, <=, <>, =, >, ><, >=, AND, EQ, GE, GT, 
              IN, LE, LT, MAX, MIN, NE, NG, NL, NOTIN, OR, ^=, |, ||, ~=.  

If the Dups dataset has the dataset as below,

 

FLT_LAYR_NMFYP_NM_TEAM_NM
DISConsistencycheckBusiness
DIDRangecheckClient

 

Then the desried result of the above program should be,

 

error_codeerror_textflt_idflt_rec_txt
100 128DIS Consistencycheck Business DID Rangecheck Client
15 REPLIES 15
novinosrin
Tourmaline | Level 20

Hi @David_Billa   A quick look tells me you are missing a comma(,) here between the keyword parameters ,flt_id = 128
flt_rec_txt=dups   

 

So will this correction help?

 

 

%IFR_WRITE_ERROR(
error_code = 100
, error_text = Validation key - unique key violated
,flt_id = 128

,flt_rec_txt=dups
);

David_Billa
Rhodochrosite | Level 12
No, it's a typo error and it didn't helped me either
Tom
Super User Tom
Super User

So post the new error, as the old error was clearly caused by having wrong value passed to the parameter because of the missing comma.

Tom
Super User Tom
Super User

It looks like you want concatenate multiple rows into one string. But I don't see any code that is actually trying to so that.

 

David_Billa
Rhodochrosite | Level 12
Because I'm not certain how to implement that logic in my program.
Tom
Super User Tom
Super User

Please post your data in a usable format.

data have;
  infile cards dsd dlm='|' truncover;
  input FLT_LAYR_NM :$10. FYP_NM :$30. _TEAM_NM :$30. ;
cards;
DIS|Consistencycheck|Business
DID|Rangecheck|Client
;
data expect;
  infile cards dsd dlm='|' truncover;
  input error_code error_text :$100. flt_id flt_rec_txt :$100. ;
cards;
100| |128|DIS Consistencycheck Business DID Rangecheck Client
;

Not clear that there is any need for macro logic at all for this problem.

data want;
  length error_code 8 error_text $100 flt_id 8 flt_rec_txt $100 ;
  keep error_code -- flt_rec_txt;
  error_code=100;
  error_text=' ';
  flt_id=128;
  do until(eof);
    set have end=eof;
    flt_rec_txt=catx(' ',flt_rec_txt,flt_layr_nm,fyp_nm,_team_nm);
  end;
run;
       error_    error_
Obs     code      text     flt_id                        flt_rec_txt

 1       100                 128     DIS Consistencycheck Business DID Rangecheck Client

David_Billa
Rhodochrosite | Level 12
There are too many checks in the form of macro program as per my initial
post. I just placed only the summarzied code for one check.

Therefore I told that I want to tweak the code only in macro
David_Billa
Rhodochrosite | Level 12

If you want to handle the logic using macros, then how can you do that? Assume there are several HAVE datasets with multiple variables.

Tom
Super User Tom
Super User

@David_Billa wrote:

If you want to handle the logic using macros, then how can you do that? Assume there are several HAVE datasets with multiple variables.


It sounds like you want to process each one and APPEND the results to some aggregate dataset.

If the structure of the files is the same then the macro it probably very simple and just need to know the name of the current dataset that needs to be processed.

%macro do_one(dsname);

/* logic to process one file */
data this_one ;
  set &dsname ;
 ... 
run;

/* Aggregate to the master list */
proc append base=all_of_them data=this_one force;
run;

%mend do_one;
David_Billa
Rhodochrosite | Level 12
Problem is structure of the files are different. Then how to tackle it?
Tom
Super User Tom
Super User

@David_Billa wrote:
Problem is structure of the files are different. Then how to tackle it?

No idea.  How are they different? Why are they different? What is it want out of them?

Perhaps you don't actually want any of the data out of the files, just to create some information about the files. Like how many observations they contain.

Kurt_Bremser
Super User

After fixing the missing comma and removing a wrong %end, it works without errors:

%macro IFR_WRITE_ERROR(
			error_code =
			, error_text =
			, flt_id =
			,flt_rec_txt =		
			);

	data protocol;
		ERROR_CODE = &error_code.;
		TEXT = "&error_text.";
		flt_id=&flt_id.;
		flt_rec_txt="&flt_rec_txt.";
	run;

%mend IFR_WRITE_ERROR;

%macro IFR_CHECK_KEYS;

	proc sql noprint;
		select count(*)
			into :dup_columns
				from dups
		;
	quit;

	%if &dup_columns. > 0 %then
		%do;
			%IFR_WRITE_ERROR(
				error_code = 100
				, error_text = Validation key - unique key violated
				,flt_id = 128
				,flt_rec_txt=dups
				);
			%let processing_code = 1;
		%end;

%mend IFR_CHECK_KEYS;

data dups;
x = 1;
output;
output;
run;

%IFR_CHECK_KEYS;
David_Billa
Rhodochrosite | Level 12
What is the use of the macro variable processing_code?
David_Billa
Rhodochrosite | Level 12

After executing your code, I see the Output as follows. Instead of populating the values of the variables from 'dups' dataset in the last variable 'flt_rec_txt' it has written the text 'dups'. Could you please help me resolve this issue here?

 

ERROR_CODETEXTflt_idflt_rec_txt
100Validation key - unique key violated128dups

 

Whereas the desired Output is

 

ERROR_CODETEXTflt_idflt_rec_txt
100Validation key - unique key violated1281

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 15 replies
  • 1897 views
  • 3 likes
  • 4 in conversation