<?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: help with error in macro compare_all in SAS Programming</title>
    <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802370#M315865</link>
    <description>&lt;P&gt;The problem is your NDATA macro variable resolves to 0 which results in invalid %DO loops. NDATA is defined in this statement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let ndata=%sysfunc(countw(&amp;amp;dlist,|));&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That suggests the macro DLIST is not populated as NDATA is the number of words in DLIST.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;DLIST appears to be a list of tables to be processed. So as others have said, please post the code calling the macro as that is the most likely cause of the errors.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edit: DLIST is derived from the temporary SAS datasets&amp;nbsp;_basedict and _compdict. Check that these datasets are created and populated.&lt;/P&gt;</description>
    <pubDate>Tue, 15 Mar 2022 23:41:12 GMT</pubDate>
    <dc:creator>SASKiwi</dc:creator>
    <dc:date>2022-03-15T23:41:12Z</dc:date>
    <item>
      <title>help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802352#M315859</link>
      <description>&lt;P&gt;Hi,&lt;/P&gt;&lt;P&gt;I'm working with a macro downloaded from this site: &lt;A href="https://communities.sas.com/t5/SAS-Communities-Library/Data-Library-Comparison-Macro-COMPARE-ALL/ta-p/634341" target="_blank" rel="noopener"&gt;Data Library Comparison Macro %COMPARE_ALL - SAS Support Communities&lt;/A&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;It is giving an error that I do not know how to fix .&lt;/P&gt;&lt;P&gt;The Macro parameters I used to initiate the macro:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;%compare_all(base = vdata,&lt;BR /&gt;compare = orig,&lt;BR /&gt;outdoc = /data/output/compare.xlsx);&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Error:&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lydiawawa_0-1647380310619.png" style="width: 634px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/69484i5EC981110C0CD5A5/image-dimensions/634x559?v=v2" width="634" height="559" role="button" title="lydiawawa_0-1647380310619.png" alt="lydiawawa_0-1647380310619.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;Full macro:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;/*------------------------------------------------------------------*
| MACRO NAME  : compare_all
| SHORT DESC  : Creates summary comparison report of two libraries 
|               of data in Excel.
*------------------------------------------------------------------*
| CREATED BY  : Meyers, Jeffrey                 (01/20/2013 3:00)
*------------------------------------------------------------------*
| VERSION UPDATES:
| 1.4 - 03/02/2020
|    Corrected issue with grabbing number of changed values in dataset
        summary table.
| 1.3 - 02/25/2020
|    Changed how IDSUMTABLE works.  Will now work on any number &amp;gt;=0.
        Will produce a summary of data changes including up to
        IDSUMTABLE number of ID variables.
|    Documentation updated.
| 1.2 - 02/24/2020
|    Fixed an issue where labels were being mismatched in variable
        summary sheets.
| 1.1 - 02/18/2020
|    Made updates for when a dataset does not share any non-ID variables
        between base and compare libraries
|    Added DEBUG option
| 1.0 - 03/15/2019
|    Initial Release
*------------------------------------------------------------------*
| PURPOSE
|
| This macro compares the datasets of two libraries together to check
| for changes in variables, datasets, and values in datasets the two
| libraries share.  The macro outputs a report of three levels into
| an Excel file.
| The first report lists all the datasets of both libraries side by side
| to compare the number of variables, observations, last updated date,
| and a count of potential new observations, lost observations, changed
| variable values, and variable attribute changes.
|
| The second level of the report is a worksheet for each datasets that is
| shared between the two libraries.  The report lists every variable contained
| by either library's dataset and compares some of the basic attributes
| (label, format, length, and type), and has a count of how many data changes
| exist from the base data to the new data.
|
| The third level of the report summarizes the changes across all variables
| potentially within levels of the ID variables.  The summary allows the user
| to quickly see what the values of the variable changed to.
|
| The fourth level of the report is for any variable that has changed values
| between the libraries.  Each changed value is listed with the base value
| and the compare value along with the ID variables.  For numeric values
| a percent and absolute change are provided. 
|
| 1.0: REQUIRED PARAMETERS
| BASE = The LIBNAME of the library containing the base data to compare with the updated data.
|        NOTE: This is the libname and not a file path.  A library must be
|              pre-specified.
| COMPARE = The LIBNAME of the library containing the updated data to compare with the base data.
|        NOTE: This is the libname and not a file path.  A library must be
|              pre-specified.
| OUTDOC = The full file path and file name of an Microsoft Excel file to output the report to.
|          Filename should include the .xlsx tag.
| 2.0: Optional PARAMETERS
| CROSSTAB_THRESHOLD = Determines how many unique combinations can exist when doing a
|                      comparison of changed values and still display them all in a 
|                      cross tab summary in the level 3 summary table.  Default is 15.
|                      minimum is 1.
| SELECT = A space delimited list of dataset names to focus the macro on comparing. The
|          case of the names does not matter, and no quotations should be included.  All
|          other datasets within the libraries will be ignored.
| ID = One or more variables can be designated ID variables that will be used to compare
|      between the same datasets (example: patient ID).  Due to different datasets having
|      different structures this parameter is flexible.  Any number of ID variables can be
|      specified, but only those that are contained in a specific dataset will be used in the
|      comparison for that dataset.  ID variables are listed in the order of the list from left
|      to right.
|      Example: ID = ARM DCNTR_ID CYCLE
|        Dataset BASELINE contains ARM and DCNTR_ID, so those are used as ID variables to compare BASELINE
|            in the order of ARM -&amp;gt; DCNTR_ID
|        Dataset TREATMENT contains ARM, DCNTR_ID, and CYCLE, so all three are used as ID variables to compare
|            TREATMENT in the order of ARM -&amp;gt; DCNTR_ID -&amp;gt; CYCLE
|        Dataset PROTOCOL contains none of the three ID variables, so none are used to compare PROTOCOL
| IDSUMTABLE = Determines how many ID variables are used to summarize the data changes for each dataset.
|              Example: if IDSUMTABLE=2 and a dataset has two ID variables then the data changes will be
|              summarized by both ID variables.  If IDSUMTABLE=2 and a dataset only has 1 ID variable then
|              it will use that one ID variable to summarize.  If IDSUMTABLE=2 and a dataset has 3 ID variables
|              then it will only use the first two ID variables in the ID list.
|              Example 2: If IDSUMTABLE=0 then it will not use any ID variables to summarize and will summarize
|              instead across all observations.
|              Default is 0.
| OUTDOC = Specifies a file path and file name to save the Excel report to.
| DEBUG = Determines if NOTES are left on and if temporary datasets are deleted.  1 is (yes) and 0 is (no).
|         Default is 0.
*------------------------------------------------------------------*
| OPERATING SYSTEM COMPATIBILITY
| UNIX SAS v9.4   :   YES
| PC SAS v9.4     :   YES
*------------------------------------------------------------------*
| MACRO CALL
|
| %compare_all (
|            BASE=,
|            COMPARE=,
|            ID=,
|            SELECT=,
|            OUTDOC=
|          );
*------------------------------------------------------------------*
| REQUIRED PARAMETERS
|
| Name      : BASE
| Default   : 
| Type      : LIBNAME
| Purpose   : REFER TO REFERENCE SECTION
|
| Name      : COMPARE
| Default   :
| Type      : LIBNAME
| Purpose   : REFER TO REFERENCE SECTION
|
| Name      : OUTDOC
| Default   :
| Type      : File path and file name
| Purpose   : REFER TO REFERENCE SECTION
*------------------------------------------------------------------*
| EXAMPLES
|
| Example 1: Basic Example Call:
  libname basedata '/some/file/path';
  libname compdata '/another/file/path';
  %compare_all(base=basedata, compare=compdata, outdoc=/filepath/filename.xlsx);
