<?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: issue with the varexist function in SAS Enterprise Guide</title>
    <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947178#M45386</link>
    <description>&lt;P&gt;The macro looks fine to me, but without having the data it's hard to know what's&amp;nbsp; happening in your CALL EXECUTE step.&amp;nbsp; I didn't test that it works with the SPDE engine.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I would a %PUT statement to your macro, to have it write to the log the value for the parameters &amp;amp;ds, &amp;amp;var, and also the returned value.&amp;nbsp; It's possible you'll be surprised by those values.&amp;nbsp; Something like:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro varexist
/*----------------------------------------------------------------------
Check for the existence of a specified variable.
----------------------------------------------------------------------*/
(ds        /* Data set name */
,var       /* Variable name */
,debug=0
);

/*----------------------------------------------------------------------
Usage Notes:

%if %varexist(&amp;amp;data,NAME)
  %then %put input data set contains variable NAME;

The macro calls resolves to 0 when either the data set does not exist
or the variable is not in the specified data set.
----------------------------------------------------------------------*/

%local dsid rc return;

/*----------------------------------------------------------------------
Use SYSFUNC to execute OPEN, VARNUM, and CLOSE functions.
-----------------------------------------------------------------------*/

%let dsid = %sysfunc(open(&amp;amp;ds));

%if (&amp;amp;dsid) %then %do;
  %if %sysfunc(varnum(&amp;amp;dsid,&amp;amp;var)) %then %let return=1;
  %else %let return=0 ;
  %let rc = %sysfunc(close(&amp;amp;dsid));
%end;
%else %let return=0;
%if &amp;amp;debug=1 %then %do ;
  %put macro call %nrstr(%%)VAREXIST(&amp;amp;ds,&amp;amp;var) returns: &amp;amp;return ;
%end ;
&amp;amp;return
%mend varexist;


%put &amp;gt;&amp;gt;%varexist(sashelp.class,name,debug=1)&amp;lt;&amp;lt; ;
%put &amp;gt;&amp;gt;%varexist(sashelp.class,nope,debug=1)&amp;lt;&amp;lt; ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 11 Oct 2024 19:18:55 GMT</pubDate>
    <dc:creator>Quentin</dc:creator>
    <dc:date>2024-10-11T19:18:55Z</dc:date>
    <item>
      <title>issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947177#M45385</link>
      <description>&lt;P&gt;Hello,&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I have issue with my if %varexist funtion or may be with the if else condition, because it never goes into the else portion of the script.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;libname dest3 spde "/.../Temp/Alain/DR";

data workingpremiumds2 ;
set dest1.workingpremiumds2 (firstobs=1 obs=5);
run;

/********************** Macro function variable exist ********************************************/
%macro varexist
/*----------------------------------------------------------------------
Check for the existence of a specified variable.
----------------------------------------------------------------------*/
(ds        /* Data set name */
,var       /* Variable name */);

/*----------------------------------------------------------------------
Usage Notes:

%if %varexist(&amp;amp;data,NAME)
  %then %put input data set contains variable NAME;

The macro calls resolves to 0 when either the data set does not exist
or the variable is not in the specified data set.
----------------------------------------------------------------------*/

%local dsid rc ;

/*----------------------------------------------------------------------
Use SYSFUNC to execute OPEN, VARNUM, and CLOSE functions.
-----------------------------------------------------------------------*/

%let dsid = %sysfunc(open(&amp;amp;ds));

%if (&amp;amp;dsid) %then %do;
  %if %sysfunc(varnum(&amp;amp;dsid,&amp;amp;var)) %then 1;
  %else 0 ;
  %let rc = %sysfunc(close(&amp;amp;dsid));
%end;
%else 0;
%mend varexist;



