<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: The fastest/efficient way to check sas7bdat files damage? in SAS Procedures</title>
    <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872158#M82672</link>
    <description>&lt;P&gt;First modify data step to name libraries with unique name:&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    do;
      lib+1;
      call execute(catx(" ","libname t"!!strip(put(lib,best.)),quote(catx("/",root,dname)), ";"));
    end;

  call execute( 'data _null_;' );
  call execute( 'do ___point=1,ceil(___nobs/2),___nobs;' );
  call execute( 'set t' !! strip(put(lib,best.)) !! '.' !! strip(scan(fn,1,".")) !! ' nobs=___nobs point=___point;');
  call execute( 'end;stop;' );
  call execute( 'run;' );

  if last.dname then
    call execute("libname t" !! strip(put(lib,best.)) !! " clear;");
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;so for every directory you will get unique library name string to search for.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And then search for the name:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  infile _T_;
  problematic_lib="T2"; /* &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; */

  input;
  IF _INFILE_ =: "NOTE: Libref " !! upcase(problematic_lib) !! " was successfully" then
    do;
      PUT _N_=;
      put _INFILE_ ;
      input;
      input;
      put _INFILE_ / /;
    end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
    <pubDate>Wed, 26 Apr 2023 08:15:38 GMT</pubDate>
    <dc:creator>yabwon</dc:creator>
    <dc:date>2023-04-26T08:15:38Z</dc:date>
    <item>
      <title>The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/871958#M82661</link>
      <description>&lt;P&gt;Hi all,&lt;/P&gt;
&lt;P&gt;We have 10tb+ of 10k+ sas7bdat files in a complex folder structure. What would be the fastest and most efficient way to check all of them for file damage (not repair), say due to download/transfer problems, corrupted sectors and what not?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A&lt;/P&gt;</description>
      <pubDate>Tue, 25 Apr 2023 18:04:24 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/871958#M82661</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-25T18:04:24Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/871989#M82662</link>
      <description>&lt;P&gt;Perhaps use a macro or some other file crawler to find them all, then run a job where you read each dataset in its own data _NULL_ step.&amp;nbsp; That will force SAS to iterate through all the data.&amp;nbsp; And the log&amp;nbsp; should should show any errors for failing to read corrupted data.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;That said, I don't have much experiences with corrupted SAS datasets (happily).&amp;nbsp; It might be overkill to read through every record of every dataset. But if you pass that test, I think it would be good evidence that your datasets are ok.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Apr 2023 19:30:10 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/871989#M82662</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2023-04-25T19:30:10Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872006#M82663</link>
      <description>&lt;P&gt;Use &lt;CODE class=" language-sas"&gt;dirsAndFiles &lt;/CODE&gt;macro basePlus package, documentation is here: &lt;A href="https://github.com/SASPAC/baseplus/blob/main/baseplus.md#dirsandfiles-macro" target="_blank"&gt;https://github.com/SASPAC/baseplus/blob/main/baseplus.md#dirsandfiles-macro&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;To install BasePlus use SAS Package Framework:&amp;nbsp;&lt;A href="https://github.com/yabwon/SAS_PACKAGES" target="_blank"&gt;https://github.com/yabwon/SAS_PACKAGES&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Do the testing like this:&lt;/P&gt;
&lt;P&gt;*) first 3 lines = enapbe SPF (temporary setup)&lt;/P&gt;
&lt;P&gt;*) next 2 lines = install basePlus and and load only &lt;CODE class=" language-sas"&gt;dirsAndFiles &lt;/CODE&gt;macro&lt;/P&gt;
&lt;P&gt;*) call to the macro will create&amp;nbsp;&lt;CODE class=" language-sas"&gt;WORK.SASDatasets&lt;/CODE&gt; dataset containing all sas dataset in&amp;nbsp;&lt;CODE class=" language-sas"&gt;/path/to/your/data/&lt;/CODE&gt; path&lt;/P&gt;
&lt;P&gt;*) create temporary file for log and start logging into _T_&lt;/P&gt;
&lt;P&gt;*) turn off some options&lt;/P&gt;
&lt;P&gt;*) for each observation from&amp;nbsp;&lt;CODE class=" language-sas"&gt;WORK.SASDatasets&lt;/CODE&gt; set run call execute which will run small data set which tries to open sas dataset&lt;/P&gt;
&lt;P&gt;*) turn off logging into _T_&lt;/P&gt;
&lt;P&gt;*) read _T_ for errors&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;filename packages "%sysfunc(pathname(work))"; /* setup WORK as temporary directory for packages */
filename SPFinit url "https://raw.githubusercontent.com/yabwon/SAS_PACKAGES/main/SPF/SPFinit.sas";
%include SPFinit; /* enable the framework */

