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



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

代码是-

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' then show 'dd.MM。

数据所在单元格中的Yyyy '。

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

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

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

在Excel本身中,标准字符似乎不能正常工作,即使电子表格是新的,并且不是通过编程创建的,即从Excel应用程序中创建的新电子表格。

在这种情况下,这似乎不是Delphi或Windows的问题(c# Windows窗体使用标准字符正确格式化日期没有问题,即使使用俄语区域设置),但它仍然留下了如何在Delphi中返回正确格式化字符串的问题。

我不热衷于做一系列条件"if"语句测试已知有问题的区域,但根据我迄今为止所做的研究,这似乎是处理问题的唯一方法。

是否有任何方法可以要求Excel通过OLE使用本地日期格式而不提供格式字符串,或者获得Excel用于在该本地化中格式化日期的字符串,以便以正确的格式提供字符串?

是的,您可以使用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安装的...OCXServers文件夹中的ExcelXP单元。

关于Application.International属性的更多信息可以在:http://msdn.microsoft.com/en-us/library/office/bb177675 (v = office.12) . aspx

我的解决方案如下:

首先,我创建一个TDate类型的var。然后我从表中填充var,然后插入它,如下所示:

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

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

最新更新