BookmarkSubscribeRSS Feed
massigrillo
Fluorite | Level 6

Hi all,

I am having issues exporting a SAS Dataset to XPT V5 by using PROC COPY.

This dataset has some columns associated to formats whose name is 8 chars long: this should be acceptable, according to

 

https://documentation.sas.com/?cdcId=pgmsascdc&cdcVersion=9.4_3.5&docsetId=movefile&docsetTarget=n01...

 

If I just remove one char from format name, making it 7 chars long, it works like a charm.

I attached sas program and sample csv to reproduce the issue.

What am i doing wrong?

Please help, thanks

7 REPLIES 7
Tom
Super User Tom
Super User

It is counting the required $ is part of the name for a character format.  This is definitely how I have used SAS since even before version 5.

 

Note that SAS will work with a name of ABCDEFGH because if the variable is character it will assume you meant to reference a character format and add the $ so that it really searches for $ABCDEFGH.

167   data test;
168     set sashelp.class;
169     format name ABCDEFGH. ;
                    ---------
                    484
NOTE 484-185: Format $ABCDEFGH was not found or could not be loaded.

170   run;

 

massigrillo
Fluorite | Level 6

Hi,

actually if I remove the $ sign here:

 

 

format
      FIELD1 AAAAAAAA.                                                                                                                                                                                         
      FIELD2 BBBBBBB.
;

 

 

it keeps on working, provided that I remove the last char of longer format;

otherwise if I keep the name untouched, it says that

 

ERROR: The format name $AAAAAAAA is illegal for file XPORTOUT.DATA.DATA.

 

 

libname csvlib "/folders/myfolders/csv";
libname xportout xport "/folders/myfolders/test.xpt";

options fmtsearch = (csvlib.formats);  
                                                                                                                                                                                           
proc format library=csvlib;                                                                                                                                                                     
	value $AAAAAAAA
		"1" = "One"
		"2" = "Two"
		"3" = "Three"
	;                                                                                                                                                                     
	value $BBBBBBB
		"4" = "Four"
		"5" = "Five"
		"6" = "Six"
	;
;
run;

data csvlib.DATA;
	infile "/folders/myfolders/test.csv"
		delimiter=","
		missover
		dsd 
		firstobs=2
	;
    label
		FIELD1 = "Field One"
		FIELD2 = "Field Two"
		FIELD3 = "Field Three"
	;
	length
		FIELD1 $2.
		FIELD2 $2.
		FIELD3 $100.
	;
	format
      FIELD1 AAAAAAAA.                                                                                                                                                                                         
      FIELD2 BBBBBBB.
	;
	input
        FIELD1 $
        FIELD2 $
        FIELD3 $
	;
run;

proc copy 
	in=csvlib
	out=xportout
	memtype=data
	;
run;

libname csvlib clear;
libname xportout clear;

so you're telling me I'm doing nothing wrong, it is just the way it works?

 

Reeza
Super User

SAS will sometimes "correct" your code to add those automatically, so it's implicit $ rather than explicit, it still takes up the space would be my guess. The log usually indicates if this has happened though - what does the log show for the code shown?

massigrillo
Fluorite | Level 6

ok, probably my previous reply was somehow misleading, let me reformulate the question:

I have a dataset that has a format whose name is 8 characters PLUS the $ sign, meaning it's a string, not a number:

 

 

value $AAAAAAAA
		"1" = "One"
		"2" = "Two"
		"3" = "Three"
	;     

 

 

Now I have to export this dataset in SAS XPT format, version 5, and I use proc copy for this purpose

 

 

proc copy 
	in=csvlib
	out=xportout
	memtype=data
	;
run;

 

 

but I have following error:

 

ERROR: The format name $AAAAAAAA is illegal for file XPORTOUT.DATA.DATA.

 

According to SAS xpt specification (see here) a format name 8 chars long should be acceptable

 

massigrillo_0-1613730081398.png

 

It seems instead that proc copy is counting the $ as one of the char of the name, thus considering as 9 characters long.

Tom confirmed this.

So my question is,

is there some option making proc copy to skip this validation check, or is there an alternative procedure/macro to achive the goal of having the xpt export without modifying the format name?

 

Tom
Super User Tom
Super User

Perhaps with actual version 5 (or earlier of SAS) you could have attached a character format with 8 characters (plus the $) but I seriously doubt it.   But even if you modify the transport file to change the 8 character field where the format name is stored to remove the leading $ and instead use all 8 positions for the name it will not work.  SAS when it tries to read that data will replace the first position with a $.  See example program below.

proc format ;
value $SHORT low-high = 'short name';
value $TOOLONGB low-high = '8 letter name' ;
value $OOLONGB low-high = '$ over first letter' ;
run;

data test;
  x='1'; y='2';
  format y $short. ;
run;

proc print data=test;
run;


* make some temporary files to use as XPT files ;
filename xxx temp;
filename yyy temp;

* Add dataset to XPT file ;
libname out xport "%sysfunc(pathname(xxx))";
data out.test; set test; run;

* Make a copy of XPT file replacing $SHORT with TOOLONGB ;
data _null_;
  infile xxx recfm=f lrecl=80  ;
  file yyy recfm=f lrecl=80 ;
  input;
  _infile_=tranwrd(_infile_,'$SHORT  ','TOOLONGB');
  put _infile_ $char80. ;
run;

* Point a libref to the updated XPT file ;
libname new xport "%sysfunc(pathname(yyy))";  

data test2; set new.test; run;

proc print data=test2; run;

proc contents data=new.test; run;
proc contents data=out.test; run;

 

 

Reeza
Super User
is there some option making proc copy to skip this validation check, or is there an alternative procedure/macro to achive the goal of having the xpt export without modifying the format name?

Unfortunately, No and No AFAIK. V5 is an antiquated transfer format, so I wouldn't expect any development around it either.
Tom
Super User Tom
Super User

Add you own logic to "fix" the format that is attached.  Here is code that truncate the long the format names.  If you use the NOFMTERR option then it will run.   Of course if these truncated formats do not exist then you will have a different issue to solve.  Perhaps you could also have code that renames the format definitions.

%let inlib=WORK;
%let outlib=OUT;
%let member=TEST;


proc sql noprint;
select catx(' '
     ,name
     , cats(case when (type='char') then '$'||substr(format,3,7) else substr(format,1,8) end,'.')
     )
  into :reformat separated by ' '
from dictionary.columns
where libname=%upcase("&inlib") and memname=%upcase("&member")
  and length(format)>8
;
%let n=&sqlobs;
quit;

data &outlib..&member;
  set &member;
%if &n %then %do;
  format &reformat ;
%end;
run;

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
  • 7 replies
  • 1529 views
  • 2 likes
  • 3 in conversation