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

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

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

mikekaganski

Цитата: siti от 19 мая 2022, 13:20да почему в этот же?
Да потому что Вы не указываете функции copyRange, что исходные данные для копирования находятся в какой-то другой книге. И не можете, потому что источник в эту функцию передаётся в форме com::sun::star::table::CellRangeAddress, который вы получаете с помощью getRangeAddress. А там указаны: номер листа, строки и столбцы начала и конца. И ни слова о книге.
С уважением,
Михаил Каганский

sokol92

Цитата: siti от 19 мая 2022, 13:20Тогда придется сперва лист шаблона копировать, а потом из него диапазон шаблона брать через copyRange

Либо использовать "по старинке" буфер обмена.
Владимир.

siti

Мои знания на уровне увидеть подобное и переделать под свои цели. Так глубоко смотреть знаний не хватает.
Вот к примеру начал переделывать процедуру, чтобы второй лист копировала в oDoc1 и опять не выходит.

Sub One_sheet_to_XLS()   ' копирование листа в новый документ
Dim oSheets1,oDesk,aFnm As Object ' Документ куда тащим лист и его листы
Dim oSheet As Object ' Документ откуда тащим и интересующий лист
Dim ii as integer

' ==== Перетаскиваем интересующий лист из текущего документа
' oDoc = ThisComponent 'Документ откуда = текущий документ, Уже в константах определено
oSheet = oDoc.Sheets("Лист2") ' лист "Лист2" документа
Set oDesk = createUnoService("com.sun.star.frame.Desktop") ' Открываем пустой документ для импорта, это будет временный файл
   oDoc1 = oDesk.LoadComponentFromUrl("private:factory/scalc", "_blank", 63, Array())
oSheets1 = oDoc1.getSheets() ' Импорт листа в пустой документ (временный файл)
oSheets1.importSheet(oDoc,oSheet.LinkDisplayName,0)
For ii = 1 To oDoc1.Sheets.Count -1     ' Удаляем ненужные листы в новом документе
oDoc1.Sheets.removeByName(oDoc1.Sheets(ii).Name)
Next

oSheet = oDoc.Sheets("Шаблон") ' лист "Шаблон" документа
oSheets1 = oDoc1.getSheets() ' Импорт листа в пустой документ (временный файл)
oSheets1.importSheet(oDoc,oSheet.LinkDisplayName ,1)
End Sub


Вставляет повторно тот же Лист2, хотя надо "Шаблон"

bigor

 
Цитата: siti от 19 мая 2022, 13:46oSheet = oDoc.Sheets("Лист2")
а так можно было :) Я для задания листа по имени знаю oSheet = oDoc.Sheets.getByName("Лист2")
Поддержать наш форум можно здесь

eeigor

Цитата: Bigor от 19 мая 2022, 14:15а так можно было  Я для задания листа по имени знаю
Код:
   oSheet = oDoc.Sheets.getByName("Лист2")
С индексом можно и покороче: вместо
   .Sheets.getByIndex(1) -> .Sheets(1)
Но .Sheets("Sheet2") -> вернёт ссылку не на второй лист, а на первый всегда (вероятно, баг: работает только с первым листом). Поэтому
   .Sheets.getByName("Sheet2")

Edit:
Я противник геттеров и сеттеров. Без них код чище. Но с ними перенос между платформами проще.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

mikekaganski

Цитата: eeigor от 19 мая 2022, 14:39.Sheets("Sheet2") -> вернёт ссылку не на второй лист, а на первый всегда

Потому что CLng("Sheet2") возвращает 0, который и используется в getByIndex.
С уважением,
Михаил Каганский

kompilainenn

Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

sokol92

Цитата: mikekaganski от 19 мая 2022, 15:14CLng("Sheet2") возвращает 0
И это странно, а при наличии опции
Option VBASupport 1
очевидно, является ошибкой.

Пишем баг?

Из описания CLng: To convert a string expression, the number must be entered as normal text ("123.5") using the default number format of your operating system.

Для справки: В VBA только функция Val вернет 0 для указанного аргумента. Все остальные функции преобразования в числовой тип являются локализованными и при невозможности преобразования текста в число вызывают ошибочную ситуацию.

Проверил LO Basic CDbl - поведение соответствует VBA.
Владимир.

eeigor

Цитата: mikekaganski от 19 мая 2022, 15:14Потому что CLng("Sheet2") возвращает 0, который и используется в getByIndex.
В Excel это тип Variant: число - по индексу, строка - по имени.

КМК, правильно - это в зависимости от типа данных аргумента вызывать или getByIndex, или getByName. Как в Excel. Куда проще...
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

sokol92

Цитата: sokol92 от 19 мая 2022, 13:40Либо использовать "по старинке" буфер обмена.
Упустил из виду getTransferable. Название темы практически такое же.
Такой подход имеет высокое быстродействие, не требуется копировать лист целиком, буфер обмена не изменяется.
Владимир.

siti

Цитата: sokol92 от 19 мая 2022, 20:35Упустил из виду getTransferable. Название темы практически такое же.
Такой подход имеет высокое быстродействие, не требуется копировать лист целиком, буфер обмена не изменяется.
Супер! Так как я так и не победил перенос второго листа, то getTransferable решило мою задачу при копировании диапазона. Спасибо.

Код из книги, если кому лень искать будет

 Dim o
 Dim oSheet
 Dim oRange
 Dim oDoc

 oRange = oDoc1.Sheets(0).getCellRangeByName("B2:C3")
 oDoc1.CurrentController.select(oRange)
 o = oDoc1.CurrentController.getTransferable()
 
 oRange = oDoc2.Sheets(0).getCellRangeByName("F1")
 oDoc2.CurrentController.select(oRange)
 oDoc2.CurrentController.insertTransferable(o)

Только я не понял, почему автор описывает переменную oDoc, которую не использует, а в тексте у него oDoc1 и oDoc2

luu

А можно ли как-то использовать метод .copyRange, чтобы он копировал только данные из диапазона, по аналогии с .setDataArray?
Т.е. хочется вставлять данные по адресу первой ячейки, не определяя заранее размерность итогового массива, но переносить только значения

mikekaganski

Цитата: luu от 13 марта 2024, 08:32хочется вставлять данные по адресу первой ячейки, не определяя заранее размерность итогового массива

У Вас какие-то ограничения по определению размерности итогового массива в коде?
С уважением,
Михаил Каганский

luu

Цитата: mikekaganski от 13 марта 2024, 09:49
Цитата: luu от 13 марта 2024, 08:32хочется вставлять данные по адресу первой ячейки, не определяя заранее размерность итогового массива

У Вас какие-то ограничения по определению размерности итогового массива в коде?

Ограничений нет, просто хочется понять, можно ли сразу вставлять данные из массива в указанный адрес без дополнительного расчета размерности. Может быть есть какой-то параметр .copyRange, который позволяет указывать ему что именно копировать, вместо безусловного переноса всех характеристик ячеек

mikekaganski

С уважением,
Михаил Каганский