BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
emaguin
Quartz | Level 8

Special question that i've been wanting to ask. Can i search the, i guess it would be the communities database, for my name, to see what i asked in the past?

 

Real question: I've looked at the documentation and it looks like it ought to work but NO, it doesn't. What don't i understand?

array vpcl{20} A2PCL1-A2PCL20;
if (A2LECPOS ge 1) then
do i=1 to 20;
vpcl{i}=vpcl{i}-1;
end;
do;
A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
end;
else if (A2LECPOS eq 0) then
do
A2PCLRXP=.s;
A2PCLAVD=.s;
end;
else do
A2PCLRXP=.p;
A2PCLAVD=.p;
end;

Thanks gene maguin

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

@emaguin wrote:
Please, I'd also like answer to the special question: can I search the database by name (mine)?



Yes, in advanced search you can specify the user to find their posts and responses.

Click on the magnifying glass on the search to get to the Advanced Search page.

Then click on Author and type in your ID and any terms you want to search. 

 

You fixed the semicolons but didn't fix the first issue so you need to resolve that first DO issue. Your logic below isn't clear enough for me to follow, which five computation statements? Which blocks are you skipping over when you have multiple? Comment with your code with what you expect to happen and someone will be able to figure it out from there most likely.

 


@emaguin wrote:
Please, I'd also like answer to the special question: can I search the database by name (mine)?
Ok, back to this. i added semicolons after the do's and the documentation shows that.
I thought about adding a narrative description and didn't. Here it is. If A2LECPOS ge 1, I want the do loop to execute and then go on to execute the five computation statements and skip over the else if and else blocks. However, it A2LECPOS eq 0, only the statements in the else if block are executed. Lastly, if A2LECPOS equals anything else (here, '.'), only the statements in the else block are executed.
Do loops have to have their own 'end' statement. How else does the compiler/interpreter know where the loop ends at. Maybe (probably) I misunderstood one respondent saying that the do loop 'end' statement is interpreted as the end of the if block. 'end' seems to have multiple meanings and, worse, they are contextual.
2765 array vpcl{20} A2PCL1-A2PCL20;
2766 if (A2LECPOS ge 1) then
2767 do i=1 to 20;
2768 vpcl{i}=vpcl{i}-1;
2769 end;
2770 do;
2771 A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
2772 A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
2773 A2PCLNCM=round(mean (of A2PCLP8 A2PCLP9 A2PCLP10 A2PCLP11 A2PCLP12
2774 A2PCLP13 A2PCLP14)*7);
2775 A2PCLHA=round(mean (of A2PCLP15 A2PCLP16 A2PCLP17 A2PCLP18 A2PCLP19
2776 A2PCLP20)*6);
2777 A2PCLTOT=mean (of A2PCLP1-A2PCLP20);
2778 end;
2779 else if (A2LECPOS eq 0) then do;
----
160
ERROR 160-185: No matching IF-THEN clause.

2780 A2PCLRXP=.s;
2781 A2PCLAVD=.s;
2782 A2PCLNCM=.s;
2783 A2PCLHA=.s;
2784 A2PCLTOT=.s;
2785 end;
2786 else do;
2787 A2PCLRXP=.p;
2788 A2PCLAVD=.p;
2789 A2PCLNCM=.p;
2790 A2PCLHA=.p;
2791 A2PCLTOT=.p;
2792 end;
2793 run;



 

 

View solution in original post

9 REPLIES 9
gamotte
Rhodochrosite | Level 12
Hello,

Please define "does not work". Can you post an extract of the log ?

After the loop you have a "do" that has no corresponding then or else.
Reeza
Super User

To find historical posts, click your name and on top of any post and your About page will have your prior posts. 

 

You're missing semicolons after your DO statements and have a DO statement without an IF/ELSE which is likely causing you issues syntax wise.

Since we don't know what you're trying to do, there's no way to say if the code is logically correct or not.

 

array vpcl{20} A2PCL1-A2PCL20;
if (A2LECPOS ge 1) then
do i=1 to 20;
vpcl{i}=vpcl{i}-1;
end;

*DO alone? Should this be an ELSE;
do;
A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);

*Which do should this match to?;
end; 

else if (A2LECPOS eq 0) then
do *missing semicolon;
A2PCLRXP=.s;
A2PCLAVD=.s;
end;
else do * missing semicolon;
A2PCLRXP=.p;
A2PCLAVD=.p;
end;

@emaguin wrote:

Special question that i've been wanting to ask. Can i search the, i guess it would be the communities database, for my name, to see what i asked in the past?

 

Real question: I've looked at the documentation and it looks like it ought to work but NO, it doesn't. What don't i understand?

array vpcl{20} A2PCL1-A2PCL20;
if (A2LECPOS ge 1) then
do i=1 to 20;
vpcl{i}=vpcl{i}-1;
end;
do;
A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
end;
else if (A2LECPOS eq 0) then
do
A2PCLRXP=.s;
A2PCLAVD=.s;
end;
else do
A2PCLRXP=.p;
A2PCLAVD=.p;
end;

Thanks gene maguin


 

Reeza
Super User
The missing semicolons won't generate an syntax error because that type of coding is valid if you only have one thing you want to do in an IF block. There are multiple statements so you need the semicolon version of the DO statement.

If <condition> then do;
...multiple sas statements;
end;
else if .... then do;
... multiple SAS statements...
end;
else do;
... multiple SAS statements...
end;

Single SAS statement version is:

if <condition> then do ..single SAS statement...;
Tom
Super User Tom
Super User

This does not look valid:

if <condition> then do ...single SAS statement...;

If you remove the DO it is valid:

if <condition> then ...single SAS statement...;

You can have any type DO statement as the "...single SAS statement...", in which case you will need to have an END to mark the end of the DO block (and also the end of the THEN clause).

if <condition> then do; ...multiple SAS statements...; end;
if <condition> then do i=1 to 10; ...multiple SAS statements...; end;
if <condition> then do while(<condition2>); ...multiple SAS statements...; end;
if <condition> then do until(<condition2>); ...multiple SAS statements...; end;
if <condition> then do i=1 to 10 while(condition2); ...multiple SAS statements...; end;

 

emaguin
Quartz | Level 8
Please, I'd also like answer to the special question: can I search the database by name (mine)?
Ok, back to this. i added semicolons after the do's and the documentation shows that.
I thought about adding a narrative description and didn't. Here it is. If A2LECPOS ge 1, I want the do loop to execute and then go on to execute the five computation statements and skip over the else if and else blocks. However, it A2LECPOS eq 0, only the statements in the else if block are executed. Lastly, if A2LECPOS equals anything else (here, '.'), only the statements in the else block are executed.
Do loops have to have their own 'end' statement. How else does the compiler/interpreter know where the loop ends at. Maybe (probably) I misunderstood one respondent saying that the do loop 'end' statement is interpreted as the end of the if block. 'end' seems to have multiple meanings and, worse, they are contextual.
2765 array vpcl{20} A2PCL1-A2PCL20;
2766 if (A2LECPOS ge 1) then
2767 do i=1 to 20;
2768 vpcl{i}=vpcl{i}-1;
2769 end;
2770 do;
2771 A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
2772 A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
2773 A2PCLNCM=round(mean (of A2PCLP8 A2PCLP9 A2PCLP10 A2PCLP11 A2PCLP12
2774 A2PCLP13 A2PCLP14)*7);
2775 A2PCLHA=round(mean (of A2PCLP15 A2PCLP16 A2PCLP17 A2PCLP18 A2PCLP19
2776 A2PCLP20)*6);
2777 A2PCLTOT=mean (of A2PCLP1-A2PCLP20);
2778 end;
2779 else if (A2LECPOS eq 0) then do;
----
160
ERROR 160-185: No matching IF-THEN clause.

2780 A2PCLRXP=.s;
2781 A2PCLAVD=.s;
2782 A2PCLNCM=.s;
2783 A2PCLHA=.s;
2784 A2PCLTOT=.s;
2785 end;
2786 else do;
2787 A2PCLRXP=.p;
2788 A2PCLAVD=.p;
2789 A2PCLNCM=.p;
2790 A2PCLHA=.p;
2791 A2PCLTOT=.p;
2792 end;
2793 run;


Reeza
Super User

@emaguin wrote:
Please, I'd also like answer to the special question: can I search the database by name (mine)?



Yes, in advanced search you can specify the user to find their posts and responses.

Click on the magnifying glass on the search to get to the Advanced Search page.

Then click on Author and type in your ID and any terms you want to search. 

 

You fixed the semicolons but didn't fix the first issue so you need to resolve that first DO issue. Your logic below isn't clear enough for me to follow, which five computation statements? Which blocks are you skipping over when you have multiple? Comment with your code with what you expect to happen and someone will be able to figure it out from there most likely.

 


@emaguin wrote:
Please, I'd also like answer to the special question: can I search the database by name (mine)?
Ok, back to this. i added semicolons after the do's and the documentation shows that.
I thought about adding a narrative description and didn't. Here it is. If A2LECPOS ge 1, I want the do loop to execute and then go on to execute the five computation statements and skip over the else if and else blocks. However, it A2LECPOS eq 0, only the statements in the else if block are executed. Lastly, if A2LECPOS equals anything else (here, '.'), only the statements in the else block are executed.
Do loops have to have their own 'end' statement. How else does the compiler/interpreter know where the loop ends at. Maybe (probably) I misunderstood one respondent saying that the do loop 'end' statement is interpreted as the end of the if block. 'end' seems to have multiple meanings and, worse, they are contextual.
2765 array vpcl{20} A2PCL1-A2PCL20;
2766 if (A2LECPOS ge 1) then
2767 do i=1 to 20;
2768 vpcl{i}=vpcl{i}-1;
2769 end;
2770 do;
2771 A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
2772 A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
2773 A2PCLNCM=round(mean (of A2PCLP8 A2PCLP9 A2PCLP10 A2PCLP11 A2PCLP12
2774 A2PCLP13 A2PCLP14)*7);
2775 A2PCLHA=round(mean (of A2PCLP15 A2PCLP16 A2PCLP17 A2PCLP18 A2PCLP19
2776 A2PCLP20)*6);
2777 A2PCLTOT=mean (of A2PCLP1-A2PCLP20);
2778 end;
2779 else if (A2LECPOS eq 0) then do;
----
160
ERROR 160-185: No matching IF-THEN clause.

2780 A2PCLRXP=.s;
2781 A2PCLAVD=.s;
2782 A2PCLNCM=.s;
2783 A2PCLHA=.s;
2784 A2PCLTOT=.s;
2785 end;
2786 else do;
2787 A2PCLRXP=.p;
2788 A2PCLAVD=.p;
2789 A2PCLNCM=.p;
2790 A2PCLHA=.p;
2791 A2PCLTOT=.p;
2792 end;
2793 run;



 

 

Kurt_Bremser
Super User

See my comments:

array vpcl{20} A2PCL1-A2PCL20;
if (A2LECPOS ge 1) then
do i=1 to 20;
vpcl{i}=vpcl{i}-1;
end; /* this semicolon ends the first IF statement */
do; /* therefore this is a stand-alone do/end */
A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
end; /* which makes the following else miss its if */
else if (A2LECPOS eq 0) then
do /* here there is no semicolon */
A2PCLRXP=.s;
A2PCLAVD=.s;
end;
else do /* again, no semicolon */
A2PCLRXP=.p;
A2PCLAVD=.p;
end;

Could it be you wanted this:

array vpcl{20} A2PCL1-A2PCL20;
if (A2LECPOS ge 1)
then do;
  do i = 1 to 20;
    vpcl{i} = vpcl{i}-1;
  end;
  A2PCLRXP = round(mean(of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5) * 5);
  A2PCLAVD = round(mean(of A2PCLP6 A2PCLP7) * 2);
end;
else if (A2LECPOS eq 0)
then do;
  A2PCLRXP = .s;
  A2PCLAVD = .s;
end;
else do;
  A2PCLRXP = .p;
  A2PCLAVD = .p;
end;

(also demonstrating the value of proper code formatting)

Astounding
PROC Star

The logic looks off here:

do;
A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
end;
else if (A2LECPOS eq 0) then
do

Since the top DO has no conditions attached to it, what is the bottom ELSE supposed to refer to?

 

On a side note, there's a missing semicolon on this statement at the bottom:  else do

Tom
Super User Tom
Super User

Indenting style can help keep track of the nesting of your code and avoid having unclosed DO loops or ELSE without prior THEN.  Here is how I would indent your example (I assumed that you wanted to execute both the DO I loop and the two assignment statments as part of the THEN clause)

if (A2LECPOS ge 1) then do;
  do i=1 to 20;
    vpcl{i}=vpcl{i}-1;
  end;
  A2PCLRXP=round(mean (of A2PCLP1 A2PCLP2 A2PCLP3 A2PCLP4 A2PCLP5)*5);
  A2PCLAVD=round(mean (of A2PCLP6 A2PCLP7)*2);
end;
else if (A2LECPOS eq 0) then do;
  A2PCLRXP=.s;
  A2PCLAVD=.s;
end;
else do;
  A2PCLRXP=.p;
  A2PCLAVD=.p;
end;

Notice a few things. 

The THEN and DO go on the same line as the IF.  Some people put the DO on a new line, but that makes it look like it is NOT part of the THEN clause.

The END statement is indented as the same level as the line that opened the block.  This will make it easier to scan the left hand margin an notice whether or not you are ending your multiple line block with the proper termination command or character.  Some people will leave the END indented, perhaps because it is just easier with editors that automatically place the cursor there when you hit the ENTER key?  To me it always leaves a jolting felling, like when you miss counted the number of steps on a flight of stairs and you foot is hanging in the air.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

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.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 9 replies
  • 1557 views
  • 3 likes
  • 6 in conversation