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

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

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

almaster13

Добрый день! Пытаюсь скопировать диапазон ячеек листа внешнего документа в текущий документ. Ничего не вставляется, но ошибку не выдает. Прошу помочь. Заранее спасибо!

Sub CopyGrafik
Dim oCDoc, oAdoc as Object
Dim oCSheet, oASheet as Object
Dim oRangeAddress as Object
Dim oCellAddress as Object
Dim oURL as String
oCdoc=thiscomponent
oURL="file:///cifs/DATA/DNT/PLAN-2024-Astra.ods"
oADoc = starDeskTop.loadComponentFromURL(oURL, "_blank", 0, Array() )
oASheet = oADoc.Sheets(2)
oRangeAddress = oASheet.getCellRangeByName("A1:V43").getRangeAddress()
oCSheet=oCdoc.sheets(3)
oCellAddress  = oCSheet.getCellRangeByName("A1").getCellAddress()
oCSheet.copyRange(oCellAddress, oRangeAddress)

oAdoc.close (-1)
End Sub

mikekaganski

#1
Чему равен oRangeAddress в момент вызова copyRange?

Не относится к делу: что означает "-1" в вызове close?
С уважением,
Михаил Каганский

bigor

Цитата: almaster13 от 25 октября 2024, 12:18Ничего не вставляется
посмотрите тему, можете начать с выводов, последний пост
Поддержать наш форум можно здесь

almaster13

Цитата: mikekaganski от 25 октября 2024, 12:23Чему равен oRangeAddress в момент вызова copyRange?

Не относится к делу: что означает "-1" в вызове close?

Я так понял, что RangeAdress() пустой (на печати выводит пустое место). Но непонятно, в чем проблема?

А oAdoc.close (-1) без агрумента выдается ошибка.

mikekaganski

Цитата: almaster13 от 25 октября 2024, 12:55Но непонятно, в чем проблема?

Проблема в понимании, что такое oRangeAddress (и я не говорил о RangeAdress()). Печать тут ни при чём - стоит посмотреть в окне Watch, чтобы увидеть, что структура содержит номера листа, строк, столбцов - но ничего о файле. Функция, куда Вы передаёте эту структуру, не может знать, что Вы хотите что-то скопировать из другого файла.

Цитата: almaster13 от 25 октября 2024, 12:55А oAdoc.close (-1) без аргумента выдается ошибка.

Естественно. Туда требуется передать булево значение, говорящее о том, что если какому-то процессу понадобиться остановить закрытие, то этот процесс потом должен сам закрыть этот документ (или нет). Но почему -1?
С уважением,
Михаил Каганский

sokol92

Цитата: almaster13 от 25 октября 2024, 12:18Пытаюсь скопировать диапазон ячеек листа внешнего документа в текущий документ.
Метод CopyRange для этого не подходит - он копирует диапазон внутри документа.
Владимир.

almaster13

#6
Цитата: mikekaganski от 25 октября 2024, 13:09
Цитата: almaster13 от 25 октября 2024, 12:55Но непонятно, в чем проблема?

Проблема в понимании, что такое oRangeAddress (и я не говорил о RangeAdress()). Печать тут ни при чём - стоит посмотреть в окне Watch, чтобы увидеть, что структура содержит номера листа, строк, столбцов - но ничего о файле. Функция, куда Вы передаёте эту структуру, не может знать, что Вы хотите что-то скопировать из другого файла.

Я понял, что нужно использовать другую команду, просто по ссылке ветка не открывается. Буду искать команду getDataArray вот только возьмет ли он текст, значения и диаграмму одновременно? Может быть, не заморачиваться и просто скопировать лист полностью?
Цитата: almaster13 от 25 октября 2024, 12:55А oAdoc.close (-1) без аргумента выдается ошибка.

Цитата: mikekaganski от 25 октября 2024, 13:09Естественно. Туда требуется передать булево значение, говорящее о том, что если какому-то процессу понадобиться остановить закрытие, то этот процесс потом должен сам закрыть этот документ (или нет). Но почему -1?

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

