Программное добавление кнопок копирования табличных частей во все документы с минимальными изменениями конфигурации (или вообще без изменения)


Работает на УТ 10.3, УПП
Механизм добавления кнопок копирование/вставки табличных частей во все документы без тотального изменения конфигурации.

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

Предлагается механизм добавления кнопок копирования/вставки без тотального изменения конфигурации. Документы можно даже не снимать с поддержки. Кнопки добавляются к каждой табличной части документа (их может быть несколько, например, "товары" и "услуги").

Upd: Сокращен состав изменений в конфигурации. Добавлена возможность сохранения буфера обмена в файл/ восстановления из файла.

Задача: в командную панель табличной части добавить кнопки копирования и вставки табличной части. Кнопка «Копировать» доступна всегда. Кнопка «Вставить» доступна если есть значения для копирования и если документ доступен для редактирования.

Решение: кнопки добавляем программно, используя вызов общих процедур для каждого документа. Значение храним в существующем параметре сеанса "ОбщиеЗначения". Кнопкой "копировать" просто помещаем объект в параметр сеанса. Кнопкой "вставить" вызываем обработку вставки, чтобы видеть что мы вставляем, иметь возможность отказаться от вставки и настроить вставляемые данные.

Альтернативное решение: Можно вообще отказаться изменений конфигурации. Для пользователя выглядеть это будет не так изящно, зато для программиста меньше забот. В альтернативном решение использован только стандартный функционал по внешним обработчикам таб.частей. Приложены два файла-обработки для действия копирования и вставки. Чтобы обработки начали работать нужно зарегистировать их в справочнике "ВнешниеОбработки" и привязать к документам и таб.частям. Обработки умеют сами себя регистрировать во внешних обработках и привязывать к документам и таб. частям. Для этого нужно просто запустить обработку и нажать кнопку "зарегистрировать"

Upd: Изменены обработки альтернативного решения. Добавлена авторегистрация обработок в справочнике "Внешние обработки"

Изменения конфигурации:

  • новая обработка «БуферОбменаТаблицаЗначений»
  • изменения роли «Пользователь» для настройки доступа к обработке
  • изменения в процедуре «МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера»
  • изменения в процедуре «УниверсальныеМеханизмы.СформироватьПодменюЗаполненияТЧ»
  • изменения в процедуре «УниверсальныеМеханизмы.ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ»
Как видно из списка измененных объектов здесь отсутствуют изменения в документах, что и было главной целью.
 
Процесс:

1. Добавляем новую обработку «БуферОбменаТаблицаЗначений». Обработка используется для "предпросмотра" вставляемого значения, возможности отказа от вставки, варианта вставки, настройки состава строк и колонок. Картинки кнопок содержатся в обработке как макеты двоичных данных. Кроме того в модуле обработки содержатся экспортные процедуры, которые управляют вставкой кнопок в форму документа и обрабатывают нажатия на кнопки. Не забудьте дать права роли «Пользователь» для доступа к этому параметру всем пользователям.  

2. Программно добавляем кнопки в командные панели формы документа. Кнопки добавляются при открытии формы документа.

Для добавления кнопок в командные панели используем процедуру, которая вызывается в каждом стандартном документе при открытии:

МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера();

В этой процедуре доступны все контексты, которые нам нужны: контекст метаданных объекта и контекст формы объекта. 

Процедура УстановитьДоступностьПоляВводаНомера(МетаданныеОбъекта, ФормаОбъекта, ПодменюДействия, ПолеВводаНомера) Экспорт

    Обр = Обработки.БуферОбменаТаблицаЗначений.Создать();
   
Обр.БуферОбмена_ДобавитьКнопкиВКомандныеПанелиФормы(МетаданныеОбъекта,ФормаОбъекта);

    Если
ФормаОбъекта.Автонумерация = АвтонумерацияВФорме.Авто Тогда
        Возврат;
    КонецЕсли;

   
СтратегияРедактирования = ПолучитьСтратегиюРедактированияНомераОбъекта(МетаданныеОбъекта);

    Если
