
/* expanddatasetslist.sas */

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

The `%expandDataSetsList()` macro is dedicated to "lazy typers".

It allows to expand data set names provides in form of a SAS list for a given library.

See examples below for the details.

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

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

The basic syntax is the following, the `<...>` means optional parameters:
~~~~~~~~~~~~~~~~~~~~~~~sas
%expandDataSetsList(
    lib
   ,datasets
  <,quote=>
  <,views=>
)
~~~~~~~~~~~~~~~~~~~~~~~

**Arguments description**:

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

2. `datasets`         - *Required*, is a list of data sets or views 
                         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. 

*. `quote`            - *Optional*, binary indicator (default `0` means "no").
                         Tells if data set names should be quoted. 

*. `views`            - *Optional*, binary indicator (default `1` means "yes").
                         Tells if views names should be listed too. 

---

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


%macro expandDataSetsList(lib, datasets, quote=0, views=1);
%LOCAL rc optionsList prefix type;
%let quote = %sysevalf(NOT(0=%superq(quote)),boolean);
%let prefix=_%sysfunc(datetime(),b8601dt15.)_;
%let optionsList=nonotes nosource nostimer nofullstimer nomprint nomlogic nosymbolgen;
%LOCAL &prefix.DataSetsListN;
%let views = %sysevalf((1=%superq(views)),boolean);
%if &views. %then %let type="DATA" "VIEW";
            %else %let type="DATA";
%let rc = %sysfunc(doSubL(%str(
  options &optionsList.;
  proc sql noprint;
    create table work.&prefix.tmp as
    select memname
    from dictionary.tables
    where libname=%upcase("&lib.")
    and memtype in ( %upcase(&type.) )
    ;
  quit;
  proc transpose 
      data=work.&prefix.tmp 
      out=work.&prefix.tmp2(drop=_NAME_ _LABEL_);
    var memname;
    id memname;
  run;
  data work.&prefix.tmp;
    array _character_[*] $ 41 _null_ &datasets.;
  run;
  data work.&prefix.listOfDataSets;
    set work.&prefix.tmp(obs=1);
    set work.&prefix.tmp2(obs=1);
  run; 
  proc transpose 
      data=work.&prefix.listOfDataSets(obs=1) 
      out=work.&prefix.tmp3(keep=_name_ col1 
          where=(col1 is not null)
          );
    var &datasets.;
  run;
  data _null_;
    call symputX("&prefix.DataSetsListN",NOBS,"L");
    stop;
    set &prefix.tmp3 nobs=NOBS;
  run;
)));
%do rc = 1 %to &&&prefix.DataSetsListN;
  %LOCAL &prefix.DataSetsList&rc.;
%end;
%let rc = %sysfunc(doSubL(%str(
  options &optionsList.;
  data _null_;
    if not NOBS then stop;
    set &prefix.tmp3 nobs=NOBS;
    call symputX(cats("&prefix.DataSetsList",_N_)
                ,ifc( &quote.=1, quote(upcase(strip(_name_))), upcase(_name_)) 
                ,"L");
  run;
  proc delete data =
    work.&prefix.tmp work.&prefix.tmp2
    work.&prefix.listOfDataSets
    work.&prefix.tmp3;
  quit;
)));
%do rc = 1 %to &&&prefix.DataSetsListN;
&&&prefix.DataSetsList&rc.
%end;
/*%put _local_;*/
%mend expandDataSetsList;



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

**EXAMPLE 0.** Create data sets for tests:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data x_a x_b x_c x_d x_e x_f;
  x=17;
run;
data y1 y2 y3 y4 y9 y10 y11 y12; 
  y=42;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 1.** Display names of listed datasets, handle not existing too:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 y9)#;

%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 notExist_1-notExist_10)#;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 2.** Display one and all datasets from `WORK`, names quoted:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%PUT %expandDataSetsList(lib=work,datasets=_ALL_, quote=1);

%PUT %expandDataSetsList(lib=work,datasets=x_a, quote=1);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 3.** In tandem with the `resolve()` function:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
data _null_;
  test=resolve('%expandDataSetsList(lib=work,datasets=x_:, quote=1)');
  put test / test hex72.;
run;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 4.** Workaround for `proc delete` not working with colon operator,
               observe a warning info for `x_:` list:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
proc delete lib=work data=%expandDataSetsList(lib=work,datasets=x_:)
;
run;

%PUT #%expandDataSetsList(lib=work,datasets=x_: y1-y4 y9)#;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


**EXAMPLE 5.** Including and excluding views:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~sas
%PUT %expandDataSetsList(lib=sashelp,datasets=_ALL_);

%PUT %expandDataSetsList(lib=sashelp,datasets=_ALL_,views=0);
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

---

*//*** 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)                               */
/*                                                                     */
/**###################################################################**/


/*
%PUT #%expandDataSetsList(lib=,datasets=)#;

%PUT #%expandDataSetsList(lib=work,datasets=)#;
*/
