Кодировка, OpenOffice Calc

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Кодировка, OpenOffice Calc

Сообщение Dane » 07.03.2008 13:15:00

Написал програмку на Lazarus для работы с Calc. Все почти хорошо, только есть такая проблема

строка:
FDocument.getSheets.insertNewByName(SheetName, SheetOrderNum);
дает в названии листа:
慃汲扳摡倠慬慺

FDocument.getSheets.insertNewByName(SheetName, 'Carlsbad Plaza');
дает нормальное название листа

Чувствую, что грабли в кодировке, но не могу понять - где?
Помогите, плз
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Padre_Mortius » 07.03.2008 14:39:11

а что за переменная SheetOrderNum?

есть подозрение что дело не в кодировке, а в этой переменной
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение Dane » 07.03.2008 15:08:51

Извините, это моя ошибка:
Вторая строка должна выглядеть так
FDocument.getSheets.insertNewByName('Carlsbad Plaza', SheetOrderNum);
SheetOrderNum - индекс втавляемого листа (integer)
SheetName - имя вставляемого листа (string)
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Padre_Mortius » 07.03.2008 17:13:34

Под какой системой работаете и какая системная локаль (если под Linux)?
Какая версия fpc и Lazarus?
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение v-t-l » 07.03.2008 23:03:37

и какие средства доступа к ООо используются?
v-t-l
энтузиаст
 
Сообщения: 735
Зарегистрирован: 13.05.2007 16:27:22
Откуда: Belarus

Сообщение Dane » 11.03.2008 10:56:22

Работаю под Windows.
Lazarus 0.9.25
Использую OLE
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Padre_Mortius » 18.03.2008 14:41:17

тестовый пример можно увидеть как это все реализуется?
Padre_Mortius
энтузиаст
 
Сообщения: 1265
Зарегистрирован: 29.05.2007 17:38:07
Откуда: Спб

Сообщение Dane » 19.03.2008 18:42:29

Как реализован класс
Код: Выделить всё
...
const
  ooTemplateExt = '.xlt';

  TOOCellInfo = record
     ColCount:integer;
     RowCount:integer;
  end;

  TOOCalc = class
    FObj: Variant;
    FDocument: Variant;
    FDesktop: Variant; // OpenOffice desktop reference (not used now)
    FActiveSheet: Variant; // Active sheet
    FVisible: Boolean;
  private
    function FileName2URL(AFileName: String): Variant;
    function CreateParam(AName: string; AData: Variant): Variant;
    function CreateValue(AName: string; AData: Variant): Variant;
    procedure SetVisible(const Value: Boolean);
  public
    constructor Create(AFileName: String);
    destructor Destroy; override;

    function ActivateSheet(AIndex: Integer): Boolean;
    procedure FreeDocument(ACloseApp: Boolean);
    procedure Load(AFileName: String);
    procedure New;
    function InsertSheet(SheetName:String; SheetOrderNum: integer): boolean;
    function RenameSheet(AIndex:integer; SheetName: String): Boolean;

    property Visible: Boolean read FVisible write SetVisible;
  end;

implementation

{ TOOCalc }

function TOOCalc.ActivateSheet(AIndex: Integer): Boolean;
begin
  Result := False;
  if not VarIsNull(FDocument) then
  begin
    FActiveSheet := FDocument.getSheets.getByIndex(AIndex - 1);
    Result:= True;
    Sleep(50); //Asyncronus, so better give it time to make the change
  end;
end;

function TOOCalc.InsertSheet(SheetName: String; SheetOrderNum: integer): Boolean;
begin
  Result := False;
  if not VarIsNull(FDocument) then
  begin
    if (SheetOrderNum<0) or (SheetOrderNum>FDocument.getSheets.getCount()) then
       SheetOrderNum := FDocument.getSheets.getCount();
    FDocument.getSheets.insertNewByName(SheetName, SheetOrderNum);
    Result:= True;
    Sleep(50); //Asyncronus, so better give it time to make the change
  end;
end;

function TOOCalc.RenameSheet(AIndex:integer; SheetName: String): Boolean;
var
   SheetObj : Variant;
begin
  Result := False;
  if not VarIsNull(FDocument) then
  begin
    SheetObj := FDocument.getSheets.getByIndex(AIndex-1);
    SheetObj.setName(SheetName);
    Result:= True;
    Sleep(50); //Asyncronus, so better give it time to make the change
  end;
end;


constructor TOOCalc.Create(AFileName: String);
begin
  FObj := CreateOleObject('com.sun.star.ServiceManager');
  if VarIsEmpty(FObj) or VarIsNull(FObj) then
    raise Exception.Create('═хтючьюцэю яюфэ Є№ com-ёхЁтхЁ "com.sun.star.ServiceManager"');
  FVisible := False;
  FDocument := Null;
  if AFileName = '' then // new document
    New
  else
    Load(AFileName);
end;

function TOOCalc.CreateParam(AName: string; AData: Variant): Variant;
begin
  Result := VarArrayCreate([0, 0], varVariant);
  Result[0] := CreateValue(AName, AData);
end;

function TOOCalc.CreateValue(AName: string; AData: Variant): Variant;
var
  Reflection: Variant;
begin
  Reflection:= FObj.createInstance('com.sun.star.reflection.CoreReflection');
  Reflection.forName('com.sun.star.beans.PropertyValue').createObject(Result);
  result.Name := AName;
  if not VarIsNull(AData) then
    result.Value:= AData;
