问题
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