简介和相关信息:
我有一个 MS Access 2007
数据库,其中有一个包含 string
字段和 numerical
字段的表。 numerical
字段的类型为 double
,可以为负值或正值。
我使用 ADO
连接到数据库,并使用 edit
API 将其数据加载到 SetDialogItemText
控件中 - edit
控件位于 dialog box
中。
用户可以编辑现有数据的值(保存更改时,我使用 edit
API 从 GetDialogItemText
控件获取数据)。
问题:
如果用户使用英语或美国语言环境,我的程序一切正常,但如果用户选择欧洲语言环境,则我的 ADO
string
不正确并报告错误。
这是预期的,因为在英语版本中它有 2 个参数 - string
和 double
但由于欧洲人使用逗号作为小数点(例如美国 123.456
是 123,456
)ADO
将其解释为 < strong>3 个参数而不是两个 - 例如:
INSERT INTO table VALUES ( 'some string', 12.5 );
---> 美国语言环境
INSERT INTO table VALUES ( 'some string', 12,5 );
---> 错误! 3个参数代替2个
更彻底地解释:
假设我们已使用欧洲语言环境将数据从数据库加载到编辑控件中:
第一个包含 string
( Some string
),第二个包含一个十进制数 ( 123,456
)。
假设用户将 string
值更改为 Some other string
并按下保存按钮。
现在我的代码从 edit
控件获取值,但由于我从第二个编辑控件获取 123,456
(记住,用户保留十进制数据不变),所以一定会发生错误,并且我的 ADO string
未正确配置,因为现在看起来像这样:
INSERT INTO table VALUES ( 'Some other string', 123,456 );
--> 错误! 3个参数
我的问题:
如果用户设置了欧洲语言环境,是否有办法将 MS Access 2007
数据库中的十进制值加载到编辑控件中,并将逗号已更改转换为点?
或者也许我可以以某种方式 subclass edit control
将逗号更改为点?
sublclassing
控件可以将用户输入限制为点和字母,因此这不是问题。我只想正确地从数据库加载数据,因此如果用户决定不编辑十进制数据(就像我上面描述的示例中那样),我的 edit
可以无错误地执行。
谢谢。
最诚挚的问候。
最佳答案
这里有两个问题。我将使用两种语言环境进行说明:
英语(加拿大)--EN-CA:使用 .
作为小数点分隔符
法语(加拿大)——FR-CA:使用 ,
作为小数点分隔符
还有一小段 VBScript 代码(因为我没有 C++)。
问题 1:十进制数与区域设置感知字符串之间的转换。
VBScript
x = 3/2
WScript.Echo x
当 Windows 区域设置为 EN-CA 时显示 1.5
,当 Windows 区域设置为 FR-CA 时显示 1,5
。该文本就是您在编辑框中看到的内容。
假设用户保持字符串不变。您不需要尝试使用十进制数的字符串表示形式,而是需要使用区域设置感知方法将字符串转换回实际的十进制数:
对于 EN-CA:
x = CDbl("1.5") + 1
WScript.Echo x
显示2.5
,表示字符串“1.5”在添加 1 之前已成功转换为 Double
。
对于 FR-CA:
x = CDbl("1,5") + 1
WScript.Echo x
显示 2,5
表示字符串“1,5”在添加 1 之前已成功转换为 Double
。
摘要:当您从用户处收到数字的文本表示形式时,您需要将该字符串转换(即解析)为实际的数字数据类型,并且解析机制必须能够识别区域设置。
问题 2:将号码存储在数据库中。
这里的问题是 Access SQL 不支持区域设置;它只“说”美国英语。因此,如果您尝试在 FR-CA 下“粘合”一条 SQL 命令
x = 3/2
sql = "INSERT INTO Table1 (DoubleField) VALUES (" & x & ")"
WScript.Echo sql
您得到INSERT INTO Table1 (DoubleField) VALUES (1,5)
,但正如您所发现的那样,失败了。
这里的解决方案是不要将 SQL 命令“粘合在一起”(无论如何,这都是一件坏事,因为 SQL 注入(inject)漏洞和其他麻烦)。相反,使用参数化查询:
Option Explicit
Dim con ' ADODB.Connection
Dim cmd ' ADODB.Command
Dim prm ' ADODB.Parameter
Dim x
Const adDouble = 5
Const adParamInput = 1
' test data:
' the following statement is valid when
' the Windows locale uses "," as the decimal separator
x = CDbl("1,5")
Set con = CreateObject("ADODB.Connection")
con.Open _
"Driver={Microsoft Access Driver (*.mdb, *.accdb)};" & _
"Dbq=C:\__tmp\main.accdb;"
Set cmd = CreateObject("ADODB.Command")
cmd.ActiveConnection = con
cmd.CommandText = "INSERT INTO Table1 (DoubleField) VALUES (?)"
Set prm = cmd.CreateParameter("?", adDouble, adParamInput, , x)
cmd.Parameters.Append prm
cmd.Execute
Set prm = Nothing
Set cmd = Nothing
con.Close
Set con = Nothing
关于c++ - 将数据从数据库正确加载到编辑控件中,以便我可以执行 ADO 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21395499/