1с как вывести таблицу значений на форму 1с
Приветствую всех читателям infostart’a. Данная статья будет посвящена вопросу создания произвольной таблицы значений на форме управляемого приложения программным способом.
Особенности задачи.
Каждый, кто программировал в обычном приложении, часто сталкивался с задачей получения произвольной таблицы значений на форме. Под произвольной таблицей значений понимается таблица, количество и тип колонок которой наперед не известно. То есть колонок может быть 3, а может 6, а может 8. В обычном приложении все просто: можно было на форме обработки разместить элемент «ТаблицаЗначений»,и затем передать в этот элемент созданную таблицу значений программным способом. Потом простой командой:
получить готовую таблицу значений на форме. Казалось бы, что может быть проще.
Это все было в обычном приложении. В управляемом приложении все изменилось. Так просто произвольную таблицу не создать. Теперь нужно либо жестко параметризировать таблицу значений на форме, либо создавать ее программным способом (описывать,ну, в этом, собственно, и суть самого управляемого приложения). Это мы и попробуем сделать: программными средствами создать произвольную таблицу значений на управляемой форме.
Решение задачи.
Первое, что мы должны сделать, это определить, как таблица появится на форме. Главное, что никакого элемента формы в обработке создавать не нужно. Мы его создадим программным способом, как и всю таблицу. То есть таблица будет описана, и создаваться в момент открытия формы или с помощью кнопки – это кому как нужно.
Создание таблицы на форме происходит через описание таблицы значений как реквизита:
Теперь мы должны создать программную таблицу значений, которая содержит данные. Если таблица значений будет получена из запроса, то все более - менее порядок. Если таблица создается вручную, то значение колонок, которые будут содержать числа или даты могут быть созданы через «ОписаниеТипов». Суть в том, что колонки в таблице значений обязательно должны иметь какой-то тип. Если, например,предполагается, что пользователь будет заполнять данные в этих колонках интерактивно, то нельзя добавлять колонку таблицы значений просто с именем, она должна иметь тип. Имейте ввиду – это очень важно т.к. эти типы мы передадим в таблицу на форме.
Создаем таблицу, которая содержит несколько колонок:
Далее мы заполним нашу программную таблицу ТЗ нужными данными. Получаем таблицу ТЗ, которая содержит необходимые значения и готова к передаче в созданный реквизит формы.
Вот такая нехитрая комбинация и наша таблица готова.
Далее укажем путь к данным и, например, можем установить ширину колонок:
Условное оформление, если нам нужно мы также пишем вручную,командное меню – вручную. Обработчики таблицы также пишутся руками. Например,что бы добавить обработчик события таблицы «Выбор»:
Для обработки данного события в форме процедуры прописывается отдельная процедура:
Обратите внимание, что обработчики таблицы срабатывают на клиенте и поэтому должны иметь команду указатель компилятора
Ну, и последнее что хотелось добавить, что после всех этих действий обязательно не забываем передать готовую таблицу в реквизит формы:
Вот что имеем в результате:
А вот обработка события "Выбор":
Послесловие.
Надеюсь, статья окажет помощь тем программистам 1С, которые начинают создавать таблицы на форме программным способом.
Вы можете скачать обработку, которая программным способом создает таблицу значения и выводит на управляемую форму с комментариями,которые помогут Вам создавать свои таблицы.
Функционал данного механизма служит для программного вывода "Таблицы значений" в реквизит управляемой формы с типом "ДанныеФормыКоллекция". Может быть полезен в задачах, где состав колонок выгружаемой таблицы значений может меняться.
Механизм предусматривает работу как с реквизитом объекта, так и с реквизитом формы.
И по сути является аналогом метода обычных форм:
Также реализована возможность быстрого добавления колонки «Отметка» и настройки доступности кнопок полей. Процедура должна быть размещена в модуле формы.
Специальные предложения
Использование метода "Сообщить" - нарушение стандартов и методик разработки.
(6) Ну. скажем так, они сами свои стандарты не очень-то соблюдают. Это не самое страшное из всей этой публикации.
Ну и по мелочам: "НЕ ЭлементКолонки = Неопределено" это два логических действия, лучше писать "ЭлементКолонки<>Неопределено".
1С 8.3 Динамический вывод Таблицы значений на форму
Процедура Вывести_ТЗ_в_Таблицу_на_форме ( ТЗ , ТабРеквизитФормы , ТабЭлементФормы = Неопределено) Экспорт
// Процедура позволяет выводить любое количество таблиц значений в таблицу формы
// (с различным количеством и названиями полей). При изменении выводимых данных –
// таблица на форме программно очищается и заменяется на новую с новым составом
// полей и данных соответствующей таблицы значений.
Если ТабЭлементФормы = Неопределено Тогда // проверка передан ли элемент формы
ТабЭлементФормы = ТабРеквизитФормы ;
КонецЕсли;
Реквизиты_для_удаления = Новый Массив ;
Элементы_для_удаления = Новый Массив ;
Реквизиты_для_вывода = Новый Массив ;
// Получаем данные (на которые элементы формы ссылаются)
// по добавленным ранее реквизитам и элементам формы
Для Каждого Элемент Из Элементы [ ТабЭлементФормы ]. ПодчиненныеЭлементы Цикл
Реквизиты_для_удаления . Добавить ( Элемент . ПутьКДанным );
Элементы_для_удаления . Добавить ( Элемент );
КонецЦикла;
// Удаляем элементы
Для Каждого УдалитьЭлемент Из Элементы_для_удаления Цикл
Элементы . Удалить ( УдалитьЭлемент );
КонецЦикла;
// Добавляем колонки из Таблицы значений в реквизит ТабРеквизитФормы
Для Каждого КолонкаТЗ Из ТЗ . Колонки Цикл
Реквизиты_для_вывода = Новый РеквизитФормы ( КолонкаТЗ . Имя , КолонкаТЗ . ТипЗначения , ТабРеквизитФормы , КолонкаТЗ . Заголовок );
Реквизиты_для_вывода . Добавить ( Реквизиты_для_вывода );
КонецЦикла;
// Удаляем старые реквизиты и выводим новые реквизиты
ИзменитьРеквизиты ( Реквизиты_для_вывода , Реквизиты_для_удаления );
// Добавляем колонки из Таблицы значений
// в элементы ТабЭлементФормы (со ссылкой на колонки в ТабРеквизитФормы)
Для Каждого КолонкаТЗ Из ТЗ . Колонки Цикл
ЭлементТЗ = Элементы . Добавить ( ТабРеквизитФормы + "_" + КолонкаТЗ . Имя , Тип ( "ПолеФормы" ), Элементы [ ТабЭлементФормы ]);
ЭлементТЗ . Вид = ВидПоляФормы . ПолеНадписи ; //Или ПолеВвода, или что-то другое;
ЭлементТЗ . ПутьКДанным = ТабРеквизитФормы + "." + КолонкаТЗ . Имя ;
КонецЦикла;
// В реквизит загружаем Таблицу значений
ЭтаФорма [ ТабРеквизитФормы ]. Загрузить ( ТЗ );
1С 8.3 Программное создание таблицы значений на форме в управляемом приложении
&НаСервере
Процедура ПриОткрытииНаСервере ()
// Описание таблицы значений как реквизита
МассивТипа = Новый Массив ;
МассивТипа . Добавить ( Тип ( "ТаблицаЗначений" ));
// Добавление ТаблицыЗначений в массив реквизитов
ОписаниеТипа = Новый ОписаниеТипов ( МассивТипа );
МассивРеквизитовФормы = Новый Массив ;
МассивРеквизитовФормы . Добавить (Новый РеквизитФормы ( "ТаблицаСотрудников" , ОписаниеТипа , "" , "ТЗСотр" ));
// Создание ТаблицыЗначений с описанием колонок
КвалификаторыСтроки = Новый КвалификаторыСтроки ( 10 );
ОписаниеСтроки_10 = Новый ОписаниеТипов ( "Строка" , , КвалификаторыСтроки );
ОписаниеСотрудника = Новый ОписаниеТипов ( "СправочникСсылка.Сотрудники" );
ТЗ = Новый ТаблицаЗначений ;
ТЗ . Колонки . Добавить ( "Код" , ОписаниеСтроки_10 );
ТЗ . Колонки . Добавить ( "Сотрудник" , ОписаниеСотрудника );
// ТЗ.Колонки.Добавить - можно и в цикле
// Добавление в массив реквизитов колонок ТаблицыЗначений
Для Каждого Колонка Из ТЗ . Колонки Цикл
МассивРеквизитовФормы . Добавить (Новый РеквизитФормы ( Колонка . Имя , Колонка . ТипЗначения , "ТаблицаСотрудников" ));
КонецЦикла;
// Удаление - если таблица существует
ЭлементТаблица = Элементы . Найти ( "ТаблицаСотрудников" );
Если ЭлементТаблица <> Неопределено Тогда
Элементы . Удалить ( ЭлементТаблица );
Иначе
ИзменитьРеквизиты ( МассивРеквизитовФормы );
КонецЕсли;
// Добавление ТаблицыЗначений на форму
ТаблицаПолейВыбора = Элементы . Добавить ( "ТЗСотр" , Тип ( "ТаблицаФормы" ));
ТаблицаПолейВыбора . ПутьКДанным = "ТаблицаСотрудников" ;
ТаблицаПолейВыбора . Отображение = ОтображениеТаблицы . Список ;
ТаблицаПолейВыбора . ПоложениеКоманднойПанели = ПоложениеКоманднойПанелиЭлементаФормы . Нет ; // Отключение командной панели
Для Каждого Колонка Из ТЗ . Колонки Цикл
НовыйЭлемент = Элементы . Добавить ( Колонка . Имя , Тип ( "ПолеФормы" ), ТаблицаПолейВыбора );
НовыйЭлемент . Вид = ВидПоляФормы . ПолеВвода ;
НовыйЭлемент . ПутьКДанным = "ТаблицаСотрудников." + Колонка . Имя ;
НовыйЭлемент . Ширина = 10 ;
// Заполнение ТаблицыЗначений
Запрос = Новый Запрос ;
Запрос . Текст =
"ВЫБРАТЬ
| Сотрудники.Код КАК Код,
| Сотрудники.ГоловнаяОрганизация КАК ГоловнаяОрганизация,
| Сотрудники.Ссылка КАК Ссылка,
| Сотрудники.Наименование КАК Наименование
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|
|УПОРЯДОЧИТЬ ПО
| Наименование" ;
РезультатЗапроса = Запрос . Выполнить ();
ВыборкаДетальныеЗаписи = РезультатЗапроса . Выбрать ();
Пока ВыборкаДетальныеЗаписи . Следующий () Цикл
Строка = ТЗ . Добавить ();
Строка . Код = ВыборкаДетальныеЗаписи . Код ;
Строка . Сотрудник = ВыборкаДетальныеЗаписи . Ссылка ;
КонецЦикла;
// Передача ТаблицыЗначений в реквизит формы
ЗначениеВРеквизитФормы ( ТЗ , "ТаблицаСотрудников" );
// Процедура - Программный вывод таблицы значений в таблицу на форму
//
// Параметры:
// ТаблицаЗначенийДляВывода - ТаблицаЗначений - ТаблицаЗначений для вывода на форму
// ИмяРеквизитаФормы - Строка - Наименование реквизита формы ДанныеФормыКоллекция
// ИспользованиеКолонкиОтметка - Булево - Вывод колокни отметка
// ТолькоКнопкаОткрытия - Булево - Отображение кнопок
//
&НаСервере
Процедура ПрограммныйВыводТаблицыЗначенийВТаблицуНаФорму ( ТаблицаЗначенийДляВывода , ИмяРеквизитаФормы , ИспользованиеКолонкиОтметка = Ложь, ТолькоКнопкаОткрытия = Истина)
// Функционал данного механизма служит для программного вывода "Таблицы значений"
// в реквизит управляемой формы с типом "ДанныеФормыКоллекция". Может быть полезен
// в задачах, где состав колонок выгружаемой таблицы значений может меняться.
// Механизм предусматривает работу как с реквизитом объекта, так и с реквизитом формы.
// Также реализована возможность быстрого добавления колонки «Отметка» и настройки доступности кнопок полей.
// Процедура должна быть размещена в модуле формы.
Если ТипЗнч ( ТаблицаЗначенийДляВывода ) = Тип ( "ТаблицаЗначений" ) Тогда
Если ТипЗнч ( ИмяРеквизитаФормы ) = Тип ( "Строка" ) Тогда
// Опрелеляем является заполняемый реквизит, реквизитом объекта или реквизитом формы
Если Объект . Свойство ( ИмяРеквизитаФормы ) И ТипЗнч ( Объект [ ИмяРеквизитаФормы ]) = Тип ( "ДанныеФормыКоллекция" ) Тогда
ПутьКДаннымФормыКоллекция = "Объект." + ИмяРеквизитаФормы ;
ОбъектДляОтображенияНаФорме = РеквизитФормыВЗначение ( "Объект." + ИмяРеквизитаФормы );
ЭтоРеквизитОбъекта = Истина;
ИначеЕсли ТипЗнч ( ЭтаФорма [ ИмяРеквизитаФормы ]) = Тип ( "ДанныеФормыКоллекция" ) Тогда
ПутьКДаннымФормыКоллекция = ИмяРеквизитаФормы ;
ОбъектДляОтображенияНаФорме = РеквизитФормыВЗначение ( ИмяРеквизитаФормы , Тип ( "ТаблицаЗначений" ));
ЭтоРеквизитОбъекта = Ложь;
КонецЕсли;
КонецЕсли;
МассивУдаляемыхРеквизитов = Новый Массив ;
МассивДобавляемыхРеквизитов = Новый Массив ;
МассивИсключаемыхРеквизитов = Новый Массив ;
// Формируем массив колонок для удаления
Для Каждого Колонка Из ОбъектДляОтображенияНаФорме . Колонки Цикл
МассивУдаляемыхРеквизитов . Добавить ( ПутьКДаннымФормыКоллекция + "." + Колонка . Имя );
КонецЦикла;
// Удаляем колонки с формы
Для Каждого Колонка Из ОбъектДляОтображенияНаФорме . Колонки Цикл
ЭлементКолонки = Элементы . Найти ( ИмяРеквизитаФормы + Колонка . Имя );
Если НЕ ЭлементКолонки = Неопределено Тогда
Элементы . Удалить ( ЭлементКолонки );
КонецЕсли;
КонецЦикла;
// Добавляем колонку "Отметка"
Если ИспользованиеКолонкиОтметка Тогда
НоваяКолонка = Новый РеквизитФормы ( "Отметка" , Новый ОписаниеТипов ( "Булево" ), ПутьКДаннымФормыКоллекция );
МассивДобавляемыхРеквизитов . Добавить ( НоваяКолонка );
КонецЕсли;
// Формируем массив колонок из таблицы значений
Для Каждого Колонка Из ТаблицаЗначенийДляВывода . Колонки Цикл
Если Колонка . ТипЗначения . Типы (). Найти ( Тип ( "Тип" )) = Неопределено Тогда
НоваяКолонка = Новый РеквизитФормы ( Колонка . Имя , Новый ОписаниеТипов ( Колонка . ТипЗначения . Типы ()), ПутьКДаннымФормыКоллекция );
МассивДобавляемыхРеквизитов . Добавить ( НоваяКолонка );
Иначе
Сообщить ( "Колонка " + Строка ( Колонка . Имя ) + " с типом: не может быть выгружена" );
МассивИсключаемыхРеквизитов . Добавить ( Колонка );
КонецЕсли;
КонецЦикла;
// Обновляем реквизиты формы
ИзменитьРеквизиты ( МассивДобавляемыхРеквизитов , МассивУдаляемыхРеквизитов );
//Создаем элементы на форме для отображения колонок
ЭлементТЗ = Элементы [ ИмяРеквизитаФормы ];
// Добавляем колонки из таблицы
Для Каждого Колонка Из ТаблицаЗначенийДляВывода . Колонки Цикл
Если МассивИсключаемыхРеквизитов . Найти ( Колонка ) = Неопределено Тогда
НовыйЭлементФормы = Элементы . Добавить ( ИмяРеквизитаФормы + Колонка . Имя , Тип ( "ПолеФормы" ), ЭлементТЗ );
НовыйЭлементФормы . Вид = ВидПоляФормы . ПолеВвода ;
// Устанавливаем доступность кнопок
Если ТолькоКнопкаОткрытия Тогда
НовыйЭлементФормы . РедактированиеТекста = Ложь;
НовыйЭлементФормы . ВыбиратьТип = Ложь;
НовыйЭлементФормы . КнопкаВыбора = Ложь;
НовыйЭлементФормы . КнопкаВыпадающегоСписка = Ложь;
НовыйЭлементФормы . КнопкаОткрытия = Истина;
НовыйЭлементФормы . КнопкаОчистки = Ложь;
Иначе
НовыйЭлементФормы . РедактированиеТекста = Истина;
НовыйЭлементФормы . ВыбиратьТип = Истина;
НовыйЭлементФормы . КнопкаВыбора = Истина;
НовыйЭлементФормы . КнопкаВыпадающегоСписка = Истина;
НовыйЭлементФормы . КнопкаОткрытия = Истина;
НовыйЭлементФормы . КнопкаОчистки = Истина;
КонецЕсли;
НовыйЭлементФормы . КнопкаРегулирования = Ложь;
НовыйЭлементФормы . КнопкаСоздания = Ложь;
НовыйЭлементФормы . КнопкаСпискаВыбора = Ложь;
НовыйЭлементФормы . ИсторияВыбораПриВводе = ИсторияВыбораПриВводе . НеИспользовать ;
НовыйЭлементФормы . БыстрыйВыбор = Ложь;
НовыйЭлементФормы . ПутьКДанным = ПутьКДаннымФормыКоллекция + "." + Колонка . Имя ;
КонецЕсли;
КонецЦикла;
// Загружаем таблицу значений в данные формы коллекцию
Если ЭтоРеквизитОбъекта Тогда
Объект [ ИмяРеквизитаФормы ]. Загрузить ( ТаблицаЗначенийДляВывода );
Иначе
ЭтаФорма [ ИмяРеквизитаФормы ]. Загрузить ( ТаблицаЗначенийДляВывода );
КонецЕсли;
Иначе
Сообщить ( "Выводить можно только таблицу значений" );
КонецЕсли;
Исключение
ОбщегоНазначенияКлиентСервер . СообщитьПользователю ( ОписаниеОшибки ());
КонецПопытки;
Читайте также: