BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
cperichon_macif
Fluorite | Level 6

Hi,

 

I have to read a dbf (version 7) file from sas.

 

As a result, i started to create a program .

However, i need to read three fields with LSB in file header like this :


4-7 32-bit number Number of records in the table. (Least significant byte first.)
8-9 16-bit number Number of bytes in the header. (Least significant byte first.)
10-11 16-bit number Number of bytes in the record. (Least significant byte first.)

 

How can i do ?

 

Thanks for your reply.

%Let NBRECORD=520400E5;

%let nbrecord=%sysfunc(inputn(&nbrecord.,hex.));

/* with lsb */
%let nbrecord=%sysfunc(inputn(&nbrecord.,????.));

Best regards.

1 ACCEPTED SOLUTION
13 REPLIES 13
cperichon_macif
Fluorite | Level 6
Unfortunately i can't .

The dbf file is Dbase version 7 !

The number (32bits) i want to read is 520400E5 (hex) .


cperichon_macif
Fluorite | Level 6

Sorry, this one : 283333 (the number of rows or records table).

Kurt_Bremser
Super User

@cperichon_macif wrote:

Sorry, this one : 283333 (the number of rows or records table).


That doesn't match at all. The hex representation of this number is 000452c5. With no method of reordering can I get the hex you posted.

Could you please post a hex dump of the first 16 bytes of the file?

 

Note that in SAS, the first position in a string is 1, not 0. So if you read the first 16 bytes into a string, the number of records is substr(string,5,4)

cperichon_macif
Fluorite | Level 6

thank you so much, you were right !

 

Do you agree with this code , if i only want to read the first 12 bytes ?.

data header;
	infile dbf recfm=n;
	informat version $char1.;
	informat year $char1.;
	informat month $char1.;
	informat day $char1.;
	format version $hex.;
	format year $hex.;
	format month $hex.;
	format day $hex.;
	input version 
		@2 year   
		@3 month 
		@4 day 
		@5 nbrecord ibr4. 
		@9 nbbyteh ibr2. 
		@11 nbbyter ibr2.  

	;

	if _n_=2 then
		stop;
run;

Here is the link of dbf file structure : http://www.dbase.com/KnowledgeBase/int/db7_file_fmt.htm

My goal is to read the file, create a sas table and apply some updates or add new records .

Then, i put down the sas table in the dbf file.

 

Best regards.

Kurt_Bremser
Super User

Looks right to me. Personally, I'd use formatted input all the way throgh, and convert to a SAS date:

data header;
infile dbf recfm=n;
input
  version $char1.
  _year $char1.
  _month $char1.
  _day $char1.
  nbrecord ibr4. 
  nbbyteh ibr2. 
  nbbyter ibr2.  
;
format
  version $hex2.
  date yymmddd10.
;
date = input(put(_year,$hex2.) !! put(_month,$hex2.) !! put(day,$hex2.),yymmdd6.);
output;
stop;
drop _year _month _day;
run;

Take care that a suitable yearcutoff= option has been set.

 

I see no mention in the SAS documentation about dBase versions being supported or not. What happens when you try to use proc import with dbms=dbf?

 

cperichon_macif
Fluorite | Level 6

Here is the log when i use the proc import :

 

 

24         proc import dbms=dbf file="&racjob.\macif.dbf" replace out=macif;
24       !                                                                   run;

NOTE: Imported 1 columns and 283333 rows of data from the dBase table file.
NOTE: WORK.MACIF data set was successfully created.
NOTE: PROCEDURE IMPORT used (Total process time):
      real time           13.37 seconds
      cpu time            2.14 seconds

 

The number of rows is good but only one column with no data !

 

Nom    Type    Longueur    Format    Informat    Libellé
DBWINUS0    Alphanumérique    0    $.    $.    DBWINUS0

     

Kurt_Bremser
Super User

Nice. One character column of length zero. So there's something that breaks SAS's dbf engine.

I'd put it to SAS technical support, just to see what they have to say.

 

Could you try to use dbfExport to create a csv file, and read that with a data step? The downside would be that you need to know the structure beforehand.

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 13 replies
  • 1735 views
  • 1 like
  • 2 in conversation