BookmarkSubscribeRSS Feed
Frank_sas
SAS Employee

Users would like to know how to create an inventory of Repository objects (folders and files) in SDD 3.x.

A basic way to create an inventory of SDD hierarchy objects is to use the SASDrugDev_getObjects remote API macro, as in the following example. We do not recommend that you use this example, except when you are building an inventory for a few hundred objects.

%*******************************************************************************

%* _SDDDAV_ is an automatic global macro variable that contains information

%*    about the current SDD instance

%* by replacing "/webdav" in _&SDDDAV_ with "/remote" we can create _SDDREMOTE_,

%*    which contains instance-independent information so that this program is

%*    portable between SDD instances

%******************************************************************************;

data _null_;

   call symput('_sddremote_'            
              ,strip(tranwrd("&_sdddav_",'/webdav','/sddremote'))

              );   

run;

%sasDrugDev_logIn(url=%str(&_sddremote_)               
                 ,sdduserid=%str(&_sddusr_)
               
                 ,sddpassword=%nrbquote(&_sddpw_)

                 );

%*******************************************************************************

%* the recursiveLevel parameter controls whether the getObjects macro retrieves

%*    data about the sub-folders and their objects

%*       0 - (default)only get data about the folder designated by SDDPath

%*       1 - only get data about the folder designated by SDDPath and its

%*             contents

%*       2 - get data about the folder designated by SDDPath and its contents

%*           and about all its sub-folders and their contents and about all

%*           their sub-folders and their contents, etc.

%******************************************************************************;

%sasDrugDev_getObjects(SDDPath=/SDD/Testing Area/frroed                     
                      ,recursiveLevel=2
                    
                      );

%sasDrugDev_logOut;

This code example is also available as the attachment, getObjects_Example1.sas.

One of the problems with the example above is that it uses recursiveLevel=2.  If you point SDDPath to the root folder of a very large repository, your request will consume a large amount of SDD resources and have a significant negative impact on all other SDD users.


The following example illustrates a better approach when you have a large number of folders to inventory.  The maxLevel macro variable is an SDD parameter that controls how many directory levels beneath the root folder will be included in the inventory.  You can run this program repeatedly, varying the values for rootPath and maxLevel, until you have covered the area of the SDD repository that you want to inventory.

%*******************************************************************************

%* maxLevel:  the number of levels beyond rootPath that will be inventoried

%* stopLevel: the deepest hierarchy level that will be inventoried

%******************************************************************************;

data _null_;

   stopLevel=countc("&rootPath",'/')

            +&maxLevel;

   call symput('stopLevel',strip(put(stopLevel,3.)));

run;

  

%*******************************************************************************

%* make sure that the WORK data sets that will be appended to are deleted

%******************************************************************************;

proc datasets library=work nolist nowarn;

   delete allObjects;

   delete folders;

quit;

%*******************************************************************************

%* _SDDDAV_ is an automatic global macro variable that contains information

%*    about the current SDD instance

%* by replacing "/webdav" in _&SDDDAV_ with "/remote" we can create _SDDREMOTE_,

%*    which contains instance-independent information so that this program is

%*    portable between SDD instances

%******************************************************************************;

data _null_;

   call symput('_sddremote_'

              ,strip(tranwrd("&_sdddav_",'/webdav','/sddremote'))

              );   

run;

%sasDrugDev_logIn(url=%str(&_sddremote_)

                 ,sdduserid=%str(&_sddusr_)            
                 ,sddpassword=%nrbquote(&_sddpw_)

                                );

%*******************************************************************************

%* the recursiveLevel parameter controls whether the getObjects macro retrieves

%*    data about the sub-folders and their objects

%*       0 - (default) only get data about the folder designated by SDDPath

%*       1 - only get data about the folder designated by SDDPath and its

%*             contents

%*       2 - get data about the folder designated by SDDPath and its contents

%*           and about all its sub-folders and their contents and about all

%*           their sub-folders and their contents, etc.

%******************************************************************************;

%sasDrugDev_getObjects(sddPath=&rootPath

                      ,recursiveLevel=1
                      );

%*******************************************************************************

%* the allObjects data set contains the inventory of all the objects in the

%*    rootPath and all its sub-folders

%******************************************************************************;

proc append base=allObjects

            data=_getObjects_;

run;

%*******************************************************************************

%* the folders data set contains a list of all the folders that are no deeper

%*    than maxLevel and have not been inventoried yet

%* NOTE: stopLevel is the deepest hierarchy level to be inventoried

%******************************************************************************;

proc append base=folders

            data=_getObjects_

               (where=(fullPathName ne "&rootPath"           and

                       type         eq 'folder'              and

                       countc(fullPathName,'/') le &stopLevel

                      )

               );

run;                                                       

%*******************************************************************************

%* assign a value to the folderCnt macro variable, initializing to zero in case

%*    the folder data set is empty

%******************************************************************************;

%let folderCnt=0;

data _null_;

   call symput('folderCnt',strip(put(nobs,5.)));

   stop;

   set folders nobs=nobs;

run;

%macro getContents; 

 
   %****************************************************************************

   %* perform this loop while there are folders that have not been inventoried
   %***************************************************************************;

   %do %while (&folderCnt gt 0);    
      %*************************************************************************

      %* select the first remaining folder as the next one to inventory

      %************************************************************************;

      data folders;

         set folders;

         if _n_ eq 1 then do;

            call symput('folderPath',strip(fullPathName));

            return;

         end;

         else

            output;

      run;

    
      %sasDrugDev_getObjects(sddPath=&folderPath

                            ,recursiveLevel=1

                            );     

    
      %*************************************************************************

      %* append the folders inventory to the overall inventory

      %************************************************************************;

      proc append base=allObjects

                  data=_getObjects_

                     (where=(fullPathName ne "&folderPath"

                            )

                     );

      run;

    
      %*************************************************************************

      %* append any sub-folders to the list of folders that need to be

      %*    inventoried

      %************************************************************************;

      proc append base=folders

                  data=_getObjects_

                     (where=(fullPathName ne "&folderPath"          and

                             type         eq 'folder'               and

                             countc(fullPathName,'/') le &stopLevel

                            )

                                               );

      run;

    
      %*************************************************************************

      %* update the value of folderCnt so that it reflects the number of folders

      %*    that still have to be inventoried

                    %************************************************************************;

      %let folderCnt=0;

      data _null_;

         call symput('folderCnt',strip(put(nobs,5.)));

         stop;

         set folders nobs=nobs;

      run;

   %end;                

%mend getContents;

%getContents; 

       

%sasDrugDev_logOut;

This code example is also available as the attachment, getObjects_Example2.sas.

This is how we usually solve this challenge. Do you use this same approach or a different one?

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

New Learning Events in April

 

Join us for two new fee-based courses: Administrative Healthcare Data and SAS via Live Web Monday-Thursday, April 24-27 from 1:00 to 4:30 PM ET each day. And Administrative Healthcare Data and SAS: Hands-On Programming Workshop via Live Web on Friday, April 28 from 9:00 AM to 5:00 PM ET.

LEARN MORE

Discussion stats
  • 0 replies
  • 813 views
  • 0 likes
  • 1 in conversation