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

I would like to understand how to tackle the multilple conditions in do, if and else if. Any help to arrange the do blocks from below profram in right way? I guess first three do blocks are not in right way. 

 

In the below program, if the flag value is 1, then I want target="&nl_path"||"/"||filename; but after executing the program it produces target="&lh_path"||"/"||filename;. It looks last else statement had statisfied instead of second if. Flag value is correctly appearing it as 1. So I want target="&nl_path"||"/"||filename;

 

data files ;
  length id 8 msg filename source target $256 ;
  did=dopen("source");
  if did<=0 then do;
      msg=sysmsg(); 
      put msg; 
      stop;
  end;
  do id=1 to dnum(did);
    filename=dread(did,id);

    if scan(lowcase(filename),-1,'.')='csv' then do;
      source="&inpath" ||"/"|| filename;
      flag = 0;

    do i = 1 to countw("&nl_rb.",",");
     if indexw(filename,scan("&nl_rb.",i,","),"_") then do;
     flag = 1;
     target="&nl_path"||"/"||filename;
   end;
   end;

     if indexw(filename,'_copied') and  "&function" EQ 'LH' then do;
        target="&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
        end;

     else if indexw(filename,'_copied') and  "&function" EQ 'NL' then do;
        target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
      end;

      else target="&lh_path"||"/"||filename;
    end;
    output;
  end;
  did=dclose(did);
  drop did msg;
run;

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Kurt_Bremser
Super User

MAXIM 34.

MAXIM 34.

MAXIM 34.

WORK

IN

STEPS

!!!

 

Test your conditions separately on an example string in a simple data step, so you can make sure they work BEFORE you use them in a larger piece of code where they are harder to debug.

 

Separate the directory read out into its own data step, so you get a dataset with all filenames to inspect first.

 

And make it a habit to use consistent indentation, so you can visually identify the blocks:

data files ;
length
  id 8
  msg filename source target $256
;
did = dopen("source");
if did <= 0
then do;
  msg = sysmsg(); 
  put msg; 
  stop;
end;
do id=1 to dnum(did);
  filename = dread(did,id);
  if scan(lowcase(filename),-1,'.') = 'csv'
  then do;
    source = "&inpath" ||"/"|| filename;
    flag = 0;
    do i = 1 to countw("&nl_rb.",",");
      if indexw(filename,scan("&nl_rb.",i,","),"_")
      then do;
        flag = 1;
        target = "&nl_path"||"/"||filename;
      end;
    end;
    if indexw(filename,'_copied') and "&function" eq 'LH'
    then do;
      target = "&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;
    else if indexw(filename,'_copied') and "&function" eq 'NL'
    then do;
      target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;
    else target = "&lh_path"||"/"||filename;
    /* this most likely causes your problems;
    if _copied is not present, this statement will override anything else */
  end;
  output;
end;
did = dclose(did);
drop did msg;
run;

See my comment remark. Making your code readable (Maxim 12) quickly let me see where the issue might be.

Your final block should be simplified to this:

    if indexw(filename,'_copied')
    then do;
      if "&function" eq 'LH'
      then target = "&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
      else if "&function" eq 'NL'
      then target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;

You might want to add a check for values of &function not in (LH,NL).

View solution in original post

7 REPLIES 7
andreas_lds
Jade | Level 19

You may want to add some text explaining what the program should do and what it is doing wrong.

David_Billa
Rhodochrosite | Level 12

updated my initial post.

David_Billa
Rhodochrosite | Level 12

@Kurt_Bremser In the filename there is no string called '_copied' is available. So this condition 

indexw(filename,'_copied')

 should not statisfy. 

Shmuel
Garnet | Level 18

@David_Billa wrote:

@Kurt_Bremser In the filename there is no string called '_copied' is available. So this condition 

indexw(filename,'_copied')

 should not statisfy. 


If there is no '_copied' substring in the filename it explains the output you get, as the last ELSE is

else target="&lh_path"||"/"||filename;

 

Shmuel
Garnet | Level 18

You can shorten the next code:

  if indexw(filename,'_copied') and  "&function" EQ 'LH' then do;
        target="&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
        end;

     else if indexw(filename,'_copied') and  "&function" EQ 'NL' then do;
        target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
      end;

      else target="&lh_path"||"/"||filename;

 

 

by replacing it to:

  if indexw(filename,'_copied') then do;
    if  "&function" EQ 'LH' then 
        target="&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    else if "&function" EQ 'NL' then 
        target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
  end;
  else target="&lh_path"||"/"||filename;
Kurt_Bremser
Super User

MAXIM 34.

MAXIM 34.

MAXIM 34.

WORK

IN

STEPS

!!!

 

Test your conditions separately on an example string in a simple data step, so you can make sure they work BEFORE you use them in a larger piece of code where they are harder to debug.

 

Separate the directory read out into its own data step, so you get a dataset with all filenames to inspect first.

 

And make it a habit to use consistent indentation, so you can visually identify the blocks:

data files ;
length
  id 8
  msg filename source target $256
;
did = dopen("source");
if did <= 0
then do;
  msg = sysmsg(); 
  put msg; 
  stop;
end;
do id=1 to dnum(did);
  filename = dread(did,id);
  if scan(lowcase(filename),-1,'.') = 'csv'
  then do;
    source = "&inpath" ||"/"|| filename;
    flag = 0;
    do i = 1 to countw("&nl_rb.",",");
      if indexw(filename,scan("&nl_rb.",i,","),"_")
      then do;
        flag = 1;
        target = "&nl_path"||"/"||filename;
      end;
    end;
    if indexw(filename,'_copied') and "&function" eq 'LH'
    then do;
      target = "&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;
    else if indexw(filename,'_copied') and "&function" eq 'NL'
    then do;
      target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;
    else target = "&lh_path"||"/"||filename;
    /* this most likely causes your problems;
    if _copied is not present, this statement will override anything else */
  end;
  output;
end;
did = dclose(did);
drop did msg;
run;

See my comment remark. Making your code readable (Maxim 12) quickly let me see where the issue might be.

Your final block should be simplified to this:

    if indexw(filename,'_copied')
    then do;
      if "&function" eq 'LH'
      then target = "&lh_path"||"/"||transtrn(filename,'_copied',trimn(' '));
      else if "&function" eq 'NL'
      then target="&nl_path"||"/"||transtrn(filename,'_copied',trimn(' '));
    end;

You might want to add a check for values of &function not in (LH,NL).

hackathon24-white-horiz.png

2025 SAS Hackathon: There is still time!

Good news: We've extended SAS Hackathon registration until Sept. 12, so you still have time to be part of our biggest event yet – our five-year anniversary!

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.

SAS Training: Just a Click Away

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

Browse our catalog!

Discussion stats
  • 7 replies
  • 1601 views
  • 4 likes
  • 4 in conversation