СтратегияРедактирования = Перечисления.СтратегияРедактированияНомеровОбъектов.Доступно Тогда
        Если
ПодменюДействия.Кнопки.Найти("РедактироватьКодНомер") <> Неопределено Тогда
           
ПодменюДействия.Кнопки.Удалить(ПодменюДействия.Кнопки.РедактироватьКодНомер);
        КонецЕсли;
       
ПолеВводаНомера.ТолькоПросмотр = Ложь;
    КонецЕсли;

   
ПолеВводаНомера.ПропускатьПриВводе = ПолеВводаНомера.ТолькоПросмотр;
   
УстановитьПодсказкуПоляВводаКодаНомера(ПолеВводаНомера, ПодменюДействия, СтратегияРедактирования);

КонецПроцедуры
// УстановитьДоступностьПоляВводаНомера()

Текст процедуры «БуферОбмена_ДобавитьКнопкиВКомандныеПанелиФормы» приведен ниже. 

Процедура создает соответствие между табличной частью и командной панелью перебором всех элементов формы . Затем в каждую командную панель вставляются 2 кнопки.

Имя кнопки состоит из секций:

  • Кнопка копирования: «КопироватьТЧВБуферОбмена_"+ИмяТабличнойЧасти
  • Кнопка вставки: «ВставитьТЧИзБуфераОбмена_"+ИмяТабличнойЧасти

Если буфер обмена не содержит «правильного» значения, то кнопка вставки видна как неактивная.

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

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

// Параметры
//_Метаданные   - метаданные объекта
//_Форма        - форма объекта
//Процедура добавляет в командные панели формы кнопки работы с буфером обмена (копирования/вставки табличных частей)
Процедура БуферОбмена_ДобавитьКнопкиВКомандныеПанелиФормы(_Метаданные,_Форма) Экспорт
    Если
_Метаданные.ТабличныеЧасти.Количество() <> 0 Тогда
       
соотвТабЧасть_КоманднаяПанель = Новый Соответствие;

        Для Каждого
ЭФ Из _Форма.ЭлементыФормы Цикл
            Если
ТипЗнч(ЭФ) = Тип("КоманднаяПанель") Тогда
                Если
ТипЗнч(ЭФ.ИсточникДействий) = Тип("ТабличноеПоле") Тогда
                   
ИмяТЧ = ЭФ.ИсточникДействий.Данные;

                   
ТабЧасть = _Метаданные.ТабличныеЧасти.Найти(ИмяТЧ);
                    Если
ТабЧасть = Неопределено Тогда
                        Продолжить;
                    КонецЕсли;

                   
//Если одной табличной части соответствует несколько панелей, то добавляем кнопки в первую, а не в последнюю
                   
Если соотвТабЧасть_КоманднаяПанель.Получить(ТабЧасть) = Неопределено Тогда
                       
соотвТабЧасть_КоманднаяПанель.Вставить(ТабЧасть,ЭФ);
                    КонецЕсли;
                КонецЕсли;
            КонецЕсли;
        КонецЦикла;

       
ВставкаВозможна = Истина;
        Если
соотвТабЧасть_КоманднаяПанель.Количество() <> 0 Тогда
            Попытка
               
ХЗ = ПараметрыСеанса.ОбщиеЗначения;
               
ЗначениеХЗ = ХЗ.Получить();
                Если
ТипЗнч(ЗначениеХЗ) <> Тип("Структура") Тогда
                   
ВставкаВозможна = ЛОЖЬ;
                Иначе
                   
ОписаниеИсточника   = ЗначениеХЗ.ОписаниеИсточника;
                   
ЗначениеТЧ          = ЗначениеХЗ.ТабличнаяЧасть;
                    Если
ТипЗнч(ЗначениеТЧ) <> Тип("ТаблицаЗначений") Тогда
                       
ставкаВозможна = ЛОЖЬ;
                    КонецЕсли;
                КонецЕсли;
            Исключение
               
ВставкаВозможна = ЛОЖЬ;
            КонецПопытки;
        Иначе
           
