BookmarkSubscribeRSS Feed
☑ This topic is solved. Need further help from the community? Please sign in and ask a new question.
TheEsotericPunk
Fluorite | Level 6

Hi folks, I am losing my mind over something that I thought should be really straightforward. I've searched online for about 3 hours now and can't find any answers. I'm trying to create a macro function that uses some variable value from a prompt to run a set of other programs sequentially. I have tried a dozen or so variations, but the heart of my code comes down to this:

 

%macro choose_progs(which_progs);

     %if &which_progs = set1

          %then %do;

               %include "mypath\folder1\program1.sas";

               %include "mypath\folder1\program2.sas";

          %end;

 

     %else

     %if &which_progs = set2 or 

            &which_progs = set3

          %then %do;

               %include "mypath\folder2\program1.sas";          /* The program names are the same for both sets but the filepath is slightly different */

               %include "mypath\folder2\program2.sas";

          %end;

%mend choose_progs;

 

%choose_progs(set1);

 

If I run this, the first file in set1 runs fine but then ends with a final log entry "NOTE: Extraneous text on %END statement ignored." and the second file never even starts.

If I have the audacity to try and run again to test a change, I just get the following: "NOTE: The quoted string currently being processed has become more than 262 characters long. You might have unbalanced quotation marks." There are definitely no unbalanced quotes, but my file paths are fairly long. All four of these programs will run fine on their own, I just for the life of me can't figure out how to automate this. I've also tried to use %include filePath("folder1\program1.sas", folder1\program2.sas"), but that doesn't work either. It still just runs the first program and stops.

 

Do any of you know what I'm doing wrong here?

1 ACCEPTED SOLUTION

Accepted Solutions
yabwon
Onyx | Level 15

Doesn't your program file contain something like this:

data _null_;
file "R:\file_to_be_included.sas";
input;
put _infile_;
cards4;
proc print data=sashelp.iris(obs=1);
run;

%macro internal_macro();
%if 1=1 %then
%do;
  data test1;
    set sashelp.cars(obs=1);
  run;
%end                       /* <== missing semicolon !!!!!!!!! HERE */
%mend internal_macro;

data test2;
  set sashelp.class(obs=1);
run;
;;;;
run;



%macro choose_progs(which_progs);
     %if &which_progs = set1
          %then %do;
               %include "R:\file_to_be_included.sas" / source2;
     %end;
     %else
     %if &which_progs = set2 or 
         &which_progs = set3
          %then %do;
                    %put THE OTHER CASE!;
                %end;
%mend choose_progs;

 
%choose_progs(set1);

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



View solution in original post

22 REPLIES 22
quickbluefish
Barite | Level 11

My first guess is that it's something to do with what's in those %include programs.  Can you remove those temporarily and just replace with, e.g., 

%put loaded from folder1;


%put loaded from folder2;

If that works, then I suspect you need to look at the included programs.  The only other thing I can think of is that sometimes I've had weird issues with not having a semicolon directly after %MEND (though this is usually just on Linux).  You might try:

* replacing this ;
%MEND choose_programs;

...with this:
%MEND; *choose_programs;
TheEsotericPunk
Fluorite | Level 6

Changing the semicolon to be right after %mend doesn't work. And I guess I don't understand how to use your other suggestion. I replaced the entire %include line with your %put line and it doesn't do anything.

quickbluefish
Barite | Level 11

What I mean is, if you comment out the include statements and replace with notes, do you see the notes in the log and does the program run without errors? 

 .... %then %do;
          /*
           %include /some/path1/prog1.sas;
           %include /some/path1/prog2.sas;  */
          %put **** path1 programs for: &which_progs;
      %end;
      %else %do;
          /*
           %include /some/path2/prog1.sas;
           %include /some/path2/prog2.sas;  */
          %put **** path2 programs for: &which_progs;
      %end;
...

So, the question is, does this program run without error?  Can you run it more than once?  If so, try uncommenting the %include statements one-by-one to see which one breaks it.  Ultimately, though, it might be hard to diagnose your problem without seeing what's going on in the programs you're including. 

 

 

 

 

Ksharp
Super User

I tested you code, and get no problem.

Maybe you need these options to check what is going on your code.

 

%macro choose_progs(which_progs);

     %if &which_progs = set1

          %then %do;

               %include "c:\temp\z\a.sas";

               %include "c:\temp\z\b.sas";

          %end;

 

     %else

     %if &which_progs = set2 or 

            &which_progs = set3

          %then %do;

               %include "c:\temp\z\aa.sas";          /* The program names are the same for both sets but the filepath is slightly different */

               %include "c:\temp\z\bb.sas";

          %end;

%mend choose_progs;

 
option mprint mlogic symbolgen;
%choose_progs(set2);

Here is LOG:

1    %macro choose_progs(which_progs);
2
3         %if &which_progs = set1
4
5              %then %do;
6
7                   %include "c:\temp\z\a.sas";
8
9                   %include "c:\temp\z\b.sas";
10
11             %end;
12
13
14
15        %else
16
17        %if &which_progs = set2 or
18
19               &which_progs = set3
20
21             %then %do;
22
23                  %include "c:\temp\z\aa.sas";          /* The program names are the same for both sets but the filepath is
23 ! slightly different */
24
25                  %include "c:\temp\z\bb.sas";
26
27             %end;
28
29   %mend choose_progs;
30
31
32   option mprint mlogic symbolgen;
33   %choose_progs(set2);
MLOGIC(CHOOSE_PROGS):  Beginning execution.
MLOGIC(CHOOSE_PROGS):  Parameter WHICH_PROGS has value set2
SYMBOLGEN:  Macro variable WHICH_PROGS resolves to set2
MLOGIC(CHOOSE_PROGS):  %IF condition &which_progs = set1 is FALSE
SYMBOLGEN:  Macro variable WHICH_PROGS resolves to set2
SYMBOLGEN:  Macro variable WHICH_PROGS resolves to set2
MLOGIC(CHOOSE_PROGS):  %IF condition &which_progs = set2 or              &which_progs = set3 is TRUE
NOTE: Writing HTML Body file: sashtml.htm
MPRINT(CHOOSE_PROGS):   proc print data=sashelp.class(obs=1);
MPRINT(CHOOSE_PROGS):  run;

NOTE: There were 1 observations read from the data set SASHELP.CLASS.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.78 seconds
      cpu time            0.45 seconds


MPRINT(CHOOSE_PROGS):   proc print data=sashelp.heart(obs=1);
MPRINT(CHOOSE_PROGS):  run;

NOTE: There were 1 observations read from the data set SASHELP.HEART.
NOTE: PROCEDURE PRINT used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


MLOGIC(CHOOSE_PROGS):  Ending execution.











Kurt_Bremser
Super User

Anytime you get

NOTE: The quoted string currently being processed has become more than 262 characters long. You might have unbalanced quotation marks.

you have to look for something unbalanced in the code. Unbalanced quotes, missing closing parentheses, %MACRO without a proper %MEND, and so on.

Note that you do not need to create and execute a macro if you only have simple unnested %IF %THEN %DO. You can run those in "open code" and remove at least part of the complexity, particularly for testing.

 

What do your include files contain? If there are more macro definitions in there, they might be part if the problem.

 

Start wit a simplified version of the process (as already suggested) and expand from there until you get a problem; you will then have clear clue where to look.

TheEsotericPunk
Fluorite | Level 6

When you say "If there are more macro definitions in there, they might be part of the problem", what do you mean by that? The files I am trying to add with %include do have other macros in them, however I have tested them all for months and they all run flawlessly on their own. All I am trying to do is wrap them all together into one process that chooses which set of files to run based on a user prompt. I have been trying to work with a simplified version of the process; the code I sent is only testing with two program files, but eventually there will be around 15 files per path. What's happening is this:

 

1. I run the code and it correctly selects the filepath.

2. It runs the first %include program just fine.

3. The log shows "NOTE: %INCLUDE (level 1) ending."

4. It starts the second file with log: "NOTE: %INCLUDE (level 1) file mypath\folder1\program2.sas is file mypath\folder1\program2.sas."

5. The log shows all of the code from program2 but none of it runs.

6. After a macro function within program2 is ended, the log generates "NOTE: Extraneous text on %END statement ignored." and then the code stops running and gives another "NOTE: %INCLUDE (level 1) ending."

 

From my actual code log here is what that looks like: 

 

1858 +%mend choose_data;                                           This is the end of the macro within program2
NOTE: Extraneous text on %END statement ignored.
1859 +
1860 +/* Run population data creation */                    These are the lines that run the macro in program2
1861 +%choose_data(&use_data.);                                 except they don't actually run.

 

So, I think when you say that having macro definitions within this may be a problem, you might be on to something.

 

Regarding the unbalanced note I get, I have looked for anything unbalanced but can't find anything. As I said above, all the %include programs run with no warnings or errors, so they are all closed fine. Another user (Ksharp) mentioned that they tried my code and it worked fine, so I think it's balanced. This is one of the parts that's so maddening. When I open SAS EG I can run the code and just get the situation above (first program runs, second one doesn't). If I try to run a second time, that's when the unbalanced error comes up and then nothing runs at all. I have to completely close and restart SAS EG to try again.

