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).
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!
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.