|
| Example 2: Select Specific Datasets:
  libname basedata '/some/file/path';
  libname compdata '/another/file/path';
  %compare_all(base=basedata, compare=compdata, select=Data1 Data2 Data3, outdoc=/filepath/filename.xlsx);
|
| Example 3: Add ID Variables:
  libname basedata '/some/file/path';
  libname compdata '/another/file/path';
  %compare_all(base=basedata, compare=compdata, select=Data1 Data2 Data3, id=ARM PATID CYCLE EVAL_DT,
               outdoc=/filepath/filename.xlsx);
*------------------------------------------------------------------*
| This program is free software; you can redistribute it and/or
| modify it under the terms of the GNU General Public License as
| published by the Free Software Foundation; either version 2 of
| the License, or (at your option) any later version.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| General Public License for more details.
*------------------------------------------------------------------*/

%macro compare_all(
    /*REQUIRED PARAMETERS*/
    base=,compare=,outdoc=,
    /*OPTIONAL PARAMETERS*/
    crosstab_threshold=15,select=,id=,idsumtable=0, debug=0);
    
    
    /**Save current options to reset after macro runs**/
    %local _mergenoby _notes _qlm _odspath _starttime _listing;
    %let _starttime=%sysfunc(time());
    %let _notes=%sysfunc(getoption(notes));
    %let _mergenoby=%sysfunc(getoption(mergenoby));
    %let _qlm=%sysfunc(getoption(quotelenmax)); 
    %let _odspath=&amp;amp;sysodspath;
    %if %sysevalf(%superq(_odspath)=,boolean) %then %let _odspath=WORK.TEMPLAT(UPDATE) SASHELP.TMPLMST (READ);
    /**Turn off warnings for merging without a by and long quote lengths**/
    /**Turn off notes**/
    options mergenoby=NOWARN nonotes noquotelenmax;
    %if &amp;amp;debug=1 %then %do; options notes; %end;
    ods path WORK.TEMPLAT(UPDATE) SASHELP.TMPLMST (READ);
    /**See if the listing output is turned on**/
    proc sql noprint;
        select 1 into :_listing separated by '' from sashelp.vdest where upcase(destination)='LISTING';
    quit;
    
    /**Process Error Handling**/
    %if &amp;amp;sysver &amp;lt; 9.4 %then %do;
        %put ERROR: SAS must be version 9.4 or later;
        %goto errhandl;
    %end;     
    %local i z nerror;
    %let nerror=0;
    

    /*Don't send anything to output window, results window, and set escape character*/
    ods select none;
    ods noresults escapechar='^';

    proc sql noprint;
        %local basepath comppath;
        select distinct path into :basepath separated by '' from sashelp.vlibnam where upcase(libname)=upcase("&amp;amp;base");
        select distinct path into :comppath separated by '' from sashelp.vlibnam where upcase(libname)=upcase("&amp;amp;compare");
    quit;
    
    %if %sysevalf(%superq(basepath)=,boolean) %then %do;
        /**Throw Error**/
        %put ERROR: (Global: BASE) Library does not exist;
        %let nerror=%eval(&amp;amp;nerror+1);
    %end; 
    %if %sysevalf(%superq(comppath)=,boolean) %then %do;
        /**Throw Error**/
        %put ERROR: (Global: COMP) Library does not exist;
        %let nerror=%eval(&amp;amp;nerror+1);
    %end; 

    /**Check for OUTDOC**/
    %if %sysevalf(%superq(outdoc)=,boolean) %then %do;
        /**Throw Error**/
        %put ERROR: (Global: OUTDOC) No output document specified;
        %let nerror=%eval(&amp;amp;nerror+1);
    %end;
    /*Global Model Numeric Variables*/
    %macro _gnumcheck(parm, min,require);
        /**Check if missing**/
        %if %sysevalf(%superq(&amp;amp;parm)^=,boolean) %then %do;
            %if %sysfunc(notdigit(%sysfunc(compress(%superq(&amp;amp;parm),-.)))) &amp;gt; 0 %then %do;
                /**Check if character value**/
                %put ERROR: (Global: %qupcase(&amp;amp;parm)) Must be numeric.  %qupcase(%superq(&amp;amp;parm)) is not valid.;
                %let nerror=%eval(&amp;amp;nerror+1);
            %end;
            %else %if %sysevalf(&amp;amp;min^=,boolean) %then %do;
                %if %superq(&amp;amp;parm) &amp;lt; &amp;amp;min %then %do;
                    /**Makes sure number is not less than the minimum**/
                    %put ERROR: (Global: %qupcase(&amp;amp;parm)) Must be greater than %superq(min). %qupcase(%superq(&amp;amp;parm)) is not valid.;
                    %let nerror=%eval(&amp;amp;nerror+1);
                %end;
            %end;
        %end;
        %else %if &amp;amp;require=1 %then %do;
            /**Throw Error**/
            %put ERROR: (Global: %qupcase(&amp;amp;parm)) Cannot be missing;
            %put ERROR: (Global: %qupcase(&amp;amp;parm)) Possible values are numeric values greater than or equal to %superq(min);
            %let nerror=%eval(&amp;amp;nerror+1);           
        %end;       
    %mend;  
    %_gnumcheck(crosstab_threshold,1,1)
    /*** If any errors exist, stop macro and send to end ***/
    %if &amp;amp;nerror &amp;gt; 0 %then %do;
        %put ERROR: &amp;amp;nerror pre-run errors listed;
        %put ERROR: Macro DATA_SPECS will cease;
        %goto errhandl;
    %end;    
    %local i;
    proc contents data=&amp;amp;base.._all_
        out=_basedict %if %sysevalf(%superq(select)^=,boolean) %then %do;
           (where=(upcase(memname) in(%do i = 1 %to %sysfunc(countw(%superq(select),%str( )));
                                          "%qupcase(%sysfunc(dequote(%qscan(%superq(select),&amp;amp;i,%str( )))))"
                                      %end;) ))                                            
        %end;
        noprint order=collate;
    proc contents data=&amp;amp;compare.._all_
        out=_compdict %if %sysevalf(%superq(select)^=,boolean) %then %do;
           (where=(upcase(memname) in(%do i = 1 %to %sysfunc(countw(%superq(select),%str( )));
                                          "%qupcase(%sysfunc(dequote(%qscan(%superq(select),&amp;amp;i,%str( )))))"
                                      %end;) ))
        %end;
        noprint order=collate;
    run;

    proc transpose data=_basedict (drop=libname) out=_basedict_ct prefix=base;
        by memname name;
        var label format length;
    proc transpose data=_basedict (drop=libname) out=_basedict_nt (rename=(base1=base2)) prefix=base;
        by memname name;
        var type length formatl formatd;
    proc transpose data=_compdict (drop=libname) out=_compdict_ct prefix=comp;
        by memname name;
        var label format length;
    proc transpose data=_compdict (drop=libname) out=_compdict_nt (rename=(comp1=comp2)) prefix=comp;
        by memname name;
        var type length formatl formatd;
    run;
    
    data _basedict_t;
        set _basedict_ct _basedict_nt;
    data _compdict_t;
        set _compdict_ct _compdict_nt;
    proc sort data=_basedict_t;
        by memname name _name_;
    proc sort data=_compdict_t;
        by memname name _name_;
    run;

    data _attr_compare;
        merge _basedict_t (in=a) _compdict_t (in=b);
        by memname name _name_;
        if a and b and (base1^=comp1 or base2^=comp2) then mismatch=1;
        else mismatch=0;
        
        if mismatch=1 then output;
    run;
    
    proc sql noprint;
        create table _var_obs_compare as
            select a.*, max(0,b.natt_diff) as natt_diff 'Variable~Attributes',
            . as lost_observations 'Lost~Observations', . as new_observations 'New~Observations', . as data_changes 'Data~Changes',
            '' as id_variables length=300 'ID Variables Used','' as null from 
            (select coalescec(a.memname,b.memname) as memname 'Dataset Name',
            base_nvars 'Number of~Variables',base_nobs 'Number of~Observations', base_updated format=mmddyy10. 'Last Updated',
            comp_nvars 'Number of~Variables',comp_nobs 'Number of~Observations', comp_updated format=mmddyy10. 'Last Updated'
            from (select memname,count(name) as base_nvars,max(nobs) as base_nobs, max(datepart(modate)) as base_updated
                    from _basedict group by memname) a full outer join
                 (select memname,count(name) as comp_nvars,max(nobs) as comp_nobs, max(datepart(modate)) as comp_updated
                    from _compdict group by memname) b
            on a.memname=b.memname
            group by calculated memname) as a left join
               (select memname, count(distinct name) as natt_diff from _attr_compare group by memname) b
               on a.memname=b.memname;
        create table _var_attr_compare as
            select Upcase(coalescec(a.memname,b.memname)) as memname 'Dataset Name',
            upcase(coalescec(a.name,b.name)) as name 'Variable Name',
            ifc(a.type=1,'Numeric','Character') as base_type 'Type', a.length as base_length 'Length', a.format as base_fmt 'Format',a.label as base_label 'Label',
            ifc(b.type=1,'Numeric','Character') as comp_type 'Type', b.length as comp_length 'Length', b.format as comp_fmt 'Format',b.label as comp_label 'Label',
            ifc(^missing(a.name) and missing(b.name),'Yes','No') as lost_variable 'Lost~Variable',
            ifc(missing(a.name) and ^missing(b.name),'Yes','No') as new_variable 'New~Variable',
            . as data_changes 'No. Data~Changes',
            '' as id_variables length=3 'ID Variables?','' as null
            from _basedict a full outer join _compdict b
            on a.memname=b.memname and upcase(a.name)=upcase(b.name)
            order by coalesce(a.varnum,b.varnum);
            
        %local dlist ndata;
        select distinct memname into :dlist separated by '|' from
            (select distinct coalescec(a.memname,b.memname) as memname from 
            _basedict a inner join _compdict as b
            on a.memname=b.memname);
        %let ndata=1;
        %let ndata=%sysfunc(countw(&amp;amp;dlist,|));
        quit;

    ods select none;
    ods noresults;
    %do i = 1 %to &amp;amp;ndata;
        %local datid datidc;
        /**Open up dataset to check for variables**/
         /*base dataset*/
         %let datid&amp;amp;i = %sysfunc(open(&amp;amp;base..%scan(&amp;amp;dlist,&amp;amp;i,|)));
         %let any_id&amp;amp;i=0;
         %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( )));
             %local id&amp;amp;i.&amp;amp;j;
             %let id&amp;amp;i.&amp;amp;j=%sysfunc(varnum(&amp;amp;&amp;amp;datid&amp;amp;i,%scan(%superq(id),&amp;amp;j,%str( ))));
         %end;
         /**Close dataset**/
         %local closedatid;
         %let closedatid=%sysfunc(close(&amp;amp;&amp;amp;datid&amp;amp;i));
         /*Compare data*/
         %let datidc&amp;amp;i = %sysfunc(open(&amp;amp;compare..%scan(&amp;amp;dlist,&amp;amp;i,|)));
         %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( )));
             %local idc&amp;amp;i.&amp;amp;j;
             %let idc&amp;amp;i.&amp;amp;j=%sysfunc(varnum(&amp;amp;&amp;amp;datidc&amp;amp;i,%scan(%superq(id),&amp;amp;j,%str( ))));
         %end;
         /**Close dataset**/
         %let closedatid=%sysfunc(close(&amp;amp;&amp;amp;datidc&amp;amp;i));
         /*Check if ID is in both datasets*/
         %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( )));
             %if &amp;amp;&amp;amp;id&amp;amp;i.&amp;amp;j &amp;gt; 0 and &amp;amp;&amp;amp;idc&amp;amp;i.&amp;amp;j &amp;gt; 0 %then %let any_id&amp;amp;i=1; 
         %end;
         proc sql noprint;
             %local vlist&amp;amp;i llist&amp;amp;i nvar&amp;amp;i;
             select name,label into :vlist&amp;amp;i separated by '|',:llist&amp;amp;i separated by '|'
                 from _basedict where upcase(name) in(select upcase(name) from _compdict where upcase(memname)=upcase("%scan(&amp;amp;dlist,&amp;amp;i,|)"))
                 and upcase(memname)=upcase("%scan(&amp;amp;dlist,&amp;amp;i,|)")
                 %if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do;
                     and upcase(name) ^in(
                        %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( )));
                            %if &amp;amp;&amp;amp;id&amp;amp;i.&amp;amp;j &amp;gt; 0 and &amp;amp;&amp;amp;idc&amp;amp;i.&amp;amp;j &amp;gt; 0 %then %do; "%qupcase(%scan(&amp;amp;id,&amp;amp;j,%str( )))" %end; 
                        %end;)
                 %end;;
             %let nvar&amp;amp;i=%sysfunc(countw(&amp;amp;&amp;amp;vlist&amp;amp;i,|));
         quit;
     
         %local idlist&amp;amp;i;
         %if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do;
            %let idlist&amp;amp;i=;
            %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( )));
                %if %sysevalf(%superq(id&amp;amp;i.&amp;amp;j)&amp;gt;0,boolean) and %sysevalf(%superq(idc&amp;amp;i.&amp;amp;j)&amp;gt;0,boolean) and %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %let idlist&amp;amp;i=&amp;amp;&amp;amp;idlist&amp;amp;i %scan(&amp;amp;id,&amp;amp;j,%str( ));
                %else %if %sysevalf(%superq(id&amp;amp;i.&amp;amp;j)&amp;gt;0,boolean) and %sysevalf(%superq(idc&amp;amp;i.&amp;amp;j)&amp;gt;0,boolean) %then %let idlist&amp;amp;i=%scan(&amp;amp;id,&amp;amp;j,%str( ));
            %end;
            proc sort data=&amp;amp;base..%scan(&amp;amp;dlist,&amp;amp;i,|) out=_base&amp;amp;i;
               by &amp;amp;&amp;amp;idlist&amp;amp;i;
            proc sort data=&amp;amp;compare..%scan(&amp;amp;dlist,&amp;amp;i,|) out=_compare&amp;amp;i;
               by &amp;amp;&amp;amp;idlist&amp;amp;i;
            run;
         %end;
         %else %do;
             data _base&amp;amp;i;
                 set &amp;amp;base..%scan(&amp;amp;dlist,&amp;amp;i,|);
             run;
             data _compare&amp;amp;i;
                 set &amp;amp;compare..%scan(&amp;amp;dlist,&amp;amp;i,|);
             run;
         %end;
         %local any_diff&amp;amp;i same_type&amp;amp;i removed&amp;amp;i added&amp;amp;i;
         %let any_diff&amp;amp;i=0;
         %let same_type&amp;amp;i=0;
         %let removed&amp;amp;i=0;
         %let added&amp;amp;i=0;
         %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
             %local any_diff&amp;amp;i._&amp;amp;j same_type&amp;amp;i._&amp;amp;j removed&amp;amp;i._&amp;amp;j added&amp;amp;i._&amp;amp;j;
             %let any_diff&amp;amp;i._&amp;amp;j=0;
             %let same_type&amp;amp;i._&amp;amp;j=0;
             %let removed&amp;amp;i._&amp;amp;j=0;
             %let added&amp;amp;i._&amp;amp;j=0;
         %end;
         %if &amp;amp;&amp;amp;nvar&amp;amp;i&amp;gt;0 %then %do;     
         data _comparison&amp;amp;i;
             merge _base&amp;amp;i (in=b keep=%if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do; &amp;amp;&amp;amp;idlist&amp;amp;i %end;
                                      %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i; %scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|) %end;
                                 rename=(%do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i; %scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)=_bvar&amp;amp;j %end;))
                   _compare&amp;amp;i (in=c keep=%if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do; &amp;amp;&amp;amp;idlist&amp;amp;i %end;
                                         %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i; %scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|) %end;
                                    rename=(%do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i; %scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)=_cvar&amp;amp;j %end;)) end=last;
             %if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do;
                 by &amp;amp;&amp;amp;idlist&amp;amp;i;
             %end;
             array any_diff {&amp;amp;&amp;amp;nvar&amp;amp;i};
             array _any_diff {&amp;amp;&amp;amp;nvar&amp;amp;i} _temporary_;
             array same_type {&amp;amp;&amp;amp;nvar&amp;amp;i};
             retain same_type removed added;
             if _n_=1 then do;
                 removed=0;added=0;
             end;
             observation=_n_;
             if b and ^c then do;
                 _removed=1;
                 removed+1;
             end;
             else _removed=0;
             if c and ^b then do;
                 added+1;
                 _added=1;
             end;
             else _added=0;
             %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
                 if _n_=1 then do;
                     if (vtype(_bvar&amp;amp;j) = vtype(_cvar&amp;amp;j)) then same_type(&amp;amp;j)=ifn((vtype(_bvar&amp;amp;j)='N'),1,2);
                     else same_type(&amp;amp;j)=0;
                 end;
                 if same_type(&amp;amp;j) and (b and c) then do;
                     any_diff(&amp;amp;j)=(_bvar&amp;amp;j^=_cvar&amp;amp;j);
                     _any_diff(&amp;amp;j)+(_bvar&amp;amp;j^=_cvar&amp;amp;j);
                 end;
             %end;

             if last then do;
                 do i = 1 to dim(any_diff);
                     call symputx("any_diff&amp;amp;i._"||strip(put(i,12.0)),_any_diff(i),'l');
                     call symputx("same_type&amp;amp;i._"||strip(put(i,12.0)),same_type(i),'l');
                     end;
                 call symputx("any_diff&amp;amp;i",sum(of _any_diff(*)),'l');
                 call symputx("same_type&amp;amp;i",dim(same_type)-sum(of same_type(*)),'l');
                 call symputx("removed&amp;amp;i",removed,'l');
                 call symputx("added&amp;amp;i",added,'l');
             end;
             drop i;
             null='';
         run;
             data _comparison&amp;amp;i._t;
                 set _comparison&amp;amp;i;
             
                 array any_diff {&amp;amp;&amp;amp;nvar&amp;amp;i};
                 array same_type {&amp;amp;&amp;amp;nvar&amp;amp;i};
                 length nvar 8. variable $60. _base _compare $300.;
                 %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
                     nvar=&amp;amp;j;
                     variable="%scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)";
                     if any_diff(&amp;amp;j)=1 then do;
                         _base=vvalue(_bvar&amp;amp;j);
                         _compare=vvalue(_cvar&amp;amp;j);
                         %if &amp;amp;&amp;amp;same_type&amp;amp;i._&amp;amp;j=1 %then %do;
                             if same_type(&amp;amp;j)=1 and ^missing(_cvar&amp;amp;j) and ^missing(_bvar&amp;amp;j) then do;
                                 _diff=_cvar&amp;amp;j-_bvar&amp;amp;j;
                             end;
                             else call missing(_diff);
                         %end;
                         %else %do;
                             call missing(_diff);
                         %end;
                         output;
                     end;
                 %end;
                 keep &amp;amp;&amp;amp;idlist&amp;amp;i nvar variable _base _compare _diff;
             run;
         
             proc sql;
                 create table _id_lvl_sum_&amp;amp;i as
                     select
                     %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                         %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                     %end;
                     sum(_added) as nadded,sum(_removed) as nremoved,
                     sum(nchanges) as nchanges
                     from (select *,sum(%do j=1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
                                            %if &amp;amp;j&amp;gt;1 %then %do; , %end; any_diff&amp;amp;j
                                        %end;) as nchanges from _comparison&amp;amp;i)
                     %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))&amp;gt;0  %then %do; 
                         group by %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                       %scan(%superq(idlist&amp;amp;i),1,%str( ))
                                  %end;
                     %end;;
                 create table _comparison&amp;amp;i._t_sum as
                     select 
                     %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                         %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                     %end;
                     nvar, variable, _base, _compare, count(*) as n, min(_diff) as min, max(_diff) as max
                     from _comparison&amp;amp;i._t
                     group by %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                  %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                              %end;
                              nvar, variable, _base, _compare;
                 create table _comparison&amp;amp;i._t_sum_final as
                     select * from _comparison&amp;amp;i._t_sum
                     group by %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                  %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                              %end;
                              nvar, variable having count(*) &amp;lt;= &amp;amp;crosstab_threshold
                     outer union corr
                     select 
                     %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                         %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                     %end;
                     nvar, variable, ifc(^missing(_base),'Non-Missing','Missing') as _base,
                     ifc(^missing(_compare),'Non-Missing','Missing') as _compare, sum(n) as n, min(min) as min, max(max) as max
                     from (select * from _comparison&amp;amp;i._t_sum
                     group by %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                    %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                              %end;
                              nvar, variable having count(*) &amp;gt;&amp;amp;crosstab_threshold)
                              group by %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                           %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                                       %end;
                                       nvar, variable, calculated _base, calculated _compare
                     order by %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                                  %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )),
                              %end;
                              nvar, variable, _base, _compare;
             quit;
             data _id_lvl_sum_&amp;amp;i;
                 merge _id_lvl_sum_&amp;amp;i _comparison&amp;amp;i._t_sum_final;
                 %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))&amp;gt;0 %then %do;
                    by %do  j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                          %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( ))
                       %end;;
                 %end;
                 %else %do;
                     retain _nadded _nremoved _nchanges;
                     if _n_=1 then do;
                         _nadded=nadded;_nremoved=nremoved;_nchanges=nchanges;
                     end;
                     else do;
                         nadded=_nadded;nremoved=_nremoved;nchanges=_nchanges;
                     end;
                     drop _nadded _nremoved _nchanges;   
                 %end;
             run;
         %end;
   %end;

   proc sql;
       %do i = 1 %to &amp;amp;ndata;
           %if %sysevalf(%superq(removed&amp;amp;i)=,boolean) %then %let removed&amp;amp;i=.;
           %if %sysevalf(%superq(added&amp;amp;i)=,boolean) %then %let added&amp;amp;i=.;
           %if %sysevalf(%superq(any_diff&amp;amp;i)=,boolean) %then %let any_diff&amp;amp;i=.;
           %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
               %if %sysevalf(%superq(any_diff&amp;amp;i._&amp;amp;j)=,boolean) %then %let any_diff&amp;amp;i._&amp;amp;j=0;
           %end;
       %end;
       UPDATE _var_obs_compare
           set lost_observations=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;removed&amp;amp;i
             %end;
             else . end,
             new_observations=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;added&amp;amp;i
             %end;
             else . end,  
             data_changes=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;any_diff&amp;amp;i
             %end;
             else . end,  
             id_variables=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then tranwrd("&amp;amp;&amp;amp;idlist&amp;amp;i",' ',', ')
             %end;
             else '' end;
       UPDATE _var_attr_compare
           set data_changes=case(memname)
                   %do i = 1 %to &amp;amp;ndata;
                       when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then case (upcase(name))
                           %if &amp;amp;&amp;amp;nvar&amp;amp;i&amp;gt;0 %then %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
                               %if %sysevalf(%superq(any_diff&amp;amp;i._&amp;amp;j)^=,boolean) %then %do;
                                    when upcase("%scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)") then %superq(any_diff&amp;amp;i._&amp;amp;j)
                               %end;
                           %end;
                           %else %do;
                              when "" then .
                           %end;
                           else . end
                   %end;
                   else . end,
               id_variables=case 
                       when upcase(name) in("" %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( ))); "%qupcase(%scan(&amp;amp;id,&amp;amp;j,%str( )))" %end;) then 'Yes'
                       else 'No' end;           
   quit;
   
   %put COMPARE_ALL: Comparisons completed, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));
     
   %if %sysevalf(%superq(outdoc)^=,boolean) %then
       %put COMPARE_ALL: Printing to &amp;amp;outdoc;
   %else %put COMPARE_ALL: Printing to &amp;amp;base._&amp;amp;compare._comparison.xlsx;
   
   %local nbsp;
   data _null_;
       call symput('nbsp','A0'x);
   run;
   ods select all;
   ods listing close;
   ods escapechar='^';
   ods excel
       %if %sysevalf(%superq(outdoc)^=,boolean) %then %do;
           file="&amp;amp;outdoc"
       %end;
       %else %do;
           file="&amp;amp;base._&amp;amp;compare._comparison.xlsx"
       %end;;
   %local topref;
   %let topref=%str(=HYPERLINK("#'Top Summary'!A4","Return to Top Summary"));
   ods excel options(sheet_name="Top Summary" frozen_Headers='5' frozen_rowheaders='1' flow='tables'
        absolute_column_width='36,13,10,12,13,10,12,9,12,12,9,25');
   %put COMPARE_ALL: Printing top summary, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));
   proc report data=_var_obs_compare nowd split='~' missing 
       style(header)={just=l fontweight=bold bordertopwidth=3pt bordertopcolor=black fontfamily='Arial'
          borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black
          fontsize=10pt background=white color=black}
       style(column)={bordercolor=black fontsize=10pt just=c fontfamily='Arial'}
       style(lines)={color=black fontweight=bold fontsize=10pt bordertopwidth=3pt bordertopcolor=black
          borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black}
       style(report)={bordertopwidth=3pt bordertopcolor=black
          borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black};
       
       columns ("Base Library (%qupcase(&amp;amp;base)): &amp;amp;basepath"
                 ("Compare Library (%qupcase(&amp;amp;compare)): &amp;amp;comppath"
                   (%if %sysevalf(%superq(select)^=,boolean) %then %do;
                        "Summary of Selected Datasets Compared (Option SELECT is in Effect: Other Datasets Could Exist in Library)"
                    %end;
                    %else %do;
                        "Summary of Datasets Compared"
                    %end;
             memname
             null=n6, (memname=mem2 memname=mem3)
             null=n2, (base_updated base_nvars base_nobs)
             null=n3, (comp_updated comp_nvars comp_nobs)
             null=n4, (natt_diff lost_observations new_observations data_changes)
             null=n5, (id_variables id_variables=n1))))
             _null_;
       define n1 / display noprint;
       define n2 / across "Base" style={background=lightblue};
       define n3 / across "Compare" style={background=lightgray};
       define n4 / across "Any Differences" style={background=lightred};
       define n6 / across "A0"x style={borderbottomstyle=none borderbottomcolor=white};
       define n5 / across "A0"x style={borderbottomstyle=none borderbottomcolor=white background=lightgreen};
       define memname / display noprint;
       define mem3 / display noprint;
       define mem2 / display 
           style(column)={borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black just=l}
           style={width=100% just=l} 
           style(header)={just=c bordertopstyle=none bordertopcolor=white};
       define base_updated / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightblue};
       define base_nvars / display style(header)={background=lightblue};
       define base_nobs / display style(header)={background=lightblue};
       define comp_nvars / display style(header)={background=lightgray};
       define comp_nobs / display style(header)={background=lightgray};
       define comp_updated / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightgray};
       
       define natt_diff / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightred};
       define lost_observations / display style(header)={background=lightred};
       define new_observations / display style(header)={background=lightred};
       define data_changes / display style(header)={background=lightred};
       define id_variables / display style={borderleftwidth=3pt borderleftcolor=black width=100% bordertopstyle=none bordertopcolor=white} left
           style(header)={background=lightgreen} style(column)={just=l};
       define _null_ / computed noprint;
       
       compute _null_;
            if _c5_^=_c8_ then do;
                call define('_c5_','style/merge','style={background=lightorange}');
                call define('_c8_','style/merge','style={background=lightorange}');
            end;
            if _c6_^=_c9_ then do;
                call define('_c6_','style/merge','style={background=lightorange}');
                call define('_c9_','style/merge','style={background=lightorange}');
            end;
            if _c10_&amp;gt;0 then call define('_c10_','style/merge','style={background=lightorange}');
            if _c11_&amp;gt;0 then call define('_c11_','style/merge','style={background=lightorange}');
            if _c12_&amp;gt;0 then call define('_c12_','style/merge','style={background=lightorange}');
            if _c13_&amp;gt;0 then call define('_c13_','style/merge','style={background=lightorange}');
            urlstring="#'"||substr('Summary-'||strip(memname),1,28)||"'!A4";
            if ^missing(_c4_) and ^missing(_c7_) then call define('_c2_','url',urlstring);
       endcomp;
   run;

   %do i = 1 %to &amp;amp;ndata;
       %put COMPARE_ALL: Printing dataset (%scan(&amp;amp;dlist,&amp;amp;i,|)) summary, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));
       ods excel options(sheet_name="Summary-%scan(&amp;amp;dlist,&amp;amp;i,|)" frozen_Headers='5' frozen_rowheaders='1' 
           absolute_column_width='29,13,12,55,17,10,12,55,17,10,9,12,12');
       %local datref&amp;amp;i;
       %if %length(Summary-%scan(&amp;amp;dlist,&amp;amp;i,|))&amp;gt;28 %then 
           %let datref&amp;amp;i==HYPERLINK("#'%substr(Summary-%scan(&amp;amp;dlist,&amp;amp;i,|),1,28)'!A4","Dataset Name: %scan(&amp;amp;dlist,&amp;amp;i,|)");
       %else %let datref&amp;amp;i==HYPERLINK("#'Summary-%scan(&amp;amp;dlist,&amp;amp;i,|)'!A4","Dataset Name: %scan(&amp;amp;dlist,&amp;amp;i,|)");
       proc report data=_var_attr_compare nowd split='~' missing 
           style(header)={just=l fontweight=bold bordertopwidth=3pt bordertopcolor=black fontfamily='Arial'
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black
               fontsize=10pt background=white color=black}
           style(column)={bordercolor=black fontsize=10pt just=c fontfamily='Arial' width=100%}
           style(lines)={color=black fontweight=bold fontsize=10pt bordertopwidth=3pt bordertopcolor=black
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black}
           style(report)={bordertopwidth=3pt bordertopcolor=black
                borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black};
       
           columns 
                 ("Dataset Name: %scan(&amp;amp;dlist,&amp;amp;i,|)"
                   ("ID Variables: &amp;amp;&amp;amp;idlist&amp;amp;i"
                       ("%superq(topref)"
               name=nm
               null=n1, (name id_variables)
               null=n2, (base_type base_label base_fmt base_length)
               null=n3, (comp_type comp_label comp_fmt comp_length)
               null=n4, (lost_variable new_variable data_changes)
               )));

           define n1 / across "A0"x;
           define n2 / across "Base" style={background=lightblue};
           define n3 / across "Compare" style={background=lightgray};
           define n4 / across "Any Differences" style={background=lightred};

           define nm / display noprint;
           define name / display style(header)={just=c bordertopstyle=none bordertopcolor=white} style={width=100%}
               style(column)={borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black just=l}
                left;
           define base_type / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightblue};
           define base_label / display left style={just=l} style(header)={background=lightblue};
           define base_length / display left style={just=l} style(header)={background=lightblue};
           define comp_length / display left style={just=l} style(header)={background=lightgray};
           define comp_label / display left style={just=l} style(header)={background=lightgray};
           define base_fmt / display left style={just=l} style(header)={background=lightblue};
           define comp_fmt / display left style={just=l} style(header)={background=lightgray};
           define lost_variable / display style(header)={background=lightred};
           define new_variable / display style(header)={background=lightred};
           define data_changes / display style(header)={background=lightred};
           define comp_type / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightgray};
           define lost_variable / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightred};
           
           define id_variables / display style={borderleftwidth=3pt borderleftcolor=black width=100%} style(header)={background=lightgreen} center;

           compute data_changes;
               if _c13_='Yes' then do;
                   call define('_c2_','style/merge','style={background=lightorange}');
                   call define('_c13_','style/merge','style={background=lightorange}');
               end;
               if _c12_='Yes' then do;
                   call define('_c2_','style/merge','style={background=lightred}');
                   call define('_c12_','style/merge','style={background=lightred}');
               end;
               if _c14_&amp;gt;0 then do;
                   call define('_c2_','style/merge','style={background=lightred}');
                   call define('_c14_','style/merge','style={background=lightred}');
               end;
               if _c3_='Yes' then do;
                   call define('_c2_','style/merge','style={background=lightgreen}');
                   call define('_c3_','style/merge','style={background=lightgreen}');
               end;
               if _c4_^=_c8_ and _c13_='No' then do;
                   call define('_c4_','style/merge','style={background=lightorange}');
                   call define('_c8_','style/merge','style={background=lightorange}');
               end;
               if _c5_^=_c9_ and _c13_='No' then do;
                   call define('_c5_','style/merge','style={background=lightorange}');
                   call define('_c9_','style/merge','style={background=lightorange}');
               end;
               if _c6_^=_c10_ and _c13_='No' then do;
                   call define('_c6_','style/merge','style={background=lightorange}');
                   call define('_c10_','style/merge','style={background=lightorange}');
               end;
               if _c7_^=_c11_ and _c13_='No' then do;
                   call define('_c7_','style/merge','style={background=lightorange}');
                   call define('_c11_','style/merge','style={background=lightorange}');
               end;
               length tempname $32.;
               if _c14_&amp;gt;0 then do;
                   if substr("%scan(&amp;amp;dlist,&amp;amp;i,|)-"||strip(_c2_),1,28)=substr("%scan(&amp;amp;dlist,&amp;amp;i,|)-"||strip(tempname),1,28) then do;
                       if tempnamen=. then tempnamen=2;
                       else tempnamen+1;
                       urlstring="#'"||substr("%scan(&amp;amp;dlist,&amp;amp;i,|)-"||strip(_c2_),1,28)||' '||strip(put(tempnamen,12.0))||"'!A4";
                   end;
                   else do;
                       urlstring="#'"||substr("%scan(&amp;amp;dlist,&amp;amp;i,|)-"||strip(_c2_),1,28)||"'!A4";
                       tempnamen=.;
                   end;
                   call define('_c2_','url',urlstring);
               end;
               tempname=_c2_;
           endcomp;
           where memname="%scan(&amp;amp;dlist,&amp;amp;i,|)";
       run;
       
       %put COMPARE_ALL: Printing dataset (%scan(&amp;amp;dlist,&amp;amp;i,|)) data changes summary, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));
       ods excel options(sheet_name="ID Summary-%scan(&amp;amp;dlist,&amp;amp;i,|)" frozen_Headers='5' frozen_rowheaders="%sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))"
           %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))&amp;gt;0  %then %do;
               absolute_column_width="%sysfunc(repeat(%str(31,),%sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))-1))13,12,13,19,31,31,13,13,13"
           %end;
           %else %do;
               absolute_column_width='13,12,13,19,31,31,13,13,13'
           %end;);
       proc report data=_id_lvl_sum_&amp;amp;i nowd split='~' missing spanrows
           style(header)={just=l fontweight=bold bordertopwidth=3pt bordertopcolor=black fontfamily='Arial'
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black
               fontsize=10pt background=white color=black}
           style(column)={bordercolor=black fontsize=10pt just=c fontfamily='Arial' width=100% vjust=top}
           style(lines)={color=black fontweight=bold fontsize=10pt bordertopwidth=3pt bordertopcolor=black
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black}
           style(report)={bordertopwidth=3pt bordertopcolor=black
                borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black};
           
           columns 
                 ("Summary of %scan(&amp;amp;dlist,&amp;amp;i,|) Summary of Data Changes"
                   ("All Available ID Variables: &amp;amp;&amp;amp;idlist&amp;amp;i"
                     %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))=0 %then %do;
                         ("Note: No ID variables used in summary"
                     %end;
                     %else %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))=%sysfunc(countw(%superq(idlist&amp;amp;i),%str( ))) %then %do;  
                         ("Note: All ID variable(s) are used in summary"
                     %end;
                     %else %do;
                         ("Note: Only first %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( ))))) ID variable(s) is used in summary"
                     %end;
                       ("%superq(topref)"
               %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
                   %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( ))
               %end;
               nremoved nadded nchanges nvar variable _base _compare n min max))));

           %if %sysevalf(%superq(idlist&amp;amp;i)^=,boolean) %then %do j = 1 %to %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))));
               define %scan(%superq(idlist&amp;amp;i),&amp;amp;j,%str( )) / order style(header)={background=lightgreen};
           %end;
           define nadded / order 'New~Observations' center style(header)={background=lightred};
           define nremoved / order 'Lost~Observations' center style(header)={background=lightred};
           define nchanges / order 'N~Data Changes' center style(header)={background=lightred};
           define nvar / order noprint;
           define variable / order 'Variable' left style(header)={background=lightred};
           define _base / display 'Base' left style(header)={background=lightblue};
           define _compare / display 'Compare' left style(header)={background=lightgray};
           define n / display 'N' center style(header)={background=lightred};
           define min / display 'Mininum' center style(header)={background=lightred};
           define max / display 'Maximum' center style(header)={background=lightred};

           compute max;
              %if %sysfunc(min(&amp;amp;idsumtable,%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))))&amp;gt;0 %then %do;
                  if ^missing(%scan(%superq(idlist&amp;amp;i),1,%str( ))) then call define(_row_,'style/merge','style={bordertopwidth=3pt bordertopstyle=solid bordertopcolor=black}');
              %end;
              if ^missing(variable) or nchanges=0 then shade+1;
              if mod(shade,2) then do;
                  call define('variable','style/merge','style={background=greyef}');
                  call define('n','style/merge','style={background=greyef}');
                  call define('_base','style/merge','style={background=greyef}');
                  call define('_compare','style/merge','style={background=greyef}');
                  call define('min','style/merge','style={background=greyef}');
                  call define('max','style/merge','style={background=greyef}');
              end;
           endcomp;                  
       run;
       
       %if &amp;amp;&amp;amp;any_diff&amp;amp;i&amp;gt;0 %then %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
           %if %superq(any_diff&amp;amp;i._&amp;amp;j) &amp;gt; 0 %then %do;
           %put COMPARE_ALL: Printing dataset (%scan(&amp;amp;dlist,&amp;amp;i,|)) variable (%scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)) specific changes, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));
               ods excel options(sheet_name="%scan(&amp;amp;dlist,&amp;amp;i,|)-%scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)" frozen_Headers='5' frozen_rowheaders='1'
                   %if &amp;amp;&amp;amp;any_id&amp;amp;i=1 %then %do;
                       absolute_column_width="%sysfunc(repeat(%str(31,),%sysfunc(countw(%superq(idlist&amp;amp;i),%str( )))-1))15,31,31,15,15"
                   %end;
                   %else %do;
                       absolute_column_width="15,31,31,15,15"
                   %end;);
       proc report data=_comparison&amp;amp;i nowd split='~' missing
           style(header)={just=l fontweight=bold bordertopwidth=3pt bordertopcolor=black fontfamily='Arial'
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black
               fontsize=10pt background=white color=black}
           style(column)={bordercolor=black fontsize=10pt just=c fontfamily='Arial' width=100%}
           style(lines)={color=black fontweight=bold fontsize=10pt bordertopwidth=3pt bordertopcolor=black
               borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black}
           style(report)={bordertopwidth=3pt bordertopcolor=black
                borderleftwidth=3pt borderleftcolor=black borderrightwidth=3pt borderrightcolor=black borderbottomwidth=3pt borderbottomcolor=black};
       
           columns 
                 ("%superq(datref&amp;amp;i)"
                   ("Variable Name (label): %scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|,m) (%scan(%superq(llist&amp;amp;i),&amp;amp;j,|,m))"
                       ("%superq(topref)"
                  observation=obs
                  %if %sysfunc(countw(&amp;amp;&amp;amp;idlist&amp;amp;i,%str( ))) &amp;gt; 0 %then %do;
                      null=n1, (&amp;amp;&amp;amp;idlist&amp;amp;i)
                  %end;
                observation
               _bvar&amp;amp;j _cvar&amp;amp;j
               abs_change pct_change)));
           %do k = 1 %to %sysfunc(countw(&amp;amp;&amp;amp;idlist&amp;amp;i,%str( )));
               define %scan(&amp;amp;&amp;amp;idlist&amp;amp;i,&amp;amp;k,%str( )) / display 
                   style(column)={%if &amp;amp;k=i %then %do; borderleftwidth=3pt borderleftcolor=black %end; just=l}
                   style={width=100%} style(header)={just=c bordertopstyle=none bordertopcolor=white background=lightgreen} left; 
           %end;

           define obs / display noprint;
           %if %sysfunc(countw(&amp;amp;&amp;amp;idlist&amp;amp;i,%str( ))) &amp;gt; 0 %then %do;
               define n1 / across "ID Variables" style(header)={background=lightgreen};
           %end;
           define observation / display 'Observation' style={borderleftwidth=3pt borderleftcolor=black width=100%} center;
           define _bvar&amp;amp;j / display style={borderleftwidth=3pt borderleftcolor=black width=100%} center 'Base' style(header)={background=lightblue};
           define _cvar&amp;amp;j / display 'Compare' style(header)={background=lightgrey};
           define abs_change / computed 'Absolute~Change' style={borderleftwidth=3pt borderleftcolor=black width=100%} center style(header)={background=lightred};
           define pct_change / computed 'Percent~Change' format=12.1 style(header)={background=lightred};

           compute pct_Change;
               if vtype(_bvar&amp;amp;j)='N' and vtype(_cvar&amp;amp;j)='N' and ^missing(_bvar&amp;amp;j) and ^missing(_cvar&amp;amp;j) then do;
                   abs_change=_cvar&amp;amp;j-_bvar&amp;amp;j;
                   if _bvar&amp;amp;j&amp;gt;0 then pct_change=100*abs_change/_bvar&amp;amp;j;
               end;
           endcomp;
           where any_diff&amp;amp;j=1;
       run;

           %end;
       %end;
    %end;
    options notes;
    ods excel close;
  
    %errhandl:
    %if &amp;amp;_listing=1 %then %do;
        ods Listing;
    %end;
    %else %do;
        ods listing close;
    %end;
    ods select all;
    ods results;
    options nonotes;
    /**Delete temporary datasets**/
    proc datasets nolist nodetails;
        %if &amp;amp;debug=0 %then %do;
        delete %do i = 1 %to &amp;amp;ndata; _base&amp;amp;i _compare&amp;amp;i _comparison&amp;amp;i  _comparison&amp;amp;i._t _id_lvl_sum_&amp;amp;i _comparison&amp;amp;i._t_sum _comparison&amp;amp;i._t_sum_final %end;
            _var_attr_compare _var_obs_compare _compdict _compdict_ct _compdict_nt _compdict_t
            _basedict _basedict_ct _basedict_nt _basedict_t  _attr_compare  
            ;
        %end;
    quit; 
    /**Reload previous Options**/ 
    ods path &amp;amp;_odspath;
    options mergenoby=&amp;amp;_mergenoby &amp;amp;_notes &amp;amp;_qlm;
    %put COMPARE_ALL has finished processing, runtime: %sysfunc(putn(%sysevalf(%sysfunc(TIME())-&amp;amp;_starttime.),mmss.));    
%mend;


&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;The segment that caused error:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;   proc sql;
       %do i = 1 %to &amp;amp;ndata;
           %if %sysevalf(%superq(removed&amp;amp;i)=,boolean) %then %let removed&amp;amp;i=.;
           %if %sysevalf(%superq(added&amp;amp;i)=,boolean) %then %let added&amp;amp;i=.;
           %if %sysevalf(%superq(any_diff&amp;amp;i)=,boolean) %then %let any_diff&amp;amp;i=.;
           %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
               %if %sysevalf(%superq(any_diff&amp;amp;i._&amp;amp;j)=,boolean) %then %let any_diff&amp;amp;i._&amp;amp;j=0;
           %end;
       %end;
       UPDATE _var_obs_compare
           set lost_observations=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;removed&amp;amp;i
             %end;
             else . end,
             new_observations=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;added&amp;amp;i
             %end;
             else . end,  
             data_changes=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then &amp;amp;&amp;amp;any_diff&amp;amp;i
             %end;
             else . end,  
             id_variables=case(memname)
             %do i = 1 %to &amp;amp;ndata;
                 when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then tranwrd("&amp;amp;&amp;amp;idlist&amp;amp;i",' ',', ')
             %end;
             else '' end;
       UPDATE _var_attr_compare
           set data_changes=case(memname)
                   %do i = 1 %to &amp;amp;ndata;
                       when "%scan(&amp;amp;dlist,&amp;amp;i,|)" then case (upcase(name))
                           %if &amp;amp;&amp;amp;nvar&amp;amp;i&amp;gt;0 %then %do j = 1 %to &amp;amp;&amp;amp;nvar&amp;amp;i;
                               %if %sysevalf(%superq(any_diff&amp;amp;i._&amp;amp;j)^=,boolean) %then %do;
                                    when upcase("%scan(&amp;amp;&amp;amp;vlist&amp;amp;i,&amp;amp;j,|)") then %superq(any_diff&amp;amp;i._&amp;amp;j)
                               %end;
                           %end;
                           %else %do;
                              when "" then .
                           %end;
                           else . end
                   %end;
                   else . end,
               id_variables=case 
                       when upcase(name) in("" %do j = 1 %to %sysfunc(countw(&amp;amp;id,%str( ))); "%qupcase(%scan(&amp;amp;id,&amp;amp;j,%str( )))" %end;) then 'Yes'
                       else 'No' end;           
   quit;&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;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 21:44:31 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802352#M315859</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-15T21:44:31Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802354#M315860</link>
      <description>&lt;P&gt;Try running it with MLOGIC and SYMBOLGEN options turned off and just the MPRINT option turned on.&lt;/P&gt;
