Версия для печати


Русский Excel и установка NumberFormat
http://www.delphikingdom.com/asp/viewitem.asp?catalogID=924

дата публикации 26-02-2004 18:09

Русский Excel и установка NumberFormatМатериал является дополнением к статье "Особенности работы с "русским" Excel'ем"

Задавать NumberFormat и колонтитулы теперь можно по-английски!

Решение заключается в том, чтоб "профиксить" вызов DispCall из модуля ComObj.pas.
При вызове Invoke, ему передается LocaleID равный 0 (Language Neutral)

(строка 1893, код PUSH EDX { LocaleID }). 
Если заменить LocaleID на $0409 (US English), то все начинает работать как нужно!

Для того чтоб это реализовать, написан модуль TrDispCall.pas. Теперь, если его включить в uses, все выглядит так:

...
// TrDispCall нужно писать ПЕРВЫМ (!!!) в uses, а потом уже
// все модули, использующие ComObj (напр. Excel2000)
uses ... TrDispCall, Excel2000;

procedure TForm1.Button1Click(Sender: TObject);
const
  lcid = LOCALE_USER_DEFAULT;
var
  XL: TExcelApplication;
  WB: TExcelWorkbook;
  ASheet: TExcelWorksheet;
  LocaleID: Integer;
begin
  XL := TExcelApplication.Create(Self);
  WB := TExcelWorkbook.Create(Self);
  ASheet := TExcelWorksheet.Create(Self);
  //  установим LocaleID = $0409 - US English
  LocaleID := DispCallLocaleID($0409); 
  try
    XL.Connect;
    WB.ConnectTo(XL.Workbooks.Add(EmptyParam, lcid));
    ASheet.ConnectTo(WB.ActiveSheet as _WorkSheet);
    XL.Visible[lcid] := True;
    // число
    ASheet.Range['A1:B5', EmptyParam].Value2 := 123456.78;
    ASheet.Range['A6:B10', EmptyParam].Value2 := -123456.78;
    // "американский" формат
    ASheet.Range['A1:A10', EmptyParam].NumberFormat :=
      '#,##0.00;[red]-#,##0.00; "пусто";[blue]"Текст!!!:" @'; // OK
    // "русский" формат
    ASheet.Range['B1:B10', EmptyParam].NumberFormatLocal :=
      Format('#%0:s##0%1:s00;[красный]-#%0:s##0%1:s00;' +
        '"пусто";[синий]"Текст!!!:" @',
        [ThousandSeparator, DecimalSeparator]); // OK
    ASheet.Range['A5:B5', EmptyParam].Value2 := 0;
    ASheet.Range['A6:B6', EmptyParam].Value2 := 'просто текст';
    // дата
    // "американский" формат
    with ASheet.Range['C1:C10', EmptyParam] do begin
      Value2 := Date;
      NumberFormat := 'd/mm/yy'; // OK
    end;
    // "русский" формат
    with ASheet.Range['D1:D10', EmptyParam] do begin
      Value2 := Date + 1;
      NumberFormatLocal := Format('ДД%0:sММ%0:sГГ', [DateSeparator]); // OK
    end;
    WB.Saved[lcid] := True;
    XL.ScreenUpdating[lcid] := True;
  finally
    ASheet.Free;
    WB.Free;
    XL.Free;
    DispCallLocaleID(LocaleID); // восстановим LocaleID = 0 (по-умолчанию)
  end;
end;

Автор идеи Евгений Федоров.



К материалу прилагаются файлы: