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
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
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;
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?
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?
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
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?
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;
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 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.