Чтение и запись (распаковка и упаковка) константы типа ХранилищеЗначения в форме константы

1. native-api 19 12.05.25 10:19 Сейчас в теме
Отраслевое решение на БСП, УФ, платформа 8.3.26.1540 (режим совместимости 8.3.21). Доработка идет в расширениях, насколько возможно.

Требуется хранить настраиваемое значение по умолчанию для заполнения новых документов.
(В данном конкретном случае: документ -- инвентарная опись, значение -- председатель и состав комиссии. Предполагается отражать только описи, проводимые в связи с определенным типом мероприятий, их (мероприятия) проводит только одно подразделение -- т.е. состав комиссии один и меняется редко.)

Согласно Общие сведения об организации хранения данных :: Организация хранения данных :: Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8, наиболее подходящей сущностью выглядит константа. А поскольку хранимые данные -- структура (ссылка + массив ссылок), единственный подходящий тип -- ХранилищеЗначения.

Чтобы редактировать такое значение, задал константе свою форму (см. вл.), создалась общая форма константы.

Предполагалось, что переводить значение константы в компоненты-реквизиты формы и обратно я буду в обработчиках ПриЧтенииНаСервере и ПередЗаписьюНаСервере. Однако, как выяснилось, для констант типа ХранилищеЗначения эти обработчики не вызываются! (Убедился, что дело не в отладчике. Если сменить тип константы на Строка, обработчики вызываются.)

Где тогда предполагается делать вышеуказанные операции? Есть ли какие-то рекомендации со стороны 1С? (Собственный поиск уже провел.) Насколько мне известно, например, при стандартной команде "обновить" ничего, кроме "ПриЧтенииНаСервере", не вызывается -- т.е. код в любом другом месте будет неадекватным решением.
Найденные решения
2. Sashares 33 12.05.25 10:32 Сейчас в теме
(1) При создании на сервере вызывается? - вот там получай значение и заполняй форму.
Добавь свою кнопку для записи значения в константу.
Либо в ПередЗаписью/ПослеЗаписи добавь свою процедуру для записи значения в константу.
native-api; +1 Ответить
9. Sashares 33 13.05.25 17:13 Сейчас в теме
(4) ТЧ - реквизит формы можно передавать как параметр в серверную функцию без контекста, только надо написать Знач.
Если ТЧ не будет редактироваться на сервере, это решает задачу.
native-api; +1 Ответить
Остальные ответы
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
2. Sashares 33 12.05.25 10:32 Сейчас в теме
(1) При создании на сервере вызывается? - вот там получай значение и заполняй форму.
Добавь свою кнопку для записи значения в константу.
Либо в ПередЗаписью/ПослеЗаписи добавь свою процедуру для записи значения в константу.
native-api; +1 Ответить
3. native-api 19 12.05.25 10:57 Сейчас в теме
(2) Меня смущало, что стандартная команда УФ "Обновить" вызывает только "ПриЧтенииНаСервере".

Но оказывается, в форме константы этой команды нет!
Тогда все в порядке!
4. native-api 19 13.05.25 16:40 Сейчас в теме
(2) Пытаясь реализовать предложенное, выяснил, что в ПередЗаписью/ПослеЗаписи формы константы нельзя делать контекстные серверные вызовы. А вызвать метод "Выгрузить()" табличного реквизита формы можно только там.

Можно, конечно, выгрузить ТЧ в массив структур и передать его в неконтекстный вызов как параметр (так сделал сейчас, точнее, выгрузил в просто массив, т.к. у меня (пока) только одна колонка) либо сделать собственную кнопку записи -- но это явно костыли.
5. Sashares 33 13.05.25 16:47 Сейчас в теме
(4)
выяснил, что в ПередЗаписью/ПослеЗаписи формы константы нельзя делать контекстные серверные вызовы.


Кто запрещает?
Замени стандартную кнопку записи на свою и делай любые вызовы.
7. spacecraft 13.05.25 17:03 Сейчас в теме
(5)
Кто запрещает?

СП )
Примечание:
В обработчике данного события нельзя использовать серверные методы формы с директивой компиляции &НаСервере, а также изменять свойства, которые могут привести к серверному вызову.
8. Sashares 33 13.05.25 17:10 Сейчас в теме
(7) Действительно, спасибо)
6. spacecraft 13.05.25 17:01 Сейчас в теме
(4) создать обработку для работы с константой.
Или на форме константы использовать свою команду сохранения.
11. native-api 19 14.05.25 11:55 Сейчас в теме
(6) Да, по прикидкам, написание обработки будет ненамного более трудоемким.
Главный минус -- нельзя будет выдавать форму для работы с константой по ПоказатьЗначение() или ОткрытьФорму("Константа.<...>.ФормаКонстант").