TheEsotericPunk
Fluorite | Level 6

I should also add that the program1 file contains macros also, but those don't seem to cause any issues. It seems only the macro in program2 causes problems. But again, I can't understand why.

Tom
Super User Tom
Super User

Remove the macro from your calling program.  It is not needed unless you are running some ancient version of SAS that does not support simple %IF/%THEN/%DO/%END blocks in open code.

 

If you are running some ancient version then:

 

Check the line lengths of your included programs just to make sure that is not an issue.  A simple data step will tell you in the notes the maximum line length read.

data _null_;
  infile 'myfile.sas' expandtabs;
  input;
run;

Make sure the programs do not have any data steps that use in-line data (or PARMCARDS statements) as those are not allowing inside of a macro.

 

The error message in your original message was about a missing semicolon following an %END statement.  Not a %MEND statement.  

 

Also check your programs for any STATEMENT comments.  Those are comments that start with * and end with ;.  In open code you can have unbalanced quotes inside of statement comments, like:

* Don't use unbalanced quotes in statement comments ;

But if you wrap that in a macro then the macro processor will treat * and Don as two tokens and then hunt for the closing quote and so "eat" the semi-colon.

DataCruncherX
Fluorite | Level 6

Hey! %include doesn’t work well inside a macro like that because it runs before the macro finishes. Try using %include outside the macro or use call execute() if you want to include files based on a condition. Hope this helps!

