 |
***************************************************************
* fixreccount.prg
*
* Title:
* Check and fix header record counter of a table
*
* Author(s):
* Shirokov A.V.
*
* Syntax:
* do fixreccount [with tcTableName[, tlNeedInfo = .f.]]
*
* Parameters:
* tcTableName - a table name
* tlNeedInfo - flag \"need debug info\". Default .f.
*
* Example:
* set printer to log.txt
* set printer on
* do fixreccount with \"test.dbf\", .t.
* set printer off
* set printer to
*
***************************************************************
* FOPEN\'s constants
*
* 0 (Default) Read Only Buffered
#define FA_READONLY 0
* 1 Write-Only Buffered
#define FA_WRITEONLY 1
* 2 Read and Write Buffered
#define FA_READWRITE 2
* 10 Read-Only Unbuffered
#define FA_READONLY_DIRECT 10
* 11 Write-Only Unbuffered
#define FA_WRITEONLY_DIRECT 11
* 12 Read and Write Unbuffered
#define FA_READWRITE_DIRECT 12
* FSEEK\'s constants
*
* 0 (Default) The beginning of the file.
#define FS_BEGIN 0
* 1 The current file pointer position
#define FS_CURRENT 1
* 2 The end of the file
#define FS_END 2
lparam tcFile, tlNeedInfo
private all
if type(\'m.tcFile\') != \'C\'
tcFile = getfile(\"DBF\", \"Browse table\")
if empty(m.tcFile)
return
endif
endif
lnFile = fopen(m.tcFile, FA_READWRITE)
if m.lnFile = -1
=MessageBox(\"Could not open \"+m.tcFile, 16, \"Error\")
return
endif
lnByte = asc(fread(m.lnFile, 1))
if not inlist(m.lnByte, ;
0*16+2, ; && FoxBASE
0*16+3, ; && FoxBASE+/dBASE III PLUS, no memo
3*16+0, ; && Visual FoxPro
4*16+3, ; && dBASE IV SQL table files, no memo
6*16+3, ; && dBASE IV SQL system files, no memo
8*16+3, ; && FoxBASE+/dBASE III PLUS, with memo
8*16+11, ; && dBASE IV with memo
12*16+11, ; && dBASE IV SQL table files, with memo
15*16+5, ; && FoxPro 2.x (or earlier) with memo
15*16+11 ; && FoxBASE
)
=MessageBox(\"The file \'\" + m.tcFile + \"\' is not DBF\", 16, \"Error\")
fclose(m.lnFile)
return
endif
=fseek(m.lnFile, 0, FS_BEGIN)
lnSize = fseek(m.lnFile, 0, FS_END)
lnRecCount = 0
fseek(m.lnFile, 4, FS_BEGIN)
for lnIndex = 1 to 4
lnByte = asc(fread(m.lnFile, 1))
lnRecCount = bitor(m.lnRecCount, bitlshift(m.lnByte, 8*(m.lnIndex-1)))
endfor
lnDataStart = 0
for lnIndex = 1 to 2
lnByte = asc(fread(m.lnFile, 1))
lnDataStart = bitor(m.lnDataStart, bitlshift(m.lnByte, 8*(m.lnIndex-1)))
endfor
lnRecLength = 0
for lnIndex = 1 to 2
lnByte = asc(fread(m.lnFile, 1))
lnRecLength = bitor(m.lnRecLength, bitlshift(m.lnByte, 8*(m.lnIndex-1)))
endfor
lnDataSize = m.lnSize - m.lnDataStart
lnFactRecCount = int(m.lnDataSize/m.lnRecLength)
lnAnswer = 0
if m.lnFactRecCount != m.lnRecCount
lnAnswer = MessageBox(m.tcFile + chr(13) + \"Do fix record counter?\", 3+32, \"Question\")
if m.lnAnswer == 6
fseek(m.lnFile, 4, FS_BEGIN)
for lnIndex=1 to 4
lnByte = bitand(bitrshift(m.lnFactRecCount, 8*(m.lnIndex-1)), 255)
fwrite(m.lnFile, chr(m.lnByte), 1)
endfor
endif
endif
fclose(m.lnFile)
if m.tlNeedInfo
? \"FIXRECCOUNT FOR \"+alltrim(m.tcFile)
? replicate(\"=\", 80)
? \"Size\", m.lnSize
? \"Data Start\", m.lnDataStart
? \"Data Size = Size - Data Start = \", m.lnSize, \"-\", m.lnDataStart, \" = \", m.lnDataSize
? \"Record Length\", m.lnRecLength
? \"Header Record Count\", m.lnRecCount
? \"Fact Record Count = Data Size / Record Length = \", m.lnDataSize, \"/\", m.lnRecLength,
\"=\",m.lnFactRecCount
if m.lnFactRecCount = m.lnRecCount
? \"NO NEED FIX\"
else
? iif(m.lnAnswer == 6, \"FIXED\", \"FIX IS SKIPED\")
endif
endif
return m.lnAnswer == 6
|
|