Не получается написать макрос для openoffice calc

Автор VEU, 16 марта 2016, 08:35

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

VEU

Помогите пожалуйста написать макрос для openoffice calc. Хочу написать макрос который мог бы в исходно открытый документ *.ods копировал значения выбранного диапазона к примеру (A1:B2) из другого файла *.ods, загвоздка еще в том что бы он копировал в определенно выбранную область т.е на пример копировал из file1.ods диапазон (A1:B2) и вставил в исходно открытый svod.ods диапазон (C3.D4). Помогите, бьюсь второй день! Хочу научится!

JohnSUN

Добро пожаловать на форум, VEU! (А что этот ник должен означать? ФИО, что ли?)
Цитата: VEU от 16 марта 2016, 08:35Хочу научится!
Похвальное желание. Тем более - добро пожаловать!
Цитата: VEU от 16 марта 2016, 08:35
Хочу написать макрос который мог бы в исходно открытый документ *.ods копировал значения выбранного диапазона к примеру (A1:B2) из другого файла *.ods, загвоздка еще в том что бы он копировал в определенно выбранную область т.е на пример копировал из file1.ods диапазон (A1:B2) и вставил в исходно открытый svod.ods диапазон (C3.D4).
Эта задача решена уже не один раз. Там всё очень просто.
Сначала скачиваешь файл по этой ссылке
Открываешь его и по Ctrl+F ищешь "copy sp" - попадаешь на строчку в оглавлении "5.23.1. Copy Spreadsheet Cells With The Clipboard"
Там же чуть ниже ещё и "Copy Spreadsheet Cells Without The Clipboard", и "An alternative to the clipboard – transferable content".
Зажимаешь Ctrl и кликаешь по строчке - перепрыгиваешь сразу в нужное место. Основная часть - собственно макрос. Остальные две строчки - пояснение к нему. Даже если не силён в английском - Гугль-переводчик легко объяснит, о чём пойдёт речь.
Если всё ещё не понятно - опять пишешь сюда и форумчане помогают разобраться что к чему.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

VEU


VEU

Я так понял, что данный макрос переносит данные из исходно открытого документа, может я не совсем понял)) только учусь). Можно ли сделать так что бы, допустим я открыл файл Svod.ods к примеру нажал кнопку и он перенес данные из File1.ods. Просто как правильно это записать, можете помочь?

Sub CopyPasteRange()
  Dim oSourceDoc, oSourceSheet, oSourceRange
  Dim oTargetDoc, oTargetSheet, oTargetCell
  Dim oDisp, octl
  Dim sUrl As String
  Dim NoArg()

  oSourceDoc=ThisComponent
  octl = oSourcedoc.getCurrentController()
  oSourceframe = octl.getFrame()
  oSourceSheet= oSourceDoc.Sheets(0)
  oSourceRange = oSourceSheet.getCellRangeByPosition(0,0,100,10000)
 
  oDisp = createUnoService("com.sun.star.frame.DispatchHelper")

  octl.Select(oSourceRange)

  oDisp.executeDispatch(octl, ".uno:Copy", "", 0, NoArg())
 
  sURL = "private:factory/scalc"
  oTargetDoc = Stardesktop.loadComponentFromURL(sURL, "_blank", 0, NoArg())
  oTargetSheet = oTargetDoc.getSheets.getByIndex(0)
 
  oTargetCell = oTargetSheet.getCellByPosition(0,0)
  oTargetDoc.getCurrentController().Select(oTargetCell)

  oTargetframe = oTargetDoc.getCurrentController().getFrame()
  oDisp.executeDispatch(oTargetFrame, ".uno:Paste", "", 0, NoArg())
End Sub

JohnSUN

Может быть, так будет понятнее
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

VEU


VEU

Здравствуйте! скажите, возможно ли сделать из этого же примера, что бы он так же брал из file1.ods диапазон ячеек (A1:B2) и (A4:B4) т.е скопировал, после вставлял в svod.ods соответственно (A1:B2) в (E7:F7) а (A4:B4) в (E10:F10). Надеюсь понятно объяснил))

Sub onBtnClick(oEvent As Variant)
Dim oSheet As Variant   
Dim lastRow As Long      
Dim oCellRangeByPosition As Variant   
Dim oFileSelector As Variant   
Dim   sFileName As String   
Dim iDoc As Variant      
Dim bDisposable As Boolean   
Dim iSheet As Variant   
Dim iCursor As Variant   
Dim iData As Variant   

   GlobalScope.BasicLibraries.LoadLibrary("Tools")
   oSheet = ThisComponent.getCurrentController().getActiveSheet()
   sFileName = oEvent.Source.getModel().getParent().getByName("selectFile").Text
   iDoc = OpenDocument(ConvertToURL(sFileName), Array(), bDisposable)
   If IsNull(iDoc) Or IsEmpty(iDoc) Then
      MsgBox("Файл с именем '" + sFileName + "' не может быть открыт", 48, "Ошибка открытия файла")
      Exit Sub
   EndIf
   iSheet = iDoc.getSheets().getByIndex(0)
   iCursor = iSheet.createCursor()
        iCursor.gotoEndOfUsedArea(True)
   iData = iCursor.getDataArray()
   lastRow = GetLastUsedRow(oSheet)
   If lastRow>0 Then lastRow = lastRow + 1
   oCellRangeByPosition = oSheet.getCellRangeByPosition(0, lastRow, UBound(iData(0)), UBound(iData)+lastRow)
   oCellRangeByPosition.setFormulaArray(iData)
   If bDisposable Then iDoc.close(True)
End Sub

JohnSUN

Можно, всё можно.
Дело в том, что нужно просто понять что это за зверь .getCellRangeByPosition и какие параметры ему передаются.
Там всё просто - номер левой колонки, номер верхней строки, номер правой колонки, номер нижней строки. При этом не забывать, что нумерация начинается с нуля.
То есть для диапазона (A1:B2) нужно написать .getCellRangeByPosition(0,0,1,1), для (A4:B4) - .getCellRangeByPosition(0,3,1,3). Эти методы нужно применять к листу исходных данных (в нашим примере это iSheet).
Точно так же и диапазоны выходные:
(E7:F7) -> oSheet.getCellRangeByPosition(4, 6, 5, 6),
(E10:F10)  -> oSheet.getCellRangeByPosition(4, 9, 5, 9)

Есть у листа еще и метод .getCellRangeByName("A4:B4") - ему можно диапазон ячеек подсовывать прямо в виде текстовой строки, не заморачиваясь пересчетом колонок и столбцов. Но, что касается меня, то стараюсь все-таки использовать .getCellRangeByPosition(). Просто был у меня случай, когда скопировал диапазон из сообщения на форуме и целый день искал ошибку в коде. А оказалось, что А12:С240 было написано РУССКИМИ буквами.

Да, а копирование данных диапазон в диапазон можно записать одной длинной строкой
oSheet.getCellRangeByPosition(4, 6, 5, 6).setFormulaArray(iSheet.getCellRangeByPosition(0,0,1,1).getDataArray())
Не смотря на "ужасный", нечитаемый вид - должна работать.

PS. И не надо копировать весь текст макроса в следующее сообщение - только тот кусочек, который вызывает вопросы. И форматируй, плз, эти фрагменты как код (такая специальная кнопочка с "диезом")
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

VEU


VEU

Чего то я упускаю! не получается, сори только учусь))

oSheet = ThisComponent.getCurrentController().getActiveSheet()

sFileName = oEvent.Source.getModel().getParent().getByName("selectFile").Text

iDoc = OpenDocument(ConvertToURL(sFileName), Array(), bDisposable)

If IsNull(iDoc) Or IsEmpty(iDoc) Then
MsgBox("Файл с именем '" + sFileName + "' не может быть открыт", 48, "Ошибка открытия файла")
Exit Sub
EndIf

iSheet = iDoc.getSheets().getByIndex(0)

    oSheet.getCellRangeByPosition(4, 6, 5, 6).setFormulaArray(iSheet.getCellRangeByPosition(0,0,1,1).getDataArray()

If bDisposable Then iDoc.close(True)

JohnSUN

#10
Не переживай, это с непривычки. Смотри внимательно:
(4, 6, 5, 6).setFormula...(0,0,1,1)
Представь себе два прямоугольника с такими координатами... Видишь? Нижний - из двух ячеек в одной строке, а второй - уже квадратик 2х2.
Чтобы оператор копирования сработал, оба прямоугольника должны быть одного размера. Или первый (4, 6, 5, 7), или второй (0,0,1,0)

(И не рассказывай, что это я ошибся!
Во-первых, это у тебя было так написано "(A1:B2) в (E7:F7)", я просто перевёл.
А во-вторых, я и так знаю, что ошибся  ;D )
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

VEU

Здравствуйте! еще раз спасибо за помощь)
Скажите пожалуйста, есть ли команда которая копирует не только значение, а вообще все что имеется в ячейках как например в стандартных функциях Calc "Специальная вставка->выделение ->вставить всё"? Просто имеется строка на некоторых ячейках зашиты формулы, хочу написать макрос что бы он копировал строку со всем содержимым и вставлял в другую пустую строку.

JohnSUN

Помнишь, как мы получали активный лист? Спрашивали у текущего документа "Кто у тебя сейчас контроллер?" (.getCurrentController())
Этот вот контроллер знает что выделено в данный момент. И, более того, может скопировать это выделение в переменную - всё-всё, значения, формулы, форматы.
Делается это приблизительно так
oCurrentController = ThisComponent.getCurrentController()
oCurrentController.select(<какой-то участок на листе, oCellRangeByPosition>)
oTransferable = oCurrentController.getTransferable()

А это скопированное можно вставить куда захочешь, то ли прямо в этот документ, то ли в другой - это сделает
oCurrentController.insertTransferable(oTransferable)
Это всё расписано в том самом "An alternative to the clipboard – transferable content", о котором я писал во втором сообщении этой темы
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

VEU