// ***********************************************************************************************
// Возвращает индекс элемента формы, заданный при помощи спецзнака "_", без спецзнака вернет 0
//
// Пример: ПолучитьИндексПоИмени("Телефон_1") вернет 1
// ПолучитьИндексПоИмени("Телефон_0") вернет 0
// ПолучитьИндексПоИмени("Телефон") вернет 0
// ***********************************************************************************************
Функция ПолучитьИндексПоИмени(Знач Имя) Экспорт
ИмяДлина = СтрДлина(Имя);
ПозицияСпецСимвола = СтрНайти(Имя, "_", НаправлениеПоиска.СКонца);
Попытка Возврат Цел(Прав(Имя, ИмяДлина - ПозицияСпецСимвола));
Исключение Возврат 0;
КонецПопытки;
КонецФункции // ПолучитьИндексПоИмени()
// ***********************************************************************************************
// Возвращает ссылку на элемент формы, заданный при помощи спецзнака "_" или без для 0 индекса
//
// Пример: ПолучитьЭлементПоИндексу(ЭтаФорма, 1, "Телефон") вернет ссылку на Элементы.Телефон_1
// ПолучитьЭлементПоИндексу(ЭтаФорма, , "Телефон") вернет ссылку на Элементы.Телефон
//
// ПолучитьЭлементПоИндексу(ЭтаФорма, 0, "Телефон") вернет ссылку на Элементы.Телефон_0,
// если Элементы.Телефон_0 не найден вернет ссылку на Элементы.Телефон
// ***********************************************************************************************
Функция ПолучитьЭлементПоИндексу(Форма, Индекс = Неопределено, ШаблонИмени) Экспорт
Элемент = Форма.Элементы.Найти(ШаблонИмени + ?(Индекс = Неопределено, "", "_" + Индекс));
Если Элемент = Неопределено И Индекс = 0 Тогда
Элемент = Форма.Элементы.Найти(ШаблонИмени);
КонецЕсли;
Возврат Элемент;
КонецФункции // ПолучитьЭлементПоИндексу()
// ***********************************************************************************************
// Ищет в группе команды соответствующие шаблону и устанавливает у них параметр видимость
//
// Пример: НайтиКомандуПоШаблонуИУстановитьВидимость(Форма.Элементы.ГруппаEmail, "Удалить", Ложь)
// ***********************************************************************************************
Процедура НайтиКомандуПоШаблонуИУстановитьВидимость(ГруппаПоиска, ШаблонПоиска, Состояние) Экспорт
Для Каждого Элемент Из ГруппаПоиска.ПодчиненныеЭлементы Цикл
Если ТипЗнч(Элемент) = Тип("КнопкаФормы") И СтрНайти(Элемент.Имя, ШаблонПоиска) <> 0 Тогда
Элемент.Доступность = Состояние;
ИначеЕсли ТипЗнч(Элемент) = Тип("ГруппаФормы") Тогда
НайтиКомандуПоШаблонуИУстановитьВидимость(Элемент, ШаблонПоиска, Состояние);
ИначеЕсли ТипЗнч(Элемент) = Тип("ПолеФормы") Тогда
НайтиКомандуПоШаблонуИУстановитьВидимость(Элемент.КонтекстноеМеню, ШаблонПоиска, Состояние)
КонецЕсли;
КонецЦикла;
КонецПроцедуры // НайтиКомандуПоШаблонуИУстановитьВидимость()
// ***********************************************************************************************
// Добавляет строку в таблицу и настраивает видимость элементов, возвращает ссылку на строку
//
// Пример: ДобавитьСтроку(ЭтаФорма, Объект.Телефоны, Элементы.ГруппаТелефон, 10)
// ***********************************************************************************************
Функция ДобавитьСтроку(Форма, ТаблицаИсточникДанных, ГруппаИсточник, МаксКоличествоСтрок = Неопределено, СкрытьЗаголовок = Истина) Экспорт
Строка = Неопределено;
Если ТаблицаИсточникДанных.Количество() <> МаксКоличествоСтрок Тогда
// Определяем текущую строку и индекс группы
Строка = ТаблицаИсточникДанных.Добавить();
Индекс = ТаблицаИсточникДанных.Количество() - 1;
// Устанавливаем видимость группы
ГруппаКопии = TableAsInputField.ПолучитьЭлементПоИндексу(Форма, Индекс, ГруппаИсточник.Имя);
Если ГруппаКопии <> Неопределено Тогда
ГруппаКопии.Видимость = Истина;
Иначе
ГруппаКопии = СкопироватьЭлемент(Форма, ГруппаИсточник, Индекс, СкрытьЗаголовок);
#Если Не Сервер Тогда
ВызватьИсключение("Создавать элементы формы можно только в серверной процедуре!" + Символы.ПС + ОписаниеОшибки());
#КонецЕсли
КонецЕсли;
// Устанавливаем доступность команды "удалить"
НайтиКомандуПоШаблонуИУстановитьВидимость(ГруппаКопии, "Удалить", Истина);
Форма.Модифицированность = Истина;
КонецЕсли;
Возврат Строка;
КонецФункции // ДобавитьСтроку()
// ***********************************************************************************************
// Удаляет строку из таблицы и настраивает видимость элементов
//
// Пример: УдалитьСтроку(ЭтаФорма, Объект.Телефоны, Элементы.ГруппаТелефон, Истина, "Уверены?")
// УдалитьСтроку(ЭтаФорма, Объект.Телефоны, Элементы.ГруппаТелефон)
// ***********************************************************************************************
&НаКлиенте
Асинх Процедура УдалитьСтроку(Форма, ТаблицаИсточникДанных, ГруппаИсточник, ЗадатьВопрос = Ложь, Вопрос = Неопределено) Экспорт
Строка = ТаблицаИсточникДанных[TableAsInputField.ПолучитьИндексПоИмени(Форма.ТекущийЭлемент.Имя)];
Индекс = ТаблицаИсточникДанных.Количество() - 1;
Вопрос = ?(Вопрос = Неопределено, "Удалить текущую запись?", Вопрос);
Подтверждено = ?(ЗадатьВопрос = Истина,
Ждать ВопросАсинх(Вопрос, РежимДиалогаВопрос.ДаНет, 0, КодВозвратаДиалога.Нет),
КодВозвратаДиалога.Да);
Если Подтверждено = КодВозвратаДиалога.Да Тогда
// Удаляем текущую строку
ТаблицаИсточникДанных.Удалить(Строка);
// Устанавливаем видимость группы
ГруппаКопии = TableAsInputField.ПолучитьЭлементПоИндексу(Форма, Индекс, ГруппаИсточник.Имя);
Если ГруппаКопии <> Неопределено И ТаблицаИсточникДанных.Количество() <> 0 Тогда
ГруппаКопии.Видимость = Ложь;
КонецЕсли;
// На ВебКлиенте при скрытии элементов формы, поля не обновляются,
// поэтому получаем группу для их принудительного обновления
#Если ВебКлиент Тогда
ГруппаРодитель = Форма.Элементы.Найти(ГруппаИсточник.Родитель.Имя);
#КонецЕсли
// Устанавливаем доступность команды "удалить"
НайтиКомандуПоШаблонуИУстановитьВидимость(ГруппаКопии, "Удалить", Ложь);
Форма.Модифицированность = Истина;
// Если ВебКлиент, обновляем все элементы группы родителя принудительно
#Если ВебКлиент Тогда
Форма.ОбновитьОтображениеДанных(ГруппаРодитель);
#КонецЕсли
КонецЕсли;
КонецПроцедуры // УдалитьСтроку()
// ***********************************************************************************************
// Устанавливает видимость групп для вывода талицы как отдельных полей ввода строк
// *Если поле не найдено, создает его программно
//
// Пример: ВывестиСтрокиТаблицыИсточника(ЭтаФорма, Объект.Телефоны, Элементы.ГруппаТелефон)
// ***********************************************************************************************
Процедура ВывестиСтрокиТаблицыИсточника(Форма, ТаблицаИсточникДанных, ГруппаИсточник, СкрытьЗаголовок = Истина) Экспорт
#Если Сервер Тогда
// Обходим все элементы таблицы источника данных
Для Индекс = 0 To ТаблицаИсточникДанных.Количество() - 1 Цикл
// Устанавливаем видимость группы
ГруппаКопии = TableAsInputField.ПолучитьЭлементПоИндексу(Форма, Индекс, ГруппаИсточник.Имя);
Если ГруппаКопии <> Неопределено Тогда
ГруппаКопии.Видимость = ГруппаИсточник.Видимость;
Иначе
ГруппаКопии = СкопироватьЭлемент(Форма, ГруппаИсточник, Индекс, СкрытьЗаголовок);
КонецЕсли;
// Устанавливаем доступность команды "удалить"
НайтиКомандуПоШаблонуИУстановитьВидимость(ГруппаКопии, "Удалить", Истина);
КонецЦикла;
#Иначе
ВызватьИсключение("Функция ВывестиСтрокиТаблицыИсточника может быть вызвана только в серверной процедуре!
|Например, внутри процедуры ПриСозданииНаСервере()" + Символы.ПС + ОписаниеОшибки());
#КонецЕсли
КонецПроцедуры // ВывестиСтрокиТаблицыИсточника()
// ***********************************************************************************************
// Процедура создает копию элемента формы
//
// Форма - Форма источник
// Источник - элемент который копируется
// Группа - необязательный параметр, группа куда будет вставлен скопированный элемент
// Индекс - индекс строки в пути к данным поля ввода
// СкрытьЗаголовок - если значение Истина, заголовок будет скрыт
// ***********************************************************************************************
Функция СкопироватьЭлемент(Форма, Источник, Индекс, СкрытьЗаголовок, Группа = Неопределено)
// Определяем группу родитель и текущий вызов на рекурсию
Если Группа = Неопределено Тогда
Группа = Форма.Элементы.Найти(Источник.Родитель.Имя);
ЭтоРекурсия = Ложь;
Иначе
ЭтоРекурсия = Истина;
КонецЕсли;
// Добавляем элемент формы
Копия = Форма.Элементы.Добавить(Источник.Имя + "_" + Индекс, ТипЗнч(Источник), Группа);
// Копируем реквизиты и параметры элемента из элемента источника
Если ТипЗнч(Источник) = Тип("ГруппаФормы") Тогда
СкопироватьГруппуФормыБезЭлементов(Форма, Источник, Копия);
// Отключаем видимость группы пока не будут скопированы все элементы
Если ЭтоРекурсия = Ложь Тогда
Копия.Видимость = Ложь;
КонецЕсли;
СкопироватьПодчиненныеЭлементы(Форма, Копия, Источник, Индекс, СкрытьЗаголовок);
ИначеЕсли ТипЗнч(Источник) = Тип("ПолеФормы") Тогда
Если Группа <> Неопределено И СкрытьЗаголовок = Истина Тогда
Цвет = ?(Группа.ЦветФона.Вид = ВидЦвета.АвтоЦвет, New Цвет(255, 255, 255), Группа.ЦветФона);
Иначе
Цвет = Неопределено;
КонецЕсли;
СкопироватьПолеФормы(Форма, Источник, Копия, Индекс, Цвет);
СкопироватьПодчиненныеЭлементы(Форма, Копия.КонтекстноеМеню, Источник.КонтекстноеМеню, Индекс, СкрытьЗаголовок);
Иначе
ЗаполнитьЗначенияСвойств(Копия, Источник);
КонецЕсли;
// Все элементы скопированы, возвращаем видимость группы
Если ЭтоРекурсия = Ложь Тогда
Копия.Видимость = Источник.Видимость;
Возврат Копия;
КонецЕсли;
КонецФункции // СкопироватьЭлемент()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура СкопироватьПодчиненныеЭлементы(Форма, ГруппаКопии, Источник, Индекс, СкрытьЗаголовок)
Для Каждого Элемент Из Источник.ПодчиненныеЭлементы Цикл
СкопироватьЭлемент(Форма, Элемент, Индекс, СкрытьЗаголовок, ГруппаКопии);
КонецЦикла;
КонецПроцедуры // СкопироватьПодчиненныеЭлементы()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура СкопироватьПолеФормы(Форма, Источник, Копия, Индекс, ЦветЗаголовка)
Если ТипЗнч(Источник) = Тип("ПолеФормы") Тогда
Копия.Вид = Источник.Вид;
// Ищем опреатор []
ЛевСкобка = СтрНайти(Источник.ПутьКДанным, "[");
ПрвСкобка = СтрНайти(Источник.ПутьКДанным, "[");
Размер = СтрДлина(Источник.ПутьКДанным);
Если ЛевСкобка = 0 ИЛИ ПрвСкобка = 0 Тогда
Копия.ПутьКДанным = Источник.ПутьКДанным;
Иначе
Копия.ПутьКданным = Лев(Источник.ПутьКДанным, ЛевСкобка) + Индекс + Прав(Источник.ПутьКДанным, Размер - ПрвСкобка - 1);
КонецЕсли;
Если Источник.Вид = ВидПоляФормы.ПолеВвода Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,, "ВыделенныйТекст, СвязьПоТипу, ПутьКДанным");
Если Источник.СвязьПоТипу.ПутьКДанным <> "" Тогда
ПутьКДаннымСвязиПриемника = СтрЗаменить(Источник.СвязьПоТипу.ПутьКДанным, Источник.Имя, Копия.Имя);
Копия.СвязьПоТипу = New СвязьПоТипу(ПутьКДаннымСвязиПриемника, Источник.СвязьПоТипу.ЭлементСвязи);
КонецЕсли;
ЗаполнитьКоллекциюСвойств(Копия.СписокВыбора, Источник.СписокВыбора);
ИначеЕсли Источник.Вид = ВидПоляФормы.ПолеПереключателя Тогда
ЗаполнитьКоллекциюСвойств(Копия.СписокВыбора, Источник.СписокВыбора);
ЗаполнитьЗначенияСвойств(Копия, Источник,,"ПутьКДанным");
ИначеЕсли Источник.Вид = ВидПоляФормы.ПолеТекстовогоДокумента Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,,"ПутьКДанным, ВыделенныйТекст");
ИначеЕсли Источник.Вид = ВидПоляФормы.ПолеФорматированногоДокумента Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,,"ПутьКДанным, ВыделенныйТекст");
Иначе
ЗаполнитьЗначенияСвойств(Копия, Источник,,"ПутьКДанным");
КонецЕсли;
Если ЦветЗаголовка <> Неопределено Тогда
Копия.ЦветТекстаЗаголовка = ЦветЗаголовка;
КонецЕсли;
СкопироватьСобытия(Копия, Источник);
КонецЕсли;
КонецПроцедуры // СкопироватьПолеФормы()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура СкопироватьГруппуФормыБезЭлементов(Форма, Источник, Копия)
Если ТипЗнч(Источник) = Тип("ГруппаФормы") Тогда
Копия.Вид = Источник.Вид;
Если Источник.Вид = ВидГруппыФормы.ОбычнаяГруппа Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,, "ПутьКДаннымЗаголовка");
ИначеЕсли Источник.Вид = ВидГруппыФормы.Страницы Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,, "ТекущаяСтраница");
СкопироватьСобытия(Копия, Источник);
ИначеЕсли Источник.Вид = ВидГруппыФормы.Страница Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,, "ПутьКДаннымЗаголовка");
ИначеЕсли Источник.Вид = ВидГруппыФормы.ГруппаКолонок Тогда
ЗаполнитьЗначенияСвойств(Копия, Источник,, "ПутьКДаннымШапки");
Иначе
ЗаполнитьЗначенияСвойств(Копия, Источник);
КонецЕсли;
КонецЕсли;
КонецПроцедуры // СкопироватьГруппуФормыБезЭлементов()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура ЗаполнитьКоллекциюСвойств(КолекцияКопия, КолекцияИсточник)
Для Каждого Элемент Из КолекцияИсточник Цикл
ЗаполнитьЗначенияСвойств(КолекцияКопия.Добавить(), Элемент);
КонецЦикла;
КонецПроцедуры // ЗаполнитьКоллекциюСвойств()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура СкопироватьСобытие(Копия, Источник, ИмяСобытия)
Действие = Источник.ПолучитьДействие(ИмяСобытия);
Если Действие <> "" Тогда
Копия.УстановитьДействие(ИмяСобытия, Действие);
КонецЕсли;
КонецПроцедуры // СкопироватьСобытие()
// ***********************************************************************************************
// Сервисная процедура
// ***********************************************************************************************
Процедура СкопироватьСобытия(Копия, Источник)
СкопироватьСобытие(Копия, Источник, "Приизменении");
СкопироватьСобытие(Копия, Источник, "НачалоВыбора");
СкопироватьСобытие(Копия, Источник, "НачалоВыбораИзСписка");
СкопироватьСобытие(Копия, Источник, "Очистка");
СкопироватьСобытие(Копия, Источник, "Выбор");
СкопироватьСобытие(Копия, Источник, "Регулирование");
СкопироватьСобытие(Копия, Источник, "Открытие");
СкопироватьСобытие(Копия, Источник, "ОбработкаВыбора");
СкопироватьСобытие(Копия, Источник, "АвтоПодбор");
СкопироватьСобытие(Копия, Источник, "ОкончаниеВводаТекста");
СкопироватьСобытие(Копия, Источник, "ПриОбновленииСоставаПользовательскихНастроекНаСервере");
СкопироватьСобытие(Копия, Источник, "ПриНачалеРедактирования");
СкопироватьСобытие(Копия, Источник, "ПередНачаломДобавления");
СкопироватьСобытие(Копия, Источник, "ПередНачаломизменения");
СкопироватьСобытие(Копия, Источник, "ПриАктивизацииСтроки");
КонецПроцедуры // СкопироватьСобытия()