3

我遇到了以下问题:

当通过我的 Delphi 程序中的 OLE 自动化 Excel 并尝试设置单元格的 NumberFormat 属性时,Excel 需要本地化格式的格式字符串。

通常,当通过在 Excel 中记录宏来检查格式时,Excel 期望它是这样的: Cells(1, 2).NumberFormat = "#,##0.00"

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

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

因此,每当从我的 Delphi 程序中设置 NumberFormat 时,我都需要将其指定为“###0,00”。

我的问题是:显然,如果我在我的程序中对这些值进行硬编码,那么当我的程序与英语或其他不同本地化版本的 Excel 一起使用时,就会出现异常。是否有设置 NumberFormat 属性的“通用”方法?(使用默认的英语语言环境?)

谢谢!

更新:我在此页面上找到了一种更优雅的方法:http: //www.delphikingdom.com/asp/viewitem.asp?catalogid=920 &mode=print 它是俄语(我也不会说)但是你可以很容易地理解代码。

4

3 回答 3

4

在 Excel 中,您有两个字段:

  • 数字格式

  • 数字格式本地

NumberFormat 采用美国标准中始终使用区域设置不变的格式,而 NumberFormatLocal 需要具有设置区域设置的格式。

例如

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

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

假设您使用 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。在那里,您可以找到对 Dispatch.Invoke 的调用,该调用将 lcid 作为第三个参数。这设置为 0。您可以使用注释中第一个链接中显示的技术来创建您自己的单元并将所有代码从 ComObj 复制到您自己的单元(或直接修改 ComObj)。只是不要忘记在单元的初始化中设置 VarDispProc 变量。最后一部分似乎并非在所有情况下都有效(可能取决于模块的顺序),但您可以在代码中设置变量:

 VarDispProc := @VarDispInvoke;

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

于 2012-06-08T11:46:07.163 回答
0

您可以让 excel 管理此选项以避免在其他系统中的差异:

.....NumberFormat :='#'+Excel.ThousandsSeparator+'##0'+Excel.DecimalSeparator+'00';
于 2018-04-12T08:00:35.830 回答
0

也可以直接设置属性值

 SetDispatchPropValue(oSheet, 
     'Range['$A$1'].NumberFormatLocal',$0409);
于 2018-08-08T13:15:59.063 回答