data _null_;
   set workingpremiumds2;
   call execute
   (compbl(cat(
   "libname source  ", engine,' "',strip(path),'";',   
   '%nrstr(%if %varexist(dest3.',strip(fname),'ORGNL_SAS_DS_ROW_NBR) = 0 %then %do;
    data dest3.',strip(fname),'; ORGNL_SAS_DS_ROW_NBR=_n_; set source.',strip(fname),';run;%end;%else %do;%put ','"the variable already exist";%end;)',    
   "libname source clear;" 
    )));
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;When I empty the folder /.../Temp/Alain/DR then I run the script, it will create 5 datasets with the variable ORGNL_SAS_DS_ROW_NBR.&amp;nbsp; But if I select only from data _null_; ...run; the 5 datasets already exist as well as the variable&amp;nbsp;ORGNL_SAS_DS_ROW_NBR so, it should put into the log file that the variable already exits. and not recreate the 5 datasets.&amp;nbsp;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But it always recreate the 5 datasets so I suspect that it never goes into the else condition.&lt;/P&gt;
&lt;P&gt;Please provide some help.&lt;/P&gt;</description>
      <pubDate>Fri, 11 Oct 2024 18:09:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947177#M45385</guid>
      <dc:creator>alepage</dc:creator>
      <dc:date>2024-10-11T18:09:45Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947178#M45386</link>
      <description>&lt;P&gt;The macro looks fine to me, but without having the data it's hard to know what's&amp;nbsp; happening in your CALL EXECUTE step.&amp;nbsp; I didn't test that it works with the SPDE engine.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I would a %PUT statement to your macro, to have it write to the log the value for the parameters &amp;amp;ds, &amp;amp;var, and also the returned value.&amp;nbsp; It's possible you'll be surprised by those values.&amp;nbsp; Something like:&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro varexist
/*----------------------------------------------------------------------
Check for the existence of a specified variable.
----------------------------------------------------------------------*/
(ds        /* Data set name */
,var       /* Variable name */
,debug=0
);

/*----------------------------------------------------------------------
Usage Notes:

%if %varexist(&amp;amp;data,NAME)
  %then %put input data set contains variable NAME;

The macro calls resolves to 0 when either the data set does not exist
or the variable is not in the specified data set.
----------------------------------------------------------------------*/

%local dsid rc return;

/*----------------------------------------------------------------------
Use SYSFUNC to execute OPEN, VARNUM, and CLOSE functions.
-----------------------------------------------------------------------*/

%let dsid = %sysfunc(open(&amp;amp;ds));

%if (&amp;amp;dsid) %then %do;
  %if %sysfunc(varnum(&amp;amp;dsid,&amp;amp;var)) %then %let return=1;
  %else %let return=0 ;
  %let rc = %sysfunc(close(&amp;amp;dsid));
%end;
%else %let return=0;
%if &amp;amp;debug=1 %then %do ;
  %put macro call %nrstr(%%)VAREXIST(&amp;amp;ds,&amp;amp;var) returns: &amp;amp;return ;
%end ;
&amp;amp;return
%mend varexist;


%put &amp;gt;&amp;gt;%varexist(sashelp.class,name,debug=1)&amp;lt;&amp;lt; ;
%put &amp;gt;&amp;gt;%varexist(sashelp.class,nope,debug=1)&amp;lt;&amp;lt; ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 11 Oct 2024 19:18:55 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947178#M45386</guid>
      <dc:creator>Quentin</dc:creator>
      <dc:date>2024-10-11T19:18:55Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947186#M45388</link>
      <description>&lt;P&gt;Can you explain what you are trying to do?&amp;nbsp; Your current logic only copies the datasets that do NOT have the variable.&amp;nbsp; What about the ones that do have the variable?&amp;nbsp; Wouldn't you want to copy them also?&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;I suspect you might have generated slightly invalid code? Perhaps a missing comma or an extra comma?&amp;nbsp; You could try stuffing the result of your string expression into a character variable in the data _null_ step and then PUT it to the SAS log and make sure it generated valid code to pass to CALL EXECUTE().&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But trying to use CALL EXECUTE can really mess up the timing of when macro code runs.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Try converting the code generation data step so that it writes the code to a file instead of trying to get CALL EXECUTE to push it onto the stack to run.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;So something like this (note this also means you can use the power of the data step PUT statement to make the code simpler and the generated code clearer.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;filename code temp;
data _null_;
   set workingpremiumds2;
   file code;
   put "libname source " engine path :$quote. ';' 
     / '%if 0=%varexist(dest3.' fname ',ORGNL_SAS_DS_ROW_NBR) %then %do;'
     / '  data dest3.' fname ';'
     / '   ORGNL_SAS_DS_ROW_NBR=_n_;'
     / '   set source.' fname ';'
     / '  run;'
     / '%end;%else %do;'
     / '  proc copy inlib=source outlib=dest3; select ' fname '; run;'
     / '%end;'
     / 'libname source clear;'
   ;
