Изменение реквизитов существующих объектов (документов) 1С без сохранения

При решении очередной задачи столкнулся с тем, что менеджерам (сотрудникам) необходимо часто менять реквизиты существующих объектов. Это дополнительные реквизиты или сведения объектов. При этом действия менеджеров не должны приводить к перепроведению документов или пересохранению объектов, т.к. изменения могут быть в закрытых периодах. Изменение данных в реквизитах должны быть доступны в закрытых периодах и не влиять на финансовые и бухгалтерские данные.

Предвосхищая предложения коллег, спешу ответить на вопрос, — почему не воспользоваться стандартным механизмом БСП дополнительных сведений и реквизитов?

Дело в том, что сотрудники компании – это пользователи, которым надо, помимо прочего, чтобы поле дополнительных реквизитов было в определенном месте на основной форме элемента.

Вот такие требования. В итоге я решил реализовать дополнительный функционал внутри конфигурации, позволяющий сделать это достаточно быстро и удобно. Решение также будет удобно использовать в расширениях конфигурации. В примере не делаю акцент на чистоту кода, поэтому делаю вкрапления кода в типовые процедуры. Для своих решений можно вынести куски кода в отдельные процедуры. Регистр сведений тоже можно доработать и сделать более универсальным. Как пример дополнительные сведения из БСП.

Привожу пример изменения конфигурации.

Нам потребуется добавить регистр сведений — «ДополнительныеРеквизитыДокументов».

Свойства регистра: Непериодический, независимый.

Независимым его необходимо сделать, т.к. объектами  с дополнительным реквизитом может быть любой объект – Документ, Справочник, План счетов или ПВХ.

Измерения:

  • ДокументСсылка – имеющий тип, объекты для которых необходим реквизит;

Синоним «Документ»

Ресурсы:

  • ОригиналПолучен – тип «Булево»;

Синоним «Оригинал получен»

В модуле менеджера накидываем процедуры и функции для работы с записями регистра

// Формирует структуру записи регистра
//
// Параметры:
//
// Возвращаемое значение:
//   <Структура>   - структурированные параметры записи регистра
//
Функция ПолучитьСтруктуруРегистра() Экспорт

Возврат Новый Структура("ДокументСсылка, ОригиналПолучен");

КонецФункции // ПолучитьСтруктуруРегистра()

// <Производит запись в регистр по заданой структуре
//
// Параметры:
//  <СтруктураЗаписи>  - <Структура> - структурированные параметры записи регистра
//
// Возвращаемое значение:
//   <Булево>   - признак успешной операции
//
Функция ЗаписатьВРегистрПоСтруктуре(СтруктураЗаписи) Экспорт

Успех = Истина;

ЗаписьРегистра = РегистрыСведений.ДополнительныеРеквизитыДокументов.СоздатьМенеджерЗаписи();
ЗаполнитьЗначенияСвойств(ЗаписьРегистра, СтруктураЗаписи);
Попытка
ЗаписьРегистра.Записать(Истина);
Исключение
ОписаниеОшибки = ОписаниеОшибки();
Успех = Ложь;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = ОписаниеОшибки;
Сообщение.Сообщить();
КонецПопытки;

Возврат Успех;

КонецФункции // ЗаписатьВРегистрПоСтруктуре()

// <Заполняет структуру полученными из базы параметрами>
//
// Параметры:
//  <СтруктураЗаписи>  - <Структура> - структурированные параметры записи регистра
//
Процедура ПолучитьДополнительныеРеквизитаДокумента(СтруктураЗаписи) Экспорт

Если Не ЗначениеЗаполнено(СтруктураЗаписи["ДокументСсылка"]) Тогда
СтруктураЗаписи["ОригиналПолучен"] = Ложь;
Возврат;
КонецЕсли;
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ

|             ДополнительныеРеквизитыДокументов.ДокументСсылка КАК ДокументСсылка,

|             ДополнительныеРеквизитыДокументов.ОригиналПолучен КАК ОригиналПолучен

|ИЗ

|             РегистрСведений.ДополнительныеРеквизитыДокументов КАК ДополнительныеРеквизитыДокументов

