Предположим, что нам необходимо организовать проведение первичных документов по дополнительному регистру бухгалтерии в соответствии с таблицей распределения, задаваемой в каждом документе. При стандартном подходе нам необходимо в каждый документ добавить табличную часть и прописать обработку записи в регистр. При ближайшем рассмотрении оказывается, что нам необходимо изменить 67 документов. Как подумаешь, что при проведении обновления придется сравнивать 67 раз возможные изменения реквизитов, форм документов и их модулей, вся бодрость духа куда-то пропадает. Как этого избежать? Нам помогут «Советы» :)
Очень хочется при открытии документа программно добавить на форму документа кнопку по нажатию которой будет открываться таблица в которую будем заносить наше распределение. Обработку записи в регистр вынесем в процедуру общего модуля (нами добавленного!), вызывать процедуру будем по подписке на событие ОбработкаПроведения.
Дабы не добавлять ТЧ в каждый документ, организуем справочник «РаспределениеОбъектов». Создаем у этого справочника ТЧ с требуемой структурой таблицы распределения, добавляем реквизит «Документ» в котором будем хранить ссылку на документ владелец. Рисуем форму элемента, которую будем вызывать для заполнения таблицы распределения. Как же нам вызвать эту форму?
Перед открытием любого документа происходит вызов процедуры общего модуля РаботаСДиалогами.УстановитьПодменюСоветы(ЭлементыФормы.ДействияФормы, "ИмяДокумента"); добавляем в процедуру строку вызова нашей процедуры, в которой будет прописан обработчик добавления кнопки на форму документа.
Процедура УстановитьПодменюСоветы(КоманднаяПанель, ПараметрОтбора = "ВсеСоветы") Экспорт
...................
// начало изменения атт
ОбъектыУправленческогоУчета.ПриОткрытииФормыУпрУчет(КоманднаяПанель);
// конец изменения атт
КонецПроцедуры // УстановитьПодменюСоветы()
Таким образом, путем добавления 1 строки, мы фактически организовали подписку на событие ПриОткрытии. Этот способ не единственный по приведенным ссылкам можно посмотреть еще несколько прекрасных вариантов
http://www.infostart.ru/projects/4288
Теперь нам необходимо добавить кнопку с обработчиком вызывающим форму элемента справочника. Проще всего добавить в модуль свою процедуру, но повторюсь, очень не хочется изменять модуль формы документа. Будем пробовать пользоваться существующими процедурами.
Для правильной отработки алгоритма нам необходимы две вещи:
-
распознать нажатие именно нашей кнопки;
-
иметь ссылку на документ из которого происходит вызов.
Попробуем поработать с процедурой ДействияФормыОткрытьСоветы(Кнопка), вызывающей процедуру общего модуля ОткрытьСоветы(Кнопка).
Нашу кнопку логичнее всего распознавать по имени, Документ будем шифровать в строку пояснения кнопки. Можно добавить небольшой бантик в виде картинки кнопки. Например если таблица распределения не введена, то картинка жирный восклицательный знак, если введена, то зеленая галочка.
Ниже приведены процедуры, в которых происходит непосредственное добавление кнопки на форму документа.
Процедура ПриОткрытииФормыУпрУчет(КоманднаяПанель) Экспорт
Попытка
ИсточникДействия = КоманднаяПанель.ИсточникДействий.ДокументОбъект;
ДобавитьКнопкуВводУпрОбъектаВДокумент(КоманднаяПанель, ИсточникДействия);
Исключение
Попытка
ИсточникДействия = КоманднаяПанель.ИсточникДействий.ДокументСписок;
ДобавитьКолонкуВТЧСпискаДокументов(КоманднаяПанель, ИсточникДействия);
Исключение
КонецПопытки;
КонецПопытки;
КонецПроцедуры
// добавляем кнопку вызова справочника распределения на командную панель
// кнопку добавляем только для документов являющихся регистраторами регистра "УправленческийБаланс"
Процедура ДобавитьКнопкуВводУпрОбъектаВДокумент(КоманднаяПанель, Документ)
Если Не ПроверитьРегистраторРегистраБухгалтерии(Документ,"УправленческийБаланс") Тогда
Возврат;
КонецЕсли;
СписИсключаемыхДоков = ПолучитьСписокВидовДокументовИсключений();
Если Не списИсключаемыхДоков.НайтиПоЗначению(Документ.Метаданные().Имя) = Неопределено Тогда
Возврат;
КонецЕсли;
// в строку пояснения шифруем наш документ
СтрокаПояснения = "Ввести объект упр. учета для: " + Документ.Метаданные().Имя + " " + СокрЛП(Документ.Номер) + " от " + Документ.Дата;
нДействие = новый Действие("ДействияФормыОткрытьСоветы");
новаяКнопка = КоманднаяПанель.Кнопки.Добавить("ВводУпрОбъекта",ТипКнопкиКоманднойпанели.Действие,"Объект упр.учета",нДействие);
новаяКнопка.Подсказка = "Ввести объект упр. учета";
новаяКнопка.Пояснение = СтрокаПояснения;
новаяКнопка.Отображение = ОтображениеКнопкиКоманднойПанели.НадписьКартинка;
УстановитьКартинкуКнопкиВводУпрОбъекта(Документ,новаяКнопка);
КонецПроцедуры
При нажатии на кнопку происходит вызов процедуры общего модуля РаботаСДиалогами ОткрытьСоветы
Процедура ОткрытьСоветы(Кнопка) Экспорт
Если Кнопка.Имя = "ВводУпрОбъекта" Тогда // изменение атт
ОбъектыУправленческогоУчета.ОткрытьФормуВыбораОбъектаУпрУчета(Кнопка);
Иначе // типовой код
Форма = Обработки.Советы.ПолучитьФорму();
Форма.ПараметрОтбора = Сред(Кнопка.Имя, 7);
Форма.Открыть();
КонецЕсли;
КонецПроцедуры // ОткрытьСоветы()
В нашей процедуре открываем форму элемента справочника распределения
Функция ПолучитьЭлементРаспределенияОбъектовУпрУчета(Документ)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РаспределениеОбъектовУправленческогоУчета.Ссылка
|ИЗ
| Справочник.РаспределениеОбъектовУправленческогоУчета КАК РаспределениеОбъектовУправленческогоУчета
|ГДЕ
| РаспределениеОбъектовУправленческогоУчета.Документ = &Документ";
Запрос.УстановитьПараметр("Документ",Документ.Ссылка);
Результат = Запрос.Выполнить();
Если Результат.Пустой() Тогда
Элемент = Справочники.РаспределениеОбъектовУправленческогоУчета.ПустаяСсылка();
Иначе
Выборка = Результат.Выбрать();
Выборка.Следующий();
Элемент = Выборка.Ссылка;
КонецЕсли;
Возврат Элемент;
КонецФункции
Процедура ОткрытьФормуВыбораОбъектаУпрУчета(Кнопка) Экспорт
// разбираем строку пояснения в которой зашифрован документ
СтрокаПояснения = Кнопка.Пояснение;
СтрокаПояснения = Сред(СтрокаПояснения,31);
СтрокаПояснения = СокрЛП(СтрЗаменить(СтрокаПояснения,"от ",""));
СтрокаПояснения = СтрЗаменить(СтрокаПояснения," ",Символы.ПС);
ВидДокумента = СтрПолучитьСтроку(СтрокаПояснения,1);
НомерДокумента = СтрПолучитьСтроку(СтрокаПояснения,2);
ДатаДокумента = СтрПолучитьСтроку(СтрокаПояснения,3);
День = Число(Лев(ДатаДокумента,2));
Месяц = Число(Сред(ДатаДокумента,4,2));
Год = Число(Прав(ДатаДокумента,4));
ДатаДокумента = Дата(Год,Месяц,День);
Если (Дата(1,1,1) = ДатаДокумента) и (НомерДокумента = "") Тогда
Сообщить("Перед выбором объекта управленческого учета документ необходимо записать",СтатусСообщения.Внимание);
Возврат;
КонецЕсли;
// ищем документ
Документ = Документы[ВидДокумента].НайтиПоНомеру(НомерДокумента,ДатаДокумента);
//открываем форму справочника
Элемент = ПолучитьЭлементРаспределенияОбъектовУпрУчета(Документ);
Если Элемент.Пустая() Тогда
Элемент = Справочники.РаспределениеОбъектовУправленческогоУчета.СоздатьЭлемент();
Элемент.Документ = Документ;
Иначе
Элемент = Элемент.ПолучитьОбъект();
КонецЕсли;
Форма = Элемент.ПолучитьФорму("ФормаЭлемента");
Форма.ОткрытьМодально();
УстановитьКартинкуКнопкиВводУпрОбъекта(Документ,Кнопка);
КонецПроцедуры
Не забываем, что при пометке на удаление документа необходимо пометить на удаление соответствующий элемент справочника, а при снятии пометки удаления с документа снять ее и со справочника. Пишем обработчик и сажаем на подписку ПриЗаписи в которой проверяем состояние пометки удаления документа.
Изменения типовых объектов сведены к изменению 2 процедур общего модуля РаботаСДиалогами, все остальное стоит сбоку и жить никому не мешает :)
Добавил пример в виде мини конфы. Скачать можно отсюда
http://www.infostart.ru/profile/9211/forum/9884/