Макрос по разному работает при разных способах запуск?...

Автор ForumOOo (бот), 19 декабря 2016, 16:24

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

ForumOOo (бот)

Компонент: Basic
Версия продукта: 5.x
Сборка: LibreOffice
ОС: Windows 7 x64

Макрос по разному работает при разных способах запуска.
Есть функция, которая должна выполняться при изменении числа в определенной ячейке.
В функции есть вызов метода clearContents.
Если вызов функции выполняется автоматически (т.е. при изменении значения определенной ячейки), метод clearContents не отрабатывает.
Если функцию вызывать из редактора VB (клавишей F5) clearContents отрабатывает.
Не могу понять, в чем дело
демо прикладываю. В демо файле при изменении значения в ячейке B1 должен стираться диапазон B10:B20 и значение B1 копироваться в C1.

Тестовый файл: http://forumooo.ru/attachments/upload/test1.ods (10.57 КБ)

--
Подпись: Lesha
Эл. почта: rageforge@yandex.ru

mikekaganski

Это не макрос, а пользовательская функция, и вы её не запускаете, а вычисляете значение. При этом она работает на наборе данных "для чтения", то есть не может ничего изменить на листе (у неё нет побочного действия).
С уважением,
Михаил Каганский

Lesha

не совсем понимаю, о чем речь... а изменить на листе очень даже может
если я добавлю в эту функцию строку типа "cSheet.getCellByPosition(5, 5).Value = d*d" она отработает

mikekaganski

#3
Хм... действительно. Но вот "cSheet.getCellByPosition(1, 1).Value = d*d" уже не работает. Так что это, видимо, говорит о том, что ячейки "выше" (раньше с точки зрения отработки) не получится изменить..... я бы назвал это багом. Не должна такая вещь работать вообще.
С уважением,
Михаил Каганский

Lesha

у меня работает и "cSheet.getCellByPosition(1, 1).Value = d*d".
LibreOffice 5.1.6.2
почему не должно работать?

JohnSUN

Цитата: Lesha от 19 декабря 2016, 16:59
не совсем понимаю, о чем речь... а изменить на листе очень даже может
если я добавлю в эту функцию строку...
Более того, она, как и планировалось, нормально очистит диапазон B10:B20 на ПЕРВОМ листе книги, если вписать =CLRDATA(<какая-то ячейка>) в ЛЮБОЙ ДРУГОЙ лист.
При вычислении функций, записанных в ячейки, содержимое ТЕКУЩЕГО листа (на котором эта функция находится) защищается от любых изменений. Иначе сплошь и рядом плохие формулы наглухо зацикливали бы вычисления и "вешали" или "валили" офис.

То что вариант с cSheet.getCellByPosition(5, 5).Value = d*d работает можно считать недоработкой, упущением. Попробуй указать =CLRDATA(F6) и пересчитать лист несколько раз (F6 это и есть CellByPosition(5, 5)). Вряд ли пользователи Calc ожидают таких результатов
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

JohnSUN

Цитата: mikekaganski от 19 декабря 2016, 17:04
я бы назвал это багом. Не должна такая вещь работать вообще.
И, похоже, давний баг - воспроизводится и в LibreOffice 4.4.6. (в OpenOffice 4.1.2 еще всё нормально, лист блокируется). Но в багзилле ничего такого не вижу.
Ну, что, Lesha? Спасибо тебе! С твоей помощью сообщество избавится от досадного бага
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

rami

Цитата: JohnSUN от 19 декабря 2016, 15:34И, похоже, давний баг - воспроизводится и в LibreOffice 4.4.6. (в OpenOffice 4.1.2 еще всё нормально, лист блокируется).
Баг не только древний, но и коварный, если в Apache OpenOffice 4.1.3 выполнить:
public function clrdata(byval d as integer) as integer
dim cSheet as Object
cSheet = ThisComponent.Sheets(0)
cSheet.getCellRangeByName("A1").value=d*d
clrdata = d
end function

то в ячейке A1 ничего не происходит, (проверял содержимое ячейки), но после сохранения и открытия в OOA или в LO появляется новое значение (d*d)

JohnSUN, проверь ещё раз с сохранением.

mikekaganski

Я проконсультировался у moggi - одного из ключевых разработчиков Calc.
Он говорит, что блокировки нет:

[17:21] mkaganski: moggi: is it OK that a user function in Calc is able to modify the sheet's content as side effect?
[17:21] moggi: mkaganski: normally not, ideally sheet functions are pure functions
[17:22] moggi: mkaganski: of course that does not prevent a user to write a function in basic that does not follow that rule
[17:46] mkaganski: moggi: so there's no read-only blocking when a user function is executed?
[17:47] moggi: mkaganski: no
[17:48] moggi: mkaganski: the whole calc core is blocking free, but you can most likely mess up the calculation engine if you change the wrong cell
[17:48] moggi: mkaganski: e.g. running into infinite loops, ...
[17:49] mkaganski: moggi: I understand. My question is because in such a function, "cSheet.getCellByPosition(5, 5).clearContents(511)" is a noop, while "cSheet.getCellByPosition(5, 5).Value = 5" works...
[17:50] mkaganski: moggi: and I hoped that allowing setting value is a bug
[17:53] moggi: mkaganski: as I mentioned you can most likely confuse calc a lot if you modify another cell while we are in the calculation of another cell


Зная, как вносятся изменения в ядро calc, этот баг не будет исправлен. Потому что уменьшение производительности в ядре - не вариант. Кстати, вероятно, и в случае с clearContents модификация может проявиться после сохранения/переоткрытия, и это один из видов того самого странного поведения, о котором говорит moggi. Единственное, что можно сказать - это не делайте так!
С уважением,
Михаил Каганский

Lesha