Копирование листа одного файла в текущий документ

Автор almaster13, 25 октября 2024, 12:18

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

almaster13

Вставил код макроса. Есть у него только один недостаток, он будет копировать поверх содержимого страниц и если запустить его несколько раз, то тех же графиков будет наложено друг на дружку ровно столько же!

Sub CopyGrafik_new

oDoc=thiscomponent

firstUrl = "file:///cifs/DATA/DNT/PLAN-2024-Astra.ods"
firstDoc = StarDesktop.loadComponentFromUrl(convertToURL(firstUrl), "_blank", 0, dimArray())

selectSheetByName(firstDoc, "Блок №1")

  dispatchURL(firstDoc,".uno:SelectAll")
  dispatchURL(firstDoc,".uno:Copy")

selectSheetByName(oDoc, "График блок 1")
  dispatchURL(oDoc,".uno:Paste")
 
  selectSheetByName(firstDoc, "Блок №2")
    dispatchURL(firstDoc,".uno:SelectAll")
    dispatchURL(firstDoc,".uno:Copy")

selectSheetByName(oDoc, "График блок 2")
  dispatchURL(oDoc,".uno:Paste")
 
    selectSheetByName(firstDoc, "Блок №3")
    dispatchURL(firstDoc,".uno:SelectAll")
    dispatchURL(firstDoc,".uno:Copy")

selectSheetByName(oDoc, "График блок 3")
  dispatchURL(oDoc,".uno:Paste")
 
    selectSheetByName(firstDoc, "Блок №4")
    dispatchURL(firstDoc,".uno:SelectAll")
    dispatchURL(firstDoc,".uno:Copy")

selectSheetByName(oDoc, "График блок 4")
  dispatchURL(oDoc,".uno:Paste")
 
firstDoc.close (true)
End Sub

Sub selectSheetByName(document, sheetName)
  document.getCurrentController.select(document.getSheets().getByName(sheetName))
End Sub

Sub dispatchURL(document, aURL)
  Dim noProps()
  Dim URL As New com.sun.star.util.URL

  frame = document.getCurrentController().getFrame()
  URL.Complete = aURL
  transf = createUnoService("com.sun.star.util.URLTransformer")
 transf.parseStrict(URL)

  disp = frame.queryDispatch(URL, "", com.sun.star.frame.FrameSearchFlag.SELF _
         OR com.sun.star.frame.FrameSearchFlag.CHILDREN)
  disp.dispatch(URL, noProps())
End Sub

Sirius34

Цитата: sokol92 от 28 октября 2024, 14:33Что касается метода close, то Михаил выше объяснял назначение его параметра логического типа. В "обычной" ситуации метод close в LO, независимо от параметра, "молча" закроет документ, даже если в нем есть не сохраненные изменения. Это поведение отличается от поведения метода Workbook.Close в Excel.
Да, был не прав, проглядел эту часть.
Собственно, никогда не закрывал просто так, если вносил какие-то изменения. Всегда сначала делал сохранение, поэтому даже не предполагал такое поведение Calc.
Век живи - век учись...
Спасибо!

almaster13

А как можно наиболее просто очистить лист макросом от содержимого? Способ выделить и удалить выдает меню, в котором нужно нажать ОК:

selectSheetByName(oDoc, "График блок 1")
  dispatchURL(oDoc,".uno:SelectAll")
  dispatchURL(oDoc,".uno:Delete")

А хотелось бы, чтобы лист очищался перед вставкой данных молча!

Sirius34

Цитата: almaster13 от 31 октября 2024, 14:20А хотелось бы, чтобы лист очищался перед вставкой данных молча!
Я делаю примерно так
oDelRng = oSht.getCellRangeByPosition(0, 0, oLastCol(oSht), oLastRow(oSht))
oDelRng.ClearContents(1 OR 2 OR 4 OR 8 OR 16 OR 32 OR 64 OR 128 OR 256 OR 512)
Единственное, что нужно - найти (вычислить) oLastCol и oLastRow.
У меня специальные функции сделаны, чтобы не приходилось каждый раз километр кода писать.
Но можно предварительно сделать
args1(0).Name = "Sel"
args1(0).Value = false
dispatcher.executeDispatch(document, ".uno:GoToEndOfData", "", 0, args1())
и считать текущую позицию.
Здесь уже небольшой простор для манёвра

