Microsoft KB Archive/119116

= How to ZAP or PACK a dBASE or FoxPro Table =

Article ID: 119116

Article Last Modified on 10/30/2003

-

APPLIES TO


 * Microsoft Visual Basic 3.0 Professional Edition
 * Microsoft Visual Basic 3.0 Professional Edition

-



This article was previously published under Q119116



SUMMARY
The following passage appears in the "Professional Features," Book 2, page 141:

dBASE and FoxPro database systems do not physically delete records, but merely mark them for deletion at a later time. You must pack the .DBF file (using your own utilities) to remove these records from the .DBF files. The CompactDatabase function will not affect attached tables.

This article shows you how to ZAP and/or PACK a dBASE or FoxPro table in Microsoft Visual Basic version 3.0 without needing separate utilities.



MORE INFORMATION
To be able to ZAP or PACK your .DBF files, you must have the following entry in your VB.INI or .INI file:

[dBase ISAM] Deleted=On

This will filter out deleted records so they do not appear in recordsets.

To perform a ZAP, you simply need to run a DELETE action query. For example, the following sample marks all the records in the AUTHORS.DBF table as deleted:

Dim db As database Set db = OpenDatabase("c:\dBaseIII", false, false, "dBase III") 'Open the database.

db.Execute "Delete From Authors"      'Execute the delete action query. db.Close                              'Close the database.

NOTE: For extremely large tables, it is more efficient to delete the Tabledef representing the table from the TableDefs collection of the database and then re-create the table structure. Please see articles Q110959 and 108147 for more information on this approach.

The following subroutine shows you how to perform a PACK. Essentially, you copy all the records to a new temporary table, delete the old one, then rename the temporary table as the original name.

Sample Code
Sub Pack_DBF (db As Database, tblname As String) Const MB_YESNO = 4                    ' Yes and No buttons Const MB_ICONEXCLAMATION = 48         ' Warning message Const IDYES = 6                       ' Yes button pressed

Dim dbdir As String, tmp As String 'Temp variables Dim i As Integer, ret As Integer  'Counter and return value of MsgBox

Dim flags As Integer                  'Flags for MsgBox ReDim idxs(0) As New index            'Holds indexes

On Error GoTo PackErr

flags = MB_YESNO Or MB_ICONEXCLAMATION ret = MsgBox("Remove All Deleted Records in " & tblname & "?", flags) If ret = IDYES Then dbdir = db.Name + "\"                     'Hold database directory

'Delete the temp file if it exists. If Dir$(dbdir & "p_a_c_k.*") <> "" Then Kill dbdir & "p_a_c_k.*" End If

'Store the indexes. For i = 0 To db.TableDefs(tblname).Indexes.Count - 1 ReDim Preserve idxs(i + 1) idxs(i).Name = db.TableDefs(tblname).Indexes(i).Name idxs(i).Fields = db.TableDefs(tblname).Indexes(i).Fields idxs(i).Primary = db.TableDefs(tblname).Indexes(i).Primary idxs(i).Unique = db.TableDefs(tblname).Indexes(i).Unique Next

'Create the new table without the deleted records. db.Execute "Select * into [p_a_c_k] from " & tblname

'Delete the current table. db.TableDefs.Delete tblname

'Rename the DBF file and any memo files. tmp = Dir$(dbdir & "p_a_c_k.*") Do While tmp <> "" 'Rename with the correct file extension; this should be on one line.

Name dbdir & tmp As dbdir & tblname & Right$(tmp, Len(tmp) - InStr(tmp, ".") + 1) tmp = Dir$ Loop

'Refresh the tabledefs and add the indexes to the new table. db.TableDefs.Refresh For i = 0 To UBound(idxs) - 1 db.TableDefs(tblname).Indexes.Append idxs(i) Next

MsgBox "'" & tblname & "' successfully Packed!", MB_ICONEXCLAMATION End If    Exit Sub

PackErr: MsgBox Error$ Exit Sub

PackEnd: End Sub

The following example code shows you how to call the above subroutine. First, you open the database the table is in, then you pass the database object and the name of the table to PACK to the subroutine. Be sure that there are not any open recordsets on the table you are trying to pack or you will get an error.

'To open file C:\SAMPLES\FOXTBL.DBF Dim db As Database Set db = OpenDatabase("c:\samples\foxtbl", False, False, "foxpro 2.5") Call Pack_DBF(db, "foxtbl") db.Close

NOTE: The above methods do not preserve formatting of numeric fields for our dBASE and FoxPro tables. To work around this limitation you should keep a template DBF file created from dBASE or FoxPro that contains the formatting you need, and use an INSERT INTO statement instead of the SELECT INTO statement shown above.

Additional query words: 3.00

Keywords: KB119116

-

[mailto:TECHNET@MICROSOFT.COM Send feedback to Microsoft]

© Microsoft Corporation. All rights reserved.