在一个产品中,我目前正在使用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;
这解决了我的问题。这是一个国际项目,被各种地方使用。