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