sokol92

Цитата: almaster13 от 25 октября 2024, 13:48Буду искать команду getDataArray вот только возьмет ли он текст, значения и диаграмму одновременно
Пожалуйста, еще раз прочитайте внимательно это сообщение.
Владимир.

almaster13

Цитата: sokol92 от 25 октября 2024, 14:18
Цитата: almaster13 от 25 октября 2024, 13:48Буду искать команду getDataArray вот только возьмет ли он текст, значения и диаграмму одновременно
Пожалуйста, еще раз прочитайте внимательно это сообщение.

В это сообщение зайти удается. Там говорится о том, что команда getTransferable позволит скопировать все содержимое, но при попытке пойти по ссылке выдается ошибка. По писку в сети описание данной команды только на английском! :(

sokol92

#9
Цитата: almaster13 от 25 октября 2024, 14:52команда getTransferable позволит скопировать все содержимое, но при попытке пойти по ссылке выдается ошибка. По писку в сети описание данной команды только на английском!
У меня переход по указанной ссылке происходит без ошибок.
В программировании уже давно всю документацию приходится читать на английском языке, и это будет в обозримом будущем. К счастью, квалификация программ для автоматического перевода уже достаточно высокая.

Поищите на нашем форуме примеры применения getTransferable.
Владимир.

sokol92

Нашел в закромах и чуть доработал универсальную функцию для копирования диапазонов (и ширины столбцов).
Пример вызова для копирования выделенного диапазона текущего документа в новый документ (начиная в ячейки A1 первого листа нового документа). Копируется также ширина столбцов исходного диапазона.

Sub TestCopyRange()
   Dim oDocTo, oRangeFrom
   oRangeFrom=ThisComponent.CurrentSelection
   oDocTo=StarDesktop.LoadComponentFromUrl("private:factory/scalc", "_blank", 0, Array())
   CopyRange oRangeFrom, oDocTo.Sheets(0).getCellByPosition(0,0), "W"
End Sub

' -------------------------------------------------------------------------------------------------
' lang:ru
' Копирует прямоугольный диапазон ячеек.
' Параметры:
' oRangeFrom  диапазон, который копируется.
' oRangeTo    копирование производится в диапазон, который начинается с левой верхней ячейки оRangeTo.
' opts        опции копирования. Если не указан или пустая строка, то производится обычное (полное) копирование диапазона.
'             Если "*", то производится копирование значений (при этом формулы будут заменены на значения).
'             Иначе одна или несколько следующих букв (регистр не имеет значения), указывающих что будет копироваться:
'             S:тексты; V:числа; D:датаВремя; F:формулы; N:комментарии; T: форматы ячеек; O:объекты; A:всё.
'             Если строка opts содержит символ "W" (регистронезависимо), то перед копированием диапазона ячеек
'             производится копирование ширины столбцов, после этого символ "W" удаляется (и не влияет на тип копирования).
'
' Возвращает результирующий диапазон или Nothing.
Function CopyRange(ByVal oRangeFrom As Object, ByVal oRangeTo As Object, Optional ByVal opts As String) As Object
  Dim oDocFrom As Object, oDocTo As Object, oSheetFrom As Object, oSheetTo As Object, adrFrom, adrTo, oTrans As Object
  Dim oDisp As Object, props(0) As New com.sun.star.beans.PropertyValue
  Dim i As Long
 
  If IsMissing(opts) Then opts=""
 
  CopyRange=Nothing
  oSheetFrom=oRangeFrom.Spreadsheet
  oSheetTo=oRangeTo.Spreadsheet
  oDocFrom=oSheetFrom.DrawPage.Forms.Parent
  oDocTo=oSheetTo.DrawPage.Forms.Parent
 
  adrFrom=oRangeFrom.RangeAddress
  adrTo=oRangeTo.RangeAddress
  oRangeTo=oSheetTo.getCellRangeByPosition(adrTo.StartColumn, adrTo.StartRow, _
           adrTo.StartColumn + adrFrom.EndColumn - adrFrom.StartColumn, _
           adrTo.StartRow    + adrFrom.EndRow    - adrFrom.StartRow)
  adrTo=oRangeTo.RangeAddress
  
  opts=UCase(opts)
  If Instr(1, opts, "W")>0 Then                       ' копируем ширины столбцов
    For i=adrFrom.StartColumn To adrFrom.EndColumn
      oSheetTo.Columns(adrTo.StartColumn + i - adrFrom.StartColumn).Width=oSheetFrom.Columns(i).Width
    Next i
    opts=Replace(opts, "W", "")
  End If             
            
 
  If opts="" Then
    If oDocFrom.RuntimeUID=oDocTo.RuntimeUID Then     ' тот же документ
      oSheetFrom.CopyRange oRangeTo.getCellByPosition(0,0).CellAddress, adrFrom
     
    Else                                              ' разные документы 
      oDocFrom.CurrentController.select oRangeFrom
      oTrans = oDocFrom.CurrentController.getTransferable()
      oDocTo.CurrentController.Select oRangeTo
      oDocTo.CurrentController.insertTransferable oTrans
    End If
 
  ElseIf opts="*" Then                                ' копируем через dataArray 
    oRangeTo.setDataArray oRangeFrom.DataArray

  Else                                                ' специальная вставка
    oDisp=createUnoService("com.sun.star.frame.DispatchHelper")
    oDocFrom.CurrentController.select oRangeFrom
    oDisp.executeDispatch(oDocFrom.CurrentController.Frame, ".uno:Copy", "", 0, Array())
    props(0).Name="Flags"
    props(0).Value=UCase(opts)
   
    oDocTo.CurrentController.select oRangeTo
    oDisp.executeDispatch(oDocTo.CurrentController.Frame, ".uno:insertContents", "", 0, props())
  End If
 
  CopyRange=oRangeTo
End Function

Владимир.

Sirius34

Цитата: almaster13 от 25 октября 2024, 13:48Данную команду увидел в чужом макросе и стал использовать, не понимая до конца суть. Трудно искать подвох, если все работает. Документ открывается а данной командой с данным аргументом он без проблем закрывается.
Как ни странно, что Excel, что LO, воспринимают, как логическую ИСТИНУ, что 1, что -1.
Поэтому, команда oAdoc.close (-1) в данном контексте как раз и закроет Ваш внешний документ с сохранением изменений, если таковые были.
Поскольку обычное копирование не предполагает внесение изменений, то разницы - как именно сохранять документ - в данном случае нет никакой.
Тем не менее, чтобы не путаться, я бы советовал использовать логическую формулировку, а не цифровую, в команде закрытия.
oAdoc.close (true) или oAdoc.close (false) соответственно

sokol92

Цитата: Sirius34 от 28 октября 2024, 09:04Как ни странно, что
Я бы заменил на "любопытно, почему..."  :)
Посмотрите в теме форума по Excel это сообщение Владимира Захарова (ZVI) и ниже.

Что касается метода close, то Михаил выше объяснял назначение его параметра логического типа. В "обычной" ситуации метод close в LO, независимо от параметра, "молча" закроет документ, даже если в нем есть не сохраненные изменения. Это поведение отличается от поведения метода Workbook.Close в Excel.
Владимир.

almaster13

#13
Большое спасибо за помощь! Постараюсь внимательно изучить предложенный вариант скрипта. А проблема решилась проще, копированием листов со всем содержимым.

Макрос выложен далее.

bigor

Цитата: almaster13 от 31 октября 2024, 09:20проблема решилась
что бы удобнее было вашим макросом пользоваться остальным, отредактируйте пост: выделите текст макроса и нажмите     
значок
Поддержать наш форум можно здесь