
/* unifyvarscasesize.sas */

/*** HELP START ***//*
 
## >>> `%unifyVarsCaseSize()` macro: <<< <a name="unifyvarscasesize-macro"></a> #######################  

The `%unifyVarsCaseSize()` macro converts *all* variables names into low-case or
upcase letters for given library and list of datasets. Only necessary conversion is
done, i.e., variable `abc` will not be converted to low-case letters. 

See examples below for the details.

The `%unifyVarsCaseSize()` macro works as pure macro code.

[NOTE:] The macro internally uses the `%expandDataSetsList()` macro.

### SYNTAX: ###################################################################

The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%unifyVarsCaseSize(
    lib
   ,ds
  <,case=>
  <,debug=>
)
~~~~~~~~~~~~~~~~~~~~~~~

**Arguments description**:

1. `lib`              - *Required*, is a name of a library
                         where data sets are looked-up.  

2. `ds`               - *Required*, is a list of data sets 
                         to be expanded. Can be named list (e.g. `x_:`),
                         can be enumerated list (e.g. `y_1-y_5`), or both.
                         Also the `_ALL_` value is accepted. 

*. `case`             - *Optional*, single letter indicator (default `L` means "low-case").
                         Tells if variables names should low-cased (`l`,`L`) or upcased ("u", "U"). 

*. `debug`            - *Optional*, binary indicator (default `0` means "no").
                         Tells if processing notes should be printed. 
---

*//*** HELP END ***/

%macro unifyVarsCaseSize(
 lib
,ds
,case=L /* L U */
,debug=0
) / minoperator;
%LOCAL rc optionsList prefix;
%let prefix=_%sysfunc(datetime(),b8601dt15.)_;
%let debug = %sysevalf(NOT(0=%superq(debug)),boolean);
%if 1=&debug. %then %let optionsList=notes source mprint fullstimer; 
%else %let optionsList=nonotes nosource nostimer nofullstimer nomprint nomlogic nosymbolgen;

%if %superq(lib)= OR %superq(ds)= %then 
  %do;
    %put WARNING: Provide correct (non-empty) values for LIB and DS parameters.;
  %end;
%else 
%if 0=%sysfunc(LIBREF(&lib.)) %then
  %do;
    %if %superq(case) IN (u U) %then
        %let case=UPCASE;
    %else
        %let case=lowcase;
 
    %let rc = %sysfunc(doSubL(%nrstr(
      %unquote(options &optionsList.;)
      %put %sysfunc(ifc(1=&debug.,%unquote(%expandDataSetsList(lib=&lib.
                                          ,datasets=&ds.
                                          ,quote=1, views=0)),));

      proc contents DATA=&lib.._ALL_ NOPRINT
        out=work.&prefix.Variables(
          keep=memname name
          where=(
            name NE &case.(name)
            and memname in (
              %unquote(%expandDataSetsList(lib=&lib.
                                          ,datasets=&ds.
                                          ,quote=1, views=0)) )
          )
        )
        ;
      run;
      proc sort data=&prefix.Variables;
        by memname name;
      run;
      data _null_;
        if 0=NOBS then stop;
        set work.&prefix.Variables end=_E_ nobs=NOBS;
        by memname;
          if 1=_N_ then call execute("PROC DATASETS LIB=&lib. NOLIST NOWARN;");
          if first.memname then call execute("MODIFY " !! strip(memname) !! "; RENAME");
          call execute( strip(name) !! " = " !! strip(&case.(name)) );
          if last.memname then call execute("; RUN;");
          if _E_ then call execute("QUIT;");
      run;
      proc delete data=work.&prefix.Variables;
      run;
    )));
  %end;
%else 
  %do;
    %put WARNING: Library %superq(LIB) does NOT exist.;
  %end;
%mend unifyVarsCaseSize;





/*** HELP START ***//*
 
### EXAMPLES AND USECASES: ####################################################

**EXAMPLE 0.** Create data sets for tests:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data aclass1 aclass2 aclass3 bclass4 bclass5 bclass6;
  set sashelp.class(obs=6);
  Nn=_N_;
  if 1=_N_ then output aclass1;
  if 2=_N_ then output aclass2;
  if 3=_N_ then output aclass3;
  if 4=_N_ then output bclass4;
  if 5=_N_ then output bclass5;
  if 6=_N_ then output bclass6;
run;
proc print data=aclass1;
run;
proc print data=bclass6;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 1.** Convert all variables names to low-case:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%unifyVarsCaseSize(work,aclass:)

proc print data=aclass1;
proc print data=aclass2;
proc print data=aclass3;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 2.** Convert all variables names to upcase:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%unifyVarsCaseSize(work,bclass4-bclass6,case=U) 

proc print data=bclass4;
proc print data=bclass5;
proc print data=bclass6;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 3.** No conversion done:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data work.abc;
  abc=42;
run;

%unifyVarsCaseSize(work,abc,debug=1)

proc print data=abc;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 4.** Variables in all data sets in `WORK` converted to upcase:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%unifyVarsCaseSize(work,_ALL_,case=L) 
%unifyVarsCaseSize(work,_ALL_,case=U) 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---

*//*** HELP END ***/



/**###################################################################**/
/*                                                                     */
/*  Copyright Bartosz Jablonski, since 2024.                           */
/*                                                                     */
/*  Code is under the MIT license. If you want - you can use it.       */
/*  But it comes with absolutely no warranty whatsoever.               */
/*  If you cause any damage or something - it will be your own fault.  */
/*  You've been warned! You are using it on your own risk.             */
/*  However, if you decide to use it don't forget to mention author.   */
/*  Bartosz Jablonski (yabwon@gmail.com)                               */
/*                                                                     */
/**###################################################################**/


/*
%unifyVarsCaseSize(,) 
%unifyVarsCaseSize(work,)
%unifyVarsCaseSize(,xxx)
%unifyVarsCaseSize(dupa,xxx)
*/
