01-04-2018 11:38 PM - edited 01-05-2018 11:36 AM
I need some SAS help with the SAS program in mainframe. The program reads a fixed length/fixed field input file and creates a pipe delimited output file.
When the input field is defined as PIC Display Numeric and the field contains zero, SAS will usually place the field on the output record with no characters, just the pipe delimiter character before the field immediately followed by another pipe character. On other output records, SAS will remove leading spaces from the field but write out the zeroes and the imbedded decimal point. I cannot determine any pattern as to when SAS will either not write any characters for the field or SAS will write out the zeroes.
Input field defined as PIC -9.9(5).
Input field contains “ 0.00000”
Output record will sometimes contain “pipe””pipe” for this field and other times it will contain “pipe”0.00000”pipe” (NOTE – the leading space in the input field is removed)
Can someone explain why SAS is writing out different values for the same input field contents?
The following is the SAS program
OPTIONS NOCENTER OBS=MAX ERRORS=2; DATA TEMP; INFILE INFIL; %INCLUDE SOURCE; RUN; DATA _NULL_; SET TEMP; FILE OUTFIL DELIMITER='|' DSD LRECL = 1000; PUT (_ALL_) (:) +(-1) '0D'X ; RUN;
01-04-2018 11:50 PM
01-05-2018 02:36 AM
Check your included source - what informats are assigned to the field(s).
If the statment is INPUT <var> $<length.> then sas will ignore leading spaces.
In order to keep the leading space it shoud be INPUT <var> $CHAR<length.>.
01-05-2018 06:39 AM
First step would be to isolate the problem. Does it occur in the INPUT statement (obscured because of %INCLUDE) or the PUT statement (obscured because of the smiley face)? At any rate, examine your variable in TEMP to determine what it contains for those problem cases. Be sure to inspect for any null characters as part of the process (hex "00").
If the data looks OK within TEMP, the problem will be with the PUT statement. If there's a problem within TEMP, the problem lies in the INPUT statement (or related statements within the %INCLUDE logic).
If you still need help after that, post what you discovered, as well as details or either %INCLUDE or PUT.
01-05-2018 11:41 AM - edited 01-05-2018 11:44 AM
Thanks and sorry for the smiley face that was due to HTML format of the text. actual code is this
PUT (_ALL_) (:) +(-1) '0D'X ;RUN;
01-05-2018 09:16 PM - edited 01-05-2018 09:17 PM
Your code indicates that you want to control the end-of-line character by explicitly writing '0D'x
The PUT statement will still implicitly write the default EOF character.
If my assumption is correct then you probably need to change your code using one of two options:
Either suppress writing EOF character using @
PUT (_ALL_) (:) +(-1) '0D'X @;
Or define the the EOF character explicitely using TERMSTR
FILE OUTFIL DELIMITER='|' DSD LRECL = 1000 termstr=CR; PUT (_ALL_) (:) +(-1);
01-06-2018 02:23 PM - edited 01-06-2018 02:32 PM
What is the question? You are using a simple data step to write all variables to delimited file. Other than the strange code to add the carriage control character it should work fine.
But why are you manually adding a CR to the end of the line? Why not just use the TERMSTR= option on the FILE statement to tell SAS what end of line characters to use?
DATA _NULL_; SET TEMP; FILE OUTFIL DSD DLM='|' LRECL=32767 TERMSTR=CRLF; PUT (_ALL_) (+0) ; RUN;
Are you really on an IBM mainframe? Wouldn't the way that the records are written to the file be controlled by the DD specifications in the JCL? What type of file ends up on your target Windows or Unix system when you download it depends on how you perform the download. If you download it using FTP protocol as an text file instead of a binary file then it will write the file using the appropriate end of line characters for your target system.
Note that when you write using the DSD option then it will put nothing between the delimiters when the value is missing ( or blank for character variables). That is why you will see two "pipes" next to each other some times. This is how delimited files are normally created. Reading it will the DSD option on the INFILE statement will tell SAS to properly recognize the missing value.
Is the question about the leading spaces?
If you are reading your 'PIC -9.9(5)' field as a NUMBER then there are no "spaces" in a number. The space is just in your fixed length file to make the field take up the full width allocated in the fixed format layout.
When SAS writes using list mode (what you are doing essentially) then any leading and trailing spaces are removed. So even a character variable that was created with leading space (or any character variable that has a value that is shorter then the variable's length) will not have leading or trailing spaces written to the output file. Example:
2354 data _null_; 2355 file log dsd dlm='|' ; 2356 x=1; y=2 ; c=' string '; 2357 put x c y ; 2358 run; 1|string|2
If you really need to preserve leading spaces in the output then here is one way using $VARYING format so that the character variable is written using formatted style instead of list style. Because of not using list mode for that variable you need to manually add the delimiter if another variable follows.
2394 data _null_; 2395 file log dsd dlm='|' ; 2396 x=1; y=2 ; c=' string '; 2397 n=lengthn(c); 2398 put x c $varying1000. n '|' y ; 2399 run; 1| string|2
To do that for a general dataset you would need to use some code generation and not just a simple variable list.