Hello,
I am working on an existing program and I am trying to figure out when the variable lengths are defined...
After running the program I see the variable length of DSSCAT is 9 char long and I would like to increase it.
But from the code, it is not clear when it is assigned.
Can someone help?
PRGM
--------
data recons (keep=SUBJID DSTERM_all DSDECOD DSCAT DSSCAT DSSTDTC ord /*GENPART*/);
%SLENGTH (DS, DSCAT DSSTDTC DSDECOD DSSCAT);
length DSTERM_all $500;
set Pbp2_gen;
*date of reconsent;
if DRECONM ne . and DRECOND ne . and DRECONY ne . then rconsdt = mdy(DRECONM, DRECOND, DRECONY);
if rconsdt ne . then DSSTDTC = put(rconsdt, e8601da.);
DSTERM_all = 'INFORMED CONSENT OBTAINED';
DSDECOD = DSTERM_all;
DSCAT = 'PROTOCOL MILESTONE';
DSSCAT = 'RECONSE3NT';
ord = 2;
if RECONS = 1;
run;
MACRO SLENGTH
--------------------------
%MACRO SLENGTH(dset, name_list);
%local i varname vlabel vlen;
%local dsid;
%let dsid = %sysfunc(open(empty_&dset));
LENGTH
%do i=1 %to %sysfunc(countw(&name_list));
%let varname = %scan(&name_list, &i);
%** DO whatever needs to be done for &NEXT_NAME;
%let vnum = %sysfunc(varnum(&dsid,&varname));
%*let vlabel = %sysfunc(varlabel(&dsid,&varname));
%let vlabel = %sysfunc(varlabel(&dsid, %sysfunc(varnum (&dsid,&varname))));
%let vlen = %sysfunc(varlen (&dsid, %sysfunc(varnum (&dsid,&varname))));
%let vtype = %sysfunc(vartype (&dsid, %sysfunc(varnum (&dsid,&varname))));
&varname $&vlen..
%end;
;
%let dsid = %sysfunc(close(&dsid));
%MEND SLENGTH;
The variable attributes are taken from a dataset called WORK.EMPTY_DS; you will see that the variable is defined with this length there.
The variable attributes are taken from a dataset called WORK.EMPTY_DS; you will see that the variable is defined with this length there.
You're absolutely right! and the empty_DS sets the variable with another macro which is opening an excel file where the variable lengths are set.
Thanks a lot!
So your macro %SLENGTH() appears to be generating a LENGTH statement. It does this by searching for the variables listed in the second argument from the dataset listed in the first argument. You can test it yourself by running executing it in a %PUT statement and see what is written to the SAS log.
You could do basically the same thing without needing macro code by just use a SET statement. It can even be one that will never actually execute.
if 1=2 then set ds(keep=DSCAT DSSTDTC DSDECOD DSSCAT);
So the answer to your question is that the length of DSSCAT is being set from the length it had in the dataset DS.
If you want set it to something else then you should remove DSSCAT from the list of variables passed to %SLENGTH() and add your own LENGTH statement.
data recons (keep=SUBJID DSTERM_all DSDECOD DSCAT DSSCAT DSSTDTC ord /*GENPART*/);
%SLENGTH (DS, DSCAT DSSTDTC DSDECOD);
length DSSCAT $20 DSTERM_all $500;
...
You might also want to prevent DSSCAT from getting the wrong format attached to it. For example if it existed in the input dataset Pbp2_gen then whatever format it had there would be attached. Since there SAS does not need to have special instructions for how to display character strings just remove the format by using a FORMAT statement that does not actually mention any format.
format dsscat ;
It's not the same dataset that is searched. EMPTY_ is prefixed to the dataset name.
You should just fix the %SLENGTH() macro.
%MACRO SLENGTH(dset, name_list);
if 1=2 then set EMPTY_&dset(keep=&name_list);
%MEND SLENGTH;
I found out that variable lengths were set in an Excel file and used by the program. So I found it cleaner to just update the Excel and it worked!
Join us for SAS Innovate 2025, our biggest and most exciting global event of the year, in Orlando, FL, from May 6-9. Sign up by March 14 for just $795.
SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.
Find more tutorials on the SAS Users YouTube channel.