run;
%include code / source2 ;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Another way would be to wrap your macro logic into a another macro.&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;%macro doit(engine,path,fname,varname);
libname source &amp;amp;engine &amp;amp;path ;
%if 0=%varexist(dest3.&amp;amp;fname,&amp;amp;varname) %then %do;
  data dest3.&amp;amp;fname;
     &amp;amp;varname=_n_;
     set source.&amp;amp;fname;
  run;
%end;
%else %do;
   proc copy inlib=source outlib=dest3; select &amp;amp;fname; run;
%end;
libname source clear;
%mend doit;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;Then the CALL EXECUTE() code would not have to content with trying to prevent the %IF and %ELSE from running at the wrong time.&amp;nbsp; But it is still useful to prevent the running of the macro at the wrong time, so wrap the %macroname inside of %NRSTR().&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data _null_;
  set workingpremiumds2;
  call execute(cats('%nrstr(%doit)(',engine
     ,',',quote(trim(path))
     ,',',fname
     ,',ORGNL_SAS_DS_ROW_NBR)'))
  ;
run;&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;PS Why not just use CATS() or CATX() instead of CAT()?&amp;nbsp; Then you can remove the multiple calls to the STRIP() function and the call to COMPBL().&lt;/P&gt;</description>
      <pubDate>Sat, 12 Oct 2024 02:02:15 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947186#M45388</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2024-10-12T02:02:15Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947197#M45389</link>
      <description>I want to read a dataset from source, then check if the variable ORGL_SAS_DS_ROW_NBR exist and if not then add the variable and copy the dataset at dest3. Otherwise, put into the log file, the variable already exist.</description>
      <pubDate>Sat, 12 Oct 2024 01:16:45 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947197#M45389</guid>
      <dc:creator>alepage</dc:creator>
      <dc:date>2024-10-12T01:16:45Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947199#M45390</link>
      <description>&lt;P&gt;I still think it would be easier to use the data _null_ step define the libref and to test if the variable exists rather then having to use your %VAREXIST() macro.&amp;nbsp; Easier to code and much easier to debug.&amp;nbsp; Plus you can save the status of the test into a dataset rather only to the SAS log.&amp;nbsp; And you could use CALL EXECUTE() without having to worry about timing issues.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data results;
   set workingpremiumds2;
   length fileref $8 inname outname $41 varnum 8 ;
   rc=libname(fileref,path,engine);
   if rc then do;
      inname=catx('.',fileref,fname);
      dsid=open(inname);
      if dsid then do;
        varnum=(dsid,'ORGNL_SAS_DS_ROW_NBR');
        dsid=close(dsid);
      end;
   end;
   if 0=varnum then do;
      outname=catx('.','dest3',fname);
      putlog 'NOTE: Copying ' inname 'to ' outname 'to add ORGNL_SAS_DS_ROW_NBR.';
      call execute(catx(' '
         ,'data',outname,';ORGNL_SAS_DS_ROW_NBR=_n_;set',inname,';run;'
         ,'libname',libref,'clear;'
      ));
   end;
   else 0&amp;lt;varnum then putlog 'NOTE: ORGNL_SAS_DS_ROW_NBR already exists in ' inname '.';
   else putlog 'NOTE: Unable to find ' fname= engine= path= ;
run;&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>Sat, 12 Oct 2024 02:54:42 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947199#M45390</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2024-10-12T02:54:42Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947211#M45391</link>
      <description>&lt;P&gt;I do not think that you need your %VAREXIST macro at all; using the VARNUM function in the DATA step itself will be&amp;nbsp;&lt;U&gt;much&lt;/U&gt; easier and straightforward.&lt;/P&gt;
&lt;P&gt;I also recommend to write to a temporary file and %INCLUDE that; CALL EXECUTE becomes unwieldy with complex code, and a temporary file allows checking the file before you use it in %INCLUDE.&lt;/P&gt;
&lt;P&gt;Example:&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data workingpremiumds2;
input path :$200. fname :$32.;
datalines;
/home/kurt.bremser/mylib class
;

