Hi All,
I am getting one error that was meeting with the condition what I passed in the below code
Req: is I have a file it contains header, detail and trailer records and it's in CSV format and I need to make it fixed format and check the record type if it in proper order then the results have been print to outfile, if the record type is not matching with the condition then it has to show the error code please find below the input records
input Recods in csv format :
H2019101813450000002
D,case#,brinsten,62005,cafitira,netherlands,
T2019101813450000002 (instead of T place I used given E then it must show the error code in spool)
above the input values
i converted it into fixed format by using format and input and put function
{"moreover i need to split those headers and trailer rec into one file and details rec has to move another file}
kindly give sum suggestion to rectify the error i getting
{Chktlr:
INFILE LSFIACEI End=EOFPCEI Missover;
Input @1 Tlrrtype $char1.
@2 Tlrdate $char8. /* Header date */
@10 Tlrtime $char4. /* Header time */
@14 Tlrqty 8.; /* Records in file */
/* Validate record type */
If Tlrrtype¬= 'T' Then Do;
Errcode = 11;
Link SasAbend;
End;}
and below the error code
When (11) Do;
Put '* Expected Records Mismatches Actual read ?.';
Put '* Expecting (T)railer record as last entry ';
Put '* in input file. Found record type = ' Tlrrtyp;
Put '* ';
Put '* The number of data records read was ';
Put '* based on the number of expected ';
Put '* records read from the header.';
Put '* The header value was : ' Hdrqty;
End;
but i am not able getting the exact error code
kindly give the solution for the above code
Thanks & regards
rohit
You haven't show the full code nor the log.
The code should look like:
data test;
infile datalines;
retain phase; drop phase;
Input @1 Tlrrtype $char1. @;
if Tlrrtype in ('H', 'T') then
input @2 Tlrdate $char8. /* Header or trailer date */
@10 Tlrtime $char4. /* Header or trailer time */
@14 Tlrqty 8. /* Records in file */
;
else
if Tlrrtype = 'D' then do;
phase = 1;
input <Detail variables > ;
end; else phase = 2;
If phase=2 then do;
phase=0;
if Tlrrtype ¬= 'T' Then Do;
Errcode = 11;
Link SasAbend;
End;
return;
SASAbend:
if errcode = 11 then do;
Put '* Expected Records Mismatches Actual read ?.';
Put '* Expecting (T)railer record as last entry ';
Put '* in input file. Found record type = ' Tlrrtyp;
Put '* ';
Put '* The number of data records read was ';
Put '* based on the number of expected ';
Put '* records read from the header.';
Put '* The header value was : ' Hdrqty;
End;
return; /* or call sasabend */
run;
code should look like:
Below a program structure which makes it eventually a bit easier for you to implement and test the required logic step by step.
/* create sample data file */
filename LSFIACEI temp lrecl=200;
data _null_;
file LSFIACEI;
infile datalines truncover;
input;
put _infile_;
datalines;
H2019101813450000002
D,case#,brinsten,62005,cafitira,netherlands,
D,case#,brinsten,62005,cafitira,netherlands,
T2019101813450000002
;
/* and here some sample code which provides a program structure you could use */
filename outfile temp /*here instead of temp some path and lrecl */ lrecl=300;
data _null_;
infile LSFIACEI dsd truncover;
input @1 rec_type $1. @;
/* Data: Most common case so have it first */
if rec_type='D' then
do;
/* read remaining data columns */
input (var1-var7) (:$20.);
file outfile;
/* below have put statement using @n if you want to write data positional to outfile */
put var1-var7;
return;
end;
/* header */
else
if rec_type='H' then
do;
input /*<header fields>*/;
/* do stuff - if trailer records are not required then just have above an empty input statement */
file print;
put _infile_;
return;
end;
/* trailer */
else
if rec_type='T' then
do;
/* read remaining data columns */
input /*<trailer fields>*/;
/* all your check logic */
file print;
put _infile_;
return;
end;
run;
Hi Patrick, Shmuel
Thanks for the quick responce please find below complete sas code bez above comments i have some confusion
(DATA _NULL_;
Format hdrdate $char8.
hdrtime $char6.;
Format tlrdate $char8.
tlrtime $char6.;
Format irectype $char1.
iCase_no $Char20.
iLicence_No Z10.
iAddress_1 $Char28.
iAddress_2 $char28.
iAddress_3 $Char28.
iAddress_4 $Char28.
iAddress_5 $Char28.
iPostcode $Char8.
iTitle $Char5.
iInitials $Char18.
iLicensee_nam $Char43.
iPhone_No $Char30.
iNINO $Char10.
i*********** $Char1.
i*********** $Char8.
i******* $Char8.
i*****idence $Char1.
iBirth_date $char8.
i********* $Char53.;
Retain debug ' ';
Retain mf_filename;
Retain idatseqd 0;
Retain hdrqty 0;
Retain hdrqtydf 0;
INFILE LSFIPCEI End=EOFACEI Missover dsd dlm=',' truncover;
/* First record will be the header */
If _n_ = 1 then Do;
Link Chkhdr;
File saslog;
put _N_ ' record reached.. running header qty ' hdrqty
' Date / Time ' hdrdate '/' hdrtime;
File LSFIPCEH;
Put ' ' /* Filename */
' ' /* Filename date */
' ' /* Seq */
@49hdrdate $8.
hdrtime $6.
@63 hdrqty Z8. @;
return;
End;
idatseqd + 1;
Input @1 irectype $ @;
If irectype = 'T' Then Do;
File LSFIPCEH;
Input @2 tlrdate $char8.
@10tlrtime $char4.
@14tlrqty 8.;
Put @71 tlrdate $Char8.
tlrtime $Char6.
@85tlrqty Z8. ;
end;
Else Do;
put 'rec #1' ;
FILE LSFIPCEO;
Input iCase_no $
iLicence_No $
iAddress_1 $
iAddress_2 $
iAddress_3 $
iAddress_4 $
iAddress_5 $
iPostcode $
iTitle $
iInitials $
iLicensee_nam $
iPhone_No $
iNINO $
i********** $
i*********** $
I********* $
i**********8 $
i********** $
i**********88 $;
Put irectype $char1.
iCase_no $Char20.
iLicence_No Z10.
iAddress_1 $Char28.
iAddress_2 $char28.
iAddress_3 $Char28.
iAddress_4 $Char28.
iAddress_5 $Char28.
iPostcode $Char8.
iTitle $Char5.
iInitials $Char18.
iLicensee_nam $Char43.
iPhone_No $Char30.
iNINO $Char10.
i*********** $Char1.
i*********** $Char8.
i******* $Char8.
i*****idence $Char1.
iBirth_date $char8.
i********* $Char5iPCE_Receipt $Char1.
FIle SASLOG;
Put irectype=
iCase_no=
iLicence_No=
iAddress_1=
iAddress_2=
iAddress_3=
iAddress_4=
iAddress_5=
iPostcode =
iTitle=
iInitials=
iLicensee_nam=
iPhone_No=
i****=
i**********=
i********=
i*******t=
i********=
i********=
i***********=;
End;
Return;
if irectype not = 'T' Then Do;
link Chktlr;
end;
ChkHdr:
INFILE LSFIACEI End=EOFACEI Missover;
Input @1 Hdrrtyp $char1.
@2 Hdrdate $char8. /* Header date */
@10Hdrtime $char4. /* Header time */
@14hdrqty 8.; /* Records in file */
/* Validate record type */
If Hdrrtyp¬= 'H' Then Do;
Errcode = 1;
Link SasAbend;
End;
Return;
Chktlr:
INFILE LSFIPCEI End=EOFPCEI Missover;
Input @1 Tlrrtyp $char1.
@2 Tlrdate $char8. /* Header date */
@10Tlrtime $char4. /* Header time */
@14Tlrqty 8.; /* Records in file */
/* Validate record type */
If Tlrrtyp¬= 'T' Then Do;
Errcode = 11;
Link SasAbend;
End;
kindly explain where should i link Chktlr for trailer check
Thanks & regards
Rohit
I'm not a big fan of "link/return" and that 's why I've proposed an alternative program structure which doesn't use "link/return".
For your code: Pay attention where the Return statements need to be; and also don't omit a return statement only because the block is at the end of your program where it hits a Run (with implicit return).
Check you program according to logic table:
Logic of program should be:
Rec_Type |
Check for error |
No error |
_N_=1 |
If rec_type NE ‘H’ |
Initialize variables, output, Check is rec_type = ‘H’ Assign Phase = 0 |
H |
|
Phase = 1; Output header |
New obs |
If phase=1 and rec_type ne ‘D’ |
|
D |
If phase not in (1,2) |
Assign phase = 2; Do loop while rec_type = ‘D’; Output Detail; End do; |
Loop exit |
If phase =2 and rec_type ne ‘T’ |
|
T |
|
Output trailer; Assign phase =0 |
H |
If phase NE 0 |
Assign phase=1; output header |
D |
|
|
T |
|
|
End of file |
If end-of-file and Phase NE 0 |
|
It's finally time to hack! Remember to visit the SAS Hacker's Hub regularly for news and updates.
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.