Отраслевое решение на БСП, УФ, платформа 8.3.26.1540 (режим совместимости 8.3.21). Доработка идет в расширениях, насколько возможно.
Требуется хранить настраиваемое значение по умолчанию для заполнения новых документов.
(В данном конкретном случае: документ -- инвентарная опись, значение -- председатель и состав комиссии. Предполагается отражать только описи, проводимые в связи с определенным типом мероприятий, их (мероприятия) проводит только одно подразделение -- т.е. состав комиссии один и меняется редко.)
Чтобы редактировать такое значение, задал константе свою форму (см. вл.), создалась общая форма константы.
Предполагалось, что переводить значение константы в компоненты-реквизиты формы и обратно я буду в обработчиках ПриЧтенииНаСервере и ПередЗаписьюНаСервере. Однако, как выяснилось, для констант типа ХранилищеЗначения эти обработчики не вызываются! (Убедился, что дело не в отладчике. Если сменить тип константы на Строка, обработчики вызываются.)
Где тогда предполагается делать вышеуказанные операции? Есть ли какие-то рекомендации со стороны 1С? (Собственный поиск уже провел.) Насколько мне известно, например, при стандартной команде "обновить" ничего, кроме "ПриЧтенииНаСервере", не вызывается -- т.е. код в любом другом месте будет неадекватным решением.
(1) При создании на сервере вызывается? - вот там получай значение и заполняй форму.
Добавь свою кнопку для записи значения в константу.
Либо в ПередЗаписью/ПослеЗаписи добавь свою процедуру для записи значения в константу.
(4) ТЧ - реквизит формы можно передавать как параметр в серверную функцию без контекста, только надо написать Знач.
Если ТЧ не будет редактироваться на сервере, это решает задачу.
(1) При создании на сервере вызывается? - вот там получай значение и заполняй форму.
Добавь свою кнопку для записи значения в константу.
Либо в ПередЗаписью/ПослеЗаписи добавь свою процедуру для записи значения в константу.
(2) Пытаясь реализовать предложенное, выяснил, что в ПередЗаписью/ПослеЗаписи формы константы нельзя делать контекстные серверные вызовы. А вызвать метод "Выгрузить()" табличного реквизита формы можно только там.
Можно, конечно, выгрузить ТЧ в массив структур и передать его в неконтекстный вызов как параметр (так сделал сейчас, точнее, выгрузил в просто массив, т.к. у меня (пока) только одна колонка) либо сделать собственную кнопку записи -- но это явно костыли.
Примечание:
В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере, а также изменять свойства, которые могут привести к серверному вызову.
(6) Да, по прикидкам, написание обработки будет ненамного более трудоемким.
Главный минус -- нельзя будет выдавать форму для работы с константой по ПоказатьЗначение() или ОткрытьФорму("Константа.<...>.ФормаКонстант").
Своя команда сохранения (точнее, две -- "Записать" и "ЗаписатьИЗакрыть") -- довольно большой костыль. В частности, перестанет работать "Форма.Записать()". К счастью, удалось обойтись намного меньшим костылем (см. (10)).
(4) ТЧ - реквизит формы можно передавать как параметр в серверную функцию без контекста, только надо написать Знач.
Если ТЧ не будет редактироваться на сервере, это решает задачу.
Вот, похоже, к-во костылей сделано минимально возможным:
модуль формы:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Перем Значение;
// Для константы типа ХранилищеЗначения не вызывается ПриЧтенииНаСервере()
Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Распаковать();
ЭтотОбъект.ПредседательКомиссии = Значение.ПредседательКомиссии;
ЭтотОбъект.ЧленыКомиссии.Загрузить(Значение.ЧленыКомиссии);
КонецПроцедуры
&НаСервереБезКонтекста
Процедура ПередЗаписьюНаСервере(Знач ПредседательКомиссии, Знач ЧленыКомиссии)
Перем Значение;
Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.ЗначениеПоУмолчанию();
Значение.ПредседательКомиссии = ПредседательКомиссии;
Значение.ЧленыКомиссии = ЧленыКомиссии.Выгрузить();
Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Упаковать(Значение);
КонецПроцедуры
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
// Для константы типа ХранилищеЗначения не вызывается ПередЗаписьюНаСервере()
// В ПередЗаписью нельзя делать контекстные серверные вызовы
ПередЗаписьюНаСервере(ЭтотОбъект.ПредседательКомиссии,
ЭтотОбъект.ЧленыКомиссии);
КонецПроцедуры
Показать
модуль менеджера:
// Распаковать в структуру
//
// Возвращаемое значение:
// Структура - см. ЗначениеПоУмолчанию
//
Функция Распаковать() Экспорт
Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Получить().Получить();
Если Не ЗначениеЗаполнено(Значение) Тогда
Значение = ЗначениеПоУмолчанию();
КонецЕсли;
Возврат Значение;
КонецФункции
// Упаковать из структуры
//
// Параметры:
// Значение - см. ЗначениеПоУмолчанию
//
Процедура Упаковать(Знач Значение) Экспорт
Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Установить(
Новый ХранилищеЗначения(Значение));
КонецПроцедуры
Функция ЗначениеПоУмолчанию() Экспорт
Перем ЧленыКомиссии;
ЧленыКомиссии = Новый ТаблицаЗначений;
ЧленыКомиссии.Колонки.Добавить("ЧленКомиссии",Новый ОписаниеТипов("СправочникСсылка.Сотрудники"));
Возврат Новый Структура("ПредседательКомиссии,ЧленыКомиссии",
Справочники.Сотрудники.ПустаяСсылка(),
ЧленыКомиссии);
КонецФункции
Показать
модуль менеджера значения:
Процедура ПередЗаписью(Отказ)
Перем Значение_;
Значение_ = ЭтотОбъект.Значение.Получить();
Образец = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.ЗначениеПоУмолчанию();
Если ТипЗнч(Значение_) <> ТипЗнч(Образец)
Или Значение_.Количество() <> Образец.Количество()
Или ТипЗнч(Значение_.ПредседательКомиссии) <> ТипЗнч(Образец.ПредседательКомиссии)
Или ТипЗнч(Значение_.ЧленыКомиссии) <> ТипЗнч(Образец.ЧленыКомиссии)
Или Не ОбщегоНазначения.КоллекцииИдентичны(Значение_.ЧленыКомиссии.Колонки, Образец.ЧленыКомиссии.Колонки, "Имя,ТипЗначения")
Тогда
Отказ = Истина;
// передача неверного типа, скорее всего -- ошибка программиста, а не пользователя
ВызватьИсключение(НСтр("ru = 'Неверный тип или структура значения'"));
КонецЕсли;
КонецПроцедуры