Заблокировать работу с документом на время работы макроса

Автор ForumOOo (бот), 30 ноября 2016, 20:33

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

JohnSUN

#15
Да, я об этом варианте тоже подумал, но решил, что формула =A1 выглядит все-таки не так страшно, как =SUM(A1)  ;)
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

mikekaganski

#16
Как это будет работать, если CountUsr > 30?

EDIT: вроде работает, если число аргументов SUM больше 30.
С уважением,
Михаил Каганский

JohnSUN

#17
На худой конец остается вариант с SUMIF или SUMPRODUCT от диапазона, полученного через OFFSET и прореженного с помощью чего-то типа MOD(COLUMN(диапазона суммирования);CountUsers)=чего-то там такое, связанное с текущей колонкой... Формула будет зубодробительной, но зато параметров будет гораздо меньше тридцати
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Alex16

Цитата: mikekaganski от  3 декабря 2016, 12:20Как это будет работать, если CountUsr > 30?
Почему вопрос возник с числом 30? Есть место быть какому-то подвоху?

Продолжу тему с блокировкой.... или не пойму с чем связано:

Есть вот такой момент кода:

Sub BeginUpdateRep
ThisReport.isUndoEnabled=False
if shtReport.isProtected() Then shtReport.unprotect(Pass)
sViewData = ThisReport.GetCurrentController.GetViewData()
ThisReport.lockControllers()
ThisReport.AddActionLock()
End Sub

Sub EndUpdateRep
ThisReport.RemoveActionLock()
ThisReport.UnlockControllers()
ThisReport.getCurrentController.RestoreViewData(sViewData)
shtReport.protect(Pass)
ThisReport.isUndoEnabled=True
End Sub

и далее где-то в коде есть вот такой вызов
....
BeginUpdateRep
LoadRep(I)
EndUpdateRep
.....


Так вот после выполнения, почему-то формулы типа =SUM(G15;M15;S15) не работают. После выполнения кода нажимаем F9 и все считается.
Но если закомментировать:
....
'BeginUpdateRep
LoadRep(I)
'EndUpdateRep
.....

Формулы начинают работать верно, но тормоза.... Из-за чего это может быть?
Хотел сделать тестовый файл, с примерным кодом, но в нем все работает как положено.

mikekaganski

#19
Цитата: Alex16 от  5 декабря 2016, 08:06Почему вопрос возник с числом 30? Есть место быть какому-то подвоху?

Если честно - моя лень.
В описании функции SUM указано, что число аргументов - до 30. Я проверил с 32 - работает. Но мне лень лезть в код и смотреть, как там реализовано и можно ли реально туда передавать любое число аргументов.

Цитата: Alex16 от  5 декабря 2016, 08:06Продолжу тему с блокировкой.... или не пойму с чем связано:
...

https://forum.openoffice.org/en/forum/viewtopic.php?f=45&t=54868

EDIT: для того, чтобы пересчитать только "dirty cells" (F9), используйте не ThisComponent.calculateAll() (Ctrl+Shift+F9), а ThisComponent.calculate().

http://opengrok.libreoffice.org/xref/core/offapi/com/sun/star/sheet/XCalculatable.idl
С уважением,
Михаил Каганский

rami

Цитата: mikekaganski от  5 декабря 2016, 08:15В описании функции SUM указано, что число аргументов - до 30. Я проверил с 32 - работает. Но мне лень лезть в код и смотреть, как там реализовано и можно ли реально туда передавать любое число аргументов.
Тридцатый аргумент забирает все оставшиеся лишними аргументы, до определённого предела это может работать, потом будет всякая ересь.

JohnSUN

#21
Цитата: Alex16 от  5 декабря 2016, 10:06
Почему вопрос возник с числом 30? Есть место быть какому-то подвоху?
Ну, скажем так - "долгое время было место подвоху"  ;D
Долгое время любые обсуждения проблем с вычислениями в Calc начинались с заявления "А вот в Экселе то-то и то-то..." Это сильно раздражало и продвинутых пользователей, и разработчиков, и просто фанатов. А некоторых просто бесило. Но, тем не менее, заставляло разработчиков "гнаться за совместимостью" - делать всё похожим на Эксель. А в Экселе, например, долгое время количество параметров во встроенной функции было ограничено именно тридцатью штуками.
Времена изменились, сейчас это ограничение выросло (если верить справке) до 255, пользователи задавая вопросы уже пишут "А вот в Гугль-Таблицах то-то и то-то...", а старые п... п... профессионалы типа меня, mikekaganski (и, мне так почему-то кажется - остальные ветераны тоже) опасаются вводить много параметров в функцию. Мало того, что можешь превысить какой-то лимит, так еще и читать-перечитывать потом эту бесконечную "портянку" замучаешься.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Alex16

Цитата: mikekaganski от  5 декабря 2016, 08:15ThisComponent.calculate().
Спасибо Всё заработало как надо

А у меня вопрос еще по процедурам BeginUpdateRep и EndUpdateRep код которых выше. Правильно ли последовательность вызовов в них, но больше вопрос по предоставленной JohnSUN фишке
sViewData = ThisReport.GetCurrentController.GetViewData()
Я снова использовал глобальную для этого переменную. Верно ли это или можно как-то так:

Sub BeginUpdateRep
ThisReport.isUndoEnabled=False
if shtReport.isProtected() Then shtReport.unprotect(Pass)
ThisReport.lockControllers()
ThisReport.AddActionLock()
End Sub

Sub EndUpdateRep
ThisReport.RemoveActionLock()
ThisReport.UnlockControllers()
ThisReport.getCurrentController.RestoreViewData(ThisReport.GetCurrentController.GetViewData())
shtReport.protect(Pass)
ThisReport.isUndoEnabled=True
End Sub

Но это: ThisReport.getCurrentController.RestoreViewData(ThisReport.GetCurrentController.GetViewData()) мне кажется какой-то бред

JohnSUN

#23
Ну, почему сразу "бред"? "Есть много в программировании такого, друг Горацио, что и не снилось нашим" (с) кажется, Шекспир в переводе Аникста.
Иногда попадаются варианты с переприсвоением, которые на первый взгляд выглядят странно.
Например, такой оператор ThisField.Anchor.String = ThisField.Anchor.String

Цитата: Alex16 от  5 декабря 2016, 15:04
А у меня вопрос еще по процедурам BeginUpdateRep и EndUpdateRep код которых выше. Правильно ли последовательность вызовов в них
Ну, в принципе все верно - всё, что блокировалось и запрещалось, в нужный момент разрешается и разблокируется в обратном порядке...

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

Alex16

Цитата: JohnSUN от  5 декабря 2016, 13:36Просто попробуй - если работает, значит некоторое время и дальше будет работать...
Успокоил :)
Цитата: JohnSUN от  5 декабря 2016, 13:36Например, такой оператор ThisField.Anchor.String = ThisField.Anchor.String
На это я уже натыкался, может быть по этому у меня и возникло это: ThisReport.getCurrentController.RestoreViewData(ThisReport.GetCurrentController.GetViewData())

Т.е. предлагаете избавится от гоблинской переменной?)

JohnSUN

Цитата: Alex16 от  5 декабря 2016, 15:50
ThisReport.getCurrentController.RestoreViewData(ThisReport.GetCurrentController.GetViewData())
Т.е. предлагаете избавится от гоблинской переменной?)
Предлагаю попробовать три варианта: оставить переменную, избавиться от неё и закомментировать эту строку вообще. И сообщить народу результат. Чтоб знали.

А вот от точек в операторах лучше избавляйся. Могу рассказать старую легенду (или это был тост?) про методы и их вызовы. Но лучше просто поверь на слово: каждая точка - это лишний кусочек времени выполнения. Есть мнение, что тот же самый оператор, но записанный в две строки
oCurrentController = ThisReport.getCurrentController
oCurrentController.RestoreViewData(oCurrentController.GetViewData())

или в три строки
With ThisReport.getCurrentController
   .RestoreViewData(.GetViewData())
End With

или даже в пять строк
With ThisReport
   With .getCurrentController
      .RestoreViewData(.GetViewData())
   End With
End With
работает лучше оригинала. Врать не стану, этот конкретный пример не проверял, не до того сейчас, не уверен даже, что записано без ачепяток. Но когда-то давно ставил эксперименты на эту тему и убедился, что в этом предрассудке что-то кроется, не на пустом месте он появился
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

mikekaganski

Цитата: JohnSUN от  5 декабря 2016, 16:11А вот от точек в операторах лучше избавляйся.
+++
Цитата: JohnSUN от  5 декабря 2016, 16:11
With ThisReport.getCurrentController
   .RestoreViewData(.GetViewData())
End With

В данном случае предпочтительно по сравнению с 5-строчным вариантом, поскольку невозможна неоднозначность при совпадении названий методов/свойств объектов ThisReport и getCurrentController, а эффективность одинаковая (однократный доступ к текущему контроллеру).
С уважением,
Михаил Каганский

JohnSUN

Ну да. Но пятистрочный вариант хорош для отладки - когда с сообщением "объект нот фаунд" бэйсик выделяет строку
With ThisReport.getCurrentController, у тебя два варианта: или getCurrentController вернул null-Nothing-Empty, или сам ThisReport не объект, а, скажем, число 3.62.
Владислав Орлов aka JohnSUN
Благодарить-не зазорно.
Подарить благо создателям офиса, нашему ресурсу, мне

Alex16

Цитата: Alex16 от  5 декабря 2016, 13:04ThisComponent.calculate().
Спасибо Всё заработало как надо
Оказалось не совсем так. Не все формулы обновляются. Причем по F9 тоже самое, но если выделить ячейку с "кривым результатом" формулы и нажать F9 то ячейка пересчитывается как надо.
ThisComponent.calculateAll() - обновляет все, и в том числе что не нужно (Список на листе) :( так что он не подходит
Как это обойти?
Хотя как вариант после calculateAll восстановить список, но может есть еще решение - обновить все ячейки с формулами?

mikekaganski

Не пробовал, но измышляю: попробуйте пройти по нужным (изменённым?) ячейкам и вызвать calculate() для них. Либо внутри, либо вне Begin/EndUpdateRep (надо поэкспериментировать).
С уважением,
Михаил Каганский