Скопировать диапазон ячеек вместе с форматированием [РЕШЕНО]

Автор vasyun, 15 августа 2014, 02:41

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

vasyun

Коллеги,

Кто подскажет как решить такую задачу:

Есть xls-файл, будем считать его шаблоном. Я пытаюсь написать макрос который открывает этот "шаблон",затем копирует некоторый диапазон ячеек и вставляет его в тот же лист но в другие ячейки.

1) Сначала сделал через getCellRangeByName
oDoc as object
oRange1 as object
oRange2 as object
oDoc = starDeskTop.loadComponentFromURL(oURL, "_blank", 0, Array() )
oSheet = oDoc.Sheets(0)
oRange1 = oSheet.getCellRangeByName ("A31:D46")
oRange2 = oSheet.getCellRangeByName("A80:D95")
oRange2.setDataArray (oRange1.getDataArray ())

Но проблема в том, что этот метод не копирует обрамления ячеек, а мне это важно. Мне нужно копировать весь контент.

2) Попробовал записать макрос. Получилось так
dim document   as object
dim dispatcher as object
rem ----------------------------------------------------------------------
rem get access to the document
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

rem ----------------------------------------------------------------------
dispatcher.executeDispatch(document, ".uno:Copy", "", 0, Array())

rem ----------------------------------------------------------------------
dim args2(5) as new com.sun.star.beans.PropertyValue
args2(0).Name = "Flags"
args2(0).Value = "A"
args2(1).Name = "FormulaCommand"
args2(1).Value = 0
args2(2).Name = "SkipEmptyCells"
args2(2).Value = false
args2(3).Name = "Transpose"
args2(3).Value = false
args2(4).Name = "AsLink"
args2(4).Value = false
args2(5).Name = "MoveMode"
args2(5).Value = 4

dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args2())

Но потом прочитал, что это не очень хороший метод т.к. время жизни команд меньше чем временя жизни API. А скрипт возможно переживёт несколько версий ООО.

Помогите. Как обойтись без executeDispatch?
LibreOffice 5.0.4.2
Apache OpenOffice 4.1.2

Yakov

Цитата: vasyun от 15 августа 2014, 01:41Как обойтись без executeDispatch?
В данном случае executeDispatch - самое правильное решение.
И убирать эти методы никто не собирается.
А недостаток этого метода в другом - невозможность исполнения в так называемом headless-режиме (режим работы на сервере без интерфейса пользователя )

rami

Цитата: vasyun от 15 августа 2014, 01:41Мне нужно копировать весь контент.
Sub CopyAll
Dim oDoc as Object
Dim oSheet as Object
Dim oRangeAddress as Object
Dim oCellAddress as Object
Dim oURL as String
oURL="file:///Адрес вашего файла.xls"
oDoc = starDeskTop.loadComponentFromURL(oURL, "_blank", 0, Array() )
oSheet = oDoc.Sheets(0)
oRangeAddress = oSheet.getCellRangeByName("A31:D46").getRangeAddress()
oCellAddress  = oSheet.getCellRangeByName("A80").getCellAddress()
oSheet.copyRange(oCellAddress, oRangeAddress)
End Sub

vasyun

to rami:
Это то что нужно!!!
Спасибо!

Ещё вопрос. Я в качестве справочника в основном пользуюсь книгой Питоньяка. Так как проще освоить макросы на примерах. Но уже давно понял, что в книге невозможно рассказать обо всех объектах и свойствах. Есть ли какой-то офлайн справочник по таким вот методам,свойствам? Сейчас если мне нужен какой-то объект или свойство приходится пользоваться xray и догадываться по абривиатуре объектов, либо лезу в поиск. Но не всегда получается добиться результата как сейчас.

Буду признателен за ссылку как на он-лайн документацию. Так и на офлайн(pdf-например) особенно.
LibreOffice 5.0.4.2
Apache OpenOffice 4.1.2

siti

Вот проблема которую не могу осилить уже несколько дней. Напишу тут, чтобы не плодить тем.

Копирование диапазона с форматированием. Взял за основу макрос, который в этой теме написали.

При запуске PresCopyForm - локальное копирование в рамках одного документа, всё работает. Создает новый лист и туда вставляет шаблон.
А при запуске Main - копирование в новый файл, в этом примере не работает, а в рабочем проекте просто LO вылетает фатально.

См. файл пример.

bigor

Цитата: siti от 19 мая 2022, 08:33А при запуске Main - копирование в новый файл, в этом примере не работает, а в рабочем проекте просто LO вылетает фатально
У меня main отрабатывает нормально, копирует первый лист исходного документа, как прописано в One_sheet_to_XLS() oSheet = oDoc.Sheets(0)
если 0 заменить на 1, то копирует второй лист со всем форматированием.
Какой LO на работе? Возможно там нет поддержки importSheet
Поддержать наш форум можно здесь

siti

Цитата: Bigor от 19 мая 2022, 10:28если 0 заменить на 1, то копирует второй лист со всем форматированием.
Там вопрос не в копировании листа, а в процедуре PresCopyForm1, которая должна скопировать диапазон
oRangeAddress = oDocFromPattern.Sheets(sh3).getCellRangeByName("A1:G17").getRangeAddress() ' адрес шаблона sh3
oCellAddress  = oDocTo.Sheets(sh2).getCellByPosition(0,0).getCellAddress() ' выбираем в цикле куда копировать шаблон
oDocTo.Sheets(sh2).copyRange(oCellAddress, oRangeAddress)


вот этот момент не работает

sokol92

Добрый день!
Опишите, пожалуйста, последовательность действий, приводящих к проблеме.

1. Открываем файл из ответа #4.
2. Запускаем макрос ...
...

Получаем ... , а должно быть ...

Если речь идет о процедуре PresCopyForm1, то там диапазон из второго листа нового документа копируется сам в себя - проверьте в отладчике номера листов в oCellAddress (sheet=1) и в oRangeAddress (sheet=1).

Если у Вас LO завершается аварийно, то для всех нас крайне важно воспроизвести ситуацию и сообщить о баге.
Владимир.

bigor

Цитата: siti от 19 мая 2022, 11:55вот этот момент не работает
я могу ошибаться, но copyRange не работает с разными книгами. Она копирует в пределах одной книги.
Поддержать наш форум можно здесь

siti

Цитата: sokol92 от 19 мая 2022, 12:32Если речь идет о процедуре PresCopyForm1, то там диапазон из второго листа нового документа копируется сам в себя - проверьте в отладчике номера листов в oCellAddress (sheet=1) и в oRangeAddress (sheet=1).
листы и там и там 1, но разные книги!

siti

Цитата: siti от 19 мая 2022, 12:53я могу ошибаться, но copyRange не работает с разными книгами. Она копирует в пределах одной книги.
это точно?

bigor

Поддержать наш форум можно здесь

sokol92

..., а LO Basic выполняет те операторы, которые указаны Вами. Раз сказано копировать из второго листа документа в этот же лист, то ...

Для копирования листов из одного документа в другой используйте importSheet.
Владимир.

siti

Цитата: sokol92 от 19 мая 2022, 13:03
..., а LO Basic выполняет те операторы, которые указаны Вами. Раз сказано копировать из второго листа документа в этот же лист, то ...

Для копирования листов из одного документа в другой используйте importSheet.
да почему в этот же?
oDocFrom=oDoc1 ' документ с источником данных
oDocFromPattern=oDoc   ' документ с источником шаблона
oDocTo=oDoc1  ' куда всё вставляем
oRangeAddress = oDocFromPattern.Sheets(sh3).getCellRangeByName("A1:G17").getRangeAddress() ' адрес шаблона sh3

oCellAddress  = oDocTo.Sheets(sh2).getCellByPosition(0,i).getCellAddress() ' выбираем в цикле куда копировать шаблон
oDocTo.Sheets(sh2).copyRange(oCellAddress, oRangeAddress) ' копируем шаблон 


oDocFromPattern=oDoc
oDocTo=oDoc1
разные же книги. Другое дело если не поддерживается копирование между разными книгами...
Тогда придется сперва лист шаблона копировать, а потом из него диапазон шаблона брать через copyRange

sokol92

Прочитайте, пожалуйста, предыдущие сообщения.

Цитата: Bigor от 19 мая 2022, 12:59oRangeAddress не содержит данных о книге

LO Basic делает то, что Вы написали, а не то, что задумали.

oRangeAddress состоит из нескольких целых чисел, больше ничего там нет.

Цитата: sokol92 от 19 мая 2022, 13:03
..., а LO Basic выполняет те операторы, которые указаны Вами. Раз сказано копировать из второго листа документа в этот же лист, то ...

Для копирования листов из одного документа в другой используйте importSheet.
Владимир.