ВставкаВозможна = ЛОЖЬ;
        КонецЕсли;

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

            Если
ВставкаВозможна Тогда
               
КнопкаВставить = КП.Кнопки.Добавить("ВставитьТЧИзБуфераОбмена_"+ТабЧасть.Имя,ТипКнопкиКоманднойПанели.Действие,,Новый Действие("НажатиеНаДополнительнуюКнопкуЗаполненияТЧ"));
               
КнопкаВставить.Картинка = ПолучитьКартинкуВставитьАктивная();
            Иначе
               
КнопкаВставить = КП.Кнопки.Добавить("ВставитьТЧИзБуфераОбмена_"+ТабЧасть.Имя,ТипКнопкиКоманднойПанели.Действие,,Новый Действие("ПроизвольныйТекстЧтобыКнопкаБылаНедоступна"));
               
КнопкаВставить.Картинка = ПолучитьКартинкуВставитьПассивная();
            КонецЕсли;
        КонецЦикла;
    КонецЕсли;
КонецПроцедуры


3. Добавление обработчика нажатия на кнопку.

Итак, кнопки в форму добавлены. Но как обработать их нажатие в форме?

Для обработки нажатия используем стандартный механизм работы с обработчиками табличных частей через внешние обработки. Стандартный механизм встроен во все документы, где есть табличные части. По вышеприведенному коду видно, что кнопкам назначен обработчик «НажатиеНаДополнительнуюКнопкуЗаполненияТЧ». Процедура этого обработчика есть во всех стандартных документах.

В стандартной УТ перед открытием любого документа вызывается процедура:

УниверсальныеМеханизмы.СформироватьПодменюЗаполненияТЧ(мКнопкиЗаполненияТЧ,СоответствиеТЧ);

Процедура устанавливает подменю "Заполнить" в командных панелях ТЧ документа при необходимости, где 

  • мКнопкиЗаполненияТЧ – дерево кнопок «пользовательской» обработки табличных частей
  • СоответствиеТЧ – соответствие табличной части и ее кнопки(подменю) заполнения

К сожалению, в процедуру передаются не сами командные панели, а только кнопки подменю «Заполнить», поэтому мы не можем ее использовать для добавления наших кнопок копирования/вставки. Именно по этой причине для добавления кнопок мы использовали другую процедуру, описанную выше.

Поэтому используем данную процедуру только для подготовки обработки нажатия на «наши» кнопки.

В контексте данной процедуры доступна переменная формы «мКнопкиЗаполненияТЧ», которая содержит дерево «пользовательских» кнопок обработки табличных частей. В конец этой процедуры добавим вызов «своей» процедуры.

Процедура СформироватьПодменюЗаполненияТЧ(ДеревоКнопок,СоответствиеТЧ) Экспорт

    Для Каждого
КлючИЗначение Из СоответствиеТЧ Цикл

       
ИмяТабличнойЧасти = КлючИЗначение.Ключ.Данные;

       
СтрокаПодменю = ДеревоКнопок.Строки.Найти(ИмяТабличнойЧасти, "Имя");

        Если
СтрокаПодменю <> Неопределено Тогда

           
// Табличное поле
           
СтрокаПодменю.Расшифровка = КлючИЗначение.Ключ;

           
ПодменюИлиКоманднаяПанель = КлючИЗначение.Значение;

            Если
ТипЗНЧ(ПодменюИлиКоманднаяПанель) = Тип("КоманднаяПанель") Тогда

               
ПодменюИлиКоманднаяПанель = ПодменюИлиКоманднаяПанель.Кнопки.Добавить(,ТипКнопкиКоманднойПанели.Подменю,"Заполнить");

            КонецЕсли;
           
СформироватьПодменю(СтрокаПодменю, ПодменюИлиКоманднаяПанель,Ложь,Истина);

        КонецЕсли;

    КонецЦикла;

   
Обр = Обработки.БуферОбменаТаблицаЗначений.Создать();
   
