Удаление строк с нулевыми значениями в одном столбце

Автор nivalenov, 6 мая 2015, 06:18

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

nivalenov

Здравствуйте! Вроде простая задача, но не получается. Необходимо перебрать строки с 10 по 713 и удалить те в которых в столбце D значения=0
Код взял в одной из тем, немного поменял. не работает вообщем.


oSheet = oDoc1.CurrentController.getActiveSheet()
myrows=oSheet.getrows

textnd = osheet.getcellbyposition(3,i).string

for i=713 to 10 step -1
If textnd = "0" Then
myrows.removebyindex(i,3)
end if
next i



JohnSUN

Как насчёт перенести чтение ноля (вычисление textnd) на строчку ниже, внутрь цикла?
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

rami

Sub main
oSheet = ThisComponent.CurrentController.getActiveSheet()
myrows=oSheet.getrows
for i=713 to 10 step -1     'цикл в обратном порядке, от конца к началу
textnd = osheet.getcellbyposition(3,i).String  'эта строка должна быть внутри цикла
If textnd = "0" Then        'условие ищет "0", но не пустую ячейку
myrows.removebyindex(i,1)   'i — это номер строки, а второй параметр количество удаляемых строк
end if
next i
End Sub

nivalenov

Спасибо,се верно. сделал так, заработало. Но только долго для 700 строк... Может есть другие способы?


odoc=thiscomponent
oSheet = oDoc.CurrentController.getActiveSheet()
myrows=oSheet.getrows

rowmax=712
rowmin=9

For i=rowmax To rowmin step -1
textnd = osheet.getcellbyposition(3,i).string
   If textnd = "0" Then
     myrows.removebyindex(i,1)
   End if  
Next i

JohnSUN

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

Андрей2014

Разве нельзя автофильтром выделить все строки "не 0", потом их выделить, скопировать...

rami

Цитата: Андрей2014 от  6 мая 2015, 15:41Разве нельзя автофильтром выделить все строки "не 0", потом их выделить, скопировать...
Можно, но не автофильтром, а обычным, и результат сохранить на новый лист. Но вопрос не об этом , а об удалении строк.

JohnSUN

+1

Можно, конечно... Но, как всегда, основной контраргумент - "Это слишком много нажатий кнопок, а операция повторяется довольно часто - нужно это сделать максимум одним нажатием..." Поэтому и пишутся такие макросы.
Вообще-то, если переформулировать задачу, нужно подтянуть наверх, к 10-ой строке, все строки до 713-ой, для которых в четвертой колонке указан не ноль.
Самый простой способ, но медленный - действительно поудалять такие строки, остальные сами подтянутся наверх.
Быстрый способ - одним оператором считать в массив все значения из A10:D173, пересортировать этот массив и, опять-таки одним оператором, записать на старое место.
Но поскольку неизвестно, о каких данных идёт речь (образца таблицы не было), то этот вариант макроса и не предлагался.
Дело в том, что если в этом диапазоне только значения (строки-числа-даты), то этим "одним оператором" будет oRange.getDataArray(), а если там попадаются формулы, то oRange.getFormulaArray(). В случае формул при сортировке нужно позаботиться об изменении адресов (если они в формулах встречаются)... В общем, задача не тривиальная. Хотя вполне решаемая...
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

rami

Цитата: JohnSUN от  6 мая 2015, 16:07Но поскольку неизвестно, о каких данных идёт речь (образца таблицы не было)
Было здесь: http://forumooo.ru/index.php/topic,4891.0.html
Есть простой и быстрый способ вручную выделить диапазон D10:D713, найти все 0 и не снимая выделение удалить строки
Если через макрос, то так:
Sub Main1   Dim oDoc, oDisp, oRange, oSDescr, oFound, args1(0) As New com.sun.star.beans.PropertyValue
oDoc=ThisComponent.CurrentController.Frame
oDisp=createUnoService("com.sun.star.frame.DispatchHelper")
oRange=ThisComponent.CurrentController.ActiveSheet.getCellRangeByPosition(3,9,3,712)
oSDescr=oRange.createSearchDescriptor()
oSDescr.SearchWords=true
oSDescr.SearchString="0"
oFound=oRange.findAll(oSDescr)
ThisComponent.getCurrentController().Select(oFound)
args1(0).Name="Flags"
args1(0).Value="R"
oDisp.executeDispatch(oDoc, ".uno:DeleteCell", "", 0, args1())
End Sub

но при этом ломаются ссылки в столбце A
Лучше всего результат фильтрации в новый лист.
Цитата: JohnSUN от  6 мая 2015, 16:07В общем, задача не тривиальная. Хотя вполне решаемая...
Если задача туманная, то и решение будет "как бы"

JohnSUN

#9
Цитата: rami от  6 мая 2015, 18:32
Было здесь: ...
Ага, вижу...
Цитата: rami от  6 мая 2015, 18:32
но при этом ломаются ссылки в столбце A
Если бы только там - можно было бы исхитриться... Например, добавить еще два именованных диапазона - что-то вроде НачалоРаздела с формулой IF($D11>0;1;0) и СледующийНомер с формулой IF($D12>0;$A11+1;$A11+0). Тогда во всей колонке A было бы только =НачалоРаздела и =СледующийНомер, а эти формулы не поломались бы.
Но там ещё формулы с суммарными итогами и т.п. Их тоже нужно защитить от разрушения...
Цитата: rami от  6 мая 2015, 18:32
Если задача туманная, то и решение будет "как бы"
И опять +1
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне