Готовый код для программного добавления кнопки (вызвать СоздатьКомандуДублироватьЗначение() из ПриСозданииНаСервере() формы), команды и сама процедура обработки:
&НаСервере
Функция СоздатьКомандуДублироватьЗначение()
НоваяКоманда = Команды.Добавить("ДублироватьЗначение");
НоваяКоманда.Действие= "ДублироватьЗначение";
НоваяКоманда.Заголовок= "Дублировать значение";
НоваяКоманда.ИзменяетСохраняемыеДанные = ?(найти(нрег(этаформа.ИмяФормы),"обработка")>0,Ложь,Истина);
НоваяКоманда.Отображение= ОтображениеКнопки.Картинка;
НоваяКоманда.Подсказка= "Дублируется значение предыдыущей ячейки, аналогично Excel. В т.ч. и выделенные строки";
НоваяКоманда.СочетаниеКлавиш= Новый СочетаниеКлавиш(Клавиша.D, , Истина); // Ctrl+D
// Опытным путем выявлено, что вызов команды сочетаниемклавиш не работает без кнопки
// при этом кнопка должна быть на форме, Видимость=Истина
// также замечено, что нажатие сочетанийклавишь активизирует кнопку
// из-за чего ЭтаФорма.ТекущийЭлемент вернет кнопку
// поэтому убираем кнопку в допМеню, этот фокус позволит получить именно текущий элемент
НоваяКнопка=Элементы.Добавить("ДублироватьЗначение",Тип("КнопкаФормы"),ЭтаФорма.КоманднаяПанель);
НоваяКнопка.вид=ВидКнопкиФормы.КнопкаКоманднойПанели;
НоваяКнопка.ИмяКоманды="ДублироватьЗначение";
НоваяКнопка.ПоложениеВКоманднойПанели=ПоложениеКнопкиВКоманднойПанели.ВДополнительномПодменю;
КонецФункции
&НаКлиенте
Функция ДублироватьЗначение()
Если Типзнч(этаформа.ТекущийЭлемент)=Тип("ТаблицаФормы") Тогда //работаем только с таблицами
ИмяТФ=этаформа.ТекущийЭлемент.Имя; // имя ТаблицыФормы
ИмяТЗ=ПолучитьПутьКДанным(ИмяТФ); // имя элемента формы может отличатся от имени реквизита
ТЗнаФорме=Вычислить(ИмяТЗ); // данные формы коллекция
ВыделенныеСтроки=Элементы[ИмяТФ].ВыделенныеСтроки;
// Определяем источник - строка предшествующая первой выделенной
// При удалении, перемещении строк, их идентификатор не меняется, и очень похож на номер строки
// при этом индекс строки меняется
ИндексСтрокиИсточника=9999999;
Для каждого ИдСтроки ИЗ ВыделенныеСтроки Цикл
ИндексСтроки=ТЗнаФорме.Индекс(ТЗнаФорме.НайтиПоИдентификатору(ИдСтроки));
ИндексСтрокиИсточника=?(ИндексСтрокиИсточника>ИндексСтроки,ИндексСтроки,ИндексСтрокиИсточника);
КонецЦикла;
ИндексСтрокиИсточника=ИндексСтрокиИсточника-1;
Если ИндексСтрокиИсточника>=0 Тогда
// опять же, имя элемента формы может отличатся от имени реквизита
// при этом ПутьКДанным колонки содержит и ПутьКДанным таблицы, исключаем
// обращатся к колонке по индексу также не стоит, т.к. порядок на форме может отличаться от порядка реквизитов
ИмяТекКолонки=стрзаменить(ПолучитьПутьКДанным(Элементы[ИмяТФ].ТекущийЭлемент.Имя),""+ИмяТЗ+".","");
ЗначениеИсточника=ТЗнаФорме[ИндексСтрокиИсточника][ИмяТекКолонки];
Для Каждого СтрТЧ ИЗ ВыделенныеСтроки Цикл
// ВыделенныеСтроки хранит не индекс строк, а их иденитфикаторы
// при удалении строк из середины обновляется индекс, но не номер строки
ТЗнаФорме.НайтиПоИдентификатору(СтрТЧ)[ИмяТекКолонки]=ЗначениеИсточника;
КонецЦикла;
Элементы[ИмяТФ].Обновить(); //обновляем данные в ТаблицеФормы
КонецЕсли;
КонецЕсли;
КонецФункции
&НаСервере
Функция ПолучитьПутьКДанным(ИмяЭлемента)
Возврат(Элементы[ИмяЭлемента].ПутьКДанным);
КонецФункции
Собственно комментарии рассказывают все подводные камни.
В теории можно подключить интерактивную запись и тем самым вызывать событие ПриИзменении(), но:
- Мне лень
- Нужно немного переделать код
- Для поддержки выделенных строк не забыть предварительно скопировать массив со строками
Собственно решение доработано и переделано уже несколько раз здесь
Комментариев нет:
Отправить комментарий