Delphi: ADOConnection, DBASE3 and character set (bug?)

我的未来我决定 提交于 2019-12-11 03:52:51

问题


Delphi XE3, Win7 Prof.

I need to write into DBASE 3 (old format) files to export data for a DOS-like application (Clipper?). Ok, I thought: MS DBASE driver can do this.

But I have problem with hungarian accents.

I tried this connection string:

Driver={Microsoft dBASE Driver (*.dbf)};DriverID=21;Dbq=c:\temp;Extended Properties=dBASE III;charSet=CP 852;Locale Identifier=1038;Character Set=CP 852;CODEPAGE=852

As I saw it cannot write only ANSI files (the DOS app accepts CP852 chars).

I tried to convert the content with AnsiToOEM, but some characters lost on save. In the record I see good content, but the saved file contains wrong accents. The test text is "árvíztűrő tükörfúrógép". The "í", "ó", "Ó" is missing from the result.

And I found some strange thing!

If the main form have an opened ADOConnection (the connected property is true in the DFM) then I will read good characters from the DBASE files, and I can write them into the file - the ANSI characters will be converted correctly. "í" is ok, "ó" is ok. This ADOConnection object could be different than the reader.

If I close this ADOConnection in IDE mode, the opened files won't be converted, so I will see some strange accented chars, and I won't write good text into the file.

It is strange, because if I open this connection on FormCreate by code, the problem will appear... I can read and write the ADOQuery records if the resource streamer read the ADOConnection's active (True value) "connected" property from the DFM!

I don't know what happened in the background, and how to force this ADO character transformation routine to work, but I wasted more days to find a working DBASE III exporter, and I have found only a buglike thing...

Does anyone know what is this? Why the ADO character encoder/decoder works only if I had a connected ADOConnection in DFM? Or how I can use ADODB.Connection instead of ADOConnection object to avoid this side effect?

Thanks for every idea!


回答1:


As I see I need to set the code page to fix the string for ADO.

var
  s: string;
  aStr1, aStr2: AnsiString;

begin
...

s := 'árvíztûrõ tükörfúrógép';
aStr1 := s;
SetLength(aStr2, Length(aStr1));
AnsiToOemBuff(PAnsiChar(aStr1), PAnsiChar(aStr2), Length(aStr1));
SetCodePage(RawbyteString(aStr2), 852, False); // THIS IS THE SOLUTION
ADOQuery1.FieldBYName('name').AsAnsiString := aStr2;

Otherwise something is converting my AnsiString again in the background.



来源:https://stackoverflow.com/questions/26169419/delphi-adoconnection-dbase3-and-character-set-bug

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!