|ГДЕ

|             ДополнительныеРеквизитыДокументов.ДокументСсылка = &ДокументСсылка";

// Установка параметров
Запрос.УстановитьПараметр("ДокументСсылка", СтруктураЗаписи["ДокументСсылка"]);
// Выполнение запроса
Результат = Запрос.Выполнить();
// Проверка результатов
Если НЕ Результат.Пустой() Тогда
Выборка = Результат.Выбрать();
Выборка.Следующий();
ЗаполнитьЗначенияСвойств(СтруктураЗаписи, Выборка);
Иначе
СтруктураЗаписи["ОригиналПолучен"] = Ложь;
КонецЕсли;

КонецПроцедуры // ПолучитьДополнительныеРеквизитаДокумента()

 

Основной функционал для работы с регистром готов. Теперь надо внести изменения в модули форм объектов.

 

В форме объекта изменяю процедуру «ПриСозданииНаСервере»

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

//...
// Различный код типовых конфигураций
//...

// Доработка под дополнительный реквизит

мРеквизитыДобавить = Новый Массив;
Реквизит = Новый РеквизитФормы("Доп_ОригиналПолучен", Новый ОписаниеТипов("Булево"), "", "Оригинал получен", Ложь);
мРеквизитыДобавить.Добавить(Реквизит);
ИзменитьРеквизиты(мРеквизитыДобавить);
НовыйЭлем = Элементы.Добавить("ФормаДоп_ОригиналПолучен", Тип("ПолеФормы"));
НовыйЭлем.Вид = ВидПоляФормы.ПолеФлажка;
НовыйЭлем.ПутьКДанным = "Доп_ОригиналПолучен";
НовыйЭлем.Заголовок = "Оригинал получен";
НовыйЭлем.ПоложениеЗаголовка = ПоложениеЗаголовкаЭлементаФормы.Авто;
НовыйЭлем.УстановитьДействие("ПриИзменении", "Обработчик_ОригиналПолученПриИзменении");
Если ЗначениеЗаполнено(Объект.Ссылка) Тогда
СтруктураЗаписи = РегистрыСведений.ДополнительныеРеквизитыДокументов.ПолучитьСтруктуруРегистра();
СтруктураЗаписи["ДокументСсылка"] = Объект.Ссылка;
РегистрыСведений.ДополнительныеРеквизитыДокументов.ПолучитьДополнительныеРеквизитаДокумента(СтруктураЗаписи);
ЭтаФорма["Доп_ОригиналПолучен"] = СтруктураЗаписи["ОригиналПолучен"];
КонецЕсли;

// конец

КонецПроцедуры

 

Вношу изменения в процедуру «ПослеЗаписи»

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)

//...
// Различный код типовых конфигураций
//...

// Доработка под дополнительный реквизит

Подключаемый_ЗаписатьДополнительныеРеквизитыНаКлиенте();

// конец
КонецПроцедуры

 

Дописываю свои процедуры и обработчики в этой же форме объекта

&НаКлиенте
Процедура Обработчик_ОригиналПолученПриИзменении(Элемент)

Если Не ЗначениеЗаполнено(Объект.Ссылка) Тогда
Возврат;
КонецЕсли;
Подключаемый_ЗаписатьДополнительныеРеквизитыНаКлиенте();

КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ЗаписатьДополнительныеРеквизитыНаКлиенте()

Подключаемый_ЗаписатьДополнительныеРеквизитыНаСервере();
ОповеститьОбИзменении(Объект.Ссылка);

КонецПроцедуры // Подключаемый_ЗаписатьДополнительныеРеквизитыНаКлиенте()

&НаСервере
Процедура Подключаемый_ЗаписатьДополнительныеРеквизитыНаСервере()

СтруктураЗаписи = РегистрыСведений.ДополнительныеРеквизитыДокументов.ПолучитьСтруктуруРегистра();
СтруктураЗаписи["ДокументСсылка"] = Объект.Ссылка;
СтруктураЗаписи["ОригиналПолучен"] = ЭтаФорма["Доп_ОригиналПолучен"];
РегистрыСведений.ДополнительныеРеквизитыДокументов.ЗаписатьВРегистрПоСтруктуре(СтруктураЗаписи);

