How to Modify the Table Header from FoxPro

Last reviewed: March 6, 1998
Article ID: Q139758
2.50 2.50a 2.50b 2.60 2.60a | 2.00 2.50 2.50a 2.50b 2.60 2.60a
WINDOWS                     | MS-DOS
kbprg kbhowto kbcode

The information in this article applies to:

  • Microsoft FoxPro for MS-DOS, versions 2.0, 2.5, 2.5a, 2.5b, 2.6, 2.6a
  • Microsoft FoxPro for Windows, versions 2.5, 2.5a, 2.5b, 2.6, 2.6a

SUMMARY

Sometimes, the FoxPro error "Not a Database File," can be corrected by modifying the table header with a hexadecimal editor. If no hexadecimal editor is available, the header can be modified by using FoxPro's low-level file functions. This article shows by example how to modify the structure of the table header.

MORE INFORMATION

WARNING: ANY USE BY YOU OF THE CODE PROVIDED IN THIS ARTICLE IS AT YOUR OWN RISK. Microsoft provides this code "as is" without warranty of any kind, either expressed or implied, including but not limited to the implied warranties of merchantability and/or fitness for a particular purpose.

Con_from.prg Sample Code

Create a program file called Con_from.prg that contains this code:

   FUNCTION con_from
   PARAMETERS filename
   * This function uses low-level file I/O to retrieve the table
   * header information and stores it in a .dbf file called Change.
   * A Browse window will automatically appear with the byte number, ASCII
   * value, and character representation for each byte. Changes to the
   * ASCII value from the Browse window will not change the database header
   * until the function CON_TO is called. A description of each byte in the
   * Browse window is presented later in this article.
   PRIVATE ALL
   IF !"."$filename
      filename=filename+'.dbf'
   ENDIF
   handle=FOPEN(filename,2)
   IF handle>0
      byte=FREAD(handle,32)
      offset=ASC(SUBSTR(byte,9,1))+(ASC(SUBSTR(byte,10,1))*256)-1
      byte1=FREAD(handle,offset-32)
      byte=byte+byte1
      CREATE TABLE CHANGE (byte_num N(2),ASCII N(4))
      FOR i=1 TO offset
         APPEND BLANK
         REPLACE byte_num WITH IIF(MOD(i,32)=0,32,MOD(i,32))
         REPLACE ASCII WITH ASC(SUBSTR(byte,i,1))
      ENDFOR
      =FCLOSE(handle)
      GO TOP
      BROWSE FIELDS byte_num,ASCII,char=CHR(ASCII)
      USE
   ELSE
      WAIT WINDOW "File not opened, Please check File Name and Path"
   ENDIF
   RETURN

The records in the Browse window are broken down into 32-byte sections. The first 32-byte section holds the file information. All other 32-byte sections hold field information. If your table has five fields, you should have a total of six 32-byte sections (one for the file and five for the fields).

Description of File Bytes

Byte Number     Description
1               File-type identifier:

                  3 - .dbf without memo (FoxBase+/FoxPro/dBASE III
                                        PLUS/dBASE IV)
                131 - .dbf with memo    (FoxBase+/dBASE III Plus)
                139 - .dbf with memo    (dBASE III)
                245 - .dbf with memo    (FoxPro)

2               Year of last update
3               Month of last update
4               Day of last update
5- 8            Number of records in file*
9-10            Offset to start of data**
11-12           Size of record***
13-28           Not used
29              Flag for compound index (.cdx)

                0 - No .cdx file attached to the database
                1 - .cdx file attached to the database

30-32           Not used

* The number of records are calculated with the following formula:
   (byte#5)+(byte#6 * 256)+(byte#7 * 256 * 256)+ (byte#8 * 256 * 256 * 256)

** The offset to the start of data is computed from the beginning
   of the file to the first data record. The offset is
   calculated with the formula (byte#9)+(byte#10 * 256)

***The size of the records is calculated with the formula
   (byte#11)+(byte#12 * 256). This number represents the sum of
   the field sizes plus 1. The extra 1 is the deletion flag.

Description of Field Bytes

1-10            Field Name
11              Must be 0
12              Field Type:

                67 - C - Character
                68 - D - Date
                76 - L - Logical
                66 - M - Memo
                78 - N - Numeric
                71 - G - General

13-14           Offset of field from beginning of record*
15-16           Not used
17-18           Field length (non-numeric fields)**
17              Field length (numeric fields)
18              Field decimals (numeric fields)
19-32           Not used

* The offset is calculated with the following formula:
   (byte#13)+(byte#14 * 256)

** The non-numeric field length is calculated with the following
   formula:  (byte#16) + (byte#17 * 256)

Con_to.prg Sample Code

Create a Program file called CON_to.prg that contains the following code:

   FUNCTION con_to
   PARAMETERS filename
   * This function takes the contents from the Change table and creates a
   * new header. WARNING: You are about to change the table header.
   PRIVATE ALL
   IF !"."$filename
      filename=filename+'.dbf'
   ENDIF
   SELECT 0
   USE CHANGE
   GO TOP
   handle=FOPEN(filename,2)
   IF handle>0
      byte=""               && No spaces between the quotation marks
      FOR i=1 TO RECCOUNT()
         byte=byte+CHR(ASCII)
         SKIP
      ENDFOR
      =FWRITE(handle,byte)
      =FCLOSE(handle)
   ENDIF
   RETURN

After the previous functions have been typed, use the following steps to change the header:

  1. Make a back up of your table. (This is strongly recommended, but it is not required.)

  2. In the Command window, type:

    =CON_FROM(filename)

    Here are two examples:

    =CON_FROM("C:/FPW26/TUTORIAL/CUSTOMER") =CON_FROM("C:/FPW26/TUTORIAL/CUSTOMER.DBF")

    The file name does not require the .dbf extension, although it will accept it.

  3. Make any necessary changes in the Browse window. Refer to the previous table for an explanation of each byte.

  4. Close the Browse window.

  5. If changes were made, type the following in the Command window:

    =CON_TO(filename)

    Here are two examples:

    =CON_TO("C:/FPW26/TUTORIAL/CUSTOMER") =CON_TO("C:/FPW26/TUTORIAL/CUSTOMER.DBF")

REFERENCES

For more information about how to modify the header of a .dbf file, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q98743
   TITLE     : "Not a Database File"; How to Modify Database Header

For more information on table structures please see the following:

Visual FoxPro version 3.x Help; search on: "HELP FILE STRUCTURES"; topic: Table Files Structure (.DBC, .DBF, .FRX, .LBX, .MNX, .PJX, .SCX, .VCX)

Visual FoxPro version 5.x Help; search on: "HELP FILE STRUCTURES"; topic: Table Files Structure (.DBC, .DBF, .FRX, .LBX, .MNX, .PJX, .SCX, .VCX)


Additional reference words: FoxWin FoxDos 2.00 2.50 2.50a 2.50b 2.60 2.60a
KBCategory: kbprg kbhowto kbcode
KBSubcategory: FxprgTable
Keywords : FxprgTable kbcode kbhowto kbprg
Version : 2.50 2.50a 2.50b 2.60 2.60a | 2.
Platform : MS-DOS WINDOWS


THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: March 6, 1998
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.