Kopusha
Участник

Offline
Сообщений: 13
|
Добрый день!
Необходимо, чтобы пользователь не мог изменить содержимое конкретной ячейки. Не подскажите, как это можно сделать.
|
|
|
Записан
|
|
|
|
JohnSUN
|
Гм... Вообще-то это делается через Формат-Ячейки (Ctrl+1) и на вкладке Защита ячейки установить нужные флажки. После этого - Сервис-Защитить документ-ЛистНо почему этот вопрос в бэйсике? Защиту нужно устанавливать динамически?
|
|
|
Записан
|
|
|
|
Kopusha
Участник

Offline
Сообщений: 13
|
Если бы всё было так просто. Есть документ с данными, последняя строка содержит хитрую формулу, которая считает сумму по различным критериям. Пользователи всегда её удаляют, поэтому надо защитить эту ячейку. Проблема в том, что количество строк в документе изменяется. Туда надо добавлять или удалять оттуда строки. Если сделать эту ячейку защищенной, то удаление или добавление строк будет приводить к ошибке. Тема по ссылке про другое.
В VBA все просто, делаешь обработчик изменения изменения данных на листе. если адрес изменяемой ячейки совпадает с адресом ячейки с формулой, то изменения отменяются. как сделать тут - я фик знает.
|
|
« Последнее редактирование: 13 Октябрь 2011, 07:41 от Kopusha »
|
Записан
|
|
|
|
Kopusha
Участник

Offline
Сообщений: 13
|
По ссылке нашёл такую штуку Sub AddChartDataListener() oCell1 = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("Form") oListener = CreateUnoListener("MyApp_", "com.sun.star.chart.XChartDataChangeEventListener") oCell1.addChartDataChangeEventListener(oListener) End Sub
Sub MyApp_chartDataChanged(oEvent) dCell = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("Form") MsgBox dCell.String 'dCell.Value End Sub Но тут вывод нового значения после изменения. А мне надо, чтобы отменить это изменение. Надеюсь понятно выражаюсь 
|
|
|
Записан
|
|
|
|
JohnSUN
|
Слушай, а может попробовать другой подход? Ну, как вариант: 1. Все-таки защитить лист от изменений. Жестко. С каким-нибудь жутким паролем. Пользователь при этом потеряет возможность удалить строку с хитрым суммированием. При этом потеряется возможность удалять-добавлять и другие строки. Но вот тут-то макросом можно компенсировать эту потерю: две кнопки с картинками "плюс" и "минус", каждая из которых будет запускать свой макрос - или вставка новой строки перед строкой с неудаляемой формулой (если там еще нет пустой строки), или удаление текущей строки (если текущая строка в диапазоне, из которого можно удалять). Преимущества: лишних строк всегда будет не больше одной и хитрое суммирование всегда будет на месте; макрос запускается не по каждому событию, а только по нажатиям кнопок. Недостаток: Если таблица высокая, а кнопки для вставки-удаления строк разместить вверху, то работать будет не очень удобно - кнопки будут уползать за край окна. Впрочем, если закрепить верх таблицы вместе с кнопками на экране (Окно - Фиксировать), то проблема отпадает.
2. Не запрещать пользователю удалять-добавлять что угодно. Но по событиям "Перед печатью", "Перед сохранением" и "При открытии" запускать макрос, который просто проверит содержимое последней заполненной строки (или ячейки?) и если там нет нашей формулы - нахально допишет её. Преимущества: никаких лишних кнопок на таблице; опять-таки макрос крутится не постоянно, а срабатывает только в нужные моменты; привязка к событиям делается штатными средствами. Недостаток: насколько я знаю наших пользователей, они и при такой организации таблицы ухитрятся всё поломать. Например, запретят использование макросов.
PS. В том макросе, который ты процитировал, используется слушатель события "изменились данные для диаграммы". Для запрета каких-либо действий лучше использовать слушатель-"держиморду" (XVetoableChangeListener). Разница не очень велика, но вроде как этот самый "VetoableChange" предназначен именно для наложения вето на запрещенные изменения....
|
|
« Последнее редактирование: 13 Октябрь 2011, 09:38 от JohnSUN »
|
Записан
|
|
|
|
RFJ
|
последняя строка содержит хитрую формулу Сделать ее первой. Делать строку с формулой последней идет от бумажной бухгалтерии. В электронной вычисления надо делать в первой.
|
|
|
Записан
|
|
|
|
RFJ
|
Пользователи всегда её удаляют Значит, она никому из пользователей не нужна. Тогда вынести ее на другой лист.
|
|
|
Записан
|
|
|
|
Kopusha
Участник

Offline
Сообщений: 13
|
Значит, она никому из пользователей не нужна. Тогда вынести ее на другой лист.
Если нет желания помочь, прошу не постить. Удаляют, потому что у них есть руки, которые только и ищут что бы такое удалить важное, чтобы потом можно было кого-нить обвинить в пропаже важных данных. Формула есть на отдельном листе, но каждый раз приходится править диапазон ячеек, из которого её считать, да и сам факт, что приходится её приходить и копипастить, если есть (я думаю) возможность просто запретить её удалять. Итог внизу - ну уж извините, директор привык, чтобы в распечатке строка итогов была внизу.
|
|
|
Записан
|
|
|
|
Kopusha
Участник

Offline
Сообщений: 13
|
VetoableChange почему-то роняет LibreOffice3.4.3 Sub AddVetoChangeListener() oCell1 = ThisComponent.getSheets().getByIndex(0).getCellRangeByName("Form") oListener = CreateUnoListener("MyApp_", "com.sun.star.chart.XVetoableChangeListener") oCell1.addChartDataChangeEventListener(oListener) End Sub вроде срабатывает нормально, но при изменении значения в ячейке (в моем случае меняю одно из значений, входящих в формулу, т.е. меняется само значение ячейки, а не формула в нём) LO без объяснений падает. Может как не так использую? функция MyApp_VetoableChange(oEvent) пустая, в ней ничего не писал.
|
|
|
Записан
|
|
|
|
JohnSUN
|
Там фишка в чем... Для регистрации XVetoableChangeListener нужно использовать не addChartDataChangeEventListener, а специальный addVetoableChangeListener
А можешь саму формулу хитрого суммирования показать? Может быть удастся её совместными усилиями переписать так, чтобы она не зависела от конкретного диапазона ячеек?
|
|
« Последнее редактирование: 13 Октябрь 2011, 11:03 от JohnSUN »
|
Записан
|
|
|
|
JohnSUN
|
Чуть подробнее о слушателях и событиях.
Сам Event, который передается в обработчик, в наш макрос, который что-то должен сделать по событию - это структура с несколькими полями. В случае ChartDataChange в эту структуру входят Type, StartColumn, EndColumn, StartRow и EndRow А в случае VetoableChangeListener у Event'а структура уже другая, PropertyChangeEvent. Там тоже пять полей, но это уже PropertyName, Further, PropertyHandle, OldValue и NewValue. Поэтому офис и путается, когда одному регистратору подсовывают другого слушателя.
|
|
|
Записан
|
|
|
|
RFJ
|
Нужен Listener, который следил бы за добавлением/удалением строк/столбцов. Нужен, если попытаются удалить строку с формулой! И использовать "именованные" диапазоны.
|
|
« Последнее редактирование: 13 Октябрь 2011, 12:15 от RFJ »
|
Записан
|
|
|
|
JohnSUN
|
А если формулу сотрут обычным Delete или Backspace? Или просто перезапишут на что-то другое?
|
|
|
Записан
|
|
|
|
RFJ
|
Всё работает на "com.sun.star.chart.XChartDataChangeEventListener" если каждый раз снова вставлять формулу myf= "=SUM(summa)" oCell=oSheet.getCellRangeByName("formula") oCell.setFormula(myf)
Нужен Listener, который следил бы за добавлением/удалением строк/столбцов. Нужен, если попытаются удалить строку с формулой! PS. В общем, всё весьма долго и нудно.
|
|
« Последнее редактирование: 13 Октябрь 2011, 12:19 от RFJ »
|
Записан
|
|
|
|
Kopusha
Участник

Offline
Сообщений: 13
|
а есть в OO подобие Wordовский variables, т.е. переменные, которые хранятся в самом документе. Типа таких глобальных переменных. Чтобы, допустим, хранить в ней текущее значение формулы. Т.е. при закрытии документа сохраняем туда формулу. Потом XChartDataChangeEventListener при срабатывании копирует её в нужную ячейку. при регистрации XVetoableChangeListener ступил  Регистрация XVetoableChangeListener требует указания параметра PropertyName типа String за которым он будет следить. Что мне туда указать, чтобы он следил и запрещал изменение/удаление формулы? Извиняюсь, но в OOBasic не шарю совсем, поэтому могу тупить 
|
|
|
Записан
|
|
|
|
|