Hi all, I am attempting to run a SAS program, that uses a macro, and it's failing in batch mode (which I'm running through a .bat file in Windows). On the same computer, I can open the .SAS file with SAS 9.3 (64 bit) and it runs fine, no error messages at all.
Here is the error part of the log:
TSV_231_20150415_1154_ehars_20150131003424425033.tsv
X:\ELR\ehars\TSV_231_20150415_1154_ehars_20150131003424425033.tsv
eRawi1
NOTE: Line generated by the invoked macro "SCANLOOP".
146 last_name$108.; informat first_name$108.; informat middle_name$108.; informat name_type input received_date $ social_security_no $
__________________
85
76
146 ! state_no $ patient_identifier $ patient_identifier_type $ last_name $ first_name $ middle_name $ name_type $ address_1 $
ERROR 85-322: Expecting a format name.
ERROR 76-322: Syntax error, statement will be ignored.
NOTE: The SAS System stopped processing this step because of errors.
WARNING: The data set WORK.ERAWI1 may be incomplete. When this step was stopped there were 0 observations and 9 variables.
-------------------------------
Here is the code of the macro I am trying to run.
-------------------------------
%let largetable = dirlist;
/* Variable (grouping variable) from table by which to split data */
%let groupvar = filename;
%MACRO SCANLOOP(SCANFILE,FIELD1);
/* First obtain the number of records */
DATA _NULL_;
IF 0 THEN SET &SCANFILE NOBS=X;
CALL SYMPUT('RECCOUNT',X);
STOP;
RUN;
/* loop from one to number of */
/* records */
%DO I=1 %TO &RECCOUNT;
/* Advance to the Ith record */
DATA _NULL_;
SET &SCANFILE (FIRSTOBS=&I);
/* store the variables */
/* of interest in */
/* macro variables */
CALL SYMPUT('VAR1',&FIELD1);
*CALL SYMPUT('VAR2',&FIELD2);
STOP;
RUN;
/* now perform the tasks that */
/* wish repeated for each */
/* observation */
%put &var1;
%let outstring = X:\ELR\ehars\&var1;
%let newtablename = eRawi&I;
/*proc import datafile="&outstring" out = "&newtablename" */
%put &outstring;
%put &newtablename;
/* 05/19/14 13:47 - use data/infile. */
data WORK.&newtablename;
%let _EFIERR_ = 0;
infile "&outstring" delimiter='09'x MISSOVER DSD lrecl=32767 firstobs=2;
/* 05/19/14 13:44 - format all as very long */
informat received_date$108.; informat social_security_no$108.; informat state_no$108.; informat patient_identifier$108.; informat patient_identifier_type$108.; informat last_name$108.; informat first_name$108.; informat middle_name$108.; informat name_type$108.; informat address_1$108.; informat address_2$108.; informat city_name$108.; informat county_name$108.; informat state_cd$108.; informat zip$108.; informat country$108.; informat phone_no$108.; informat race_1$108.; informat race_2$108.; informat ethnicity_1$108.; informat birth_date mmddyy10.; informat sex$108.; informat fac_name$108.; informat fac_type$108.; informat fac_address_1$108.; informat fac_address_2$108.; informat fac_city_name$108.; informat fac_county_name$108.; informat fac_state_cd$108.; informat fac_country$108.; informat fac_zip$108.; informat fac_phone_no$108.; informat prov_name$108.; informat prov_address_1$108.; informat prov_address_2$108.; informat prov_city_name$108.; informat prov_county_name$108.; informat prov_state_cd$108.; informat prov_country$108.; informat prov_zip$108.; informat prov_phone_no$108.; informat collection_date$108.; informat specimen_type$108.; informat lab_test_cd$108.; informat lab_test$108.; informat lab_test_result$108.; informat lab_test_interpretation$108.; informat lab_test_units$108.; informat lab_test_viral_range$108.; informat lab_test_specimen_id$108.; informat lab_test_accession_no$108.; informat specimen_receive_date$108.; informat result_date$108.; informat lab_clia_uid$108.; informat lab_clia_name$108.; informat document_comments$2000.; informat msh_clia_no$108.; informat msh_clia_name$108.;
/* 05/19/14 13:44 - format all as text. */
input received_date $ social_security_no $ state_no $ patient_identifier $ patient_identifier_type $ last_name $ first_name $ middle_name $ name_type $ address_1 $ address_2 $ city_name $ county_name $ state_cd $ zip $ country $ phone_no $ race_1 $ race_2 $ ethnicity_1 $ birth_date sex $ fac_name $ fac_type $ fac_address_1 $ fac_address_2 $ fac_city_name $ fac_county_name $ fac_state_cd $ fac_country $ fac_zip $ fac_phone_no $ prov_name $ prov_address_1 $ prov_address_2 $ prov_city_name $ prov_county_name $ prov_state_cd $ prov_country $ prov_zip $ prov_phone_no $ collection_date $ specimen_type $ lab_test_cd $ lab_test $ lab_test_result $ lab_test_interpretation $ lab_test_units $ lab_test_viral_range $ lab_test_specimen_id $ lab_test_accession_no $ specimen_receive_date $ result_date $ lab_clia_uid $ lab_clia_name $ document_comments $ msh_clia_no $ msh_clia_name $;
if _ERROR_ then call symputx('_EFIERR_',1); /* set ERROR detection macro variable */
_filename = "&var1";
run;
/* 11/18/14 08:42 - add filename */
%END;
%MEND SCANLOOP;
/* Call SCANLOOP */
%SCANLOOP(dirlist,&groupvar);
-------------------------------
Any ideas what could be the problem? Thank you.
Does your actual code file look like what you pasted into the forum? Because your lines of text are WAAAAAAAAAAAAAAAAY too long. No human could read a line of text that is that long and it looks like SAS can't read it either. It is generally best to restrict lines of code to 75 characters. 1,365 is just little bit too long.
1 data _null_;
2 input;
3 list;
4 cards4;
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6---
5 informat received_date$108.; informat social_security_no$108.;
64 informat state_no$108.; informat patient_identifier$108.; infor
127 mat patient_identifier_type$108.; informat last_name$108.; info
190 rmat first_name$108.; informat middle_name$108.; informat name_
253 type$108.; informat address_1$108.; informat address_2$108.; in
316 format city_name$108.; informat county_name$108.; informat stat
379 e_cd$108.; informat zip$108.; informat country$108.; informat p
442 hone_no$108.; informat race_1$108.; informat race_2$108.; infor
505 mat ethnicity_1$108.; informat birth_date mmddyy10.; informat
568 sex$108.; informat fac_name$108.; informat fac_type$108.; infor
631 mat fac_address_1$108.; informat fac_address_2$108.; informat f
694 ac_city_name$108.; informat fac_county_name$108.; informat fac_
757 state_cd$108.; informat fac_country$108.; informat fac_zip$108.
820 ; informat fac_phone_no$108.; informat prov_name$108.; informat
883 prov_address_1$108.; informat prov_address_2$108.; informat pr
946 ov_city_name$108.; informat prov_county_name$108.; informat pro
1009 v_state_cd$108.; informat prov_country$108.; informat prov_zip$
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6---
1072 108.; informat prov_phone_no$108.; informat collection_date$108
1135 .; informat specimen_type$108.; informat lab_test_cd$108.; info
1198 rmat lab_test$108.; informat lab_test_result$108.; informat lab
1261 _test_interpretation$108.; informat lab_test_units$108.; inform
1324 at lab_test_viral_range$108.; informat lab_test_specimen_id$108
1387 .; informat lab_test_accession_no$108.; informat specimen_recei
1450 ve_date$108.; informat result_date$108.; informat lab_clia_uid$
1513 108.; informat lab_clia_name$108.; informat document_comments$2
1576 000.; informat msh_clia_no$108.; informat msh_clia_name$108.;
NOTE: DATA statement used (Total process time):
real time 0.04 seconds
cpu time 0.03 seconds
6 ;;;;
You have an INFORMAT statement without an INFORMAT and a terminating semicolon:
last_name$108.; informat first_name$108.; informat middle_name$108.; informat name_type input received_date $ social_security_no $
I would run this program with the options mprint and symbolgen to attempt to capture all of the code actually generated.
It almost looks like something is cutting off the text as INFORMAT NAM_TYPE as there is a lot of text between there and the INPUT but it looks like the error is because the code is looking for a format name in the position occupied by social_security_no .
You may need to look at the line length in the code file and see if the submitted code is exceeding line lengths that the SAS processor is expecting for code files. This might occur because of batch defaults.
Does your code have any linefeeds in that block of informat statements? If you have another section of code generating that I would look into making sure the code is a bit prettier. Seeing things like informat social_security_no$108.; makes me a bit uncomfortable. True, the space isn't required for a character format BUT the logic generating something like that fails if you are using an informat like 8. as that would make a differently named variable and miss the actual informat.
Consider writing the generated code to a text file and then including that file.
Does your actual code file look like what you pasted into the forum? Because your lines of text are WAAAAAAAAAAAAAAAAY too long. No human could read a line of text that is that long and it looks like SAS can't read it either. It is generally best to restrict lines of code to 75 characters. 1,365 is just little bit too long.
1 data _null_;
2 input;
3 list;
4 cards4;
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6---
5 informat received_date$108.; informat social_security_no$108.;
64 informat state_no$108.; informat patient_identifier$108.; infor
127 mat patient_identifier_type$108.; informat last_name$108.; info
190 rmat first_name$108.; informat middle_name$108.; informat name_
253 type$108.; informat address_1$108.; informat address_2$108.; in
316 format city_name$108.; informat county_name$108.; informat stat
379 e_cd$108.; informat zip$108.; informat country$108.; informat p
442 hone_no$108.; informat race_1$108.; informat race_2$108.; infor
505 mat ethnicity_1$108.; informat birth_date mmddyy10.; informat
568 sex$108.; informat fac_name$108.; informat fac_type$108.; infor
631 mat fac_address_1$108.; informat fac_address_2$108.; informat f
694 ac_city_name$108.; informat fac_county_name$108.; informat fac_
757 state_cd$108.; informat fac_country$108.; informat fac_zip$108.
820 ; informat fac_phone_no$108.; informat prov_name$108.; informat
883 prov_address_1$108.; informat prov_address_2$108.; informat pr
946 ov_city_name$108.; informat prov_county_name$108.; informat pro
1009 v_state_cd$108.; informat prov_country$108.; informat prov_zip$
RULE: ----+----1----+----2----+----3----+----4----+----5----+----6---
1072 108.; informat prov_phone_no$108.; informat collection_date$108
1135 .; informat specimen_type$108.; informat lab_test_cd$108.; info
1198 rmat lab_test$108.; informat lab_test_result$108.; informat lab
1261 _test_interpretation$108.; informat lab_test_units$108.; inform
1324 at lab_test_viral_range$108.; informat lab_test_specimen_id$108
1387 .; informat lab_test_accession_no$108.; informat specimen_recei
1450 ve_date$108.; informat result_date$108.; informat lab_clia_uid$
1513 108.; informat lab_clia_name$108.; informat document_comments$2
1576 000.; informat msh_clia_no$108.; informat msh_clia_name$108.;
NOTE: DATA statement used (Total process time):
real time 0.04 seconds
cpu time 0.03 seconds
6 ;;;;
http://support.sas.com/kb/5/953.html
Your input lines are MUCH (and I mean M - U - C - H) too long. They most probably are truncated the moment SAS reads the text file.
Big hint: if preparing SAS programs for batch mode, keep any line length below 80. Makes the code readable even when all you have is a PuTTY connection.
Another hint: pack your informats into a statement like:
informat
var1 $format1.
var2 $format2.
....
;
Do the same with your input statement (each variable on its own line).
And once you have defined a variable as character through the informat, the $ in the input statement is superfluous.
Sorry, zero code formatting or good programming practices = TL;DR
Further to Kurt's link, there is a default record length on batch files of 256 characters that is probably the cause of your error:
SAS can handle sources that are way much tooo loooong for humans. The requirement is that all settings/options for record lengths should not introduce some restriction.
Could be: SAS(R) 9.4 Companion for z/OS, Third Edition (cardimage) or lrecl SAS(R) 9.3 System Options: Reference, Second Edition or SAS(R) 9.3 System Options: Reference, Second Edition
The first step is verifying all options are the same in interactive en batch approach. better almost the same as some values are switching by default
Thanks for the helpful replies! It did turn out to be the line length. I think it would be great if a clear message was provided about it (e.g. line may have been truncated) but I'm glad it's fixed either way.
Actually, the log already tells you in this sequence:
informat name_type input
You can see the incomplete informat statement followed by the beginning of the next line, which signals the truncation of the input line (SAS also somehow misses the LF and therefore continues the line in the log)
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.