Своя команда сохранения (точнее, две -- "Записать" и "ЗаписатьИЗакрыть") -- довольно большой костыль. В частности, перестанет работать "Форма.Записать()". К счастью, удалось обойтись намного меньшим костылем (см. (10)).
9. Sashares 33 13.05.25 17:13 Сейчас в теме
(4) ТЧ - реквизит формы можно передавать как параметр в серверную функцию без контекста, только надо написать Знач.
Если ТЧ не будет редактироваться на сервере, это решает задачу.
native-api; +1 Ответить
10. native-api 19 14.05.25 11:13 Сейчас в теме
Вот, похоже, к-во костылей сделано минимально возможным:

модуль формы:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	Перем Значение;
	// Для константы типа ХранилищеЗначения не вызывается ПриЧтенииНаСервере()
	Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Распаковать();
	ЭтотОбъект.ПредседательКомиссии = Значение.ПредседательКомиссии;
	ЭтотОбъект.ЧленыКомиссии.Загрузить(Значение.ЧленыКомиссии);
КонецПроцедуры

&НаСервереБезКонтекста
Процедура ПередЗаписьюНаСервере(Знач ПредседательКомиссии, Знач ЧленыКомиссии)
	Перем Значение;
	Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.ЗначениеПоУмолчанию();
	Значение.ПредседательКомиссии = ПредседательКомиссии;
	Значение.ЧленыКомиссии = ЧленыКомиссии.Выгрузить();
	
	Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Упаковать(Значение);
КонецПроцедуры

&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
	// Для константы типа ХранилищеЗначения не вызывается ПередЗаписьюНаСервере()
	// В ПередЗаписью нельзя делать контекстные серверные вызовы
	ПередЗаписьюНаСервере(ЭтотОбъект.ПредседательКомиссии,
			ЭтотОбъект.ЧленыКомиссии);
КонецПроцедуры
Показать


модуль менеджера:

// Распаковать в структуру
//
// Возвращаемое значение:
//   Структура  - см. ЗначениеПоУмолчанию
//
Функция Распаковать() Экспорт
	Значение = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Получить().Получить();
	Если Не ЗначениеЗаполнено(Значение) Тогда
		Значение = ЗначениеПоУмолчанию();
	КонецЕсли;
	Возврат Значение;
КонецФункции

// Упаковать из структуры
//
// Параметры:
//  Значение  - см. ЗначениеПоУмолчанию
//
Процедура Упаковать(Знач Значение) Экспорт
	Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.Установить(
		Новый ХранилищеЗначения(Значение));
КонецПроцедуры

Функция ЗначениеПоУмолчанию() Экспорт
	Перем ЧленыКомиссии;
	ЧленыКомиссии = Новый ТаблицаЗначений;
	ЧленыКомиссии.Колонки.Добавить("ЧленКомиссии",Новый ОписаниеТипов("СправочникСсылка.Сотрудники"));
	Возврат Новый Структура("ПредседательКомиссии,ЧленыКомиссии",
			Справочники.Сотрудники.ПустаяСсылка(),
			ЧленыКомиссии);
КонецФункции
Показать


модуль менеджера значения:

Процедура ПередЗаписью(Отказ)
	Перем Значение_;
	Значение_ = ЭтотОбъект.Значение.Получить();
	Образец = Константы.Акр_СоставИнвентаризационнойКомиссииПоАккредитации.ЗначениеПоУмолчанию();
	
	Если ТипЗнч(Значение_) <> ТипЗнч(Образец)
		Или Значение_.Количество() <> Образец.Количество()
		Или ТипЗнч(Значение_.ПредседательКомиссии) <> ТипЗнч(Образец.ПредседательКомиссии)
		Или ТипЗнч(Значение_.ЧленыКомиссии) <> ТипЗнч(Образец.ЧленыКомиссии)
		Или Не ОбщегоНазначения.КоллекцииИдентичны(Значение_.ЧленыКомиссии.Колонки, Образец.ЧленыКомиссии.Колонки, "Имя,ТипЗначения")
	Тогда
		Отказ = Истина;
		// передача неверного типа, скорее всего -- ошибка программиста, а не пользователя
		ВызватьИсключение(НСтр("ru = 'Неверный тип или структура значения'"));
	КонецЕсли;
КонецПроцедуры
Показать
Оставьте свое сообщение

Для получения уведомлений об ответах подключите телеграм бот:
Инфостарт бот