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;
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).
You may want to add some text explaining what the program should do and what it is doing wrong.
updated my initial post.
Check if
indexw(filename,'_copied')
actually results in the position you are looking for.
@Kurt_Bremser In the filename there is no string called '_copied' is available. So this condition
indexw(filename,'_copied')
should not statisfy.
@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;
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;
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).
April 27 – 30 | Gaylord Texan | Grapevine, Texas
Walk in ready to learn. Walk out ready to deliver. This is the data and AI conference you can't afford to miss.
Register now and lock in 2025 pricing—just $495!
Still thinking about your presentation idea? The submission deadline has been extended to Friday, Nov. 14, at 11:59 p.m. ET.
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.
Ready to level-up your skills? Choose your own adventure.