Продолжу свои публикации по конфигурациям 1С. В этот раз опишу механизм исправления документов и регистров. Ранее уже писал статью Пример создания документа с движениями в ERP 2.5.7, где описывал создание документа в конфигурации ERP 2.5 и подключение его к подсистемам.
Т.к. каркас конфигурации у нас один - БСП, в этой статье я пропущу описание подключения к стандартным подсистемам.
В любом случае все создаваемые документы я по умолчанию подключаю к подсистемам "Даты запрета редактирования", "Префиксация документов и справочников", "Подключаемые команды", "Печать", "Отчеты" и "Управление доступом". Если документ делает движения, то добавляется отчет "Движения документа". Далее уже по ситуации и требованиям.
Пример создавался на моем тестовом решении задачи билета №1 экзамена "Специалист по ЗУП 3.1", поэтому возможно вы найдете что-то знакомое в названиях документов и регистров :)
Для начала опишу пользовательскую часть.
В форме проведенного документа у нас выводится надпись "Исправить".
При нажатии команды у нас открывается копия документа, где мы можем внести исправления. При проведении созданного документа-исправления, движения старого документа сторнируются, а сам исправленный документ становится недоступным для изменения.
Интересно при этом реализовано сохранение старых движений. В конфигурации создаются копии независимых непериодических регистров сведений с постфиксом "Испр". В них добавляются измерения "РегистраторИзмерение" и "ПериодИзмерение", если основной регистр периодический.
При проведении документа-исправления, оригинальные движения копируются в регистр (испр.), а при отмене исправления копируются обратно.
Итак. Как это сделано :)
У меня создан документ экз_ГрафикРаботВОсобыхУсловиях (График работ в особых условиях).
Который делает движения по непериодическому регистру сведений экз_ГрафикиРаботВоВредныхУсловиях (Графики работ во вредных условиях).
1. Добавить подписку на события "экз_ПолучитьПрежнийИсправленный"
Источник: | ДокументОбъект.экз_ГрафикРаботВОсобыхУсловиях |
---|---|
Событие: | ПередЗаписью |
Обработчик: | ИсправлениеПериодическихСведений.ПолучитьПрежнийИсправленный |
2. Добавить подписку на события "экз_ОтменитьИсправлениеПериодическихСведений"
Источник: | ДокументОбъект.экз_ГрафикРаботВОсобыхУсловиях |
---|---|
Событие: | ОбработкаУдаленияПроведения |
Обработчик: | ИсправлениеПериодическихСведений.ОтменитьИсправлениеПериодическихСведений |
3. Добавить в документ реквизит "ИсправленныйДокумент" с типом ДокументСсылка.экз_ГрафикРаботВОсобыхУсловиях
4. В подвал формы документа (группа где мы размещаем ответственного и комментарий) добавить группу "ГруппаИсправление"
5. В форме документа в событие "ПриСозданииНаСервере" добавим
Если Параметры.Ключ.Пустая() Тогда
ПриПолученииДанныхНаСервере();
КонецЕсли;
6. В форме документа в событие "ПриЧтенииНаСервере" добавим
ПриПолученииДанныхНаСервере();
7. И добавим саму процедуру ПриПолученииДанныхНаСервере()
&НаСервере
Процедура ПриПолученииДанныхНаСервере()
ИсправлениеДокументовЗарплатаКадры.ГруппаИсправлениеДополнитьФорму(
ЭтотОбъект, Истина, Истина, Ложь);
ИсправлениеДокументовЗарплатаКадры.ПрочитатьРеквизитыИсправления(ЭтотОбъект, "ПериодическиеСведения");
ИсправлениеДокументовЗарплатаКадрыКлиентСервер.УстановитьПоляИсправления(ЭтотОбъект, "ПериодическиеСведения");
КонецПроцедуры
8. В форме документа в событие ПослеЗаписиНаСервере добавим
Если Не ПараметрыЗаписи.Свойство("ЗакрытьПослеЗаписи") Или Не ПараметрыЗаписи.ЗакрытьПослеЗаписи Тогда
ИсправлениеДокументовЗарплатаКадры.ПрочитатьРеквизитыИсправления(ЭтотОбъект, "ПериодическиеСведения");
ИсправлениеДокументовЗарплатаКадрыКлиентСервер.УстановитьПоляИсправления(ЭтотОбъект, "ПериодическиеСведения");
КонецЕсли;
9. В форме документа в событии "ОбработкаОповещения" добавим
ИсправлениеДокументовЗарплатаКадрыКлиент.ОбработкаОповещения(ЭтотОбъект, ИмяСобытия, Параметр, Источник);
10. В форме документа добавим обработчики подключаемых команд
// ИсправлениеДокументов
&НаКлиенте
Процедура Подключаемый_Исправить(Команда)
ИсправлениеДокументовЗарплатаКадрыКлиент.Исправить(ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ПерейтиКИсправлению(Команда)
ИсправлениеДокументовЗарплатаКадрыКлиент.ПерейтиКИсправлению(ЭтотОбъект);
КонецПроцедуры
&НаКлиенте
Процедура Подключаемый_ПерейтиКИсправленному(Команда)
ИсправлениеДокументовЗарплатаКадрыКлиент.ПерейтиКИсправленному(ЭтотОбъект);
КонецПроцедуры
// Конец ИсправлениеДокументов
11. В форме документа в событие "ПослеЗаписи" добавим
ИсправлениеДокументовЗарплатаКадрыКлиент.ПослеЗаписи(ЭтотОбъект, ПараметрыЗаписи);
12. В модуле документа в обрабочик событий "ОбработкаЗаполнения" добавим
Если ТипЗнч(ДанныеЗаполнения) = Тип("Структура") Тогда
Если ДанныеЗаполнения.Свойство("Действие") Тогда
Если ДанныеЗаполнения.Действие = "Исправить" Тогда
ИсправлениеДокументовЗарплатаКадры.СкопироватьДокумент(ЭтотОбъект, ДанныеЗаполнения.Ссылка);
ИсправленныйДокумент = ДанныеЗаполнения.Ссылка;
КонецЕсли;
КонецЕсли;
КонецЕсли;
13. В модуле документа в обработчик события "ОбработкаПроведения" добавим
Документы.экз_ГрафикРаботВОсобыхУсловиях.ОбработкаПроведения(ЭтотОбъект, Отказ, РежимПроведения);
В котором соответственно опишем всю логику проведения документа.
Процедура ОбработкаПроведения(ДокументОбъект, Отказ, РежимПроведения) Экспорт
ПроведениеСервер.ПодготовитьНаборыЗаписейКРегистрацииДвижений(ДокументОбъект, , , ЗначениеЗаполнено(ДокументОбъект.ИсправленныйДокумент));
РеквизитыДляПроведения =
Новый Структура("Ссылка, ИсправленныйДокумент, Дата",
ДокументОбъект.Ссылка, ДокументОбъект.ИсправленныйДокумент, ДокументОбъект.Дата);
ИсправлениеДокументовЗарплатаКадры.ПриПроведенииИсправления(
ДокументОбъект.Ссылка,
ДокументОбъект.Движения,
РежимПроведения,
Отказ,
РеквизитыДляПроведения,,
ДокументОбъект,
"Дата");
ИсправлениеПериодическихСведений.ИсправлениеПериодическихСведений(
ДокументОбъект,
Отказ,
РежимПроведения,
ДокументОбъект.Ссылка,
ДокументОбъект.ИсправленныйДокумент);
ДанныеДляПроведения = ДанныеДляПроведения(ДокументОбъект.Ссылка, ДокументОбъект.Организация);
ДокументОбъект.Движения.экз_ГрафикиРаботВоВредныхУсловиях.Записывать = Истина;
Для Каждого СтрокаДанных Из ДанныеДляПроведения.ГрафикРаботВОсобыхУсловияхСотрудники Цикл
ЗаполнитьЗначенияСвойств(ДокументОбъект.Движения.экз_ГрафикиРаботВоВредныхУсловиях.Добавить(), СтрокаДанных);
КонецЦикла;
КонецПроцедуры
Обратите внимание. У меня идет вызов процедуры ИсправлениеДокументовЗарплатаКадры.ПриПроведенииИсправления, в которой идет проверка, что текущий документ входит в подписку "ПолучитьПрежнийИсправленный". Если это условие выполняется, то дополнительно вызывается метод ИсправлениеПериодическихСведений.ИсправлениеПериодическихСведений.
В моем случае идет доработка через расширение и создана собственная копия подписки "экз_ПолучитьПрежнийИсправленный". Поэтому в коде я отдельно делаю вызов ИсправлениеПериодическихСведений.ИсправлениеПериодическихСведений.
Так же для корректной работы необходимо добавить экспортную процедуру
// Формирует сторно записи отменяющие движения исправленного документа по регистрам подсистемы.
//
// Параметры:
// Движения - КоллекцияДвижений, Структура - Коллекция движений в которую будут добавлены сторно записи.
// ИсправленныйДокумент - ДокументСсылка - Документ, записи которого необходимо сторнировать.
// Записывать - Булево - Если Истина, то наборы будут записаны сразу, если Ложь, то наборам будет установлен признак Записывать = Истина.
//
Процедура СторнироватьДвиженияДокумента(Движения, ИсправленныйДокумент, Записывать = Ложь) Экспорт
МетаданныеРегистров = МетаданныеРегистровПодсистемы();
ДвиженияВСтруктуре = ТипЗнч(Движения) = Тип("Структура");
Набор = Неопределено;
Для Каждого МетаданныеРегистра Из МетаданныеРегистров Цикл
ИмяРегистра = МетаданныеРегистра.Имя;
Если ДвиженияВСтруктуре Тогда
Движения.Свойство(ИмяРегистра, Набор);
Иначе
Набор = Движения.Найти(ИмяРегистра);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Как уже писал ранее необходимо создать регистр сведений "экз_ГрафикиРаботВоВредныхУсловияхИспр" Непериодический и Независимый. Регистр является копией основного, только с добавленным измерением "РегистраторИзмерение"
Вот собственно и все. Наш документ готов.
ps: Все вышеописанное реализовано через расширение, в т.ч. документ и регистры. Пример полностью рабочий, но при подготовке данной статьи, мог что-то пропустить в описании. Сообщите мне, если найдете неточности.
Протестировано на платформе 1С:Предприятие 8.3 (8.3.20.1613) и конфигурации Зарплата и управление персоналом, редакция 3.1 (3.1.16.108). (Выбран старый релиз, т.к. на текущий момент на нем сдается экзамен).