3

在我目前使用的一个产品中,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 中发现不可读的内容 是否要恢复此工作簿的内容?

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

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

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

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

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

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

我并不热衷于对已知有问题的语言环境进行一系列条件“if”语句测试,但根据我迄今为止所做的研究,这似乎是解决问题的唯一方法。

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

4

2 回答 2

6

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

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

于 2013-06-06T06:43:53.557 回答
0

我的解决方案如下:

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

var
  tReportDate : TDate;

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

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

希望这能有所帮助。

于 2013-11-28T13:57:18.303 回答