Копирование форматированной строки

Автор Fiona, 25 июня 2020, 07:16

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

Fiona

Добрый день!
Опять обращаюсь за помощью к неравнодушным...
Есть особым образом форматированная таблица. В скрытом защищенном столбце "А" стоит формула для выгрузки строк по определенному алгоритму. Но выяснилось, что при заполнении этой таблицы из внешнего файла количество строк меньше, чем в исходнике. Определенно, insertByIndex здесь не подходит. Есть функция для добавления необходимого количества строк из  самой таблицы (для работы пользователя), ее я переписала под LO, она работает так, как мне нужно. А аналогичная функция при загрузке данных из внешнего файла через макрос ну никак не хочет работать. И потом докидывает данные ниже таблицы без всяких формул и форматов. Помогите, пожалуйста... Где я накосячила? :-[

Sub AddLine (ByRef oSheet As Object, ByVal flag As Integer)

Dim oRows, nEndRow, counter, oDispatcher
        On Error GoTo Err1    
       
   If flag > 0 Then
   
  oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
ThisComponent.CurrentController.select(oSheet)
nEndRow = Cells(Cells.Rows.count, "A").End(xlUp).row

       counter = 0
       Do While counter <= flag
       counter = counter + 1
       oRows = oSheet.getRows()
               Rows(nEndRow).Select
       dispatcher.executeDispatch(ThisComponent.CurrentController.Frame, ".uno:InsertRowsBefore", "", 0, Array())  
       Rows(nEndRow - 1).Select
       oDispatcher.executeDispatch(ThisComponent.CurrentController.Frame, ".uno:Copy", "", 0, Array())
       Rows(nEndRow).Select
       oDispatcher.executeDispatch(ThisComponent.CurrentController.Frame, ".uno:Paste", "", 0, Array())
       Loop
Err1:
   End If

End Sub

Fiona

Все молчат... Вернулась к достойному Питоньяку: REM Set source doc/currentController/frame/sheet/range. Сообразила, что getCurrentController() логичнее прописать после определения активного листа (активного фрейма у меня нет) - insert отработал, а что с paste не так? Так еще прикол - строка последняя 16 определяется, а область приходится указывать минус 1, иначе курсор переходит на строку ниже последней заполненной "А17:J17"...
Переход на следующий лист - и insert пять не работает... где-то что-то залипло? как это работает вообще?!!

Sub AddLine (ByRef sh As Object, ByVal flag As Integer)

Dim  nPrevRow,nEndRow, nEndCol, counter as Integer
Dim oRows, oSourceSheet, oSheets, oDispatcher,  oCtl, oDocument,oSourceframe,oSourceRange As Object
Dim NoArg()
Dim oTargetSheet, oTargetCell, oTargetframe
         On Error GoTo Err1    
       
    If flag > 0 Then
    oDocument   = ThisComponent
    oCtl = oDocument.getCurrentController()
  oDispatcher = createUnoService("com.sun.star.frame.DispatchHelper")

        oSheets = oDocument.GetSheets()
        oSourceSheet = oSheets.getByName(sh.Name)
ThisComponent.CurrentController.select(oSourceSheet)
oSourceframe = oCtl.getFrame()
oCtl = oDocument.getCurrentController()
nEndRow = Cells(Cells.Rows.count, "A").End(xlUp).row
nEndRow = nEndRow - 1
nPrevRow = nEndRow - 1
nEndCol = GetLastCol(oSourceSheet)       
        counter = 0
        oSourceSheet.CellProtection.IsLocked = False
        Do While counter <= flag

oSourceRange = oSourceSheet.getCellRangeByPosition(0,nEndRow,nEndCol,nEndRow)
oCtl.Select(oSourceRange)
        oDispatcher.executeDispatch(oSourceframe, ".uno:InsertRowsBefore", "", 0, NoArg())
    oSourceRange = oSourceSheet.getCellRangeByPosition(0,nPrevRow,nEndCol,nPrevRow)
oCtl.Select(oSourceRange)
oDispatcher.executeDispatch(oSourceframe, ".uno:Copy", "", 0, NoArg())
    oSourceRange = oSourceSheet.getCellRangeByPosition(0,nEndRow,nEndCol,nEndRow)
oCtl.Select(oSourceRange)
        oDispatcher.executeDispatch(oSourceframe, ".uno:Paste", "", 0, NoArg())

     counter = counter + 1
        Loop
         oSourceSheet.CellProtection.IsLocked = True
Err1:
    End If

End Sub

mikekaganski

Возможно, проблема в том, что работа с Вашей задачей подразумевает, что отвечающему надо ещё выдумать набор данных. Как Вы думаете, нельзя ли подсказать спрашивающему, что можно выложить тестовый набор для облегчения задачи, с описанием того, что должно происходить при вызове макроса, и того, что спрашивающий вместо этого видит на самом деле?
С уважением,
Михаил Каганский

bk

Строки я вставляю так: getRows().insertByIndex
Копирую так: oSheet.copyRange(rngTo, rngFrom), где
rngTo - com.sun.star.table.CellAddress 'структура
rngFrom - com.sun.star.table.CellRangeAddress 'структура
Если докидывает снизу и без формул и форматов, значит что-то не то копирует. Плюс, если вижу что у меня докидывает снизу, вероятно с циклом проблема. Но без данных действительно не разберешь.

Fiona

Так я тоже пыталась... Не копирует...

bk

По-моему, на диапазон такая ссылка должна быть: oSheet.getCellRangeByPosition(*,*,*,*).getRangeAddress()
не хватает этого .getRangeAddress()

Fiona

Попробовала так после вставки строки

oRangeAddress = oSourceSheet.getCellRangeByPosition(0,nPrevRow,nEndCol,nPrevRow).getRangeAddress()
oTargetCell  = oSourceSheet.getCellByPosition(0, nEndRow).getCellAddress() 
oSourceSheet.copyRange(oTargetCell, oRangeAddress)

кодировка структуры есть, ссылка на именованный диапазон тоже.
Но с переходом на следующий лист даже вставка не работает... Где логика?

kompilainenn

Fiona, покажите уже файл и скажите желаемый результат
Поддержать разработчиков LibreOffice можно тут, а наш форум вот тут

bk

#8
Del

bk

#9
мне кажется у Вас в цикле проблема. переменные, которые внутри цикла определены до него, т.е. он работает с одними и теми же значениями (может ошибаюсь, глаза замылились).
Попробуйте вставку сделать "залпом", один раз, если есть возможность определить сколько строк надо вставлять getRows().insertByIndex(s, n), где s - куда (нумерация строк с нуля), n - сколько строк. Снимите хотя бы эту проблему. Затем определите диапазон, который копируете. И затем в цикле выполните copyRange во вставленные строки. В последнем у Вас должна быть переменная для строк.
Либо копируемый диапазон тоже в цикл (если он каждый раз отличается по форме и содержанию).

Fiona

Вы правы в том, что недостаточно информации. Но я не могу ее выложить в полном объёме. Цикл идет вне этой процедуры по всем листам книги. Если есть листы, где количество строк меньше, чем в файле импорта, добавляем строки (иначе куда потом копировать данные?) По отладчику видно, что лист, ячейка, область определены корректно, здесь нет зацикливания. Переменные тоже локальные. Попробую через insertbyindex. Должна же строка встать на место!
Спасибо за поддержку!

Fiona

Фиаско... Оказывается, все дело в скрытых столбцах... Курсор не может встать на скрытую ячейку?