In the below code, I want value of TARGET variable to resolve as per below mentioned if else statement. But it's not working as excepted. Based on the file name and macro variable, value of TARGET for one record is right but for other file name, I want the value of TARGET is as SOURCE but I'm getting missing value.
Am I missing something in else if and else Statement?
Macro variable NL_RB resolves to 0169,0417
Files placed in 'INPATH' are,
IFR_GT_TRD_2_0163_1_20201009T075212.csv
IFR_GT_TRD_2_0169_1_20201009T075212.csv
%let function=NL; %let inpath=/var/sasdata/GT; %let lh_path=/var/sasdata/LH; %let nl_path=/var/sasdata/NL; 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' and ("&function" EQ 'NL' or "&function" EQ 'LH') then do; source="&inpath" ||"/"|| filename; if "&function" EQ 'NL' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do; 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; end; else if "&function" EQ 'LH' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do; flag = 0; do i = 1 to countw("&lh_rbukrs.",","); if indexw(filename,scan("&lh_rbukrs.",i,","),"_") then do; flag = 1; target = "&lh_path"||"/"||filename; end; end; end; else target="&inpath" ||"/"|| filename; end; output; end; did=dclose(did); drop did msg; run;
Actual Output:
id | filename | source | target | flag |
1 | IFR_GT_TRD_2_0163_1_20201009T075212.csv | /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv | 0 | |
2 | IFR_GT_TRD_2_0169_1_20201009T075212.csv | /var/sasdata/GT/IFR_GT_TRD_2_0169_1_20201009T075212.csv | /var/sasdata/NL/IFR_GT_TRD_2_0169_1_20201009T075212.csv | 1 |
Excepted Output:
id | filename | source | target | flag |
1 | IFR_GT_TRD_2_0163_1_20201009T075212.csv | /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv | /var/sasdata/GT/IFR_GT_TRD_2_0163_1_20201009T075212.csv | 0 |
2 | IFR_GT_TRD_2_0169_1_20201009T075212.csv | /var/sasdata/GT/IFR_GT_TRD_2_0169_1_20201009T075212.csv | /var/sasdata/NL/IFR_GT_TRD_2_0169_1_20201009T075212.csv | 1 |
Start with fixing the inconsistent indentation of your code, so that blocks can be easier recognised. I don't debug left-aligned code.
Do what I told you in your other thread: make your code readable (the current formatting is useless crap, pardon the word), so you can follow the branches more easily.
It seems ro arise because 0163 is not in your macro variable.
You say "Macro variable NL_RB resolves to 0169,0417"
Guessing that you actually want a 0163 in there somewhere as the position in the "expected" output that matches the 0169 on the first row is 0163.
So if you tell the program to look for something but not matching what you expect then do not expect the output to be as desired.
You might also want to learn the concatenation functions other than the || operator such as
target = "&nl_path"||"/"||filename;
could be
target = catx('/', "&nl_path", filename);
Which can avoid some of the potential issues that arise with || and trailing blanks in values, plus is easier on th eyes if you are placing multiple / between many strings.
Save yourself (and those trying to follow your questions) a lot of time and run the step to generate the list of file first.
%let inpath=/var/sasdata/GT;
data files ;
length id 8 msg filename $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);
output;
end;
did=dclose(did);
drop did msg;
run;
Then run a separate step to try to apply your renaming/moving rules.
%let lh_path=/var/sasdata/LH;
%let nl_path=/var/sasdata/NL;
%let function=NL;
data files_to_move ;
set files;
length source target $256 ;
if scan(lowcase(filename),-1,'.')='csv' and ("&function" EQ 'NL' or "&function" EQ 'LH') then do;
source="&inpath" ||"/"|| filename;
if "&function" EQ 'NL' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
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;
end;
else if "&function" EQ 'LH' and scan(lowcase(filename),5,'_') not in ('5601','6010','6020') then do;
flag = 0;
do i = 1 to countw("&lh_rbukrs.",",");
if indexw(filename,scan("&lh_rbukrs.",i,","),"_") then do;
flag = 1;
target = "&lh_path"||"/"||filename;
end;
end;
end;
else target="&inpath" ||"/"|| filename;
output;
end;
run;
Then you don't risk messing up the code to read the list of files and you don't force us to try and figure out what parts of the program are related to getting the list of file names and which part is related to your actual question. Plus now you can post a data step that creates the list of filenames you want share with us so we can help you figure out how to manipulate them. Just post a simple data step like this:
data files;
input filename :$256. ;
cards;
IFR_GT_TRD_2_0163_1_20201009T075212.csv
IFR_GT_TRD_2_0169_1_20201009T075212.csv
;
Please explain the RULES in words that the code is trying to implement. What is &FUNCTION? Are there always 7 parts to the filename separated by underscores? What do the parts of the filenames mean?
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.