&lt;P&gt;Then the SAS log will be easier to read and tell exactly what code it was the macro generated that triggered the error from SAS.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;If I had to guess a cause without actually trying to figure out that long macro I guess that&lt;/P&gt;
&lt;P&gt;1) Your datasets are using non standard variable names and a macro from 10 years ago did not expect that to happen.&lt;/P&gt;
&lt;P&gt;Or&amp;nbsp;&lt;/P&gt;
&lt;P&gt;2) one of the datasets either has no variables or perhaps has no numeric or character variables and the macro was not expecting that situation.&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 21:59:58 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802354#M315860</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-03-15T21:59:58Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802357#M315861</link>
      <description>&lt;P&gt;Hi after turning off the options, here is the log output:&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="lydiawawa_0-1647382212132.png" style="width: 569px;"&gt;&lt;img src="https://communities.sas.com/t5/image/serverpage/image-id/69485i5E4588FFD2D18B10/image-dimensions/569x399?v=v2" width="569" height="399" role="button" title="lydiawawa_0-1647382212132.png" alt="lydiawawa_0-1647382212132.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 22:10:49 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802357#M315861</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-15T22:10:49Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802358#M315862</link>
      <description>I can rule out #2 , both datasets have numeric and character variables.</description>
      <pubDate>Tue, 15 Mar 2022 22:12:19 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802358#M315862</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-15T22:12:19Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802360#M315863</link>
      <description>&lt;P&gt;So it is not generating valid SAS code.&lt;/P&gt;