КонецПроцедуры // Подключаемый_ЗаписатьДополнительныеРеквизитыНаСервере()

Этого достаточно, чтобы начать работать с дополнительным реквизитом.

В дополнение привожу изменения кода для форы списка.

В форме списка изменяю процедуру «При созданииНаСервере»

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

//...
// Различный код типовых конфигураций
//...

// Доработка под дополнительный реквизит

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

//конец

КонецПроцедуры

 

А также вставляю свою дополнительную процедуру для формирования текста запроса списка

&НаСервереБезКонтекста
Функция Подключаемый_ПолучитьТекстЗапросаНаСервере()

Возврат "ВЫБРАТЬ
|    ДокументДокументТест.Ссылка КАК Ссылка,
|    ДокументДокументТест.ПометкаУдаления КАК ПометкаУдаления,
|    ДокументДокументТест.Номер КАК Номер,
|    ДокументДокументТест.Дата КАК Дата,
|    ДокументДокументТест.Проведен КАК Проведен,
|    ДокументДокументТест.ТектовыйРеквизит КАК ТектовыйРеквизит,
|    ДокументДокументТест.МоментВремени КАК МоментВремени,
|    ЕСТЬNULL(ДополнительныеРеквизитыДокументов.ОригиналПолучен, ЛОЖЬ) КАК ОригиналПолучен
|ИЗ
|    Документ.ДокументТест КАК ДокументДокументТест
|                    ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДополнительныеРеквизитыДокументов КАК ДополнительныеРеквизитыДокументов
|                    ПО ДополнительныеРеквизитыДокументов.ДокументСсылка = ДокументДокументТест.Ссылка";

КонецФункции

 

Данное решение можно тиражировать. При необходимости, требуется не много времени для реализации и добавления в другие объекты.

Пример реализации приведен в базе, которая доступна для скачивания. Реализация для платформы 8.3.13 и выше.

8 Comments

  1. VmvLer

    — создать обработку с выбором дополнительных реквизитов или сведения объектов.

    — записывать только их.

    Reply
  2. BraunAlex

    (1)

    или сведения объектов

    А на форму в нужное место? Все равно конфигу менять.

    Reply
  3. VmvLer

    есть расширения же

    для эстетов в последних платформах создали всплывающие формы

    Reply
  4. BraunAlex

    (3)

    есть расширения же

    А кто против?

    Чем больше вариантов решения тем лучше

    Reply
  5. par_62

    По моему не надо огород городить, а создать отдельную форму длкумента и воспользоватьмя БСП шными доп реквизитами и идентификаторами для разработчиков ( ежели таковая есть).

    Добавить свою пописку на процедуру менеджера документа по получению формы. Создать привязки форм к пользователям. А в этой форме уже размещать доп реквизиты и т.п. как угодно.

    Reply
  6. BraunAlex

    (5)

    По моему не надо огород городить, а создать отдельную форму длкумента

    В стандартных конфигурациях в модуле формы может быть типовой код. Строк типового кода может быть от 0 до ОченьМногоСтрокКода. Их надо поддерживать и не терять типовую функциональность от дистрибьютора.

    Твое предложение увеличивает расходы на поддержку конфигурации, Даже если это будет расширение.

    Reply
  7. par_62

    Ок. Но есть и обратная сторона. Обычно кроме этих реквизитов в дальнейшем потребуется и доп функционал. По крайней мере, в моей практике это постоянно. Начинается также как описал аатор, а затем входят во вкус- нужны доп контроли, регистрации и тому подобное. Согласен,если использовать описанное в статье к общим вопросам ,тогда может и так

    Reply
  8. BraunAlex

    (7)

    а затем входят во вкус- нужны доп контроли, регистрации и тому подобное

    Аппетит приходит во время еды.

    Я не претендую на «Самое крутое решение». Это один из вариантов, который пока что работает (уже более года)

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *