Сразу оговорюь, что всё сказаное в статье справедливо для всех конфигураций 1С, где применяются дополнительные реквизиты (т.е. конфигураций, где в основе лежат "стандартные подсистемы"). Однако, я использовал дополнительные реквизиты только в 1С: Бухгалтерия 2.0.
В организации где много пользователей базы данных и есть разделение обязаностей не редко возникает ситуация, когда один человек делает документы, а другой их проверяет или же человек сам проверяет документы после себя, но должен знать какие документы он уже проверил, а какие нет. Такая ситуация возникла и у меня: документы выгружаются из торговой программы в бухгалтерия, бухгалтер их проверяет и должен поставить отметку что документ проверен. Иногда бывает поставщики привозят не правильные документы и тогда отметку ставить не нужно, пока поставщики не привезут правильные документы. Иногда это затягивается на несколько месяцев и документы попадают в закрытый период.
Задача сделать механизм учета не корректных документов без переделок (или с минимальными переделками) типовой конфигурации и с возможностью вести учет в закрытом для редактирования периоде (т.е. без перепроведения документов).
Тут приходит на помощь механизм, который в стандартных подсистемах (типовых конфигурациях) называется "Дополнительные реквизиты". В частности мы будем использовать следующие его особенности:
- Возможность добавления информации к документу без изменения самого документа;
- Возможность добавления дополнительной информации к документу без изменения конфигурации.
(Дополнительные реквизиты - это регистр сведений в котором хранится ссылка на документ и наименование дополнительного реквизита, который связан с документом. Само значение хранится в ПланеВидовХаррактеристик.)
И так, первое что нужно сделать - это добавить дополнительный реквизит, кнопка добавления располагается в командной панели журнала документов или в самом документе (в режиме предприятия):
Чтобы не модифицировать существующий журнал, я создал новый журнал документов, в котором сделал кнопку на командной панели "Проверен". Эта кнопка инвертирует статус документа "Проверено".
Код для получения статуса документа (чтения дополнительного реквизита):
Процедура ЖурналДокументовСписокПриВыводеСтроки(Элемент, ОформлениеСтроки, ДанныеСтроки) Запрос = Новый Запрос(); Запрос.УстановитьПараметр("НазначениеСвойств", ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(ДанныеСтроки.Ссылка)); Запрос.УстановитьПараметр("ОбъектОтбораЗначений", ДанныеСтроки.Ссылка); Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ | СвойстваОбъектов.Наименование, | ЗначенияСвойствОбъектов.Значение КАК ПричинаЗамены, | ЕСТЬNULL(ЗначенияСвойствОбъектов.Значение, ЛОЖЬ) КАК Проверен |ИЗ | (ВЫБРАТЬ | СвойстваОбъектов.Ссылка КАК Ссылка, | СвойстваОбъектов.Наименование КАК Наименование, | СвойстваОбъектов.ПометкаУдаления КАК ПометкаУдаления | ИЗ | ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов | ГДЕ | СвойстваОбъектов.НазначениеСвойства В(&НазначениеСвойств) | И СвойстваОбъектов.ПометкаУдаления = ЛОЖЬ | И (СвойстваОбъектов.Наименование = ""Проверено"" | ИЛИ СвойстваОбъектов.Наименование = ""ПричинаЗамены"")) КАК СвойстваОбъектов | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов | ПО (ЗначенияСвойствОбъектов.Свойство = СвойстваОбъектов.Ссылка) | И (ЗначенияСвойствОбъектов.Объект = &ОбъектОтбораЗначений)"; Выборка = Запрос.Выполнить().Выбрать(); ОформлениеСтроки.Ячейки.Проверен.ОтображатьФлажок = Истина; Пока Выборка.Следующий() Цикл Если Выборка.Наименование = "Проверено" Тогда ОформлениеСтроки.Ячейки.Проверен.Флажок = Выборка.Проверен; ИначеЕсли Выборка.Наименование = "ПричинаЗамены" Тогда ОформлениеСтроки.Ячейки.ПричинаЗамены.Значение = Выборка.ПричинаЗамены; КонецЕсли; КонецЦикла; Если ДанныеСтроки.Ссылка.Метаданные().Имя = "ОперацияБух" Тогда ОформлениеСтроки.Ячейки.СуммаДокумента.Значение = ДанныеСтроки.Ссылка.СуммаОперации; ИначеЕсли ДанныеСтроки.Ссылка.Метаданные().Имя = "ОтчетОРозничныхПродажах" Тогда ОформлениеСтроки.Ячейки.СуммаДокумента.Значение = ДанныеСтроки.Ссылка.Оплата.Итог("СуммаОплаты"); ИначеЕсли ДанныеСтроки.Ссылка.Метаданные().Имя = "ПереоценкаТоваровВРознице" Тогда ОформлениеСтроки.Ячейки.СуммаДокумента.Значение = ДанныеСтроки.Ссылка.Товары.Итог("СуммаПереоценки"); ИначеЕсли ДанныеСтроки.Ссылка.Метаданные().Имя = "ПриходныйКассовыйОрдер" Тогда ОформлениеСтроки.Ячейки.СуммаДокумента.Значение = ДанныеСтроки.Ссылка.СуммаДокумента; КонецЕсли; КонецПроцедуры
Код для изменения (записи) реквизита:
Процедура ДействияФормыПроверен(Кнопка) НаборЗаписейЗначенияСвойств = РегистрыСведений.ЗначенияСвойствОбъектов.СоздатьНаборЗаписей(); СвойстваИЗначения = ПолучитьСтатус(ЭлементыФормы.ЖурналДокументовСписок.ТекущиеДанные.Ссылка); Для каждого Строка Из СвойстваИЗначения Цикл Если Строка.СвойстваОбъектовНаименование = "Проверено" И Строка.Проверен <> Истина Тогда Запись = НаборЗаписейЗначенияСвойств.Добавить(); Запись.Объект = ЭлементыФормы.ЖурналДокументовСписок.ТекущиеДанные.Ссылка; Запись.Свойство = Строка.Свойство; Запись.Значение = Не Строка.Проверен; КонецЕсли; Если ЗначениеЗаполнено(Строка.Значение) И Строка.Значение <> Ложь И Строка.СвойстваОбъектовНаименование <> "Проверено" Тогда Запись = НаборЗаписейЗначенияСвойств.Добавить(); Запись.Объект = ЭлементыФормы.ЖурналДокументовСписок.ТекущиеДанные.Ссылка; Запись.Свойство = Строка.Свойство; Запись.Значение = Строка.Значение; КонецЕсли; КонецЦикла; НаборЗаписейЗначенияСвойств.Отбор.Объект.Установить(ЭлементыФормы.ЖурналДокументовСписок.ТекущиеДанные.Ссылка); Попытка НаборЗаписейЗначенияСвойств.Записать(); Исключение КонецПопытки; ЖурналДокументовСписок.Обновить(); КонецПроцедуры
Я привёл пример кода только для записи одного дополнительного реквизита "Проверен", у меня есть ещё реквизит причина заметы, но с ним всё аналогично.
С отчетами тоже всё просто: в универсальном отчете по документу появяться дополнительный реквизиты в группе "ссылка".
Права на изменение/чтение реквизита:
У меня права на изменение дополнительных реквизитов были у всех. Но их легко ограничить программно, добавив в начало процедуры чтения/записи код:
Если Не РольДоступна("ПолныеПрава") Тогда Возврат; КонецЕсли;
или
Если Не (ИмяПользователя() = "Вася" Или Найти(ИмяПользователя(), "Петя") > 0) Тогда Возврат; КонецЕсли;
Старался расписать достаточно подробно и коснуться всех аспектов использования дополнительных реквизитов, чтобы не пришлось даже искать где кнопка добавить реквизит.
UPD 16.07.2012
Функция ПолучитьСтатус(Объект) Запрос = Новый Запрос(); Запрос.УстановитьПараметр("НазначениеСвойств", ОбщегоНазначения.ПолучитьСписокНазначенийСвойствКатегорийОбъектовПоСсылке(Объект)); Запрос.УстановитьПараметр("ОбъектОтбораЗначений", Объект); Запрос.Текст = "ВЫБРАТЬ РАЗРЕШЕННЫЕ РАЗЛИЧНЫЕ | СвойстваОбъектов.Наименование КАК СвойстваОбъектовНаименование, | СвойстваОбъектов.ПометкаУдаления КАК ПометкаУдаления, | СвойстваОбъектов.Ссылка КАК Свойство, | ЗначенияСвойствОбъектов.Значение КАК Значение, | ЕСТЬNULL(ЗначенияСвойствОбъектов.Значение, ЛОЖЬ) КАК Проверен |ИЗ | (ВЫБРАТЬ | СвойстваОбъектов.Ссылка КАК Ссылка, | СвойстваОбъектов.Наименование КАК Наименование, | СвойстваОбъектов.ПометкаУдаления КАК ПометкаУдаления | ИЗ | ПланВидовХарактеристик.СвойстваОбъектов КАК СвойстваОбъектов | ГДЕ | СвойстваОбъектов.НазначениеСвойства В(&НазначениеСвойств)) КАК СвойстваОбъектов | ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияСвойствОбъектов КАК ЗначенияСвойствОбъектов | ПО (ЗначенияСвойствОбъектов.Свойство = СвойстваОбъектов.Ссылка) | И (ЗначенияСвойствОбъектов.Объект = &ОбъектОтбораЗначений) | |УПОРЯДОЧИТЬ ПО | СвойстваОбъектовНаименование"; ТабЗнач = Запрос.Выполнить().Выгрузить(); Возврат ТабЗнач; КонецФункции