data mylib.class;
set sashelp.class;
run;

libname dest3 "~/dest3";

/* up to here, everything is just preparation */

%let checkvar = ORGNL_SAS_DS_ROW_NBR;

filename incfile temp;

data _null_;
set workingpremiumds2;
file incfile;
length fileref $8 line $80;
fileref = "SOURCE";
rc = libname(fileref,path);
if rc = 0 or findw(sysmsg(),"ERROR") = 0
then do;
  did = open(catx(".",fileref,fname));
  putlog did=;
  if did
  then do;
    rc = varnum(did,upcase("&amp;amp;checkvar."));
    if rc = 0
    then do;
      line = cats("libname source '",path,"';");
      put line;
      line = cats("data dest3.",fname,";");
      put line;
      line = cats("set source.",fname,";");
      put line;
      line = "&amp;amp;checkvar. = _n_;";
      put line;
      put "run;";
      put "libname source clear;";
    end;
    rc = close(did);
  end;
  rc = libname(fileref,"");
end;
run;

data _null_;
infile incfile;
input;
put _infile_;
run;&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Sat, 12 Oct 2024 15:00:32 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947211#M45391</guid>
      <dc:creator>Kurt_Bremser</dc:creator>
      <dc:date>2024-10-12T15:00:32Z</dc:date>
    </item>
    <item>
      <title>Re: issue with the varexist function</title>
      <link>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947230#M45394</link>
      <description>&lt;P&gt;Here is an example that is similar to what you are trying that illustrates the timing issue of trying to issue macro code via CALL EXECUTE.&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-sas"&gt;data class; set sashelp.class; run;
data _null_;
  call execute('libname source (work);');
  call execute('%put not quoted=%varexist(source.class,sex);');
  call execute('%nrstr(%put) nrstr quoted=%nrstr(%varexist)(source.class,sex);');
  call execute('libname source clear;');
run;
&lt;/CODE&gt;&lt;/PRE&gt;
&lt;P&gt;So we are trying to run code that&amp;nbsp;&lt;/P&gt;
&lt;P&gt;1) Sets up a libname.&lt;/P&gt;
&lt;P&gt;2) Checks for the existence of a variable in a dataset in that libname.&lt;/P&gt;
&lt;P&gt;3) Clears the libname.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The example has two different methods of coding the second item.&amp;nbsp; One with no macro quoting.&amp;nbsp; And one with %NRSTR() wrapped around each macro function or macro statement or macro call.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Here is the resulting SAS log&lt;/P&gt;
&lt;PRE&gt;1    data class; set sashelp.class; run;

NOTE: The data set WORK.CLASS has 19 observations and 5 variables.
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


2    data _null_;
3      call execute('libname source (work);');
4      call execute('%put not quoted=%varexist(source.class,sex);');
5      call execute('%nrstr(%put) nrstr quoted=%nrstr(%varexist)(source.class,sex);');
6      call execute('libname source clear;');
7    run;

not quoted=0
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


NOTE: CALL EXECUTE generated line.
1   + libname source (work);
NOTE: Libref SOURCE was successfully assigned as follows:
      Levels:           1
      Engine(1):        V9
      Physical Name(1): (system-specific file/path name)
2   + %put nrstr quoted=%varexist(source.class,sex);
nrstr quoted=1
3   + libname source clear;
NOTE: Libref SOURCE has been deassigned.
&lt;/PRE&gt;
&lt;P&gt;As you can see the %PUT without the macro quoting ran while the DATA _NULL_ step was still working and since the libref SOURCE had not yet been defined the %VAREXIST() function call did not find the variable.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;But the second one ran after the data step.&amp;nbsp; And after the LIBNAME statement so it did find that SEX existed in SOURCE.CLASS.&amp;nbsp; Plus you can see the actual source code that CALL EXECUTE() was able to push onto the stack to run after the data _NULL_ step.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Sun, 13 Oct 2024 01:38:08 GMT</pubDate>
      <guid>https://communities.sas.com/t5/SAS-Enterprise-Guide/issue-with-the-varexist-function/m-p/947230#M45394</guid>
      <dc:creator>Tom</dc:creator>
      <dc:date>2024-10-13T01:38:08Z</dc:date>
    </item>
  </channel>
</rss>

