OLE Excel输出中的国际日期格式问题

时间:2013-06-05 17:18:16

标签: excel delphi localization ole

在我正在使用Excel产品的产品中,使用Delphi的OLE生成电子表格。电子表格包含许多日期,其中应用程序从系统设置加载短日期格式并将其应用于单元格。除非系统格式设置为至少俄语,巴什基尔语,鞑靼语,雅库特语,哈萨克语和乌兹别克语(可能还有其他我没有尝试过),否则这种方法很有效。

代码是 -

xlws.Cells[irow,icol] := ActivityData.Target_Date;
xlvalidrange := xlws.Range[xlws.Cells[irow,icol],xlws.Cells[irow,icol]];
xlvalidrange.NumberFormat:= LocShortDateFormat;

在这种情况下(在调试时),ActivityData.Target_Date是41192,这是Excel存储日期和时间的格式,LocShortDateFormat等于'dd.MM.yyyy'。这与Windows中显示的俄语存储日期格式相匹配,并使用代码 -

以编程方式检索
LocShortDateFormat := ShortDateFormat;

使用此格式打开电子表格会显示消息 -

  

Excel在Spreadsheet.xlsx中找到了不可读的内容您是否要恢复此工作簿的内容?

执行此操作时,数据仅显示为单元格中的NO,格式为41192。更奇怪的是,手动应用格式字符串'dd.MM.yyyy'然后在单元格中显示'dd.MM.yyyy'代替数据。

同样适用于任何标准日期/时间字符串格式化字符。通过选择“日期”类别和相应类型作为格式,可以手动将数据更改为日期格式,然后正确显示,因此这不是数据问题,而是格式字符串。

当手动选择正确的日期格式时,Excel使用的格式字符串是ДД.ММ.ГГГГ - 手动更改调试时使用的格式字符串会在生成的电子表格中生成正确的输出,并且不可读的内容消息将消失。

奇怪的是,中文,日文,塞尔维亚文和马其顿文(作为非英文字符集语言的样本)都使用标准的日期/时间格式字符。

在Excel本身,标准字符似乎无法正常运行,即使电子表格是新的并且尚未以编程方式创建,即从Excel应用程序中创建的新电子表格。

在这种情况下,它似乎不是Delphi或Windows问题(C #Windows表单使用标准字符正确格式化日期没有问题,即使使用俄语语言环境),但它仍然存在如何获得返回的问题Delphi中正确的格式化字符串。

我并不热衷于做一系列有条件的“if”语句测试已知存在问题的语言环境,但这似乎是根据我迄今为止所做的研究来处理问题的唯一方法。 / p>

有没有办法让Excel通过OLE使用本地日期格式而不提供格式化字符串,或者获取Excel用于格式化本地化日期的字符串以便以正确的格式提供字符串?

2 个答案:

答案 0 :(得分:5)

是的,您可以使用Excel应用程序实例上的International属性获取各种国际化/本地化字符和字符串。后期绑定的例子:

function GetExcel_International(const aExcel: OleVariant; const aIndex: Integer): string;
begin
  try
    Result := aExcel.International[aIndex];
  except
    ...
  end;
end;

我们使用它来获取构成格式化字符串的各种字符:

ExcelYearCharacter := GetExcel_International(FExcelApplication, xlYearCode);
ExcelMonthCharacter := GetExcel_International(FExcelApplication, xlMonthCode);
ExcelDayCharacter := GetExcel_International(FExcelApplication, xlDayCode);
ExcelHourCharacter := GetExcel_International(FExcelApplication, xlHourCode);
ExcelMinuteCharacter := GetExcel_International(FExcelApplication, xlMinuteCode);

然后我们使用它们从Windows转换为Excel格式:

function ConvertWindowsLocalDateStringToExcel(const aString: string): string;
begin
  Result := StringReplace(aString, UpperCase(WindowsYearCharacter),
            UpperCase(ExcelYearCharacter), [rfReplaceAll]);
  Result := StringReplace(Result, LowerCase(WindowsYearCharacter),
            LowerCase(ExcelYearCharacter), [rfReplaceAll]);

  Result := StringReplace(Result, UpperCase(WindowsMonthCharacter),
            UpperCase(ExcelMonthCharacter), [rfReplaceAll]);
  Result := StringReplace(Result, LowerCase(WindowsMonthCharacter),
            LowerCase(ExcelMonthCharacter), [rfReplaceAll]);

  Result := StringReplace(Result, UpperCase(WindowsDayCharacter),
            UpperCase(ExcelDayCharacter), [rfReplaceAll]);
  Result := StringReplace(Result, LowerCase(WindowsDayCharacter),
            LowerCase(ExcelDayCharacter), [rfReplaceAll]);
end;

所有xl...常量都来自我们自己的一个单元,但您也应该能够在早期绑定的Delphi OLE服务器包装器中找到它们。例如,在Delphi / RAD Studio安装的ExcelXP文件夹中的...\OCX\Servers单元中。

有关Application.International属性的更多信息,请访问: http://msdn.microsoft.com/en-us/library/office/bb177675(v=office.12).aspx

答案 1 :(得分:0)

我的解决方案如下:

首先,我制作var类型TDate。 然后我从表中填写var然后插入它,如下所示:

var
  tReportDate : TDate;

....<br><br>
    tReportDate := FieldByName('DateReport').AsDateTime;<br>
    ExcelApp.Cells[StartColumnid, 1].Value := tReportDate;

这解决了我的情况。这是一个国际项目,并被各种地方使用。

希望这可以提供帮助。