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).
Available on demand!
Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.
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.