Обр.БуферОбмена_ДополнитьПодменюЗаполненияТЧ(ДеревоКнопок,СоответствиеТЧ);

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

Текст процедуры «БуферОбмена_ДополнитьПодменюЗаполненияТЧ» приведен ниже.

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

//Добавляем в дерево кнопок информацию о «своих» кнопках. Это дерево используется для определения обработчика при нажатии кнопки в форме.
//Отличать кнопки и из назначение будем по значению колонки «расшифровка».
//В стандартном решении поле расшифровка имеет тип "ВнешняяОбработка", а у нас тип "строка"
Процедура БуферОбмена_ДополнитьПодменюЗаполненияТЧ(_ДеревоКнопок,_СоответствиеТЧ) Экспорт
    Для Каждого
Элем Из _СоответствиеТЧ Цикл
       
НовСтрока = _ДеревоКнопок.Строки.Добавить();
       
НовСтрока.Расшифровка = "Полимагнит.БуферОбмена.Копировать";
       
НовСтрока.Имя = "КопироватьТЧВБуферОбмена_"+Элем.Ключ.Имя;

       
НовСтрока = _ДеревоКнопок.Строки.Добавить();
       
НовСтрока.Расшифровка = "Полимагнит.БуферОбмена.Вставить";
       
НовСтрока.Имя = "ВставитьТЧИзБуфераОбмена_"+Элем.Ключ.Имя;
    КонецЦикла;
КонецПроцедуры

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

Как уже было сказано выше, для обработки нажатия доп.кнопок в стандартных документах используется общий обработчик «НажатиеНаДополнительнуюКнопкуЗаполненияТЧ». Используем его. В форме обработчик вызывает процедуру:

УниверсальныеМеханизмы.ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ()

В процедуре доступна строка дерева кнопок «мКнопкиЗаполненияТЧ» и контекст объекта документа. Строка дерева – это фактически инструкция к тому, как обрабатывать кнопку. В стандартном решении колонка «Расшифровка» содержит тип «СправочникСсылка.ВнешниеОбработки». У нас же это строка. Воспользуемся этим для определения того, что нажата именно "наша" кнопка. Добавим через «Иначе» вызов своей процедуры:

// Процедура - обработчик нажатия любой из дополнительных кнопок заполнения табличных частей
// Параметры:
//    СтрокаКнопки     : строка дерева значений, содержащая "инструкцию" к обработке кнопки
//    ЭтотОбъект       : контекст объекта документа
Процедура ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ(СтрокаКнопки,ЭтотОбъект) Экспорт

   
Расшифровка = СтрокаКнопки.Расшифровка;

    Если
ТипЗНЧ(Расшифровка) = Тип("СправочникСсылка.ВнешниеОбработки") Тогда
       
ИмяФайла = КаталогВременныхФайлов()+"PrnForm.tmp";
       
ОбъектВнешнейФормы = Расшифровка.ПолучитьОбъект();

        Если
ОбъектВнешнейФормы = Неопределено Тогда
           
Сообщить("Ошибка получения внешней обработки заполнения табличной части документа. Возможно обработка была удалена", СтатусСообщения.Важное);
            Возврат;
        КонецЕсли;

       
ДополнительныеПараметры = Неопределено;
       
МетаданныеОбъекта = ЭтотОбъект.Метаданные();
       
СсылкаОбъекта = Неопределено;
        Если
Метаданные.Документы.Содержит(МетаданныеОбъекта) Тогда
           
СсылкаОбъекта = Документы[МетаданныеОбъекта.Имя].ПустаяСсылка();
        ИначеЕсли
Метаданные.Справочники.Содержит(МетаданныеОбъекта) Тогда
           
СсылкаОбъекта = Справочники[МетаданныеОбъекта.Имя].ПустаяСсылка();
        КонецЕсли;

        Если
СсылкаОбъекта <> Неопределено Тогда
            Для Каждого
Стр Из Расшифровка.Принадлежность Цикл
                Если (
Стр.СсылкаОбъекта = СсылкаОбъекта) И (СокрЛП(Стр.ТабличнаяЧастьИмя) = СтрокаКнопки.Родитель.Имя) Тогда
                   