Sirius34

В принципе, можно и так сделать

Args1(0).Name = "ToPoint"
Args1(0).Value = "A1"
dispatcher.executeDispatch(CCF, ".uno:GoToCell", "", 0, Args1())

Args2(0).Name = "Sel"
Args2(0).Value = True
dispatcher.executeDispatch(CCF, ".uno:GoToEndOfData", "", 0, Args2())

Args3(0).Name = "Flags"
Args3(0).Value = "R"
dispatcher.executeDispatch(CCF, ".uno:DeleteCell", "", 0, Args3())

bigor

Цитата: Sirius34 от 31 октября 2024, 16:09oDelRng.ClearContents(1 OR 2 OR 4 OR 8 OR 16 OR 32 OR 64 OR 128 OR 256 OR 512)
эквивалентно oDelRng.ClearContents(1023)
А диапазон можно с избытком задать фиксированный

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

almaster13

Прошу пояснить еще один вопрос по выложенному в листинге макросу. Он замечательно работает, если запускать его из окна отладки макросов, но при привязке его к кнопке на странице листа файла, не копирует графики и ошибку тоже не выдает. Может быть, есть какой то секрет настройки самой кнопки или это недостаток макроса?

bigor

Цитата: almaster13 от  1 ноября 2024, 08:40вопрос по выложенному в листинге макросу
к макросу нужен ваш файл.
Поддержать наш форум можно здесь

almaster13

Цитата: bigor от  1 ноября 2024, 13:24
Цитата: almaster13 от  1 ноября 2024, 08:40вопрос по выложенному в листинге макросу
к макросу нужен ваш файл.


Вот два файла. Файл пояснительная записка с помощью макроса должен копировать 4 листа из файла Plan-2024-Astra. Макрос и кнопка в файле пояснительной записки. Макрос из окна отладки макросов работает, с кнопки оставляет страницы пустыми. Ошибок не выдается.

almaster13

Разобрался с очисткой содержимого листов, изменил копирование листов на диапазон ячеек, но графики продолжают копироваться только через окно отладки макросов, но не работают через кнопку. Такое ощущение, что с кнопки информация не загружается в буфер обмена. Может быть, что то нужно дополнительно указывать в настройках элемента "Кнопка"?

Sub CopyGrafik_new

oCDoc=thiscomponent
sURLFolderA = "file:///cifs/DATA/DNT/PLAN-2024-Astra.ods"
oADoc = StarDesktop.loadComponentFromUrl(convertToURL(sURLFolderA), "_blank", 0, dimArray())

Dim oDoc As Object, oSheet As Object, oSheets As Object
  Dim oCellRange As Object
  Dim nSheets As Long

  oSheets = oCDoc.Sheets
  nSheets = oCDoc.Sheets.Count
  oSheet = oSheets.getByIndex(3)
  oCellRange = oSheet.getCellRangeByName("A1:AC65")
  oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
    oSheet = oSheets.getByIndex(4)
  oCellRange = oSheet.getCellRangeByName("A1:AC65")
  oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
     oSheet = oSheets.getByIndex(5)
  oCellRange = oSheet.getCellRangeByName("A1:AC65")
  oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
     oSheet = oSheets.getByIndex(6)
  oCellRange = oSheet.getCellRangeByName("A1:AC65")
  oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)

selectSheetByName(oADoc, "Блок №1")

  dispatchURL(oADoc,".uno:SelectAll")
  dispatchURL(oADoc,".uno:Copy")

selectSheetByName(oCDoc, "График блок 1")
  dispatchURL(oCDoc,".uno:Paste")
 
  selectSheetByName(oADoc, "Блок №2")
    dispatchURL(oADoc,".uno:SelectAll")
    dispatchURL(oADoc,".uno:Copy")

selectSheetByName(oCDoc, "График блок 2")
  dispatchURL(oCDoc,".uno:Paste")
 
    selectSheetByName(oADoc, "Блок №3")
    dispatchURL(oADoc,".uno:SelectAll")
    dispatchURL(oADoc,".uno:Copy")

selectSheetByName(oCDoc, "График блок 3")
  dispatchURL(oCDoc,".uno:Paste")
 
    selectSheetByName(oADoc, "Блок №4")
    dispatchURL(oADoc,".uno:SelectAll")
    dispatchURL(oADoc,".uno:Copy")

selectSheetByName(oCDoc, "График блок 4")
  dispatchURL(oCDoc,".uno:Paste")
 
oADoc.close (true)

End Sub

almaster13

В общем, пришлось искать другой метода без использования буфера обмена. Данный макрос работает с кнопки. Был бы рад, если бы по нему высказали замечания или предложили возможные улучшения, чтобы пополнить свои знания и, возможно, поднять для всех другие интересные темы.
Sub CopyGraphics 'copy/paste with formatting

    Dim FileProperties(2) As New com.sun.star.beans.PropertyValue
    Dim y as integer
    FileProperties(0).Name = "FilterName"
    FileProperties(0).Value ="scalc: Text - txt - csv (StarOffice Calc)"
    FileProperties(1).Name = "USE_CONFIG"
    FileProperties(1).Value ="3"
    FileProperties(2).Name = "Hidden"
    FileProperties(2).Value = True
dim oCDoc, oADoc as object, oCSheet, oASheet, oCSheets as object, oCur as object, oRange1 , oRange2, oCellRange as object, p(), s$, data, i&, j&
Dim nSheets As Long

y=2024
    oCDoc=thiscomponent
    sURL = "file:///cifs/DATA/DNT/PLAN-"+y+"-Astra.ods"' выбор адреса документа откуда копируем, год соответствует значению Y, можно брать его из значения ячейки
    oAdoc = StarDesktop.loadComponentFromURL(sURL, "_blank", 0, FileProperties())' открытие документа откуда копируем
   
   nSheets = oCDoc.Sheets.Count
   oCSheets = oCDoc.Sheets
   
    oCSheet = oCSheets.getByIndex(3)' очистка листа №4 источника от всех видов данных и форматирования
    oCellRange = oCSheet.getCellRangeByName("A1:AC65")
    oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
    oCSheet = oCSheets.getByIndex(4)' очистка листа №5 источника от всех видов данных и форматирования
    oCellRange = oCSheet.getCellRangeByName("A1:AC65")
    oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
    oCSheet = oCSheets.getByIndex(5)' очистка листа №6 источника от всех видов данных и форматирования
    oCellRange = oCSheet.getCellRangeByName("A1:AC65")
    oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)
   
    oCSheet = oCSheets.getByIndex(6)' очистка листа №7 источника от всех видов данных и форматирования
    oCellRange = oCSheet.getCellRangeByName("A1:AC65")
    oCellRange.clearContents(_
    com.sun.star.sheet.CellFlags.VALUE OR _
    com.sun.star.sheet.CellFlags.DATETIME OR _
    com.sun.star.sheet.CellFlags.STRING OR _
    com.sun.star.sheet.CellFlags.ANNOTATION OR _
    com.sun.star.sheet.CellFlags.FORMULA OR _
    com.sun.star.sheet.CellFlags.HARDATTR OR _
    com.sun.star.sheet.CellFlags.STYLES OR _
    com.sun.star.sheet.CellFlags.OBJECTS OR _
    com.sun.star.sheet.CellFlags.EDITATTR)

oCSheet=oCDoc.sheets(3)' лист 4 текущего документа, куда вставляем диапазон ячеек
    oASheet=oADoc.Sheets.getByName("Блок №1") 'документ источник выбор листа по названию
    oRange1=oASheet.getCellRangeByName("A1:W50")'выбор диапазона ячеек листа источника
oADoc.CurrentController.Select(oRange1) 'выбираем указанный диапазон ячеек источника
data=oADoc.CurrentController.getTransferable 'копируем диапазон ячеек источника

oRange2=oCSheet.getCellRangeByName("A1:W50")' выбираем аналогичный диапазон ячеек в текущем документе
' i=oRange2.RangeAddress.StartColumn : j=oRange2.RangeAddress.StartRow 'start column, start row
' oRange2=oCSheet.getCellRangeByPosition(i, j, i+oRange1.RangeAddress.EndColumn-oRange1.RangeAddress.StartColumn, j+oRange1.RangeAddress.EndRow-oRange1.RangeAddress.StartRow) 'output range gotten from the size of input range

oCDoc.CurrentController.Select(oRange2) 'переходим к диапазону ячеек источнику
oCDoc.CurrentController.insertTransferable(data) 'вставляем данные

    oCSheet=oCDoc.sheets(4)' лист 5 текущего документа, куда вставляем диапазон ячеек
    oASheet=oADoc.Sheets.getByName("Блок №2") 'документ источник выбор листа по названию
    oRange1=oASheet.getCellRangeByName("A1:W50")'выбор диапазона ячеек листа источника
oADoc.CurrentController.Select(oRange1) 'выбираем указанный диапазон ячеек источника
data=oADoc.CurrentController.getTransferable 'копируем диапазон ячеек источника

oRange2=oCSheet.getCellRangeByName("A1:W50")' выбираем аналогичный диапазон ячеек в текущем документе
' i=oRange2.RangeAddress.StartColumn : j=oRange2.RangeAddress.StartRow 'start column, start row
' oRange2=oCSheet.getCellRangeByPosition(i, j, i+oRange1.RangeAddress.EndColumn-oRange1.RangeAddress.StartColumn, j+oRange1.RangeAddress.EndRow-oRange1.RangeAddress.StartRow) 'output range gotten from the size of input range

oCDoc.CurrentController.Select(oRange2) 'переходим к диапазону ячеек источнику
oCDoc.CurrentController.insertTransferable(data) 'вставляем данные
   
    oCSheet=oCDoc.sheets(5)' лист текущего документа, куда вставляем диапазон ячеек
    oASheet=oADoc.Sheets.getByName("Блок №3") 'документ источник выбор листа по названию
    oRange1=oASheet.getCellRangeByName("A1:W50")'выбор диапазона ячеек листа источника
oADoc.CurrentController.Select(oRange1) 'выбираем указанный диапазон ячеек источника
data=oADoc.CurrentController.getTransferable 'копируем диапазон ячеек источника

oRange2=oCSheet.getCellRangeByName("A1:W50")' выбираем аналогичный диапазон ячеек в текущем документе
' i=oRange2.RangeAddress.StartColumn : j=oRange2.RangeAddress.StartRow 'start column, start row
' oRange2=oCSheet.getCellRangeByPosition(i, j, i+oRange1.RangeAddress.EndColumn-oRange1.RangeAddress.StartColumn, j+oRange1.RangeAddress.EndRow-oRange1.RangeAddress.StartRow) 'output range gotten from the size of input range

oCDoc.CurrentController.Select(oRange2) 'переходим к диапазону ячеек источнику
oCDoc.CurrentController.insertTransferable(data) 'вставляем данные

    oCSheet=oCDoc.sheets(6)' лист текущего документа, куда вставляем диапазон ячеек
    oASheet=oADoc.Sheets.getByName("Блок №4") 'документ источник выбор листа по названию
    oRange1=oASheet.getCellRangeByName("A1:W50")'выбор диапазона ячеек листа источника
oADoc.CurrentController.Select(oRange1) 'выбираем указанный диапазон ячеек источника
data=oADoc.CurrentController.getTransferable 'копируем диапазон ячеек источника

oRange2=oCSheet.getCellRangeByName("A1:W50")' выбираем аналогичный диапазон ячеек в текущем документе
' i=oRange2.RangeAddress.StartColumn : j=oRange2.RangeAddress.StartRow 'start column, start row
' oRange2=oCSheet.getCellRangeByPosition(i, j, i+oRange1.RangeAddress.EndColumn-oRange1.RangeAddress.StartColumn, j+oRange1.RangeAddress.EndRow-oRange1.RangeAddress.StartRow) 'output range gotten from the size of input range

oCDoc.CurrentController.Select(oRange2) 'переходим к диапазону ячеек источнику
oCDoc.CurrentController.insertTransferable(data) 'вставляем данные
End Sub

sokol92

Цитата: almaster13 от  8 ноября 2024, 15:16Был бы рад, если бы по нему высказали замечания или предложили возможные улучшения
См. сообщение #10 в этой теме.  :)
Владимир.