Does anyone know why this statement doesn't work? The macro variable PathwayDone is created after the first running of this program in a separate program. After manual research is done, a separate programs runs this program again with the macro variable created so that it continues on to the "nextProgram" .
In separate program:
%Let pathwayDone=1 ; /* This macro variable is created after manual research is done in a separate program that calls the program below.*/
******************
The first time the code below runs should NOT include the nextprogram. sas and should stop.
%Let path = c:\SASprograms\ ;
data _Null_ ;
if %symexist(PathwayDone) then %Include "&path.NextProgram.sas" ;
else do;
%put "**** STOP PROGRAM to RESEARCH RESULTS *****" ;
end;
run;
when you declare
%Let pathwayDone=1 ;
is it a global variable?
Also are these runs taking place in the same sas session?
Yes. Pathwaydone is a global macro variable and programs run in the same session.
This may or may not be a full solution, but DATA steps don't use macro programming tools. The %PUT statement is not part or the DATA step, nor is %SYMEXIST. The DATA step can utilize PUT and SYMEXIST.
%symexist, %include and %put are acted upon immediately when the code is encountered during the collection phase for the data step.
So first %symexist is replaced with its result (1 or 0), next the %include is executed, so you get
data _null_;
if 0 then /* here the complete code of the included file will be placed */;
else do;
end;
run;
%put leaves no code for the data step, it only writes text to the log.
So, depending on the contents of your include file, you will get some error messages until SAS can make sense of a new step, and from then on, the program will execute, followed by ERROR messages for the else do; end; that probably is then invalid code.
Always keep in mind: the macro language is a pre-processor and acted upon first before anything else happens. The only things macro that work inside a running data step are the defined data step interfaces, like call symput() or the symget() function (not the %symget() macro function!!)
Generally, if I see a conditional execution of another program, I would suspect that the process itself is not good. Why can the next program not run? Is it because there is no data, use an empty dataset or one that indicates there is no data. Anyways, you could do:
data _null_ ; if &pathwaydone. then call execute('%Include "&path.NextProgram.sas";'); else do; %put "**** STOP PROGRAM to RESEARCH RESULTS *****" ; end; run;
This will only create the line to call the sas program if pathwaydone=1 (and is global!). Although if it based on how much data, then you could simply use that dataset - say in the below instance abc - and do away with all the macro bits:
data _null_ ; set abc (obs=); call symput('%Include "&path.NextProgram.sas";'); run;
Thank you. It sounds like I should use your first suggestion and not use %symexist (or the one below that I just posted). I have a large project that requires alot of code that can be broken down into separate in-depth blocks of code that need to be processed in a linear fashion (one after the other) so I thought it would be more organized to put these in separate SAS files and use the include statement.
Between the two programs that run the code in question and the one it steps to, there would be down time to do manual research, add data to an existing dataset then re-run the program to refresh calculations and step to the next include file only if the data has been added. I chose to use the global macro variable pathwaydone=1 in a different SAS program to indicate the manual step is complete. Here's another way I tried which seems to work:
%macro emr() ;
%if %symexist(pathwayDone) %then %do;
%Include "&path.NextProgram.sas" ;
%end;
%else %do ;
%put "************ Stop Program. Research additional data, create AppendData csv file **************" ;
%put "******************** When AppendData.csv is ready to import then run SAS script: AppendProgram.SAS (Append Program. sas will refresh data then run Next Program.sas **********************" ;
%end ;
%mend ;
%emr();
So, I do use conditional execution of a program to go to another. If this is not good, what would you suggest? I have about 8 different SAS files using "Include" to run various code. I'm new to SAS and building this sort of data analysis system so I thought this was the easiest way to organize the code. I could create macros then call them in one main program but that started to get confusing and more difficult to explain to co-workers who might be running the programs eventually. I am converting a multi-tab Excel spreadsheet driven by hundreds of columns and formulas to a SAS based dataset so the program files can get long using various data steps, proc SQL, hash objects, etc.
Thanks for your answer and any other ideas are welcome!
To be honest, if its really that complex that you can't have one program which includes various other text files at certain points, then maybe something like Enterprise Guide wouold work for you. In that you can visually setup nodes and links between those nodes and apply conditions on when things get executed. Form what you have written however it seems like two programs to me. One to get you to manual review, and then another for processing the results. Not sure why you would want to combine those separate processes into one.
The best approach really depends on detailed knowledge of what you need to do. For example, a key question would be:
So without that type of detailed knowledge, here's one way to go. It will require use of SAS macro language.
Set up a SAS data set named STATUS with the status of each task:
task_1_status=0;
task_2_status=0;
task_3_status=0;
task_4_status=0;
A human looks at the data and calculations for task 1, and determines that it is ready to run. Outside of your main program, that person changes the STATUS data:
task_1_status=1;
When your main program runs, it brings in this STATUS data set and notices that TASK_1_STATUS=1. So it runs TASK 1 and at the end changes the STATUS data set:
task_1_status=2;
The main program skips all the other steps because their status is 0.
Next, a human examines the results and when the changes have been made for task 2, changes the STATUS data set:
task_2_status=1;
The next time the main program runs, it finds this change, runs TASK 2, and at the end changes the STATUS data set:
task_2_status=2;
One benefit of this approach is that you have a master data set that shows how many steps have been completed thus far.
Thanks for your suggestion. I'll have to think about whether or not it will benefit our purposes. Even with the task database, I would probably use separate programs and use %include to step through the entire process. The main reason why I am combining manual steps with processes is to avoid as many manual steps as possible. One manual step however cannot be automated at this time so the program stops for that processs then picks up again to refresh calculations after adding data. So far, the %include works to step through all the processes and avoids alot of copying/pasting output into Excel in different locations but I am always open to use any SAS efficiencies and appreciate the suggestions you have offered! I will try focusing on the use of macros more for sure. Thanks again.
Build your skills. Make connections. Enjoy creative freedom. Maybe change the world. Registration is now open through August 30th. Visit the SAS Hackathon homepage.
Register today!Learn how use the CAT functions in SAS to join values from multiple variables into a single value.
Find more tutorials on the SAS Users YouTube channel.
Select SAS Training centers are offering in-person courses. View upcoming courses for: