ducker88
Messages postés277Date d'inscriptionlundi 9 février 2004StatutMembreDernière intervention 4 mai 2008
-
11 sept. 2007 à 16:34
ducker88
Messages postés277Date d'inscriptionlundi 9 février 2004StatutMembreDernière intervention 4 mai 2008
-
18 sept. 2007 à 15:49
>Bonjour à tous,
Voila deux ans que je travaille sur foxpro (tant bien que mal...) et j'apprend aujourd'hui qu'il est possible que la base ai été migré de foxpro vers visual foxpro et que cette manipulation n'aurait pas été faites sur les fichiers.
Quelqu'un pourrais t'il eclairé ma lanterne car j'ai du mal a comprendre. J'ai toujours pensé jusqu'a maintenant que les fichiers etaient les meme depuis le debut de foxpro.
Comment voir en quel version sont les fichiers ainsi que la base, et comment les faires migrer.
Mike Gagnon
Messages postés381Date d'inscriptionvendredi 15 octobre 2004StatutMembreDernière intervention24 octobre 20132 17 sept. 2007 à 12:53
Voici un example comment determiner certaines informations sur un table Foxpro
close all
public filehandle, rdfile, ctype, nrecords, nposrec1, nreclen, nfldpos, cfield
public cfldtype, nflddec, nfldlen, nfldcnt, lhasmem, lhascdx, lisdbc, lisbin
public nfldflag, cassdbc, nfilesize, dtmp, nAutoIncrNextVal, nAutoIncrStepVal
public cSetDate, cSetCentury, lcdxmemdbcError, nfilesizediff, lisvfp, nFldProblem
dimension dbfhdr[32]
cSetDate = SET('DATE')
cSetCentury = SET('CENTURY')
SET DATE YMD
SET CENTURY off
cfldtype=''
nfldlen=0
nfldcnt=0
nfldflag=0
nfilesize=0
cassdbc=''
rdfile=space(30)
lcdxmemdbcError=.f.
* get filename
do getfname
* read fileheader
do readheader
lisvfp = (dbfhdr[1]=48 or dbfhdr[1]=49)
ctype = FileType(dbfhdr[1]) && determine the filetype
nrecords=dbfhdr[5]+dbfhdr[6]*256+dbfhdr[7]*256^2+dbfhdr[8]*256^3 && calculate the number of records (bytes 5,6,7 and 8)
nreclen=dbfhdr[11]+dbfhdr[12]*256 && calculete the record length (bytes 11 and 12)
nposrec1=dbfhdr[9]+dbfhdr[10]*256 + 1 && calculate the position of the first record (bytes 9 and 10)
dtmp=CTOD(tran(dbfhdr[2],'@L 99')+'/'+tran(dbfhdr[3],'@L 99')+'/'+tran(dbfhdr[4],'@L 99')) && check for a valid update date
do cdxmemdbc && determine if this dbf has a structural index file and/or a memo file
? 'Headerinfo on '+rdfile
?
? 'Code / Type :',tran( dbfhdr[1],'@L 99')+' '+ctype
? 'Last update :',tran(dbfhdr[2],'@L 99')+' '+tran(dbfhdr[3],'@L 99')+' '+tran(dbfhdr[4],'@L 99')
? 'Number of records:',ltrim(str(nrecords))
? 'Position 1st rec :',ltrim(str(nposrec1,5))
? 'Header length :',ltrim(str(nposrec1-1,5))
? 'Record length :',ltrim(str(nreclen,5))
? 'File size :',ltrim(str(nfilesize,8))
? 'Struct Index File:',iif(lcdxmemdbcError,'Unknown/Invalid code found',iif(lhascdx,'Yes','No'))
? 'Memo file ;',iif(lcdxmemdbcError,'Unknown/Invalid code found',iif(lhasmem,'Yes','No'))
? 'File is a VFP DBC:',iif(lcdxmemdbcError,'Unknown/Invalid code found',iif(lisdbc,'Yes','No'))
? 'Number of fields :',ltrim(str( iif(lisvfp,(nposrec1-296)/32, (nposrec1-33)/32) ) )
? 'Codepage mark :',ltrim(str(dbfhdr[30]))+' (',ShowCodePageInfo(dbfhdr[30])+' )'
nEnddef=0
nFldProblem=0
FOR x=64 TO nfilesize-1 step 32
=FSEEK(filehandle, x,0)
nbyte= ASC(FREAD(filehandle,1))
IF nbyte= 13 && 0x0D
nEnddef = x+1
EXIT
ENDIF
NEXT
?
* read field definitions...
* the field definitions start at byte 33
* so first move to that position
* check filetype for different approach when it is a visual foxpro file
do case
case dbfhdr[1]=3 or dbfhdr[1]=131 or dbfhdr[1]=139 or dbfhdr[1]=245 && Not a VFP file
=fseek(filehandle,32,0) && position at field def positions
? 'Structure of '+rdfile
***1234567890123456789012345678901234567890123456789
? 'Field/name type length offset'
? ' in rec'
? '---------------------------------'
do while fseek(filehandle,0,1) < nposrec1-32
nfldcnt=nfldcnt+1
cfield=fread(filehandle,11)
cfield=STRTRAN(cfield,CHR(0),' ')
cfldtype=fread(filehandle,1)
nfldpos=asc(fread(filehandle,1))
=fseek(filehandle,3,1)
nfldlen=asc(fread(filehandle,1))
* if the field is type N find out how many decimals there are
if cfldtype='N'
nflddec=asc(fread(filehandle,1))
=fseek(filehandle,14,1)
else
=fseek(filehandle,15,1)
endif
? tran(nfldcnt,'@L 999'),padr(cfield,11), cfldtype,str(nfldlen,5)+iif(cfldtype='N','.'+ltrim(str(nflddec)),' '),str(nfldpos,5)
* test field length specificatons
DO CASE
CASE cfldtype='D' && this field should have a length of 8 bytes
IF nfldlen<>8
?? ' Invalid fieldlength, length should be 8'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype$'GIPTY' && these fields are invalid for non visual foxpro dbfs
?? 'Invalid fieldtype'
nFldProblem=nFldProblem+1
CASE cfldtype='C' && this field should have a length of 1-254 bytes
IF !BETWEEN(nfldlen,1,254)
?? ' Invalid fieldlength, length should be 1-254'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype$'NF' && these fields all should have a length of 1-20 bytes
IF !BETWEEN(nfldlen,1,20)
?? ' Invalid fieldlength, length should be 1-20'
nFldProblem=nFldProblem+1
IF nflddec> 18 && field decimals must be fieldlen - 2 maximal
nFldProblem=nFldProblem+1
?? ' Invalid number of decimals, max value is 18'
ENDIF
ELSE && field length in normal range, check number of decimals
IF nflddec>0 && field decimals defined and fieldlen OK
IF nfldlen - nflddec< 2 && field decimals must be fieldlen - 2 maximal
?? ' Invalid number of decimals, max value is '+LTRIM(STR(nfldlen - 2))
nFldProblem=nFldProblem+1
ENDIF
ENDIF
ENDIF
CASE cfldtype='L' && this field should have a length of 1 byte
IF nfldlen<>1
?? ' Invalid fieldlength, length should be 1'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype='M' && this field should have a length of 4 bytes
IF nfldlen<>4
?? ' Invalid fieldlength, length should be 4'
nFldProblem=nFldProblem+1
ENDIF
ENDCASE
enddo
? '---------------------------------'
case lisvfp && visual foxpro file
=fseek(filehandle,32,0) && position at field def positions
? 'Structure of '+rdfile
***1234567890123456789012345678901234567890123456789
? 'Field/name type length offset fieldflag AutoIncr AutoIncr '
? ' in rec NextValue StepValue'
? '----------------------------------------------------------------------'
do while fseek(filehandle,0,1) < nposrec1-(295)
nAutoIncrNextVal = 0
nAutoIncrStepVal = 0
nfldcnt=nfldcnt+1
cfield=fread(filehandle,11) && first 11 bytes
cfldtype=fread(filehandle,1) && byte 12
* bytes 13, 14, 15 and 16
nfldpos=asc(fread(filehandle,1))+asc(fread(filehandle,1))*256+asc(fread(filehandle,1))*256^2+asc(fread(filehandle,1))*256^3
nfldlen=asc(fread(filehandle,1)) && byte 17
* if the field is type N F B or Y find out how many decimals there are
DO case
CASE cfldtype$'NFBY'
nflddec=asc(fread(filehandle,1)) && byte 18
nfldflag=asc(fread(filehandle,1)) && byte 19
=fseek(filehandle,13,1) && skip 13 bytes
CASE cfldtype='I'
nflddec=asc(fread(filehandle,1)) && byte 18
nfldflag=asc(fread(filehandle,1)) && byte 19
nAutoIncrNextVal = ASC(FREAD(filehandle,1)) + ASC(FREAD(filehandle,1))* 256 + ;
ASC(FREAD(filehandle,1))* 256^2 + ASC(FREAD(filehandle,1)) * 256^3 && bytes 20,21,22 and 23
nAutoIncrStepVal = ASC(FREAD(filehandle,1)) && byte 24
=fseek(filehandle,8,1) && skip 8 bytes
OTHERWISE
nfldflag=asc(fread(filehandle,1)) && byte 18
=fseek(filehandle,14,1) && skip 14 bytes
ENDCASE
? tran(nfldcnt,'@L 9999'),padr(cfield,11)
?? ' '+ cfldtype + ' '
?? str(nfldlen,5)+iif(cfldtype='N','.'+ltrim(str(nflddec)),' ')
?? str(nfldpos,7)
Do case
case nfldflag = 1
?? ' System column '
case nfldflag = 2
?? ' Null values ok'
case nfldflag = 4
?? ' Binary column '
CASE nfldflag = 6
?? ' Null val & bin'
CASE nfldflag = 12
?? ' Autoincr. '
otherwise
?? ' '
ENDCASE
IF nAutoIncrNextVal>0
?? PADR(nAutoIncrNextVal,10)+' '+STR(nAutoIncrStepVal,3)
ENDIF
* test field length specificatons
DO CASE
CASE cfldtype$'DTBY' && these fields all should have a length of 8 bytes
IF nfldlen<>8
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+'Invalid fieldlength, length should be 8'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype$'GIMP' && these fields all should have a length of 4 bytes
IF nfldlen<>4
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+'Invalid fieldlength, length should be 4'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype='C' && this field should have a length of 1-254 bytes
IF !BETWEEN(nfldlen,1,254)
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+'Invalid fieldlength, length should be 1-254'
nFldProblem=nFldProblem+1
ENDIF
CASE cfldtype$'NF' && these fields all should have a length of 1-20 bytes
IF !BETWEEN(nfldlen,1,20)
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+' Invalid fieldlength, length should be 1-20'
nFldProblem=nFldProblem+1
IF nflddec> 18 && field decimals must be fieldlen - 2 maximal
?? ' Invalid number of decimals, max value is 18'
nFldProblem=nFldProblem+1
ENDIF
ELSE && field length in normal range, check number of decimals
IF nflddec>0 && field decimals defined and fieldlen OK
IF nfldlen - nflddec< 2 && field decimals must be fieldlen - 2 maximal
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+' Invalid number of decimals, max value is '+LTRIM(STR(nfldlen - 2))
nFldProblem=nFldProblem+1
ENDIF
ENDIF
ENDIF
CASE cfldtype='L' && this field should have a length of 1 byte
IF nfldlen<>1
?? IIF(dbfhdr[1]=49,' ', SPACE(30))+'Invalid fieldlength, length should be 1'
nFldProblem=nFldProblem+1
ENDIF
ENDCASE
enddo
=fseek(filehandle,1,1) && skip one byte
nassdbc=asc(fread(filehandle,1))
? '----------------------------------------------------------------------'
if nassdbc=0
? rdfile+' is not associated with a DBC'
else
=fseek(filehandle,-1,1) && skip back one byte
cassdbc=fread(filehandle,263)
nsppos=at(chr(0),cassdbc)
if nsppos>0
cassdbc=left(cassdbc,nsppos-1)
endif
? rdfile+' is associated with '+cassdbc
endif
endcase
?
? 'Some checks...'
nfilesizediff = nrecords*nreclen+nposrec1 - nfilesize
? 'Physical filesize ok :', ;
IIF(nfilesizediff=0,'Yes', 'NO, '+ ;
IIF(nfilesizediff>0,'TRUNCATED ','TOO LARGE ') ;
+'('+LTRIM( STR( ABS(nfilesizediff) ) )+' bytes)' )
? 'Last update date valid :', + IIF(!EMPTY(dtmp),'Yes','No')
? 'Header record terminator (0x0D) found at:', LTRIM(STR( nEnddef)), IIF(nEnddef = nposrec1 - 1 -iif(lisvfp,263,0),' OK',' Error in header')
? 'Record length according to fielddefinitions is '+ltrim(STR(nfldpos+nfldlen))+' which is '+IIF(nfldpos+nfldlen = nreclen,'OK','WRONG')
? 'There were '+IIF(nFldProblem>0,LTRIM(STR(nFldProblem)),'no')+' problems with the field definitions'
?
=fclose(filehandle) && close the table
* restore some original settings that were changed possibly....
SET DATE (cSetDate) && restore original set date setting
SET CENTURY &cSetCentury && restore original set century setting
RELEASE ALL
RETURN
***********************************************************
PROCEDURE cdxmemdbc
do case
case dbfhdr[29]=0
lhascdx=.f.
lhasmem=.f.
lisdbc=.f.
case dbfhdr[29]=1
lhascdx=.t.
lhasmem=.f.
lisdbc=.f.
case dbfhdr[29]=2
lhascdx=.f.
lhasmem=.t.
lisdbc=.f.
case dbfhdr[29]=3
lhascdx=.t.
lhasmem=.t.
lisdbc=.f.
case dbfhdr[29]=4
lhascdx=.f.
lhasmem=.f.
lisdbc=.t.
case dbfhdr[29]=5
lhascdx=.t.
lhasmem=.f.
lisdbc=.t.
case dbfhdr[29]=6
lhascdx=.f.
lhasmem=.t.
lisdbc=.t.
case dbfhdr[29]=7
lhascdx=.t.
lhasmem=.t.
lisdbc=.t.
otherwise
lhascdx=.f.
lhasmem=.f.
lisdbc=.f.
lcdxmemdbcError=.t.
endcase
return
procedure getfname
CLEAR
SET STEP ON
rdfile = GETFILE("dbf")
*!* @ 5,5 say 'Enter dbfname to investigate: ' get rdfile pict '@!'
*!* read
rdfile=alltrim(rdfile)
if len(rdfile)=0
return
endif
CLEAR
PUBLIC filehandle
filehandle=FOPEN(rdfile) && Open the file
if filehandle < 0
wait(rdfile+' NOT FOUND')
return
endif
return
procedure readheader
nfilesize =FSEEK(filehandle, 0 ,2) && move pointer to last byte to get filesize
=FSEEK(filehandle, 0,0) && Move pointer to first byte
bytecount=1
do while bytecount < 33
dbfhdr[bytecount] = asc(fgets(filehandle,1))
* if you want to see the contents of these bytes
* remove the * from the next line
* ? bytecount,dbfhdr[bytecount]
bytecount=bytecount+1
enddo
return
FUNCTION FileType
parameters ctyp
public c_type
do case
case ctyp=2
c_type='Foxbase'
case ctyp=3
c_type='Foxbase/Foxpro/dBaseIII/IV no memo'
case ctyp=48
c_type='Visual Foxpro'
case ctyp=49
c_type='Visual Foxpro 8+ AutoIncr'
case ctyp=50
c_type='Visual Foxpro 9+,Varchar,Varbinary or Blob-enabled'
case ctyp=67
c_type='dBase IV SQL table no memo'
case ctyp=99
c_type='dBase IV SQL system file no memo'
case ctyp=131
c_type='Foxbase/dBaseIII Plus with memo'
case ctyp=139
c_type='dBaseIV with memo'
case ctyp=203
c_type='dBaseIV SQL table with memo'
case ctyp=245
c_type='Foxpro 2.x with memo'
case ctyp=251
c_type='Foxbase'
otherwise
c_type='Unknown or invalid type'
endcase
return c_type
FUNCTION ShowCodePageInfo
PARAMETERS nCP
public cCP
DO case
CASE nCP = 0 && 0x00
cCP = 'No codepage defined'
CASE nCP = 1 && 0x01
cCP = 'Codepage 437 US MSDOS'
CASE nCP = 2 && 0x02
cCP = 'Codepage 850 International MS-DOS'
CASE nCP = 3 && 0x03
cCP = 'Codepage 1252 Windows ANSI'
CASE nCP = 4 && 0x04
cCP = 'Codepage 10000 Standard MacIntosh'
CASE nCP = 100 && 0x64
cCP = 'Codepage 852 Easern European MS-DOS'
CASE nCP = 101 && 0x65
cCP = 'Codepage 866 Russian MS-DOS'
CASE nCP = 102 && 0x66
cCP = 'Codepage 865 Nordic MS-DOS'
CASE nCP = 103 && 0x67
cCP = 'Codepage 861 Icelandic MS-DOS'
CASE nCP = 104 && 0x68
cCP = 'Codepage 895 Kamenicky (Czech) MS-DOS'
CASE nCP = 105 && 0x69
cCP = 'Codepage 620 Mazovia (Polish) MS-DOS'
CASE nCP = 106 && 0x6A
cCP = 'Codepage 737 Greek MS-DOS (437G)'
CASE nCP = 107 && 0x6B
cCP = 'Codepage 857 Turkish MS-DOS'
CASE nCP = 120 && 0x78
cCP = 'Codepage 950 Chinese (Hong Kong SAR, Taiwan) Windows'
CASE nCP = 121 && 0x79
cCP = 'Codepage 949 Korean Windows'
CASE nCP = 122 && 0x7A
cCP = 'Codepage 936 Chinese (PRC, Singapore) Windows'
CASE nCP = 123 && 0x7B
cCP = 'Codepage 932 Japanese Windows'
CASE nCP = 124 && 0x7C
cCP = 'Codepage 874 Thai Windows'
CASE nCP = 125 && 0x7D
cCP = 'Codepage 1255 Hebrew Windows'
CASE nCP = 126 && 0x7E
cCP = 'Codepage 1256 Arabic Windows'
CASE nCP = 150 && 0x96
cCP = 'Codepage 10007 Russian MacIntosh'
CASE nCP = 151 && 0x97
cCP = 'Codepage 10029 MacIntosh EE'
CASE nCP = 152 && 0x98
cCP = 'Codepage 10006 Greek MacIntosh'
CASE nCP = 200 && 0xC8
cCP = 'Codepage 1250 Eastern European Windows'
CASE nCP = 201 && 0xC9
cCP = 'Codepage 1251 Russian Windows'
CASE nCP = 202 && 0xCA
cCP = 'Codepage 1254 Turkish Windows'
CASE nCP = 203 && 0xCB
cCP = 'Codepage 1253 Greek Windows'
OTHERWISE
cCP = 'Unknown / invalid codepage'
ENDCASE
RETURN cCP
les fichiers ne sont en effet pas les mêmes, et l'information concernant la version de fox sous laquelle ils sont est stockée dans le header de la table:
extrait de l'aide de VFP9:
Table Header Record Structure
Byte offset |
Description |
----
0,
File type: 0x02
FoxBASE: 0x03
FoxBASE+/Dbase III plus, no memo: 0x30
Visual FoxPro: 0x31
Visual FoxPro, autoincrement enabled: 0x32
Visual FoxPro, Varchar, Varbinary, or Blob-enabled: 0x43
dBASE IV SQL table files, no memo: 0x63
dBASE IV SQL system files, no memo: 0x83
FoxBASE+/dBASE III PLUS, with memo: 0x8B
dBASE IV with memo: 0xCB
dBASE IV SQL table files, with memo: 0xF5
FoxPro 2.x (or earlier) with memo: 0xFB
FoxBASE,
----
1 - 3,
Last update (YYMMDD),
----
4 – 7,
Number of records in file,
----
8 – 9,
Position of first data record,
----
10 – 11,
Length of one data record, including delete flag,
----
12 – 27,
Reserved,
----
28,
Table flags: 0x01 file has a structural .cdx 0x02 file has a Memo field 0x04 file is a database (.dbc) This byte can contain the sum of any of the above values. For example, the value 0x03 indicates the table has a structural .cdx and a Memo field.,
----
29,
Code page mark,
----
30 – 31,
Reserved, contains 0x00,
----
32 – n,
Field subrecords The number of fields determines the number of field subrecords. One field subrecord exists for each field in the table.,
----
n+1,
Header record terminator (0x0D),
----
n+2 to n+264,
A 263-byte range that contains the backlink, which is the relative path of an associated database (.dbc) file, information. If the first byte is 0x00, the file is not associated with a database. Therefore, database files always contain 0x00.
ducker88
Messages postés277Date d'inscriptionlundi 9 février 2004StatutMembreDernière intervention 4 mai 2008 18 sept. 2007 à 15:49
Bonjour Michel,
Merci pour ce petit programme, c'est exactement ce qu'il me fallait.
Le programme me retourne 30 pour le type de fichier, j'en conclu donc par ces informations qu'ils sont du type FoxBASE+/Dbase III plus, no memo.
Existe t'il une solution pour faire passer ces fichier en 0x43 c'est a dire en fichier foxpro ?