yabwon
Onyx | Level 15

" %include doesn’t work well inside a macro like that because it runs before the macro finishes. " - please explain what do you mean by this sentence? Because in the form it is, it is false.

 

Bart

_______________
Polish SAS Users Group: www.polsug.com and communities.sas.com/polsug

"SAS Packages: the way to share" at SGF2020 Proceedings (the latest version), GitHub Repository, and YouTube Video.
Hands-on-Workshop: "Share your code with SAS Packages"
"My First SAS Package: A How-To" at SGF2021 Proceedings

SAS Ballot Ideas: one: SPF in SAS, two, and three
SAS Documentation



Tom
Super User Tom
Super User

Most likely the value passed in does not match either %IF condition so none of the include statements run.

 

Since the only difference is the path just put the path into a macro variable.  Then you only need to code one set of %INCLUDE statements.  

 

Amir
PROC Star

Hi,

 

Not sure what version of SAS you are using, but try checking your log for the below warning, once your %include has been invoked:

 

 

WARNING: Truncated record.

 

 

 

This can indicate that a line of code has been truncated in the %include code (due to its line length), which in turn can exhibit the symptoms you have described. If you find the message in the log, then try referring to 39619 - Options you can use on the %INCLUDE statement such as a LRECL= specification to see if that helps.

 

 

Thanks & kind regards,

Amir.

TheEsotericPunk
Fluorite | Level 6

I don't get that warning.

Patrick
Opal | Level 21

@Ksharp already demonstrated that the syntax as such is o.k. so it must be an issue with the code you're including. 

To get more info into the log for debugging, execute your macro with the following options:

option mprint mlogic symbolgen source2; 

So something like:

option mprint mlogic symbolgen source2; 
%macro choose_progs(which_progs);
  %if &which_progs = set1 %then
    %do;
      %include "mypath\folder1\program1.sas";
      %include "mypath\folder1\program2.sas";
    %end;
  %else
  %if &which_progs = set2 or &which_progs = set3 %then 
    %do;
      %include "mypath\folder2\program1.sas";
      %include "mypath\folder2\program2.sas";
    %end;
%mend choose_progs;

%choose_progs(set1);

 

What happens if you run the selected %include statements outside of the macro?

      %include "mypath\folder1\program1.sas" /source2;
      %include "mypath\folder1\program2.sas" /source2;

hackathon24-white-horiz.png

The 2025 SAS Hackathon Kicks Off on June 11!

Watch the live Hackathon Kickoff to get all the essential information about the SAS Hackathon—including how to join, how to participate, and expert tips for success.

YouTube LinkedIn

How to Concatenate Values

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.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 22 replies
  • 1834 views
  • 13 likes
  • 10 in conversation
OSZAR »