?
Solved

Reading variable length EBCDIC in SAS

Posted on 2016-08-24
9
Medium Priority
?
215 Views
Last Modified: 2016-09-07
I am trying to read an incoming mainframe file that contains a variable length field that contains EBCDIC data.

To read this field, I am currently using $VARYING informat, but this is only suitable for reading variable length ASCII fields. What I am looking for is an informat that reads a variable length field AND converts to readable format in the output.

Here is my code :-

			/* P31 - NAME_LINE_1 */
			if Bitmap_1a='..............................1.'B then
			do;
				input
				b_ADDESS_LINE_1_len $370FIB2.
				b_ADDESS_LINE_1 $VARYING23. b_ADDESS_LINE_1_len
				@;
				data_length = data_length - b_NAME_LINE_1_len - 2;
			end;

Open in new window


The problem with the above code is that it populates the output with the EBCDIC, but I need the variable field converting to ASCII. Is there a way to convert a variable length field from EBCDIC to ASCII without relying on the informat / format statements?
0
Comment
Question by:Martin r
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 19

Expert Comment

by:Thommy
ID: 41768962
You should read the book Reading External Data Files Using SAS: Examples Handbook

Check the table of contents. There are a lot of examples including reading EBCDIC data...
0
 
LVL 19

Expert Comment

by:Thommy
ID: 41768989
And also check this from SAS Knowledge Base...
Reading EBCDIC Files on ASCII Systems
0
 

Author Comment

by:Martin r
ID: 41769050
Thanks for the comments Thommy, but I have already looked at the recommended documentation online, and this is really a last resort for me - as there is nothing anywhere that indicates SAS is actually capable of reading variable length EBCDIC informats. In fact, I don't think it is....:-|

I have no difficulty reading  fixed-length EBCDIC fields, as well as the binary fields that specify the record-length and segment-length - this is all working. It's just there is no INFORMAT that will allow me to read and convert EBCDIC to ASCII for a variable length field.

I did just have a thought though - I could read the field as "FIXED EBCDIC" and then reset the pointer back to the correct position according to the value of the b_ADDESS_LINE_1_len field. It would only be a simple matter of chopping the surplus data from the end of the field.
0
Veeam Task Manager for Hyper-V

Task Manager for Hyper-V provides critical information that allows you to monitor Hyper-V performance by displaying real-time views of CPU and memory at the individual VM-level, so you can quickly identify which VMs are using host resources.

 
LVL 8

Accepted Solution

by:
ShannonEE earned 2000 total points
ID: 41774240
Even better would be -

		/* P31 - NAME_LINE_1 */
			if Bitmap_1a='..............................1.'B then
			do;
				input
				b_ADDESS_LINE_1_len $370FIB2.
				b_ADDESS_LINE_EBCDIC $VARYING23. b_ADDESS_LINE_1_len
				@;
				data_length = data_length - b_NAME_LINE_1_len - 2;
				b_ADDESS_LINE_1 = inputc(b_ADDRESS_LINE_EBCDIC,  $EBCDIC. b_ADDRESS_LINE_1_len);
			end;

Open in new window


Note that you need to specify both a type ( $ ) and max width for both

b_ADDESS_LINE_1  and
b_ADDRESS_LINE_EBCDIC

Failure to specify a width can lead to very mysterious run time problems.

Maybe that max length is 23 as you have on the $VARYING informat, but it is best also to have a statement

length   b_ADDESS_LINE_1  b_ADDRESS_LINE_EBCDIC $ 23;

Open in new window


This does the varying field length issue in the input statement and then uses the INPUTC function to do the conversion from EBCDIC.

Regards,

Ian
1
 
LVL 16

Expert Comment

by:theo kouwenhoven
ID: 41785907
Hi Martin,

I don't know if this will help, but normally the Ebcdic to Ascii translation will be automatically don by the DB-driver, unless it's Binary-data (Bitmap).
The Varlength fields in a DB2 database has the first 2-positions filled with the length of the data.
0
 

Author Closing Comment

by:Martin r
ID: 41786506
Thanks ShannonEE!

The solution is exactly what I was after. The solution ShannonEE provided is for RUNTIME FUNCTION to allow conversion during the loop.

http://support.sas.com/kb/50/013.html

I have managed to convert the variable length field now so can ensure the output is all formatted in ASCII. The final code was as follows :-

                  /* P31 - REFERENCIA DEL ADQUIRENTE */
                  if Bitmap_1a='..............................1.'B then
                  do;
                        input
                        b_acquirer_reference_len $EBCDIC2.
                        b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
                        @;
                        data_length = data_length - b_acquirer_reference_len - 2;
                        b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC23.");
                  end;

Thanks all for your help!!
0
 

Author Comment

by:Martin r
ID: 41786528
****UPDATED****

The above solution worked, but produced excessive notes due to specifying the maximum length for format. Therefore I used a concatenation to enable the length variable to be used in the format construction. The final code was as follows :-

                  /* P31 - REFERENCIA DEL ADQUIRENTE */
                  if Bitmap_1a='..............................1.'B then
                  do;
                        length b_acquirer_reference_ebcdic b_acquirer_reference_ascii $ 23;
                        input
                        b_acquirer_reference_len $EBCDIC2.
                        b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
                        @;
                        data_length = data_length - b_acquirer_reference_len - 2;
                        b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC" || b_acquirer_reference_len || "." );
                  end;
0
 
LVL 8

Expert Comment

by:ShannonEE
ID: 41787032
Martinr,

The posted code missed a comma.  With the INPUTC  function sas makes the format up at run time (which you did), but if you specify the 3rd parameter (which I attempted to do) then it should construct the format without any NOTES or WARNINGS.  As in

		b_ADDESS_LINE_1 = inputc(b_ADDRESS_LINE_EBCDIC,  $EBCDIC.   ,   b_ADDRESS_LINE_1_len);

Open in new window


(A comma after $EBCDIC and before b_ADDRESS_LINE_1_LEN  was missing)
I didn't test out the code because currently I don't have access to a mainframe to write test data and the code is quite specific to your situation.

As an aside, note that on the mainframe the record format and length is specified in the DCB and (from what I remember) includes F, FB, V, VB, VBA, D, DB, U, (and probably a host of other formats).  Obtaining the record length will be different for each record format.

In your case it appears that the field length is in another field within the record and so getting the record length from the data structure as read in an ASCII environment will be useless for inputting the variable length field that you need to do here.
1
 

Author Comment

by:Martin r
ID: 41787331
Thanks ShannonEE, that's a neater expression. I should point out that I am using SAS Enterprise Guide (Windows) - hence requiring the output in ASCII; so I have to specify the format in quotes.

/* P31 - REFERENCIA DEL ADQUIRENTE */
if Bitmap_1a='..............................1.'B then
do;
	length b_acquirer_reference_ebcdic b_acquirer_reference_ascii $ 23;
	input
	b_acquirer_reference_len $EBCDIC2.
	b_acquirer_reference_ebcdic $VARYING23. b_acquirer_reference_len
	@;
	data_length = data_length - b_acquirer_reference_len - 2;
	b_acquirer_reference_ascii = inputc(b_acquirer_reference_ebcdic, "$EBCDIC." , b_acquirer_reference_len);
end;

Open in new window

0

Featured Post

Get your Disaster Recovery as a Service basics

Disaster Recovery as a Service is one go-to solution that revolutionizes DR planning. Implementing DRaaS could be an efficient process, easily accessible to non-DR experts. Learn about monitoring, testing, executing failovers and failbacks to ensure a "healthy" DR environment.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article is written by John Gates, CISSP. Gates, the SNUG President-Elect, currently holds the position of Manager of Information Systems at Lake Park High School in Roselle, Illinois.
This article will show how Aten was able to supply easy management and control for Artear's video walls and wide range display configurations of their newsroom.
Simple Linear Regression
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…
Suggested Courses

770 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question