&lt;P&gt;Not sure what it is trying to do.&amp;nbsp; See if you can find the section where it is trying to generate that SQL UPDATE statement and figure out why it is not generating a valid CASE clause.&amp;nbsp;&lt;/P&gt;
&lt;P&gt;It really looks like it skipped something, like the name of the dataset.&lt;/P&gt;
&lt;P&gt;I would check the steps above the one that is failing.&amp;nbsp; It looks like it is trying to use UPDATE to store the resutls of something.&amp;nbsp; Most likely the results did not get created properly.&amp;nbsp; The failure did not cause a SAS error, but it threw off the macro so that it started generating invalid code.&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 22:16:43 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802360#M315863</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2022-03-15T22:16:43Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802369#M315864</link>
      <description>&lt;P&gt;Strongly suspect that your "error" is not the first problem. You get messages about a Do loop that will not execute because you are going from 1 to 0 (the macro language doesn't like that). So everything inside that loop isn't happening and any code that requires something from that loop will likely fail. That 0 end likely means something much earlier is missing.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;You do not show your actual call to the macro so it isn't even possible for us to see a possible obvious problem.&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 23:15:18 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802369#M315864</guid>
      <dc:creator>ballardw</dc:creator>
      <dc:date>2022-03-15T23:15:18Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802370#M315865</link>
      <description>&lt;P&gt;The problem is your NDATA macro variable resolves to 0 which results in invalid %DO loops. NDATA is defined in this statement:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%let ndata=%sysfunc(countw(&amp;amp;dlist,|));&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;That suggests the macro DLIST is not populated as NDATA is the number of words in DLIST.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;DLIST appears to be a list of tables to be processed. So as others have said, please post the code calling the macro as that is the most likely cause of the errors.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Edit: DLIST is derived from the temporary SAS datasets&amp;nbsp;_basedict and _compdict. Check that these datasets are created and populated.&lt;/P&gt;</description>
      <pubDate>Tue, 15 Mar 2022 23:41:12 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802370#M315865</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-03-15T23:41:12Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802392#M315866</link>
      <description>Hi, this is the code I used to call the macro&lt;BR /&gt;&lt;BR /&gt;%compare_all(base = vdata,&lt;BR /&gt;compare = orig,&lt;BR /&gt;outdoc = /data/output/compare.xlsx);&lt;BR /&gt;&lt;BR /&gt;There are only one dataset in each library respectively, vdata and orig. I don't how would that leads to the error.</description>
      <pubDate>Wed, 16 Mar 2022 00:03:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802392#M315866</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-16T00:03:42Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802393#M315867</link>
      <description>&lt;P&gt;Could it have something to do with the proc contents command section? dlist is imported from &lt;CODE class=""&gt;_basedict&lt;/CODE&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;PRE&gt;&lt;CODE class=""&gt;    proc contents data=&amp;amp;base.._all_
        out=_basedict %if %sysevalf(%superq(select)^=,boolean) %then %do;
           (where=(upcase(memname) in(%do i = 1 %to %sysfunc(countw(%superq(select),%str( )));
                                          "%qupcase(%sysfunc(dequote(%qscan(%superq(select),&amp;amp;i,%str( )))))"
                                      %end;) ))                                            
        %end;
        noprint order=collate;
    proc contents data=&amp;amp;compare.._all_
        out=_compdict %if %sysevalf(%superq(select)^=,boolean) %then %do;
           (where=(upcase(memname) in(%do i = 1 %to %sysfunc(countw(%superq(select),%str( )));
                                          "%qupcase(%sysfunc(dequote(%qscan(%superq(select),&amp;amp;i,%str( )))))"
                                      %end;) ))
        %end;
        noprint order=collate;
    run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Wed, 16 Mar 2022 00:22:47 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802393#M315867</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-16T00:22:47Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802403#M315872</link>
      <description>I think the problem is the datasets compared in the libraries has to have the same name.</description>
      <pubDate>Wed, 16 Mar 2022 02:06:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802403#M315872</guid>
      <dc:creator>lydiawawa</dc:creator>
      <dc:date>2022-03-16T02:06:33Z</dc:date>
    </item>
    <item>
      <title>Re: help with error in macro compare_all</title>
      <link>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802411#M315876</link>
      <description>&lt;P&gt;I think you are correct. You can easily test that by renaming the dataset names to match.&lt;/P&gt;</description>
      <pubDate>Wed, 16 Mar 2022 02:45:33 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Programming/help-with-error-in-macro-compare-all/m-p/802411#M315876</guid>
      <dc:creator>SASKiwi</dc:creator>
      <dc:date>2022-03-16T02:45:33Z</dc:date>
    </item>
  </channel>
</rss>