ДополнительныеПараметры = Стр.ДополнительныеПараметрыОбработки.Получить();
                    Прервать;
                КонецЕсли;
            КонецЦикла;
        КонецЕсли;

       
ДвоичныеДанные = ОбъектВнешнейФормы.ХранилищеВнешнейОбработки.Получить();
       
ДвоичныеДанные.Записать(ИмяФайла);
        Попытка
           
Обработка = ВнешниеОбработки.Создать(ИмяФайла);
        Исключение
           
Сообщить("Ошибка исполнения внешней обработки табличной части документа."+Символы.ПС+ОписаниеОшибки(), СтатусСообщения.Важное);
            Возврат;
        КонецПопытки;

       
// Передать внешней обработке дополнительные параметры
       
Если ДополнительныеПараметры <> Неопределено Тогда
           
// Если у внешней обработки есть реквизит для дополнительных параметров, присвоить ему значение
           
Если НЕ Обработка.Метаданные().Реквизиты.Найти("ДополнительныеПараметры") = Неопределено Тогда
               
Обработка.ДополнительныеПараметры = ДополнительныеПараметры;
            КонецЕсли;
        КонецЕсли;

        Попытка
           
Обработка.Инициализировать(ЭтотОбъект, СтрокаКнопки.Родитель.Имя, СтрокаКнопки.Родитель.Расшифровка);
        Исключение
           
ОбщегоНазначения.СообщитьОбОшибке(ОписаниеОшибки(),, "Заполнение ТЧ не произведено!");
        КонецПопытки;
    Иначе
//доработки
       
Обр = Обработки.БуферОбменаТаблицаЗначений.Создать();
        Обр.БуферОбмена_ОбработатьНажатиеНаКнопку(СтрокаКнопки,ЭтотОбъект);
    КонецЕсли;

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

Текст процедуры «БуферОбмена_ОбработатьНажатиеНаКнопку» приведен ниже. 

Описание процедуры:

  • Через значение расшифровки определяем какая кнопка нажата – копирования или вставки.
  • Имя табличной части получаем через имя кнопки. Помним, что
    • Кнопка копирования: «КопироватьТЧВБуферОбмена_"+ИмяТабличнойЧасти
    • Кнопка вставки: «ВставитьТЧИзБуфераОбмена_"+ИмяТабличнойЧасти
  • Отсекая известные символы получаем имя табличной части.
  • Через контекст объекта и имя табличной части получаем значение табличной части.

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

При вставке из буфера обмена вызывается обработка «БуферОбменаТаблицаЗначений». Не буду приводить листинг обработки. Кратко: перед вставкой обработка показывает вставляемое значение (таблицу), в заголовке видно строковое представление источника таблицы (документа). Существует возможность вставить строки с удалением существующих, добавить строчки ниже или отказаться от действия. Кроме того можно изменять состав добавляемых колонок через настройку их видимости в форме обработки. В объект-приемник вставляются только видимые колонки.

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

// Процедура - обработчик нажатия кнопку работы с буфером обмена (копировать/вставить)
// Параметры:
//    _СтрокаКнопки     : строка дерева значений, содержащая "инструкцию" к обработке кнопки
//    _ЭтотОбъект       : контекст объекта документа
Процедура БуферОбмена_ОбработатьНажатиеНаКнопку(_СтрокаКнопки,_ЭтотОбъект) Экспорт
   
Расшифровка = _СтрокаКнопки.Расшифровка;

   
ИмяКнопки = _СтрокаКнопки.Имя;

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

       
//предварительно обработаем таблицу значениий. Есть значения, которые нельзя копировать
       
ОбработатьТЗПриПомещенииВБуферОбмена(ЗначениеТабличнойЧасти,_ЭтотОбъект,ИмяТЧ);

       
стХЗ = Новый Структура();
       
стХЗ.Вставить("ОписаниеИсточника",Строка(_ЭтотОбъект));
       
