dbftool.lpr 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574
  1. program dbftool;
  2. { Reads and exports DBF files. Can create a demo DBF file to test with.
  3. Demonstrates creating DBF tables, filling it with data,
  4. and exporting datasets.
  5. }
  6. {$mode objfpc}{$H+}
  7. uses {$IFDEF UNIX} {$IFDEF UseCThreads}
  8. cthreads, {$ENDIF} {$ENDIF}
  9. Classes,
  10. SysUtils,
  11. CustApp,
  12. DB,
  13. dbf,
  14. dbf_fields,
  15. dbf_common,
  16. dateutils,
  17. fpdbexport,
  18. fpcsvexport,
  19. fpdbfexport,
  20. fpfixedexport,
  21. fprtfexport,
  22. fpsimplejsonexport,
  23. fpsimplexmlexport,
  24. fpsqlexport,
  25. fptexexport,
  26. fpxmlxsdexport;
  27. type
  28. { TDBFTool }
  29. TDBFTool = class(TCustomApplication)
  30. private
  31. procedure ExportDBF(var MyDbf: TDbf);
  32. protected
  33. procedure DoRun; override;
  34. public
  35. constructor Create(TheOwner: TComponent); override;
  36. destructor Destroy; override;
  37. procedure WriteHelp; virtual;
  38. end;
  39. procedure CreateDemoDBFs(Directory: string; TableLevel: integer);
  40. // Creates 2 demonstration DBFs in Directory with dbase compatibility level
  41. // TableLevel
  42. // and specified codepage (if not CODEPAGE_NOT_SPECIFIED)
  43. var
  44. NewDBF: TDBF;
  45. i: integer;
  46. begin
  47. NewDBF := TDBF.Create(nil);
  48. try
  49. if Directory = '' then
  50. NewDBF.FilePath := '' { application directory}
  51. else
  52. NewDBF.FilePathFull := ExpandFileName(Directory) {full absolute path};
  53. if TableLevel <= 0 then
  54. NewDBF.TableLevel := 4 {default to DBase IV}
  55. else
  56. NewDBF.TableLevel := TableLevel;
  57. NewDBF.TableName := 'CUSTOMER.DBF';
  58. writeln('Creating ', NewDBF.TableName, ' with table level ', NewDBF.TableLevel);
  59. if TableLevel >= 30 then
  60. begin
  61. NewDBF.FieldDefs.Add('CUST_NO', ftAutoInc);
  62. end
  63. else
  64. NewDBF.FieldDefs.Add('CUST_NO', ftInteger);
  65. NewDBF.FieldDefs.Add('CUSTOMER', ftString, 25);
  66. NewDBF.FieldDefs.Add('CITY', ftString, 25);
  67. NewDBF.FieldDefs.Add('COUNTRY', ftString, 15);
  68. NewDBF.CreateTable;
  69. NewDBF.Open;
  70. for i := 1 to 5 do //keep size manageable until we have working files
  71. begin
  72. NewDBF.Append;
  73. if (NewDBF.FieldDefs.Find('CUST_NO').DataType <> ftAutoInc) then
  74. NewDBF.FieldByName('CUST_NO').AsInteger := i;
  75. case i of
  76. 1:
  77. begin
  78. NewDBF.FieldByName('CUSTOMER').AsString := 'Michael Design';
  79. NewDBF.FieldByName('CITY').AsString := 'San Diego';
  80. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  81. end;
  82. 2:
  83. begin
  84. NewDBF.FieldByName('CUSTOMER').AsString := 'Michael Design';
  85. NewDBF.FieldByName('CITY').AsString := 'San Diego';
  86. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  87. end;
  88. 3:
  89. begin
  90. NewDBF.FieldByName('CUSTOMER').AsString := 'VC Technologies';
  91. NewDBF.FieldByName('CITY').AsString := 'Dallas';
  92. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  93. end;
  94. 4:
  95. begin
  96. NewDBF.FieldByName('CUSTOMER').AsString := 'Klämpfl, Van Canneyt';
  97. NewDBF.FieldByName('CITY').AsString := 'Boston';
  98. NewDBF.FieldByName('COUNTRY').AsString := 'USA';
  99. end;
  100. 5:
  101. begin
  102. NewDBF.FieldByName('CUSTOMER').AsString := 'Felipe Bank';
  103. NewDBF.FieldByName('CITY').AsString := 'Manchester';
  104. NewDBF.FieldByName('COUNTRY').AsString := 'England';
  105. end;
  106. end;
  107. NewDBF.Post;
  108. end;
  109. NewDBF.Close;
  110. finally
  111. NewDBF.Free;
  112. end;
  113. NewDBF := TDBF.Create(nil);
  114. try
  115. if Directory = '' then
  116. NewDBF.FilePath := '' { application directory}
  117. else
  118. NewDBF.FilePathFull := ExpandFileName(Directory) {full absolute path};
  119. if TableLevel <= 0 then
  120. NewDBF.TableLevel := 4 {default to DBase IV}
  121. else
  122. NewDBF.TableLevel := TableLevel;
  123. NewDBF.TableName := 'EMPLOYEE.DBF';
  124. writeln('Creating ', NewDBF.TableName, ' with table level ', NewDBF.TableLevel);
  125. if TableLevel >= 30 then
  126. begin
  127. NewDBF.FieldDefs.Add('EMP_NO', ftAutoInc);
  128. end
  129. else
  130. NewDBF.FieldDefs.Add('EMP_NO', ftInteger);
  131. NewDBF.FieldDefs.Add('FIRST_NAME', ftString, 15);
  132. NewDBF.FieldDefs.Add('LAST_NAME', ftString, 20);
  133. NewDBF.FieldDefs.Add('PHONE_EXT', ftString, 4);
  134. NewDBF.FieldDefs.Add('JOB_CODE', ftString, 5);
  135. NewDBF.FieldDefs.Add('JOB_GRADE', ftInteger);
  136. NewDBF.FieldDefs.Add('JOB_COUNTR', ftString, 15); //Note 10 character limit for table/field names in most DBases
  137. NewDBF.FieldDefs.Add('SALARY', ftFloat);
  138. NewDBF.CreateTable;
  139. NewDBF.Open;
  140. for i := 1 to 5 do //keep size manageable until we have working files
  141. begin
  142. NewDBF.Append;
  143. if (NewDBF.FieldDefs.Find('EMP_NO').DataType <> ftAutoInc) then
  144. NewDBF.FieldByName('EMP_NO').AsInteger := i;
  145. case i of
  146. 1:
  147. begin
  148. NewDBF.FieldByName('FIRST_NAME').AsString := 'William';
  149. NewDBF.FieldByName('LAST_NAME').AsString := 'Shatner';
  150. NewDBF.FieldByName('PHONE_EXT').AsString := '1702';
  151. NewDBF.FieldByName('JOB_CODE').AsString := 'CEO';
  152. NewDBF.FieldByName('JOB_GRADE').AsInteger := 1;
  153. NewDBF.FieldByName('JOB_COUNTR').AsString := 'USA';
  154. NewDBF.FieldByName('SALARY').AsFloat := 48000;
  155. end;
  156. 2:
  157. begin
  158. NewDBF.FieldByName('FIRST_NAME').AsString := 'Ivan';
  159. NewDBF.FieldByName('LAST_NAME').AsString := 'Ishenin';
  160. NewDBF.FieldByName('PHONE_EXT').AsString := '9802';
  161. NewDBF.FieldByName('JOB_CODE').AsString := 'Eng';
  162. NewDBF.FieldByName('JOB_GRADE').AsInteger := 2;
  163. NewDBF.FieldByName('JOB_COUNTR').AsString := 'Russia';
  164. NewDBF.FieldByName('SALARY').AsFloat := 38000;
  165. end;
  166. 3:
  167. begin
  168. NewDBF.FieldByName('FIRST_NAME').AsString := 'Erin';
  169. NewDBF.FieldByName('LAST_NAME').AsString := 'Powell';
  170. NewDBF.FieldByName('PHONE_EXT').AsString := '1703';
  171. NewDBF.FieldByName('JOB_CODE').AsString := 'Admin';
  172. NewDBF.FieldByName('JOB_GRADE').AsInteger := 2;
  173. NewDBF.FieldByName('JOB_COUNTR').AsString := 'USA';
  174. NewDBF.FieldByName('SALARY').AsFloat := 45368;
  175. end;
  176. 4:
  177. begin
  178. NewDBF.FieldByName('FIRST_NAME').AsString := 'Margaret';
  179. NewDBF.FieldByName('LAST_NAME').AsString := 'Tetchy';
  180. NewDBF.FieldByName('PHONE_EXT').AsString := '3804';
  181. NewDBF.FieldByName('JOB_CODE').AsString := 'Eng';
  182. NewDBF.FieldByName('JOB_GRADE').AsInteger := 3;
  183. NewDBF.FieldByName('JOB_COUNTR').AsString := 'England';
  184. NewDBF.FieldByName('SALARY').AsFloat := 28045;
  185. end;
  186. 5:
  187. begin
  188. NewDBF.FieldByName('FIRST_NAME').AsString := 'Sergey';
  189. NewDBF.FieldByName('LAST_NAME').AsString := 'Bron';
  190. NewDBF.FieldByName('PHONE_EXT').AsString := '3807';
  191. NewDBF.FieldByName('JOB_CODE').AsString := 'Admin';
  192. NewDBF.FieldByName('JOB_GRADE').AsInteger := 3;
  193. NewDBF.FieldByName('JOB_COUNTR').AsString := 'England';
  194. NewDBF.FieldByName('SALARY').AsFloat := 24468;
  195. end;
  196. end;
  197. NewDBF.Post;
  198. end;
  199. NewDBF.Close;
  200. finally
  201. NewDBF.Free;
  202. end;
  203. end;
  204. procedure GetDBFList(Results: TStringList);
  205. // Gets list of all .dbf files in a directory and its subdirectories.
  206. var
  207. r: TSearchRec;
  208. begin
  209. results.Clear;
  210. if FindFirst('*.dbf', faAnyFile -
  211. {$WARNINGS OFF}
  212. faVolumeID - faSymLink
  213. {$WARNINGS ON}
  214. , r) = 0 then
  215. begin
  216. repeat
  217. if (r.Attr and faDirectory) <> faDirectory then
  218. begin
  219. results.add(expandfilename(r.Name));
  220. end;
  221. until (FindNext(r) <> 0);
  222. findclose(r);
  223. end;
  224. end;
  225. function BinFieldToHex(BinarySource: TField): string;
  226. // Convert binary field contents to strings with hexadecimal representation.
  227. // Useful for displaying binary field contents.
  228. var
  229. HexValue: PChar;
  230. begin
  231. Result := '';
  232. HexValue := StrAlloc(Length(BinarySource.AsBytes));
  233. try
  234. try
  235. BinToHex(PChar(BinarySource.AsBytes), HexValue, Length(BinarySource.AsBytes));
  236. Result := 'size: ' + IntToStr(Length(BinarySource.AsBytes)) + '; hex: ' + HexValue;
  237. except
  238. on E: Exception do
  239. begin
  240. Result := 'exception: ' + E.ClassName + '/' + E.Message;
  241. end;
  242. end;
  243. finally
  244. StrDispose(HexValue);
  245. end;
  246. end;
  247. procedure PrintRecord(DBf: TDBf; RecordNumber: integer);
  248. // Prints contents of a record to screen
  249. var
  250. i: integer;
  251. begin
  252. writeln('Record ' + IntToStr(RecordNumber));
  253. for i := 0 to DBf.Fields.Count - 1 do
  254. begin
  255. if DBF.fields[i].IsNull then
  256. writeln('Field ', DBf.Fields[i].FieldName, ' is ***NULL***')
  257. else
  258. if DBF.Fields[i].DataType in [ftVarBytes, ftBytes] then
  259. writeln('Field ', DBF.Fields[i].FieldName, ' has value: binary ' + BinFieldToHex(DBF.Fields[i]))
  260. else
  261. writeln('Field ', DBf.Fields[i].FieldName, ' has value: ' + DBf.fields[i].AsString);
  262. end;
  263. end;
  264. { TDBFTool }
  265. procedure TDBFTool.ExportDBF(var MyDbf: TDbf);
  266. // Exports recordset to another format depending on user selection
  267. var
  268. ExportFormatText: string;
  269. ExportSettings: TCustomExportFormatSettings;
  270. Exporter: TCustomFileExporter;
  271. begin
  272. ExportFormatText := UpperCase(GetOptionValue('exportformat'));
  273. try
  274. case ExportFormatText of
  275. 'ACCESS', 'MSACCESS':
  276. begin
  277. Exporter := TXMLXSDExporter.Create(nil);
  278. ExportSettings := TXMLXSDFormatSettings.Create(true);
  279. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  280. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  281. AccessCompatible;
  282. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  283. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  284. end;
  285. 'ADO', 'ADONET', 'ADO.NET':
  286. begin
  287. Exporter := TXMLXSDExporter.Create(nil);
  288. ExportSettings := TXMLXSDFormatSettings.Create(true);
  289. (ExportSettings as TXMLXSDFormatSettings).CreateXSD := true;
  290. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  291. ADONETCompatible;
  292. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  293. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  294. end;
  295. 'CSVEXCEL', 'EXCELCSV', 'CREATIVYST':
  296. begin
  297. Exporter := TCSVExporter.Create(nil);
  298. ExportSettings := TCSVFormatSettings.Create(true);
  299. (ExportSettings as TCSVFormatSettings).RowDelimiter:=LineEnding;
  300. //todo: delimiter?
  301. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  302. end;
  303. 'CSV', 'CSVRFC4180', 'CSVLIBRE', 'CSVLIBREOFFICE':
  304. begin
  305. Exporter := TCSVExporter.Create(nil);
  306. ExportSettings := TCSVFormatSettings.Create(true);
  307. (ExportSettings as TCSVFormatSettings).DecimalSeparator := '.';
  308. (ExportSettings as TCSVFormatSettings).StringQuoteChar := '"';
  309. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.csv');
  310. end;
  311. 'DATASET', 'DELPHI':
  312. begin
  313. Exporter := TXMLXSDExporter.Create(nil);
  314. ExportSettings := TXMLXSDFormatSettings.Create(true);
  315. (ExportSettings as TXMLXSDFormatSettings).ExportFormat :=
  316. DelphiClientDataset;
  317. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  318. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  319. end;
  320. 'EXCEL', 'EXCELXML':
  321. begin
  322. Exporter := TXMLXSDExporter.Create(nil);
  323. ExportSettings := TXMLXSDFormatSettings.Create(true);
  324. (ExportSettings as TXMLXSDFormatSettings).ExportFormat := ExcelCompatible;
  325. (ExportSettings as TXMLXSDFormatSettings).DecimalSeparator := '.';
  326. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  327. end;
  328. 'JSON':
  329. begin
  330. Exporter := TSimpleJSONExporter.Create(nil);
  331. ExportSettings := TSimpleJSONFormatSettings.Create(true);
  332. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.json');
  333. end;
  334. 'SIMPLEXML', 'XML':
  335. begin
  336. Exporter := TSimpleXMLExporter.Create(nil);
  337. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  338. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.xml');
  339. end;
  340. 'RTF':
  341. begin
  342. Exporter := TRTFExporter.Create(nil);
  343. ExportSettings := TSimpleXMLFormatSettings.Create(true);
  344. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.rtf');
  345. end;
  346. 'SQL':
  347. begin
  348. Exporter := TSQLExporter.Create(nil);
  349. ExportSettings := TSQLFormatSettings.Create(true);
  350. (ExportSettings as TSQLFormatSettings).QuoteChar := '"';
  351. (ExportSettings as TSQLFormatSettings).DecimalSeparator := '.';
  352. (ExportSettings as TSQLFormatSettings).TableName := ChangeFileExt(MyDBF.TableName,'');
  353. (ExportSettings as TSQLFormatSettings).DateFormat := 'yyyy"-"mm"-"dd'; //ISO 8601, yyyy-mm-dd
  354. (ExportSettings as TSQLFormatSettings).TimeFormat := 'hh":"nn":"ss'; //ISO 8601, hh:mm:ss;
  355. (ExportSettings as TSQLFormatSettings).DateTimeFormat :=
  356. (ExportSettings as TSQLFormatSettings).DateFormat + '"T"' + (ExportSettings as TSQLFormatSettings).TimeFormat; //ISO 8601
  357. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.sql');
  358. end;
  359. 'TEX', 'LATEX':
  360. begin
  361. Exporter := TTeXExporter.Create(nil);
  362. ExportSettings := TTeXExportFormatSettings.Create(true);
  363. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.tex');
  364. end;
  365. 'TEXT', 'FIXED', 'FIXEDTEXT':
  366. begin
  367. Exporter := TFixedLengthExporter.Create(nil);
  368. ExportSettings := nil;
  369. Exporter.FileName := MyDBF.FilePathFull + ChangeFileExt(MyDBF.TableName, '.txt');
  370. end
  371. else
  372. begin
  373. writeln('***Error: Unknown export format ' + ExportFormatText + ' specified' + '. Aborting');
  374. Exporter := nil;
  375. ExportSettings := nil;
  376. Terminate;
  377. Exit;
  378. end;
  379. end;
  380. if assigned(ExportSettings) then
  381. Exporter.FormatSettings := ExportSettings;
  382. Exporter.Dataset := MyDBF;
  383. MyDBF.First; // we've just read the last record - make sure export starts at beginning
  384. Exporter.Execute;
  385. writeln('Completed export to ' + Exporter.FileName);
  386. finally
  387. if assigned(Exporter) then
  388. Exporter.Free;
  389. if assigned(ExportSettings) then
  390. ExportSettings.Free;
  391. end;
  392. end;
  393. procedure TDBFTool.DoRun;
  394. var
  395. DBFs: TStringList;
  396. Demo: boolean;
  397. ErrorMsg: string;
  398. FileNo: integer;
  399. MyDbf: TDbf;
  400. RecCount: integer;
  401. TableLevel: integer; //todo: use it
  402. begin
  403. // quick check parameters
  404. ErrorMsg := CheckOptions('h', 'codepage: createdemo exportformat: help tablelevel:');
  405. if ErrorMsg <> '' then
  406. begin
  407. ShowException(Exception.Create(ErrorMsg));
  408. Terminate;
  409. Exit;
  410. end;
  411. // parse parameters
  412. if HasOption('h', 'help') then
  413. begin
  414. WriteHelp;
  415. Terminate;
  416. Exit;
  417. end;
  418. DBFs := TStringList.Create;
  419. try
  420. Demo := false;
  421. if HasOption('createdemo') then
  422. Demo := true;
  423. TableLevel := 4; //DBF
  424. if HasOption('tablelevel') then
  425. TableLevel := StrToIntDef(GetOptionValue('tablelevel'), 4);
  426. if Demo then
  427. begin
  428. try
  429. CreateDemoDBFs('', TableLevel);
  430. except
  431. on E: Exception do
  432. begin
  433. writeln('*** Error creating demo databases: ' + E.Message);
  434. Terminate;
  435. Exit;
  436. end;
  437. end;
  438. end;
  439. // Process all dbfs if no files specified
  440. if DBFs.Count = 0 then
  441. GetDBFList(DBFs);
  442. if DBFs.Count = 0 then
  443. writeln('Could not find any dbf files');
  444. for FileNo := 0 to DBFs.Count - 1 do
  445. begin
  446. if not (fileexists(DBFs[FileNo])) then
  447. begin
  448. // for some reason, fpc trunk suddenly returns the directory as well...
  449. //writeln('Sorry, file ',DBFs[FileNo],' does not exist.');
  450. break;
  451. end;
  452. MyDbf := TDbf.Create(nil);
  453. try
  454. try
  455. MyDbf.FilePath := ExtractFilePath(DBFs[FileNo]);
  456. MyDbf.TableName := ExtractFileName(DBFs[FileNo]);
  457. MyDbf.ReadOnly := true;
  458. writeln('*** Opening: ' + DBFs[FileNo]);
  459. MyDbf.Open;
  460. writeln('Database tablelevel: ' + IntToStr(MyDbf.TableLevel));
  461. writeln('Database codepage: ' + IntToStr(MyDBF.CodePage));
  462. RecCount := 1;
  463. while not (MyDbf.EOF) do
  464. begin
  465. PrintRecord(MyDBF, RecCount);
  466. MyDBF.Next;
  467. RecCount := RecCount + 1;
  468. writeln('');
  469. end;
  470. if HasOption('exportformat') then
  471. begin
  472. try
  473. ExportDBF(MyDbf);
  474. except
  475. on E: Exception do
  476. begin
  477. writeln('*** Problem exporting file ', FileNo, ': ', E.Message);
  478. end;
  479. end;
  480. end;
  481. MyDbf.Close;
  482. except
  483. on E: Exception do
  484. begin
  485. writeln('*** Error reading file ', FileNo, ': ', E.Message);
  486. end;
  487. end;
  488. finally
  489. MyDbf.Free;
  490. end;
  491. end;
  492. finally
  493. DBFs.Free;
  494. end;
  495. // stop program loop
  496. Terminate;
  497. end;
  498. constructor TDBFTool.Create(TheOwner: TComponent);
  499. begin
  500. inherited Create(TheOwner);
  501. StopOnException := true;
  502. end;
  503. destructor TDBFTool.Destroy;
  504. begin
  505. inherited Destroy;
  506. end;
  507. procedure TDBFTool.WriteHelp;
  508. begin
  509. writeln('Usage: ', ExeName, ' -h');
  510. writeln(' --createdemo create demo database');
  511. writeln(' --tablelevel=<n> optional: desired tablelevel for demo db');
  512. writeln(' 3 DBase III');
  513. writeln(' 4 DBase IV');
  514. writeln(' 7 Visual DBase 7');
  515. writeln(' 25 FoxPro 2.x');
  516. writeln(' 30 Visual FoxPro');
  517. writeln(' --exportformat=<text> export dbfs to format. Format can be:');
  518. writeln(' access Microsoft Access XML');
  519. writeln(' adonet ADO.Net dataset');
  520. writeln(' csvexcel Excel/Creativyst format CSV text file (with locale dependent output)');
  521. writeln(' csvRFC4180 LibreOffice/RFC4180 format CSV text file');
  522. writeln(' dataset Delphi dataset XML');
  523. writeln(' excel Microsoft Excel XML');
  524. writeln(' fixedtext Fixed length text file');
  525. writeln(' json JSON file');
  526. writeln(' rtf Rich Text Format');
  527. writeln(' simplexml Simple XML');
  528. writeln(' sql SQL insert statements');
  529. writeln(' tex LaTeX file');
  530. end;
  531. var
  532. Application: TDBFTool;
  533. begin
  534. Application := TDBFTool.Create(nil);
  535. Application.Title := 'DBFTool';
  536. Application.Run;
  537. Application.Free;
  538. end.