[Решено] переключение в другое окно с установкой параметров страницы

Автор Sirius34, 16 января 2022, 00:51

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

Sirius34

Здравствуйте всем!

По работе пришлось конвертировать файлы Excel для использования в LibreOffice (контора перешла на Linux).
Многие файлы были с макросами. Большую часть макросов получилось конвертировать, пусть и не на 100%, но необходимые операции, в целом, выполняются.
С одним только моментом пока никак не получается...
В ходе работы макроса необходимо:
1. один из листов открытой книги скопировать в новый файл
2. переключиться в этот самый новый файл, установить для листа определенные параметры страницы и диапазон печати (установить границы, сквозные строки, масштаб, отключить колонтитулы)
С первой процедурой всё получается, копирование происходит, новый файл открывается, название файла меняется на нужное.
А вот вторая задача... Никак не пойму - как переключиться в новый файл??
Мне, в принципе, после выполнения процедуры 2 даже не обязательно будет переключаться (возвращаться) в первоначальную книгу, это не критично.
Пытался решить проблему через костыль: сначала установил параметры для копируемого листа, а потом уже копировал его в новый файл, но оказалось, что LO при таком копировании параметры страницы и диапазоны печати не сохраняет :(
Кто-нибудь может подсказать - как решить проблему или хотя бы её часть?

Возможно, хотя не представляю как это реализовать, можно прописать макрос в КОПИРУЕМОМ листе, чтобы макрос выполнялся при активации (открытии) листа (книги), пусть даже он будет почти всегда работать вхолостую, фактически не меняя уже существующие параметры, но такой вариант вполне бы устроил.

Заранее спасибо.

И ещё одно. В этом скрипте устанавливаются параметры диапазона печати.
Как мне в значении для параметра "PrintArea" нужно прописать, чтобы печаталось всё, а не только выбранный диапазон?
Запись макроса даёт значение "", что, в результате, вообще исключает всё из диапазона печати.

dim args3(2) as new com.sun.star.beans.PropertyValue
args3(0).Name = "PrintArea"
args3(0).Value = "$A$1:$Z$72"
args3(1).Name = "PrintRepeatRow"
args3(1).Value = "$1:$1"
args3(2).Name = "PrintRepeatCol"
args3(2).Value = ""

dispatcher.executeDispatch(document, ".uno:ChangePrintArea", "", 0, args3())

Я пробовал вообще оставить только параметр PrintRepeatRow и его значение, а остальные строки убрал, но это не помогло.
Что нужно поправить?

sokol92

#1
Добрый день!
Здесь много вопросов в одном. Лучше всего, приложите пример файла с кодом и опишите последовательность действий - тогда помощь будет эффективнее.
Объектная модель LibreOffice Calc кардинально отличается от объектной модели MS Excel. Но и в Calc, и в Excel мы можете одновременно корректировать все открытые книги, поэтому не совсем понятно, что такое "переключиться в новый файл".

Excel допускает сокращенное указание на объект. Когда, например, Вы пишите Range("A1"), то это сокращение от Application.Range, что, в свою очередь, интерпретируется как диапазон листа ActiveSheet (при условии, что код VBA находится в стандартном модуле). В Calc же ко всем объектам нужно обращаться по "фамилии, имени, отчеству".  :)
Владимир.

Sirius34

Цитата: sokol92 от 16 января 2022, 15:24
...приложите пример файла с кодом и опишите последовательность действий...

Собственно, я большую часть описал.
Вот скрипт (я вырезал только расчётную часть, когда много-много арифметических и статистических блоков работает, она несущественна в данном случае).


Rem Attribute VBA_ModuleType=VBAModule
Option VBASupport 1
Public Sub dup_book_26()

Dim DestSh As Worksheet
Dim FN As String
   
DestSh = "Knizhka"

ThisWorkbook.Sheets(DestSh).Select
   
' Тут находится основной скрипт, всякие расчеты на листе DestSh. Он большой, нет смысла приводить

   
'выгрузка готовой книги в новый файл
DateString = Format(Now, "dd.mm.yyyy hh.mm")
FN ="Книга по состоянию на " & DateString & ".ods"

Dim iPath As String
iPath = ThisWorkbook.Path
   
ThisWorkbook.Sheets(DestSh).Copy
       
ActiveWorkbook.SaveAs Filename:=iPath & Application.PathSeparator & FN, FileFormat:=xlOpenXMLWorkbook, _
        ReadOnlyRecommended:=False

    'print and page parameters

ActiveWorkbook.Sheets("Knizhka").Select

Dim document As Object, pageStyles As Object
 
  document   = ThisComponent
  pageStyles = document.StyleFamilies.getByName("PageStyles")

  Dim sheet As Object, style As Object
 
    sheet = document.Sheets("Knizhka")
    style = pageStyles.getByName(sheet.PageStyle)
    style.ScaleToPagesX = 2
    style.ScaleToPagesY = 99
    style.IsLandscape = True
  style.HeaderOn = False
  style.HeaderIsOn = False
  style.FooterOn = False
  style.FooterIsOn = False
  style.TopMargin = 2000
  style.BottomMargin = 1000

dim dispatcher as object

document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

dim args3(2) as new com.sun.star.beans.PropertyValue
args3(0).Name = "PrintArea"
args3(0).Value = "$A$1:$Z$72"
args3(1).Name = "PrintRepeatRow"
args3(1).Value = "$1:$1"
args3(2).Name = "PrintRepeatCol"
args3(2).Value = ""

dispatcher.executeDispatch(document, ".uno:ChangePrintArea", "", 0, args3())

MsgBox "Работа скрипта завершена. " & vbCrLf & "Создан файл ""Книга по состоянию на " & DateString & ".ods"""
   
End Sub

То есть, выбранный лист сохраняется копированием в отдельный (новый) файл, потом нужно только задать параметры страницы.
Сохранение уже пусть пользователь делает.

Sirius34

Такая мысль еще появилась, но не знаю точно, как система шаблонов работает при создании новых файлов.
А если, допустим, в шаблон заранее добавить макрос, который при активации любого листа книги будет устанавливать параметры страницы и диапазон печати (лишнее - не проблема,
печатать всё равно только один лист будут), а потом на базе этого шаблона как раз и создавать новый файл из макроса?
Файл шаблона не проблема разместить рядом с рабочими файлами...

economist

Можно сделать универсальной обработку любых документов (даже чужих) макросами: без шаблонов и даже без макросов в самих документах. Для этого создаем сетевую (LAN) библиотку макросов, рисуем к ней диалог и вызывать его сочетанием клавиш.

Диалог с макросами при запуске сам определяет "контекст" в котором его вызывали, что за документ открыт (по ячейкам, по полям, кто открыл, его права и отдел итд итп. И предлагает нужные действия, активируя те или иные кнопки на диалоге, запрашивая контролами переменные сведения итп. Ну, например:

- Карточку/ОСВ 1С - сжать
- Список сотрудников - упростить  
- Ежедневный отчет - пересохранить в PDF и отправить по почте итд

У меня такой диалог несет в себе три сотни макросов, многие из которых срабатывают автоматически, типа настройки параметров печати страницы, включения стиля A1 вместо R1C1, автоотображения ярылков, и прочей ерунды, на которую страна тратит тонны человеко-часов зря.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Sirius34

Цитата: economist от 17 января 2022, 21:30Можно сделать универсальной обработку любых документов (даже чужих) макросами: без шаблонов и даже без макросов в самих документах. Для этого создаем сетевую (LAN) библиотку макросов, рисуем к ней диалог и вызывать его сочетанием клавиш.
В моём случае необходимо именно только одно телодвижение пользователя - запуск базового макроса, который выполняет ряд операций на исходной вкладке, после чего эта вкладка копируется, как новый файл, а затем в этом самом новом файле для этой вкладки устанавливаются определенные параметры страницы и диапазона печати.
Пользователю остается только сохранить оба файла - исходный и новый.
Теоретически, макрос изменения параметров можно запустить из формы - это не проблема. Но опять же - как заставить именно этот макрос отработать в новом файле, а не в том, из которого запускался исходный макрос выгрузки?

eeigor

#6
На активный документ указывает свойство ThisComponent:
   oDoc1 = ThisComponent

Цитата: Sirius34 от 16 января 2022, 00:51Никак не пойму - как переключиться в новый файл?
Доступ к новому документу:
   sFileURL = ConvertToURL("c:\users\itsme\desktop\tempfile.ods")
   oDoc2 = StarDesktop.loadComponentFromURL(sFileURL, "_blank", 0, Array())
И посмотрите здесь и тут.
Ubuntu 18.04 LTS • LibreOffice 7.5.1.2 Community

economist

Должна быть готовая Basic команда копирования листа в новую книгу ODS, со всем содержимым, форматированием и областями печати. Или процедуру это кто-то написал. Мест где искать, по хорошему, всего три: тут, там (https://forum.openoffice.org) и в 2-х книжках Питоньяка.

Выполнение макроса в листе другой книги - не проблема, передаем макросу другой объект (новая книга, лист, диапазон ячеек или имя ячеек). Имя для этой книги или заранее известно, и это только что создаваемый _blank- документ.

Писать на смеси двух диалектов с Option VBASupport 1 - можно, но недолго, скорее в период "перехода" на LO Basic. Со временем этот стиль придется бросить, т.к. такие макросы у людей нередко дохнут через год-два, разбираться труднее чем сразу написать на родном LO Basic.
Руб. за сто, что Питоньяк
Любит водку и коньяк!
Потому что мне, без оных, -
Не понять его никак...

Sirius34

Получилось. Пришлось слегка усложнить процесс, так как "без костыля" открывалось аж два одинаковых окна, но с разными названиями.
В итоге секунд 15-20 лишних получилось плюсом к времени работы скрипта, но общий результат меня устроил.
Спасибо огромное всем за помощь!
Вопрос можно закрывать.

Sirius34

Цитата: economist от 17 января 2022, 22:00Писать на смеси двух диалектов с Option VBASupport 1 - можно, но недолго, скорее в период "перехода" на LO Basic. Со временем этот стиль придется бросить, т.к. такие макросы у людей нередко дохнут через год-два, разбираться труднее чем сразу написать на родном LO Basic.

Это понятно. Конкретно сейчас просто ОЧЕНЬ нужен был базовый результат, причём быстро, а оказалось всё несколько сложнее.
Я всё равно планирую основной скрипт дорабатывать, так как руководители обещают слегка изменить отчётность.
Так что заодно буду переделывать и другие скрипты + функции под другой "диалект" бэйсика :)
Подзреваю, что подводных камней ещё вылезет...