如何在自动化不同的本地化版本的Excel时正确设置NumberFormat属性

我遇到了以下问题:

当从我的Delphi程序通过OLE自动化Excel,并尝试设置单元格的NumberFormat属性时,Excel正在期待格式化string以本地化的格式。

正常情况下,通过在Excel中loggingmacros来检查格式时,Excel将如下所示:Cells(1,2).NumberFormat =“#,## 0.00”

这意味着千位分隔符是“,”而小数点分隔符是“。”。

实际上,我正在使用Excel的本地化版本。 在我的语言环境中,千位分隔符是“”,小数点分隔符是“,”。

所以每当从我的Delphi程序中设置NumberFormat,我需要指定它像“### 0,00”。

我的问题是:显然,如果我在程序中对这些值进行硬编码,那么当我的程序与英文或另一个不同的本地化版本的Excel一起使用时将会出现exception。 有没有“通用”的方式来设置NumberFormat属性? (使用默认的英文区域?)

谢谢!

更新:我发现了一个更优雅的方式来做到这一点: http : //www.delphikingdom.com/asp/viewitem.asp?catalogid=920&mode=print这是在俄罗斯(我不会说太多)但你可以很容易地理解代码。

在Excel中你有两个字段:

  • 的NumberFormat

  • NumberFormatLocal

NumberFormat采用美国标准中始终为locale不变的格式,NumberFormatLocal需要设置locale的格式。

例如

Sub test() Dim r As Range Set r = ActiveWorkbook.ActiveSheet.Range("$A$1") r.NumberFormat = "#,##0.00" Set r = ActiveWorkbook.ActiveSheet.Range("$A$2") r.NumberFormat = "#.##0,00" Set r = ActiveWorkbook.ActiveSheet.Range("$A$3") r.NumberFormatLocal = "#,##0.00" Set r = ActiveWorkbook.ActiveSheet.Range("$A$4") r.NumberFormatLocal = "#.##0,00" End Sub 

使用德文设置(十进制数字和千位:)可以为您提供$ A $ 1和$ A $ 4的正确格式的数字。 如果您在Windows中将区域设置更改为您喜欢的任何内容并尝试(如果格式正常),则可以对其进行testing。

假设你使用Delphi 5并且有这样的代码来启动Excel(并且可以访问ComObj.pas):

 var oXL, oWB, oSheet : Variant; LocaleId : Integer; begin oXL := CreateOleObject('Excel.Application'); oXL.Visible := True; oWB := oXL.Workbooks.Add; oSheet := oWB.ActiveSheet; oSheet.Range['$A$1'].NumberFormatLocal := '#.##0,00'; oSheet.Range['$A$2'].NumberFormatLocal := '#,##0.00'; LocaleID:= DispCallLocaleID($0409); try oSheet.Range['$A$3'].NumberFormat := '#.##0,00'; oSheet.Range['$A$4'].NumberFormat := '#,##0.00'; finally DispCallLocaleId( LocaleId); end; end; 

那么默认情况下每个调用都会通过调用ComObj.DispatchInvoke的ComObj.VarDispInvoke。 在那里你可以findDispatch.Invoke的调用,它将作为lcid的第三个参数。 设置为0.您可以使用注释中的第一个链接中显示的技术来创build自己的单元,并将ComObj中的所有代码复制到您自己的单元(或直接修改ComObj)。 只要不要忘记在单元的初始化中设置VarDispProcvariables。 最后一部分在所有情况下似乎都不起作用(可能取决于模块的顺序),但是您可以在代码中设置variables:

  VarDispProc := @VarDispInvoke; 

您必须将VarDispInvoke放入ComObj复制模块的界面部分。 第一个链接的代码不能直接工作,因为它修改了上面的Delphi示例中没有调用的另一个方法。
只需更改numberformat调用的语言环境即可(以避免副作用)。
上面的例子与所描述的修改一起适用于我的德语excel。 如果没有修改或调用DispCallLocaleId,我会看到与您描述的相同的问题。