Download resize.sasSubmit a comment

%macro resize (data=, out=);

  %* Author: Richard DeVenezia
  %* Resize a dataset by minimizing the length of each character column.
  %* Minimal length is defined as the shortest length that does not
  %* lose any data in a column.  Note: After minimizing, some columns
  %* might be too short to store new values when editing or adding rows.
  %* data - data set to resize
  %* out - output data set
  %* mod:
  %* 11/17/98 rad initial coding

  %if (%superq(DATA)= or %superQ(OUT)=) %then %do;
    %put You must specify both data= and out=;
    %goto ByeBye;

  proc contents noprint data=&DATA out=_contnt_(index=(varnum));

  %local dsid nvars rc needed;

  %let dsid=%sysfunc(open(_contnt_));
  %if &dsid %then %do;
    %let nvars=%sysfunc(attrn(&dsid,NOBS));
    %let rc=%sysfunc(close(&dsid));
  %else %goto ByeBye;

  %local zero;
  %do i=1 %to &nvars;
    %local var&i typ&i len&i mln&i;

  data _null_;
    set _contnt_;
    call symput ('var'||left(_n_), name);
    if type=2
      then call symput ('typ'||left(_n_), '$');
      else call symput ('typ'||left(_n_), ' ');
    call symput ('len'||left(_n_), length);

  proc sql noprint;
    drop table _contnt_;

    %do i=1 %to &nvars;
      %if &&typ&i=$ %then ,max(length(&&var&i)) ;
    %do i=1 %to &nvars;
      %if &&typ&i=$ %then ,:mln&i ;
    from &DATA

  %let needed = 0;
  %do i = 1 %to &nvars;
    %if &&typ&i=$ %then
      %let needed = %eval (&needed OR (&&mln&i < &&len&i));

  %if (%superq(data) ne %superq(out)) or &needed %then %do;

    %if not &needed %then
      %put NOTE: There is nothing to resize, but OUT is different than DATA;

    data &OUT;
      retain %do i=1 %to &nvars; &&var&i %end;;
      length %do i=1 %to &nvars;
                %if &&typ&i=$ %then &&var&i $ &&mln&i ;
      set &DATA;

  %else %do;
    %put NOTE: OUT is same as DATA (&data) and DATA has no slack, resize not done.;


%mend resize;

%resize (data=sashelp.class, out=work.class)
%resize (data=work.class, out=work.class)
%resize (data=work.class, out=work.class2)