стХЗ.Вставить("ТабличнаяЧасть",ЗначениеТабличнойЧасти);

       
ХЗ = Новый ХранилищеЗначения(стХЗ);
       
ПараметрыСеанса.ОбщиеЗначения = ХЗ;

    ИначеЕсли
Расшифровка = "Полимагнит.БуферОбмена.Вставить" Тогда

       
ИмяТЧ = СокрЛП(СтрЗаменить(ИмяКнопки,"ВставитьТЧИзБуфераОбмена_",""));
       
Приемник = _ЭтотОбъект[ИмяТЧ];

        Попытка
           
ХЗ = ПараметрыСеанса.ОбщиеЗначения;
           
ЗначениеХЗ = ХЗ.Получить();
            Если
ТипЗнч(ЗначениеХЗ) <> Тип("Структура") Тогда
               
Сообщить("Буфер обмена не содержит значений нужного типа!");
                Возврат;
            Иначе
               
ОписаниеИсточника   = ЗначениеХЗ.ОписаниеИсточника;
               
ЗначениеТЧ          = ЗначениеХЗ.ТабличнаяЧасть;
                Если
ТипЗнч(ЗначениеТЧ) <> Тип("ТаблицаЗначений") Тогда
                   
Сообщить("Буфер обмена не содержит значений нужного типа!");
                    Возврат;
                КонецЕсли;
            КонецЕсли;
        Исключение
           
Сообщить("Буфер обмена не содержит значений нужного типа!");
            Возврат;
        КонецПопытки;

       
ОбработатьТЗПриИзвлеченииИзБуфераОбмена(ЗначениеТЧ,_ЭтотОбъект);

       
Обр = ЭтотОбъект;
       
Обр.ОписаниеИсточника = ОписаниеИсточника;
       
ФормаТаб = Обр.ПолучитьФорму();
       
ФормаТаб.ТЧ = ЗначениеТЧ;
       
ОтветФормы = ФормаТаб.ОткрытьМодально();

        Если
ОтветФормы = Неопределено Тогда
           
//Это отмена
       
Иначе
           
Источник = ФормаТаб.ТЧ;

            Если
ОтветФормы = "ОчиститьВставить" Тогда
               
Приемник.Очистить();
            КонецЕсли;

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

        КонецЕсли;
    КонецЕсли;

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

Обработчик при помещении в буфер обмена может использоваться для настройки состава копируемых данных в зависимости от вида документа. В обработчике оставлен закомментированный код, который может быть использован для примера.

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

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

Аналогично можно использовать обработчик при извлечении из буфера обмена. В обработчике оставлен закомментированный код, который может быть использован для примера.

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

Процедура ОбработатьТЗПриИзвлеченииИзБуфераОбмена(_ТЗ,_ЭтотОбъект)

   
//Если ТипЗнч(_ЭтотОбъект) = Тип("ДокументОбъект.Заявка") Тогда
    //  КолонкаНоменклатура = _ТЗ.Колонки.Найти("Номенклатура");
    //  Если КолонкаНоменклатура <> Неопределено Тогда
    //      КолонкаНоменклатура.Имя = "Наименование";
    //  КонецЕсли;
    //КонецЕсли;

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

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

ПримечаниеПроцедура находится в модуле обработки "БуферОбменаТаблицаЗначений", копировать ее из статьи нет необходимости. Текст процедуры приведен для наглядности.

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

Подведем итог.

Для решения задачи нам пришлось внести следующие изменения в конфигурацию:

  • Добавить обработку «БуферОбменаТаблицаЗначений»
  • Настроить доступ роли «Пользователь» к обработке
  • Внести изменения в процедуру «МеханизмНумерацииОбъектов.УстановитьДоступностьПоляВводаНомера»
  • Внести изменения в процедуру «УниверсальныеМеханизмы.СформироватьПодменюЗаполненияТЧ»
  • Внести изменения в процедуру «УниверсальныеМеханизмы.ОбработатьНажатиеНаДополнительнуюКнопкуЗаполненияТЧ»


Файлы обработки:

-