Run a simple test program.
Copy the SAS log and post it into the window that opens when you click on the Insert Code icon (looks like < / > ) on the menu bar above the text box.
So assuming the field you want to read starts at position 533 this data step will read the first observation only. The LIST statement will dump the actual contents of the line (as seen by SAS).
The OBS=1 will make it just do one line. If the probably is not on that line you could try looking at other lines of the file by using combination of the FIRSTOBS= and OBS= settings.
data _null_:
infile myfile lrecl=1000 recfm=f encoding='any' obs=1;
input
@533 string1 $char2.
@533 string2 $ascii2.
@533 number1 pib2.
@533 number2 s370fpib2.
;
put string1= $hex4.
/ string2= $hex4.
/ number1= comma12.
/ number2= comma12.
;
list;
run;
I haven't worked with SAS on a mainframe for a long time now, but I still work with (quasi-) mainframe data.
Just so we don't overlook anything:
To allow us to somehow recreate your issue, I want to ask for this: determine the line number of an offending line, and then run
data _null_;
infile ..... recfm=f lrecl=... firstobs=X obs=X;
input;
length string $40;
i = 1;
do until (i > length(_infile_) - 40;
string = substr(_infile_,i,40);
put i=;
put string $hex80.;
i + 40;
end;
run;
X is your offending line number.
After that, you should have a hex listing of the input buffer of that line in the log in nicely readable 40-byte chunks, from which we can then try to recreate that input buffer and apply possible solutions, so please post the log of that step into a log box opened with this button:
Edit out the filename if that is sensitive.
@MarkATremel wrote:
Um, no offense, but I did not accept this as the solution. This is twice now where I am not even on the page and the question I have posted is marked as solve. The first time I thought I may have done it accidentally, but not this time.
You should see a button to unselect the answer. You might want to try a different browser if the current one is not interacting well with the site.
I don't understand what the goal of this exercise is.
If you want to read and write the values without modification use the $CHAR or $VARYING informat to read and the $CHAR or $VARYING format to write.
Do you want to modify the value being read? What type of modification are you trying to do?
Make sure that SAS is not trying to transcode the records in your source file as if they were characters stored in some encoding. If you are reading the file using RECFM=F on the INFILE statement then that should not be a problem. If you are not reading the file using RECFM=F then you will have other problems in addition to transcoding. For example if you use RECFM=V and some byte that is part of a binary field happens to be the hex code '0A'x then SAS will treat that as the linrefeed character that marks the end of the record.
Well, the goal is this: I need to decipher the contents of those two bytes. I was told that in order for me to decipher the information, I needed to evaluate the first or high order nibble separately from the lower three nibbles. Here is what I was told: "Convert 2 byte hex value of message to an actual condition code. Example '2118'x converts to a character value of 'E280. You get this by taking the last three bits of the '118'x and converting them to decimal (which is 280). Then take the first bit of '2'x and concatenate '0'x to it to make '20'x which can then be converted by using the table below. You can now see that '20'x equals a decimal '32' which is an 'E' code. Overridden an overridden E280 would be seen as '2918'. As a general rule, anything over '8' in the second bit would need to have '8' subtracted from it to find out what the true suspense code was. Another example -- X'3001' which would be a 'P001'. If it were an overridden 'P001' it would look like X'3801' on the hex dumped claim."
I am not trying to defend this code or change it (which it cannot be). The file is a million years old and has many other coded values done in similar (but always different) manners. However, someone in my group had already done this conversion in SAS but retired last year and did not tell anyone where the code is to decipher this mess. So, I am sure it is just hitting on the right informat and conversion statement or function to get me a string that contains the hex equivalent of the value I read in. Of course, now that I have this lovely problem to solve, I too am considering retirement!!! (Just kidding....)
They don't seem to understand the difference between a bit and nibble. A bit is one binary digit. A nibble is 4 binary digits. There are 8 bits in a bytes and two nibbles in a byte. There are 16 bits in two bytes and 4 nibbles in 2 bytes.
Let's look at the two byte string with the hex code of '2118'x. If you read that using S370FPIB informat you get the number 8,472. If you take the remainder when dividing by 16**3 you get the 3 least significant digits, which is 280.
If you want the first nibble take integer value of dividing by 16**3. If you want to treat that as a digit in the 16s place of your hex number then just multiply by 16. Or subtract the number you found that has the last three nibbles and divide by 2**8 to remove the second byte (which will be all zeros).
102 data test; 103 string='2118'x ; 104 number = input(string,s370fpib2.); 105 number1 = mod(number,16**3); 106 number2 = (number - number1)/256; 107 put (_all_) (=/); 108 format string $hex4.; 109 run; string=2118 number=8472 number1=280 number2=32
Save $250 on SAS Innovate and get a free advance copy of the new SAS For Dummies book! Use the code "SASforDummies" to register. Don't miss out, May 6-9, in Orlando, Florida.
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.