Как данныеформыколлекция перевести в таблицу значений 1с
Поиск в коллекциях значений
Область применения: управляемое приложение, мобильное приложение, обычное приложение.
1. При двух и более операциях поиска в объекте ТаблицаЗначений с большим количеством строк (*) рекомендуется:
- Индексировать колонки, по которым выполняется поиск;
- Но только те из них, которые обладают хорошей селективностью (т.е. каждому значению этой колонки должно соответствовать небольшое количество строк). В противном случае, индексирование не даст эффекта, либо он будет отрицательным (потрачено лишнее время на индексирование).
* Примечание: следует ориентироваться на 1000 строк и более, а также учитывать не только размер таблицы, в которой выполняется поиск, но и сколько раз он выполняется. Например, даже если таблица относительно небольшая в 100 строк, но поиск по ней выполняется 100 раз, ее тоже имеет смысл индексировать. В то же время, нет смысла индексировать таблицу из-за только одной единственной операции поиска.
2. Для поиска значений предусмотрены два метода объекта ТаблицаЗначений :
При поиске значения в одной колонке таблицы значений оба метода одинаково эффективно используют индекс, если он был задан (см. п.1).
Однако при поиске значения сразу по нескольким (или по всем) колонкам необходимо учитывать следующие ограничения.
2.1. Не следует использовать метод Найти для поиска по нескольким колонкам в таблицах значений с большим количеством строк, даже если проиндексированы все колонки, обладающие хорошей селективностью. Это ограничение вызвано тем, что метод Найти выполняет поиск с применением индекса только по одному полю.
Например:
ТЗ.Индексы.Добавить("Колонка1");
ТЗ.Индексы.Добавить("Колонка2");
. = ТЗ.Найти("найдется все", "Колонка1, Колонка2"); // Индекс НЕ используется!
В этом примере, несмотря на наличие индекса для колонок Колонка1 и Колонка2 , поиск все равно будет выполняться перебором всех строк в таблице значений (что очень ресурсоемко на больших объемах данных).
2.2. При использовании метода НайтиСтроки в таблицах значений с большим количеством строк следует обеспечить, чтобы список полей индекса был точно таким же, как он задан в структуре поиска (порядок полей не важен). В противном случае, индекс не будет задействован, и поиск будет выполняться перебором всех строк в таблице значений (что очень ресурсоемко на больших объемах данных).
Например:
ТЗ.Индексы.Добавить("Колонка1"); // Индекс1
ТЗ.Индексы.Добавить("Колонка2"); // Индекс2
. = ТЗ.НайтиСтроки(Новый Структура("Колонка1, Колонка2 ", "Ищу1","Ищу2")); // Индекс НЕ используется!
. = ТЗ.НайтиСтроки(Новый Структура("Колонка1", "Ищу1") ); // OK - используется Индекс1
. = ТЗ.НайтиСтроки(Новый Структура("Колонка2", "Ищу2") ); // OK - используется Индекс2
. = ТЗ.НайтиСтроки(Новый Структура("Колонка1, Колонка2", "Ищу1","Ищу2")); // OK - индекс используется
. = ТЗ.НайтиСтроки(Новый Структура("Колонка2, Колонка1", "Ищу2","Ищу1")); // OK - индекс используется
. = ТЗ.НайтиСтроки(Новый Структура("Колонка1", "Ищу1") ); // Индекс НЕ используется!
. = ТЗ.НайтиСтроки(Новый Структура("Колонка2", "Ищу2") ); // Индекс НЕ используется!
2.3. Аналогичное ограничение действует и для метода Скопировать таблицы значений при вызове с параметром ПараметрыОтбора ( Структура ).
3. В тех случаях, когда для таблицы значений применяется сортировка по колонкам, содержащим ссылочные значения, необходимо учитывать, что при этом для каждой из этих колонок для всех строк таблицы значений системой будет выполнено обращение к информационной базе за представлением этой ссылки.
- В тех случаях, когда требуется сортировка по наименованию – сразу, на этапе заполнения, добавлять в таблицу дополнительные колонки с представлениями, и сортировку выполнять уже по ним. Если, конечно, это не вызовет аналогичных многократных обращений к информационной базе;
- В остальных случаях – сортировать «по ссылке», а не по представлению. Для этого в методе Сортировать следует использовать объект СравнениеЗначений :
ОбъектСравнения = Новый СравнениеЗначений;
ТаблицаДокументов.Сортировать("Дата,Ссылка", ОбъектСравнения);
Особенно это важно для таблиц с большим количеством (несколько сотен и тысяч) строк, в алгоритмах критических ко времени исполнения.
3.1. При поиске в объекте Массив с большим количеством элементов(*) следует отказаться от массива в пользу:
- объекта Соответствие , если не важен порядок элементов;
- индексированной ТаблицаЗначений , если порядок элементов значим.
Это обусловлено тем, что в указанных случаях поиск занимает в большинстве случаев константное время, а в массиве поиск выполняется перебором и поэтому пропорционален количеству элементов.
* Примечание: следует ориентироваться на 1000 элементов и более, а также учитывать не только размер массива, но и сколько раз выполняется поиск. Например, если поиск выполняется многократно, в частности, в цикле, то эта рекомендация также действительна для массивов меньшего размера (до 1000 элементов). Особого внимания требуют универсальные механизмы, которые могут применяться на сколь угодно больших объемах данных.
3.2. При необходимости обеспечить уникальность элементов в большом массиве следует однократно в конце алгоритма вызвать функцию СвернутьМассив или процедуру ДополнитьМассив с параметром ТолькоУникальныеЗначения = Истина (модуль ОбщегоНазначения Библиотеки стандартных подсистем).
4. Аналогичный недостаток существует и у объекта ДеревоЗначений , в котором не предусмотрено индексов и поиск выполняется перебором (как в массиве). В указанных выше случаях объект ДеревоЗначений следует заменять индексированным объектом ТаблицаЗначений .
Таблица значений часто применяется при программировании на 1С, потому что имеет множество полезных возможностей и работает очень быстро. Таблица значений создается в памяти и не сохраняется в базе данных, т.е. это временный набор данных.
//можно указать тип данных каждой колонки
//если тип данных колонки не указан, то можно хранить данные любого типа
Синтаксис: НоваяКолонка(<Идентификатор>, <Тип>, <Длина>, <Точность>, <Заголовок>, <Ширина>, <Формат>, <Положение>)
Добавление строк в таблицу значений
Перебор строк таблицы значений
Сортировка таблицы значений
Поиск в таблице значений
Синтаксис: НайтиЗначение(<Знач>,<Строка>,<Колонка>)
Возвращает число: 0 - значение не найдено; 1 - значение найдено
Если указан параметр <Строка>, то поиск производится только по заданной строке
Если указан параметр <Колонка>, то поиск производится только по заданной колонке
Итоги и группировка таблицы значений
//часто требуется группировать строки и подсчитывать итоги по группам,
//в этом случае применяется метод Свернуть
Удаление строк и колонок из таблицы значений
ВНИМАНИЕ
Часто требуется удалить строки, удовлетворяющие определенному условию.
Так как при удалении строки из таблицы значений следующая строка становится текущей,
то указанная ниже программа может удалить НЕ ВСЕ необходимые строки.
В этом случае я рекомендую использовать следующий прием:
А вот еще один правильный алгоритм, предложенный Wlad:
Замечание(Туц). Предыдущий вариант не совсем правильный. Случай, когда последняя строка попадает под условие и в условии идёт обращение к строке таблицы, приводит к ошибке. Т.е. происходит попытка чтения для строки 0.
И ещё вариант, предложенный Туц:
Замечание (vligm). А я использую такой алгоритм (это, собственно говоря, шаблон):
Таблица значений как элемент диалога
Таблица значений может использоваться в экранных формах как элемент диалога с пользователем.
Методы УстановитьЗначение и ПолучитьЗначение
Эти методы позволяют обращаться к данным в таблице значений для чтения и записи.
Они могут пригодиться в особых случаях при написании универсальных программ (мастеры отчетов и т.д.).
Синтаксис: УстановитьЗначение(<Строка>,<Колонка>,<Знач>)
Синтаксис: ПолучитьЗначение(<Строка>,<Колонка>)
Здравствуйте.
Необходимо передать на сервер.
Пока передал через структуру. Но это неудобно, так как при создании структуры пришлось все поля (имена) "руками" переносить в структуру -неудобно.
Вопрос: Как передать ДанныеФормыЭлементКоллекции на Сервер?
Если без структуры в общем случае не обойтись, тогда
Вопрос 2: Как автоматически создать структуру по всем колонкам ДанныеФормыКоллекция?
Как программно считать все имена колонок ДанныеФормыКоллекция?
(1) Не совсем понятна цель. Городите какой-то легковесный контекст для облегчения тяжелых серверных вызовов?Если нет - то можно же на сервере в контексте формы выгрузить ДанныеФормыКоллекция в таблицу значений и дальше уже работать с ней как угодно вне контекста формы. А теперь расскажите зачем это все понадобилось и чем не понравились стандартные механизмы? (2) Какие стандартные механизмы?
Программно заполняю форму. Скопировал обработчик ПриИзменении из типовой конфы себе в модуль и вызываю его с клиента, чтобы ничего в обработчике не трогать - отправляю туда структуру вместо ДФЭК. (4) А! Дошло.
Не. Универсального способа создать структуру по полям "ДанныеФормыЭлементКоллекции" вроде нету.
Везде где встречал - хардкодингом формировали. В типовых в том числе. а что мешает на сервере Объект.ДанныеФормыКоллекции.Выгрузить() и уже нашу ТЗ передать дальше по серверу? Формы на сервере нет и не будет(не сейчас точно). Можно, конечно, извратиться.
Например, при создании формы запихивать шаблон структуры с полями в клиентскую переменную.
ЗЫ. Шаблон получать - выгрузить на сервере ДанныеФормыКоллекция в ТЗ (одну строку, если ТЧ непуста) и обойти колонки.
у меня получилось как-то так:
Если это УФ и ТаблицаФормы, которая программно создаётся запросом и выводится на форму, то потом считать её содержимое можно через такой вариант:
ЭтаФорма.ИмяРеквизитаТакКакВыЕгоНазвалиПриВыводеНаФорму.Выгрузить()
вы вывели на УФ вот такой процедурой какую-то таблицу созданную заранее запросом или руками:
"ТабРеквизит" - в данном примере и есть та самая табличная часть, содержимое, которой можно получить по ЭтаФорма.ТабРеквизит.Выгрузить()
// ЭтаФорма - форма, на которой выводится таблица значений
// ТабВКоде - таблица значений, созданная программно
&НаСервере
Процедура ВывестиТаблицуЗначенияВКодеВТаблицуНаФорме(ЭтаФорма, ТабВКоде, ГруппаФормы=Неопределено) Экспорт
// Если уже создавали на форме таблицу значений - удалим её.
ТабНаФорме = ЭтаФорма.Элементы.Найти("ТабНаФорме");
Если ТабНаФорме <> Неопределено Тогда
ЭтаФорма.Элементы.Удалить(
ТабНаФорме
);
УдаляемыеРеквизиты = Новый Массив;
УдаляемыеРеквизиты.Добавить("ТабРеквизит");
ЭтаФорма.ИзменитьРеквизиты(, УдаляемыеРеквизиты);
КонецЕсли;
// Делаем описание типа ТаблицаЗначений
МассивТипов = Новый Массив;
МассивТипов.Добавить(Тип("ТаблицаЗначений"));
ОписаниеТипа = Новый ОписаниеТипов(МассивТипов);
// Создаём описание реквизита на основании этого типа
НовыеРеквизиты = Новый Массив;
НовыеРеквизиты.Добавить(
Новый РеквизитФормы("ТабРеквизит", ОписаниеТипа)
);
// Создаём этот реквизит (с именем ТабРеквизит)
ЭтаФорма.ИзменитьРеквизиты(НовыеРеквизиты);
// Создаём элемент на форме с именем ТабНаФорме
// и связываем его с реквизитом ТабРеквизит
ТаблицаПолейВыбора = ЭтаФорма.Элементы.Добавить("ТабНаФорме", Тип("ТаблицаФормы"),ГруппаФормы);
ТаблицаПолейВыбора.ПутьКДанным = "ТабРеквизит";
ТаблицаПолейВыбора.Отображение = ОтображениеТаблицы.Список;
ТаблицаПолейВыбора.УстановитьДействие("ПриНачалеРедактирования", "ТабРеквизитПриНачалеРедактирования");
ТаблицаПолейВыбора.УстановитьДействие("ПередОкончаниемРедактирования", "ТабРеквизитПередОкончаниемРедактирования");
// реквизит ТабРеквизит и соответствующий
// ему элемент формы ТабНаФорме созданы
// нами программно выше
// 1. добавляем колонки из ТабВкоде в реквизит ТабРеквизит
НовыеРеквизиты = Новый Массив;
Для Каждого Колонка Из ТабВКоде.Колонки Цикл
НовыеРеквизиты.Добавить(
Новый РеквизитФормы(
Колонка.Имя, Колонка.ТипЗначения,
"ТабРеквизит"
)
);
КонецЦикла;
// 2. добавляем колонки из ТабВКоде в элемент ТабНаФорме
Для Каждого Колонка Из ТабВКоде.Колонки Цикл
НовыйЭлемент = ЭтаФорма.Элементы.Добавить(
"ТабРеквизит" + "_" + Колонка.Имя, Тип("ПолеФормы"), ЭтаФорма.Элементы["ТабНаФорме"]
);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеВвода;
НовыйЭлемент.ПутьКДанным = "ТабРеквизит" + "." + Колонка.Имя;
Переход с обычного на управляемое приложение обязывает программиста изменить уже ставшие привычными приёмы написания программного кода.
В этой статье предложены шаблоны программного кода, которые позволяют выполнять различные операции с Таблицой Значений или Деревом Значений в управляемой форме.
В 1С:классификации Таблица Значений и Дерево Значений (ТЗ и ДЗ) представляют собой не сохраняемый в базе объект. В связи с этим, описание коллекций значений для программирования выполняется оперативно в момент обращения к ним.
Для сокращения трудозатрат программиста, в статье предложена универсальная процедура вывода ТаблицыЗначений или ДереваЗначений на экран. Эта процедура программно заполняет колонки реквизита управляемой формы, что весьма удобно при отладке.
На примерах показаны различия работы с КоллекциямиЗначений в толстом и тонком клиентах управляемой формы.
Из примеров следуют общие правила:
А) для толстого клиента ограничений нет. Примеры 1 и 4.
Б) для тонкого клиента – обработку коллекции необходимо выполнять на сервере, там же следует обеспечить вывод результата на экран.
Предложенная универсальная процедура СоздатьКолонкиУпр() программно добавляет колонки в реквизиты формы и преобразовывает коллекциюЗначений в ДанныеФормы.
Универсальную процедуру СоздатьКолонкиУпр() рекомендуется размещать в общем модуле конфигурации. Если это невозможно, то процедура успешно работает в модуле внешнего отчета.
В обычном приложение аналогом является процедура СоздатьКолонки(), которая удаляет старые колонки и загружает новые колонки из источника данных в табличное поле.
Примечание.
Разница между обычным и управляемым приложениями уже была изложена в аналогах.
Эта статья систематизирует методы работы с коллекциями значений и предлагает удобные для копирования варианты программного кода. Цель статьи – сократить трудозатраты программиста при выборе между толстым и тонким клиентами для использования таблицы (ТЗ) или дерева значений (ДЗ) в качестве источника данных для СистемыКомпоновкиДанных (СКД).
Блок-схема подготовки источника внешних данных для СКД на основании не сохраняемых в базе объектов приведена на прилагаемом рисунке.
Третья группа примеров на Видео демонстрирует реализацию всех веток блок – схемы.
Текст озвучки видео.
Сейчас будут показаны варианты программирования работы с таблицей и деревом значений в тонком и толстом клиентах управляемого приложения.
Откроем 1С:Предприятие в Тонком и Толстом клиентах.
Во всех примерах состав колонок Таблицы Значений или Дерева Значений произвольный, то есть заранее не известен. Программное заполнение реквизитов управляемой формы будет выполнено функцией СоздатьКолонкиУпр().
1) В толстом клиенте никаких ограничений нет. Пример №1 выводит на экран новую таблицу. Пример №4 редактирует существующую таблицу. Все операции можно выполнять на клиенте.
Толстый клиент закрываем.
Остальные примеры рассмотрим в тонком клиенте.
2) В тонком клиенте (пример №2) дерево создается на сервере. Пример №5 редактирует существующее дерево на сервере.
- Пример №6 преобразовывает ДеревоЗначений в таблицу. Это действие востребовано при передаче внешних данных в СКД.
3) Если программист вынужден передать в обработку КоллекциюЗначений через клиента, то это можно выполнить с помощью временного хранилища. Смотрим пример №3.
- Пример №7 показывает как таблицу преобразовать в дерево, используя макет ОсновнаяСхемаКомпоновкиДанных.
4) Заполним ТаблицуЗначений заново и в примере №8 преобразуем её в табличный документ. Теперь можно напечатать результат.
5) Далее отключим конфигуратор и демонстрируем, что ручной ввод с экрана новых строк не нарушает алгоритмов преобразования. (Примечание. Работа с добавлением колонок была показано ранее.)
- Создаём таблицу значений (Пример.3)
- и добавляем строку вручную.
- и добавляем строки в последний уровень и первый,
- Меняем значение первой колонки
6) Третья группа примеров посвящена применению Системы Компоновки Данных (СКД). Здесь будет продемонстрировано практическое использование ранее изложенных приемов для ввода данных в СКД.
- Примеры третьей группы полезны программисту в случаях, когда возникает необходимость применить методы обработки данных не доступные в СКД.
- Пример 10.1. Получаем табличный документ типовой работой СКД со справочником на основании макетаДЗ.Обращаем внимание, что макетДЗ не имеет настроек на ввод данных из внешнего набора, т.е макетДЗ можно построить конструктором.
- Пример 10.2. Получаем тоже самое в форме ДереваЗначений. Добавляем строку и меняем ей родителя на «Блузу».
- Пример 10.3. Возвращает изменённое ДеревоЗначений в формат ТабличногоДокумента по структуре, заданной в макетеДЗ. Такое преобразование востребовано, например, для печати результата типовыми методами.
- Видим, что в сложных для программиста случаях, данные табличного документа можно скорректировать либо вручную, либо программно, используя промежуточное дерево значений.
- Предварительно преобразуем ДЗ в ТЗ. (Пример.6)
- Пример 10.4. Повторяет то же самое для ТаблицыЗначений.
- Техническое решение примеров 10.3 и 10.4 обеспечивает функция ВернутьТабДокСервер(), которая:
- В пустой макет «СКДТонкийКлиент» программно устанавливает НаборДанныхОбъект, который заполняем внешними данными из отредактированной ТЗ.
- Настройки копируем из макетаДЗ.
- Результатом будет требуемый ТабличныйДокумент, учитывающий внесенные изменения в таблицу значений ТЗ.
7) Заключение. Демонстрация показала:
- Процедура СоздатьКолонкиУпр() выполняет такие же функции как процедура. СоздатьКолонки() обычного приложения.
- Если исходная коллекция и результат её преобразования размещены в одной управляемой форме, то необходимо очищать колонки источника во избежание дублирования наименований в приёмнике. (Процедура ОчиститьКоллекциюЗначенийНаСервере()).
- В тонком клиенте модули управления коллекцией значений обязательно следует размещать на сервере.
- Для преобразования коллекции значений в табличной документ с независимым макетомСКД можно применить функцию Скд_ВнешниеДанные().
- Независимый макетСКД можно создать на основании другого макета, например, макетДЗ. Для решения этой задачи можно применить функцию ВернутьТабДокСервер().
- Примечание. Программный код представлен способом, повышающим удобство копирования в разработку. Размеры базовых блоков программного кода, назначенных к копированию в разработку, не превышают четырёх строк.
Желаю успехов всем и каждому.
Описание Процедуры СоздатьКолонкиУпр()
Синтаксис:
СоздатьКолонкиУпр(<ФормаЭта>, <ИмяРеквизита>, <КоллекцияЗначений>)
Параметры:
Тип:УправляемаяФорма. Форма, в реквизите которой требуется программно определить состав колонок.
Тип:Строка. Имя реквизита как указано в управляемой форме. Этому реквизиту следует определить состав колонок. Тип реквизита должен быть либо ТаблицаЗначений, либо ДеревоЗначений.
Тип:ТаблицаЗначений, ДеревоЗначений, АдресВременногоХранилища. Источник данных, который следует вывести на экран. Тип источника данных должен быть либо ТаблицаЗначений, либо ДеревоЗначений. Причем, для этого реквизита состав колонок указанный в управляемой форме должен быть пустым.
Описание:
Для любого прикладного объекта типа таблицаЗначений или деревоЗначений, программно создаётся состав колонок реквизита управляемой формы. Затем прикладной объект преобразовывается в данные формы и выводится на экран.
Процедура применяется в случаях, когда состав колонок коллекцииЗначений заранее не определён.
Доступность:
Примечание:
Описание Функции ВернутьТабДокСервер()
Синтаксис:
ВернутьТабДокСервер (<ТЗисточник >, < АдресМакетаСКД >, < НастройкиСКД_1>)
Параметры:
Тип:ТаблицаЗначений. Источник данных для формирования результата СКД.
Тип:Строка. Адрес временного хранилища, в которое помещен макет схемы компоновки данных (Тип:СхемаКомпоновкиДанных).
< НастройкиСКД _1> (обязательный)
Тип:НастройкиКомпоновкиДанных. Текущие настройки макета СКД.
Описание:
Возвращает ТабличныйДокумент с данными из ТаблицыЗначений (ТЗисточник) преобразованными по структуре МакетаСКД
Доступность:
Примечание:
Описание Функции скд_ВнешниеДанные ()
Синтаксис:
Скд_ВнешниеДанные (<ТЗ_внешниеДанные>, <ТипРезультата="ТабДок">, <АдресМакетаСКД="">, <НастройкиСКД=Неопределено>)
Параметры:
Тип:ТаблицаЗначений. ДанныеФормыКоллекция. Источник данных для формирования результата СКД.
< ТипРезультата > (не обязательный)
Тип:Строка. Допустимые значения: «ТабДок», «ТабличныйДокумент», «ДЗ», «ДеревоЗначений», «ТЗ», «ТаблицаЗначений».
< АдресМакетаСКД > (не обязательный)
< НастройкиСКД > (не обязательный)
Тип:НастройкиКомпоновкиДанных. Текущие настройки макета СКД.
Описание:
Возвращает результат СКД заданного типа с данными из ТаблицыЗначений преобразованными по структуре МакетаСКД
Читайте также: