[РЕШЕНО] Перенос данных с листа на лист(сдвиг ячеек)

Автор Aleksandr H., 19 июля 2016, 11:20

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

Aleksandr H.

ЦитироватьLO Версія: 5.1.4.2
Код збірки: f99d75f39f1c57ebdd7ffc5f42867c12031db97a

Задание:
- с листа "упак28" скопировать на лист "Pak_raport" ячейки А-S строк по критериям:
а) заголовок
б) в столбце С (PLAN) есть любая запись
в) в столбце Е (pack) есть запись "ПАК-4411"

- отсортировать лист "Pak_raport" по A за возростанием, S за возростанием.

Результат - лист "Reseult"

Мои наработки - макрос PerenestyUpakofkuNaArkuszPAK_Raport()

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

Спасибо.

rami

Цитата: Aleksandr H. от 19 июля 2016, 09:20До последнего обновления макрос работал нормально, сейчас же, после вставки ячеек на лист Pak_report, верхнии ячейки сдвигаются вправо.
Не знаю, что там на LibreOffice 5.1.4.2, эта ветка мне сразу не понравилась и я её вообще не ставил. Попробовал на LibreOffice 5.2.0, не работает, всякий бред по офису гоняет :o

Переделал всё заново.

Aleksandr H.

#2
Цитата: rami от 19 июля 2016, 11:35Переделал всё заново.
Ваашпе шыкарно: без циклов, без скачков с листа на лист. Спасибо.


Aleksandr H.


Подскажите еще в какой строке определяется лист на который вставлять данные и сама команда копирования
oRange=ThisComponent.getSheets().getByIndex(1).getCellRangeByName("A1:S999")
oFilterDesc=oRange.createFilterDescriptor(True) ' фильтр
oFields(0).Field=1 ' поле для условия
oFields(0).Operator=com.sun.star.sheet.FilterOperator.NOT_EMPTY ' условие
oFields(1).Field=4 ' поле для условия
oFields(1).StringValue="ПАК-4411" ' критерий
oFields(1).Operator=com.sun.star.sheet.FilterOperator.EQUAL ' условие
oFields(1).Connection=1
oFilterDesc.setFilterFields(oFields()) ' добавить фильтра
oFilterDesc.ContainsHeader=True ' включить названия столбцов
oFilterDesc.CopyOutputData=True '
oRange.filter(oFilterDesc) ' применить фильтр


rami

По умолчанию всегда первый лист ячейка A1, по другому адресу так:
Dim oCellAddress As New com.sun.star.table.CellAddress
oCellAddress.Sheet=0   'первый лист
oCellAddress.Column=2  'столбец "C"
oCellAddress.Row=30    'строка "31"
oRange=ThisComponent.getSheets().getByIndex(1).getCellRangeByName("A1:S999")
oFilterDesc=oRange.createFilterDescriptor(True)
oFields(0).Field=1
oFields(0).Operator=com.sun.star.sheet.FilterOperator.NOT_EMPTY
oFields(1).Field=4
oFields(1).StringValue="ПАК-4411"
oFields(1).Operator=com.sun.star.sheet.FilterOperator.EQUAL
oFields(1).Connection=1
oFilterDesc.setFilterFields(oFields())
oFilterDesc.ContainsHeader=True
oFilterDesc.CopyOutputData=True
oFilterDesc.OutputPosition=oCellAddress   'адрес для вставки левого верхнего угла
oRange.filter(oFilterDesc)

Aleksandr H.

rami, спасибо за участие.
Еще нужен ликбез.
1. Если не известен номер листа, а только имя, как узнать индекс для листа с именем "Pak_raport" для вставки в oCellAddress.Sheet?
2. Надо на лист Pak_raport вставлять только текст и форматы. (не формулы), а сейчас вставляет и формулы.

rami

1. oCellAddress.Sheet=ThisComponent.getSheets().getByName("Pak_raport").RangeAddress.Sheet

2. Тогда нужно убрать формулы либо из исходных данных, либо из результата с помощью Вставить как..

Aleksandr H.

По п.2
строка oRange.filter(oFilterDesc) вставляет данные. Значи они уже в буфере и можем "Вставить как..."?
Sub PerenestyUpakofkuNaArkuszPAK_RaportRAMI_v2
Dim oRange, oFilterDesc
Dim oFields(1) As New com.sun.star.sheet.TableFilterField
Dim oCellAddress As New com.sun.star.table.CellAddress

oRange=thiscomponent.sheets.getByname(thiscomponent.getcurrentcontroller.activesheet.name).getCellRangeByName("A1:S999")
msgbox thiscomponent.getcurrentcontroller.activesheet.name

REM КОПИРУЕМ ИСХОДНИК
oCellAddress.Sheet = ThisComponent.getSheets().getByName("Pak_raport").RangeAddress.Sheet '3
oCellAddress.Column = 0
oCellAddress.Row = 0

oFilterDesc=oRange.createFilterDescriptor(True)
oFields(0).Field=1
oFields(0).Operator=com.sun.star.sheet.FilterOperator.NOT_EMPTY
oFields(1).Field=4
oFields(1).StringValue="ПАК-4411"
oFields(1).Operator=com.sun.star.sheet.FilterOperator.EQUAL
oFields(1).Connection=1
oFilterDesc.setFilterFields(oFields())
oFilterDesc.ContainsHeader=True
oFilterDesc.CopyOutputData=True
oFilterDesc.OutputPosition = oCellAddress

'---------------------------------------------------------------
'        oRange.filter(oFilterDesc) '<=== ЗДЕСЬ ВСТАВКА НА ЛИСТ
' значит фрагмент уже в буфере? Можем вставить как...?

REM РЕАЛИЗОВАНИЕ ВСТАВИТЬ КАК...
document   = ThisComponent.CurrentController.Frame
dispatcher = createUnoService("com.sun.star.frame.DispatchHelper")
SheetPaste =ThisComponent.Sheets.getByName("Pak_raport")
ThisComponent.getCurrentController().setActiveSheet(SheetPaste)  ' перешли на лист Пак_Рапорт
        dim args2(0) as new com.sun.star.beans.PropertyValue
args2(0).Name = "ToPoint"
args2(0).Value = "A2" ' ячейка в которую вставляем
dispatcher.executeDispatch(document, ".uno:GoToCell", "", 0, args2()) ' перейти к ячейке
  set args2 = nothing
dim args5(5) as new com.sun.star.beans.PropertyValue
args5(0).Name = "Flags"
args5(0).Value = "SVDT"  ' флаги по которым вставляються значения+формат
args5(1).Name = "FormulaCommand"
args5(1).Value = 0
args5(2).Name = "SkipEmptyCells"
args5(2).Value = false
args5(3).Name = "Transpose"
args5(3).Value = false
args5(4).Name = "AsLink"
args5(4).Value = false
args5(5).Name = "MoveMode"
args5(5).Value = 4

dispatcher.executeDispatch(document, ".uno:InsertContents", "", 0, args5())  ' вставить диапазон с буфера обмена
set args5 = nothing 

REM СОРТИРОВКА
ThisComponent.Sheets.getByName("Pak_raport").getCellRangeByName("A1:S999").Rows.OptimalHeight=True
ThisComponent.Sheets.getByName("Pak_raport").getCellRangeByName("A1:S999").Columns.OptimalWidth=True
Dim oSortFields(1) As New com.sun.star.util.SortField
Dim oSortDesc(0) as New com.sun.star.beans.PropertyValue
oRange=ThisComponent.Sheets.getByName("Pak_raport").getCellRangeByName("A2:S999")
oSortFields(0).Field=1
oSortFields(0).SortAscending=True
oSortFields(0).FieldType=com.sun.star.util.SortFieldType.ALPHANUMERIC
oSortFields(1).Field=18
oSortFields(1).SortAscending=True
oSortFields(1).FieldType=com.sun.star.util.SortFieldType.NUMERIC
oSortDesc(0).Name="SortFields"
oSortDesc(0).Value=oSortFields()
oRange.Sort(oSortDesc())


End Sub

rami

Цитата: Aleksandr H. от 17 августа 2016, 14:22строка oRange.filter(oFilterDesc) вставляет данные. Значи они уже в буфере и можем "Вставить как..."?
Нет, в буфере может быть что угодно, но не результат фильтра.

rami

В самом конце макроса после сортировки добавьте:oRange.setDataArray(oRange.DataArray)

Aleksandr H.

К сожалению не работает так как хочу.

rami

Проблема в формулах, первый документ в этой теме формул не содержал, поэтому проблем не было. Возникли два вида проблемы:
1. формулы в результате фильтрации ссылаются на ячейки за пределами диапазона фильтрации (диапазон A1:S999, а ссылка на столбец V)
2. формулы в результате фильтрации ссылаются на ячейки которые удаляются фильтром
Сейчас должно быть нормально. Проверяйте:

Aleksandr H.

Цитата: rami от 19 августа 2016, 16:19
Проблема в формулах, первый документ в этой теме формул не содержал, поэтому проблем не было.
Я посчитал что формулы необязательно вставлять, как оказалось ошибочно посчитал. Спасибо за код.