Программный вызов SetOptimalColumnWidth [РЕШЕНО]

Автор Vadim, 11 августа 2011, 13:17

0 Пользователи и 1 гость просматривают эту тему.

Vadim

 OOo 3.3.0
 Экспортирую данные в эл. таблицу посредством Asp.NET C#. Нужно отформатировать колонки так, чтобы они имели оптимальную ширину (т.е. поставить выравнивание по содержимому). Создаю новый документ в скрытом режиме, заполняю его, вызываю SetOptimalColumnWidth, сохраняю и закрываю. Но в процессе возникает нюанс: с командой вызова появляется окошко "Оптимальная ширина столбца" (Формат -> Столбец -> Оптимальная ширина), которое ожидает подтверждения (клика на "ОК"). Так как все это автоматизация и выполняется на сервере, то конечно же, никто вручную не подтвердит.
  Вопрос:
     Как сделать чтобы команда выполнилась (или по крайней мере, как имитировать нажатие "ОК" в этом окне) ?

Вот то, что имею сейчас:
C#
using OOo = unoidl.com.sun.star;
using UNO = unoidl.com.sun.star.uno;
..
XComponent oDoc;
..
// тут выбираю область (ячейки заголовка)
XController currController = ((XModel)oDoc).getCurrentController();
OOo.view.XSelectionSupplier xSel = (OOo.view.XSelectionSupplier)currController;
XCellRange oRange = oSheet.getCellRangeByPosition(0, 0, colCount, 0);
xSel.select(new uno.Any(oRange.GetType(), oRange));

// далее вызываю  SetOptimalColumnWidth
UNO.XComponentContext localContext = uno.util.Bootstrap.bootstrap();
XMultiServiceFactory ServiceFactory = (XMultiServiceFactory)localContext.getServiceManager();
XDispatchHelper oDispHelper = (XDispatchHelper)ServiceFactory.createInstance("com.sun.star.frame.DispatchHelper");
XFrame frame = ((XModel)oDoc).getCurrentController().getFrame();            
oDispHelper.executeDispatch((XDispatchProvider)frame, ".uno:SetOptimalColumnWidth", "", 0, new OOo.beans.PropertyValue[0]);
..


Пока проверяю вот это решение, которое на Java.
Других способов задать SetOptimalColumnWidth пока не нашел, прошу подсказать более подходящий вариант.

JohnSUN

Там фишка кроется в последнем параметре executeDispatch. У тебя он просто пустой, вот офис и пристает с дурацкими вопросами.
Попробуй задать .Name = "aExtraWidth" и .Value, например, = 200
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

RFJ

Пример с http://www.oooforum.org/forum/viewtopic.phtml?t=9677
Sub OptimalColumnWidth
   oDoc = ThisComponent
   oSheet = oDoc.getSheets().getByIndex(0)
   oColumns = oSheet.getColumns()
   
   iLastColumn = 10 'last column to be applied with OptimalWidth
   
for iIndex = 0 to iLastColumn
   oColumn = oColumns.getByIndex(iIndex)
   oColumn.OptimalWidth = true
next iIndex
End Sub

JohnSUN

Да, бэйсик в этом отношении проще и роднее...

А из других языков приходится большую часть делать через DispatchHelper.

Если мне приходится с ним сталкиваться, пользуюсь [MEMO] Использование диспетчера (Thank you, dr.Faust!) и книгой slots.sxc (Thank you, Mr.Pitonyak!)
В slots в последнем столбце перечисляются параметры, которые могут быть использованы в команде.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

RFJ

ЦитироватьПока проверяю вот это решение, которое на на Java.
Это то же самое, что я привел на Basic.

ЦитироватьА из других языков приходится большую часть делать через DispatchHelper.
Совсем не обязательно. Можно и без DispatchHelper. Даже нужно.

Vadim

  Благодарю за ссылки и советы.

Цитата: JohnSUN от 11 августа 2011, 14:00
Там фишка кроется в последнем параметре executeDispatch. У тебя он просто пустой, вот офис и пристает с дурацкими вопросами.
Попробуй задать .Name = "aExtraWidth" и .Value, например, = 200
Уже пробовал - результат такой же, вылазит окно, но уже с моим параметром (а не default-ным).

Цитата: RFJ от 11 августа 2011, 14:59
Это то же самое, что я привел на Basic.
Знаю, но мне Basic здесь никак не поможет. Веб-сервер на шарпе, вот на нем и приходиться извращаться с ОО.
И те API, которые отлично работают для той же Java, не всегда подойдут для C# (что меня все больше удивляет).

  Успел протестить еще пару методов, даже учитывал уже такой известный дефект как XTableColumns.getByIndex broken. Но пока что ни один вариант в обход DispatchHelper не работает - выдает исключения преобразования типов.
  Буду "копать" дальше по методам без Dispatch-а.

Vadim

Хех )  Таки нашел решение!
помог этот Thread, на который натолкнулся со всезнающего Гугла )
Оказалось, если добавить .Value в getByIndex(), то все работает как надо.

В общем решение выглядит так:
C#
            XColumnRowRange oColRange = (XColumnRowRange)oSheet;
            OOo.container.XIndexAccess xTableCols = (XIndexAccess)oColRange.getColumns();             
            Object column;   
     
            for (int j = 0; j < colCount; j++)
            {
                column = xTableCols.getByIndex(j).Value;
                if (column != null)
                    ((XPropertySet)column).setPropertyValue("OptimalWidth", new uno.Any((Boolean)true));               
            }


Закрываю топик.