%installPackage(BasePlus) /* install package */
%loadPackage(BasePlus, cherryPick=dirsAndFiles) 


%dirsAndFiles(
  /path/to/your/data/
,ODS=WORK.SASDatasets
,details=0
,keepDirs=0
,keepFiles=1
,longFormat=1
,fileExt=sas7bdat
)


filename _T_ TEMP;
proc printto log =_T_;
run;

options NOFMTERR NOSOURCE NOSTIMER; /* !!! */

data _null_;
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    call execute(catx(" ","libname test",quote(catx("/",root,dname)), ";"));

  call execute( 'data _null_;' );
  call execute( 'do ___point=1,ceil(___nobs/2),___nobs;' );
  call execute( 'set test.' !! strip(scan(fn,1,".")) !! ' nobs=___nobs point=___point;');
  call execute( 'end;stop;' );
  call execute( 'run;' );

  if last.dname then
    call execute("libname test clear;");

run;

proc printto;
run;
data _null_;
run;
 
data _null_;
  infile _T_;
  input;
  IF _INFILE_ =: "ERROR:" then
    do;
      PUT _N_=;
      put _INFILE_ /;
    end;
run;

/*
  filename _T_ clear;
*/&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Tue, 25 Apr 2023 20:12:05 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872006#M82663</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-04-25T20:12:05Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872071#M82669</link>
      <description>&lt;P&gt;Wow, thank you very much! Had that repo starred but didn't install it. Let me try this approach.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Apr 2023 23:53:20 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872071#M82669</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-25T23:53:20Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872072#M82670</link>
      <description>&lt;P&gt;Thank you! The _NULL_ part makes complete sense.&lt;/P&gt;</description>
      <pubDate>Tue, 25 Apr 2023 23:53:48 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872072#M82670</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-25T23:53:48Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872085#M82671</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Code works great! One detail though, could it be possible to output the folder or the path where the file is located?&lt;/P&gt;
&lt;P&gt;I get this output&lt;/P&gt;
&lt;PRE&gt;_N_=8159
ERROR: File TEST.NYAM_QT1983.DATA is damaged. I/O processing did not complete.&lt;/PRE&gt;
&lt;P&gt;But there are several folders with the same filename so it's hard to know which file exactly is damaged.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you!&lt;/P&gt;</description>
      <pubDate>Wed, 26 Apr 2023 01:53:02 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872085#M82671</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-26T01:53:02Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872158#M82672</link>
      <description>&lt;P&gt;First modify data step to name libraries with unique name:&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    do;
      lib+1;
      call execute(catx(" ","libname t"!!strip(put(lib,best.)),quote(catx("/",root,dname)), ";"));
    end;

  call execute( 'data _null_;' );
  call execute( 'do ___point=1,ceil(___nobs/2),___nobs;' );
  call execute( 'set t' !! strip(put(lib,best.)) !! '.' !! strip(scan(fn,1,".")) !! ' nobs=___nobs point=___point;');
  call execute( 'end;stop;' );
  call execute( 'run;' );

  if last.dname then
    call execute("libname t" !! strip(put(lib,best.)) !! " clear;");
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;so for every directory you will get unique library name string to search for.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;And then search for the name:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  infile _T_;
  problematic_lib="T2"; /* &amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt;&amp;lt; */

  input;
  IF _INFILE_ =: "NOTE: Libref " !! upcase(problematic_lib) !! " was successfully" then
    do;
      PUT _N_=;
      put _INFILE_ ;
      input;
      input;
      put _INFILE_ / /;
    end;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Wed, 26 Apr 2023 08:15:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872158#M82672</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-04-26T08:15:38Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872159#M82673</link>
      <description>&lt;P&gt;Or even faster, without scanning log file:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data libraries( where = (library in ("T2" "T5")) );
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    do;
      lib+1;
      library = cats("T",lib);
      length path $ 2048;
      path = catx("/",root,dname);
      output;
    end;
  keep library path;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Wed, 26 Apr 2023 08:21:51 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872159#M82673</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-04-26T08:21:51Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872215#M82674</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
You could try REPAIR statement in PROC DATASETS.
If there were some datasets corrupted ,you will find ERROR in log.
P.S. assuming you are using Windows and could run OS command by sas.
*/

%let path= c:\temp  ;


options validvarname=any validmemname=extend;
filename x pipe %sysfunc(quote(dir "&amp;amp;path.\*.sas7bdat" /s /b));
data path;
infile x length=len;
input path $varying200. len;
lib=prxchange('s/[^\\]+$//',1,strip(path));
dsn=scan(path,-2,' .\');
run;
data _null_;
 set path;
 by lib notsorted;
 if first.lib then call execute(catt('libname x v9 "',lib,'";%put NOTE:path=',lib,
 ';proc datasets library=x nolist nodetails memtype=data;repair '));
 call execute(dsn);
 if last.lib then call execute(';quit;libname x clear;');
run;;
&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 26 Apr 2023 11:48:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872215#M82674</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-04-26T11:48:47Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872416#M82675</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;By the way,&amp;nbsp; I wanted to say thank you for your efforts in developing the SAS packages framework! This should be recognized by SAS at the highest level.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;About the list, I have 100s of files incomplete in what it seems 10s of different paths/libs with about 2 to 5 levels. Would it be possible for an error output to be like a list:?&lt;/P&gt;
&lt;P&gt;z:\dir a\dir 1\ dir cc\xyz123.bdat&lt;/P&gt;
&lt;P&gt;z:\dir f\dir 22\ dir dd\abc123.bdat&lt;/P&gt;
&lt;P&gt;.....&lt;/P&gt;
&lt;P&gt;This way i don't have to manually look for libs with the problematic files.&lt;/P&gt;
&lt;P&gt;It also seems the errors are different some are not sas7bdat files at all and some are incomplete. Your original code by the way is very fast given the amount of data it looks at. It definitely doesn't read all of the files completely but can still identify problems.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you very much!&lt;/P&gt;</description>
      <pubDate>Wed, 26 Apr 2023 23:56:56 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872416#M82675</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-26T23:56:56Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872418#M82676</link>
      <description>&lt;P&gt;Hi KSharp,&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Thank you! Is there a way to make it identify the problems and &lt;U&gt;not&lt;/U&gt; try to repair the dataset? I am not familiar with this proc function. In case there is an error, we will just redownload the file. We definitely don't want to repair them or alter them in any way at this stage.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Is there a way to change the 2nd block with proc datasets to make it just test the file without repairing?&lt;/P&gt;</description>
      <pubDate>Thu, 27 Apr 2023 00:04:53 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872418#M82676</guid>
      <dc:creator>astrae_research</dc:creator>
      <dc:date>2023-04-27T00:04:53Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872446#M82677</link>
      <description>&lt;P&gt;Thanks for kind words, it's nice to hear that SPF is of value to someone &lt;span class="lia-unicode-emoji" title=":slightly_smiling_face:"&gt;🙂&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Lets back to the subject, try this (adjust paths for packages and search path):&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;filename packages "C:\SAS_WORK\SAS_PACKAGES"; /* directory for packages */
%include packages(SPFinit.sas);

%loadPackage(BasePlus, cherryPick=dirsAndFiles) 


%dirsAndFiles(
  C:\SAS_WORK /*/path/to/your/data/ */
,ODS=WORK.SASDatasets
,details=0
,keepDirs=0
,keepFiles=1
,longFormat=1
,fileExt=sas7bdat
)


filename _T_ TEMP;
proc printto log =_T_;
run;

options NOFMTERR NOSOURCE NOSTIMER LS=MAX PS=MAX; /* !!! */

data _null_;
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    do;
      lib+1;
      call execute(catx(" ","libname t"!!strip(put(lib,best.)),quote(catx("/",root,dname)), ";"));
    end;

  call execute( 'data _null_;' );
  call execute( 'do ___point=1,ceil(___nobs/2),___nobs;' );
  call execute( 'set t' !! strip(put(lib,best.)) !! '.' !! strip(scan(fn,1,".")) !! ' nobs=___nobs point=___point;');
  call execute( 'end;stop;' );
  call execute( 'run;' );

  if last.dname then
    call execute("libname t" !! strip(put(lib,best.)) !! " clear;");
run;

proc printto;
run;

options FMTERR SOURCE STIMER;
data _null_;
run;
 
data ListOfErrors(where=(ErrTXT like '%.DATA%'));
  infile _T_;
  input;
  length ErrTXT $ 256;
  IF _INFILE_ =: "ERROR:" then
    do;
      put _N_ @10 "&amp;gt;&amp;gt;&amp;gt;" _INFILE_ /;
      n = _N_;
      ErrTXT = _infile_;
      output;
    end;
run;

data libraries (compress=char);
  set WORK.SASDatasets;
  by dname notsorted;

  if first.dname then
    do;
      lib+1;
      length library $ 8 path $ 2048;
      library = cats("T",lib);
      path = catx("/",root,dname);
      output;
    end;
  keep library path;
run;
proc sort data=libraries;
  by library;
run;


data listOfBrokenData;
  set ListOfErrors;
  p = PRXMATCH('/T(\d+)\.([1-9A-Z_]+)\.DATA/', ErrTXT);
  length library $ 8 ds $ 51;
  ds = scan(substr(ErrTXT,p),1," ");
  library = scan(ds,1,".");
  ds      = lowcase(scan(ds,2,".")!!'.sas7bdat');
  keep library ds;
run;
proc sort data=listOfBrokenData nodupkey;
  by library ds;
run;

data listOfBrokenData;
  merge listOfBrokenData(in=in) libraries;
  by library;
  if in;
  path=catx('/',path,ds);
run;
proc sort data=listOfBrokenData sortseq=linguistic(numeric_colation=on);
  by library ds;
run;
proc print;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Bart&lt;/P&gt;</description>
      <pubDate>Thu, 27 Apr 2023 06:38:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872446#M82677</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-04-27T06:38:26Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872532#M82678</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/120002"&gt;@astrae_research&lt;/a&gt;&amp;nbsp;Below some code that will list all SAS tables (.sas7bdat files) that SAS couldn't open successfully.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The os dir command will return all existing .sas7bdat files under &amp;amp;root_path recursively (I'd be using the find command for Linux).&lt;/P&gt;
&lt;P&gt;The SAS open() function will then attempt to open these files.&lt;/P&gt;
&lt;P&gt;I've opened as SAS file with a text editor and just deleted a few bytes. That's the one which gets captured in below example.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let root_path=c:\temp;
filename filelist pipe "dir /B/S &amp;amp;root_path.\*.sas7bdat";
data work.failed_SASTable_open;
  length pathAndSASFile $1000 msg $256;
  keep pathAndSASFile msg;

  infile filelist truncover;
  input pathAndSASFile $1000.;
  _did=open(strip(pathAndSASFile),,,'f');
  if _did =0 then 
    do;
      msg=sysmsg();
      output;
    end;
  else
    do;
      _rc=close(_did);
    end;
run;
filename filelist clear;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="Patrick_0-1682594983534.png" style="width: 684px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/83322iC50FD57D319A21B9/image-dimensions/684x67?v=v2" width="684" height="67" role="button" title="Patrick_0-1682594983534.png" alt="Patrick_0-1682594983534.png" /&gt;&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;Given your use case you can of course enhance above to only include files create after some date. The basic idea is to create a list of *.sas7bdat files where you store the full path and filename including the suffix and then use the SAS open() function with the f parameter to test if you can open the file.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;A different approach would be to create a hash (checksum) of your files in source, use the same algorithm in target to also create a hash and then compare the two.&lt;BR /&gt;If you're moving data from a recent SAS version in source then you could use SAS function&amp;nbsp;&lt;A href="https://documentation.sas.com/doc/en/pgmsascdc/9.4_3.5/lefunctionsref/n0n1i6477d9a9in1lflbgj24dx5f.htm" target="_self"&gt;HASHING_FILE()&lt;/A&gt; - else you would need some other tool for this.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Apr 2023 21:59:38 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872532#M82678</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-04-27T21:59:38Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872540#M82679</link>
      <description>&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;/*
You also could try copy dataset.
If it was corrupted,you would see an error info in log.
*/

%let path= c:\temp  ;


options validvarname=any validmemname=extend nofmterr ;
filename x pipe %sysfunc(quote(dir "&amp;amp;path.\*.sas7bdat" /s /b));
data _null_;
infile x length=len;
input path $varying200. len;
call execute(catt("options obs=1;data x;set '",path,"';run;"));
run;

options obs=max;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Thu, 27 Apr 2023 11:51:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872540#M82679</guid>
      <dc:creator>Ksharp</dc:creator>
      <dc:date>2023-04-27T11:51:08Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872550#M82680</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/12447"&gt;@Patrick&lt;/a&gt;&amp;nbsp;Great idea!! I wish I came up with&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="sas"&gt;_did=open(strip(pathAndSASFile),,,'f');&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;myself. Definitely more elegant than my "log scanning". [jealous face emoji] &lt;span class="lia-unicode-emoji" title=":winking_face:"&gt;😉&lt;/span&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;One thing I would add is that I would wrapped it up inside DuSubL() function, so all that temporary "WC000000XXX" libraries, created when open() function works, won't be assigned in the main session:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;filename packages "C:\SAS_WORK\SAS_PACKAGES"; /* directory for packages */
%include packages(SPFinit.sas);

%loadPackage(BasePlus, cherryPick=dirsAndFiles) 

%dirsAndFiles(
  C:\SAS_WORK /*/path/to/your/data/ */
,ODS=WORK.SASDatasets
,details=0
,keepDirs=0
,keepFiles=1
,longFormat=1
,fileExt=sas7bdat
)

data _null_;
rc= DoSubL("
filename _T_ DUMMY;
proc printto log =_T_;
run;

data work.failed_SASTable_open;

  set WORK.SASDatasets;
  length pathAndSASFile $ 2048;
  pathAndSASFile = catx('/',root,dname,fn);

  _did=open(strip(pathAndSASFile),,,'f');
  if _did =0 then 
    do;
      msg=sysmsg();
      output;
    end;
  else
    do;
      _rc=close(_did);
    end;
  keep pathAndSASFile msg;
run;

proc printto;
run;
");
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Bart&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;P.S.&amp;nbsp;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/10892"&gt;@PaigeMiller&lt;/a&gt;&amp;nbsp;- maybe you will like this "practical" use of DoSubL().&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Apr 2023 12:23:09 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872550#M82680</guid>
      <dc:creator>yabwon</dc:creator>
      <dc:date>2023-04-27T12:23:09Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872555#M82681</link>
      <description>&lt;P&gt;&lt;a href="https://communities.sas.com/t5/user/viewprofilepage/user-id/35763"&gt;@yabwon&lt;/a&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Hi Bart,&lt;/P&gt;
&lt;P&gt;I wasn't even aware that the open() function creates all these libraries in the background and I'm a bit disappointed that the close() function doesn't clean them up.&lt;/P&gt;
&lt;P&gt;I've done a test with a pre-existing wc000012 library and SAS recognized that there was already such a pre-existing libref and didn't overwrite it but just jumped to the next available number.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I consider using dosubl() makes the code unnecessarily complicated for this use case. Given that this code gets likely run isolated in its own session even all these wc... libraries are imho about cosmetics. If you really need to get rid of them then I'd go for a libname function to clean them out. Below code will do "the right thing" under the assumption that there is no pre-existing wc.... libref.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let root_path=c:\temp;
filename filelist pipe "dir /B/S &amp;amp;root_path.\*.sas7bdat";
data work.failed_SASTable_open;
  length pathAndSASFile $1000 msg $256;
  keep pathAndSASFile msg;

  infile filelist truncover;
  input pathAndSASFile $1000.;
  _did=open(strip(pathAndSASFile),,,'f');
  if _did =0 then 
    do;
      msg=sysmsg();
      output;
    end;
  else
    do;
      _rc=close(_did);
      _n+1;
      _rc=libname(cats('wc',put(_n,z6.)));
    end;
run;
filename filelist clear;
&lt;/CODE&gt;&amp;nbsp;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Thu, 27 Apr 2023 12:44:26 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/872555#M82681</guid>
      <dc:creator>Patrick</dc:creator>
      <dc:date>2023-04-27T12:44:26Z</dc:date>
    </item>
    <item>
      <title>Re: The fastest/efficient way to check sas7bdat files damage?</title>
      <link>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/962454#M83934</link>
      <description>&lt;P&gt;I was recently tasked with this and found that the fastest and easiest way to test a data set is using a procedure like proc print as shown below with the obs=0 option on the data set. No matter how large the SAS data set is, it runs in a fraction of a second and produces no output to the results window.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;proc print data=&amp;lt;SAS data set name&amp;gt;(obs=0);&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Or&lt;/P&gt;&lt;P&gt;proc print data="&amp;lt;full file path to sas7bdat file&amp;gt;"(obs=0);&lt;/P&gt;&lt;P&gt;run;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The latter method is better in case the file is not a SAS data set and does not show up in the SAS library. It will return a damaged message or a message stating that it is not a SAS data set.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Cheers,&lt;/P&gt;&lt;P&gt;&amp;nbsp; Brian&lt;/P&gt;</description>
      <pubDate>Sat, 22 Mar 2025 16:03:23 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Procedures/The-fastest-efficient-way-to-check-sas7bdat-files-damage/m-p/962454#M83934</guid>
      <dc:creator>BrianVarney</dc:creator>
      <dc:date>2025-03-22T16:03:23Z</dc:date>
    </item>
  </channel>
</rss>