end;

destructor TOOCalc.Destroy;
begin
  FreeDocument(False);
  FObj := Null;
  inherited;
end;

function TOOCalc.FileName2URL(AFileName: String): Variant;
begin
  result:= '';
  if LowerCase(Copy(AFileName, 1, 8)) <> 'file:///' then
    Result := 'file:///';
  Result := Result + StringReplace(AFileName, '\', '/', [rfReplaceAll, rfIgnoreCase]);
end;

procedure TOOCalc.FreeDocument(ACloseApp: Boolean);
begin
  if not VarIsNull(FDocument) then
  begin
    if ACloseApp then
      FDocument.Dispose;
    FActiveSheet := Null;
    FDocument := Null;
  end;
end;

procedure TOOCalc.Load(AFileName: String);
var
  Param: Variant;
begin
  FreeDocument(True);
  FDesktop := FObj.CreateInstance('com.sun.star.frame.Desktop');

  Param := VarArrayCreate([0, 1], varVariant);
  Param[0] := CreateValue('AsTemplate', True); //AnsiCompareStr(ExtractFileExt(AFileName), ooTemplateExt) = 0);
  Param[1] := CreateValue('Hidden', not Visible);

  FDocument := FDesktop.LoadComponentFromURL(FileName2URL(AFileName), '_blank', 0, Param);
  ActivateSheet(1);
end;

procedure TOOCalc.New;
begin
  FreeDocument(True);
  FDesktop := FObj.CreateInstance('com.sun.star.frame.Desktop');
    //Create the document...
  FDocument:= FDesktop.LoadComponentFromURL('private:factory/scalc', '_blank', 0, CreateParam('Hidden', not Visible));
  ActivateSheet(1);
end;

procedure TOOCalc.SetVisible(const Value: Boolean);
begin
  if Value = FVisible then
    Exit;
  if VarIsNull(FDocument) then
    Exit;
  FDocument.getCurrentController.getFrame.getContainerWindow.setVisible(Value);
  FVisible := Value;
end;
...


юнит
Код: Выделить всё
...
var
  Form1: TForm1;
   OObj:TOOCalc;
   OObj2:TOOCalc;

begin
   OObj := TOOCalc.Create(SrcFileName.Text);
   OObj2 := TOOCalc.Create(TrgFileName.Text);
   OObj2.ActivateSheet(1);
   CHotelName := 'New Hotel';
   OObj2.RenameSheet(1, CHotelName);
   ...
end;
...


Помогите, плз. Очень надо решить проблему!!!
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Dane » 08.04.2008 15:24:40

Есть поправки. После долгих изучений вопроса могу сказать, что точно проблема в кодировке. Подскажите куда можно ткнуться, чтобы посмотреть стандартные функции перекодировки FPC?
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Attid » 09.04.2008 00:10:58

в поиск по сайту обсуждалось, стандартных средств очень мало.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение Dane » 10.04.2008 18:24:18

Хмм. Не помогает. Ничего не понимаю: в ячейку вставляется на "ура", а в ярлык - квадратики (одна и таже переменная).
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Сообщение Attid » 10.04.2008 22:34:55

а самим ОО не жаловался ? там есть где нибуть форум техподдержки ?
или стукнись к нашим кто русский сборку делает , они же еще что-то около 200 патчей накладывают которые спецефичны для русского языка.
Аватара пользователя
Attid
долгожитель
 
Сообщения: 2585
Зарегистрирован: 27.10.2006 17:29:15
Откуда: 44°32′23.63″N 41°2′25.2″E

Сообщение Dane » 11.04.2008 10:28:15

На форум OpenOffice я залез в самую первую очередь и, конечно, там тоже уже наследил :0) Пока вразумительных ответов не получал. Понятно, что изначальная кодировка OpenOffice - UTF8. Но поведение с именованием ярлыка мне не очень понятно. Интересно, что если в том, что бросается на название листа (переменная SheetName) есть латинские буквы 'w' или 'p' то они отображаются правильно среди квадратиков.
Dane
новенький
 
Сообщения: 27
Зарегистрирован: 02.02.2008 23:49:44

Re: Кодировка, OpenOffice Calc

Сообщение AAlexA » 20.08.2008 16:10:46

Подобная ситуация, но русский текст не вставляется даже в ячейку,
Код: Выделить всё
OO := CreateOleObject('com.sun.star.ServiceManager');
  Desktop := OO.createInstance('com.sun.star.frame.Desktop');
   Document := Desktop.LoadComponentFromURL(
                  'private:factory/scalc', '_blank', 0,
                  VarArrayCreate([0, -1], varVariant));
  Sheets := Document.GetSheets;
  Sheet := Sheets.getByIndex(0);
  Cell := Sheet.getCellByPosition(0, 0);
  Cell.setString(t);   

латиница вставляется нормально если t вариант или widestring. При t:string каждый вставляемый символ удваивается. При этом на Делфи 7 всё работает нормально. Кто может что посоветовать?

Добавлено спустя 1 час 16 минут 36 секунд:
Со вставкой текста в ячейку проблема решилась опцией компилятора
{$codepage utf-8}
Лазарус 0.9.25
Опен Офис 2.4.1
AAlexA
незнакомец
 
Сообщения: 4
Зарегистрирован: 29.07.2008 10:18:52


Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: MailRu[bot], Yandex [Bot] и гости: 2

Рейтинг@Mail.ru