1С выборка табличной части документа

Вступайте в мою группу помощник программиста.
В ней мы обсуждаем программирование в 1С.

Документы

Описание:

Документ — одно из основных понятий системы 1С:Предприятие. При помощи документов организуется ввод в систему информации о совершаемых хозяйственных операциях, а также ее просмотр и корректировка.

В большинстве своем документы, которые создаются в процессе настройки конфигурации задачи, являются электронными аналогами стандартных бумажных документов, являющихся основаниями для тех или иных учетных действий или расчетов. Тем не менее, использование этого типа данных может выходить далеко за рамки простой фиксации изменений, внесенных в учетные регистры.

Структура каждого конкретного вида документа определяется при его создании в конфигураторе. У любого вида документа существуют реквизиты, которые создаются автоматически — это "Дата" и "Номер". Номер создается, если при конфигурировании длина номера указана больше 0. Другие реквизиты документа определяются в конфигураторе отдельно для каждого создаваемого вида документа.

Документы в языке 1С 8.3, 8.2 (в примерах)

С уважением, Владимир Милькин (преподаватель школы 1С программистов и разработчик обновлятора).

Подписывайтесь и получайте новые статьи и обработки на почту (не чаще 1 раза в неделю).

Вступайте в мою группу ВКонтакте, Одноклассниках, Facebook или Google+ — самые последние обработки, исправления ошибок в 1С, всё выкладываю там в первую очередь.

Как помочь сайту: расскажите (кнопки поделиться ниже) о нём своим друзьям и коллегам. Сделайте это один раз и вы внесете существенный вклад в развитие сайта. На сайте нет рекламы, но чем больше людей им пользуются, тем больше сил у меня для его поддержки.

Нажмите одну из кнопок, чтобы поделиться:

Как выбрать данные из табличной части документа в 1С:Предприятие 8.0,8.1,8.2, 8.3?

Как выбрать данные из табличной части документа в 1С:Предприятие 8.0,8.1,8.2, 8.3?
Воспользуемся запросом. Покажем на примере:

В данном примере получаем информацию из табличной части Товары документа Реализация товаров и услуг. Затем в цикле выводим в окно сообщений полученную информацию.
Обратите внимание на Как перебрать все строки в таблице документа?

Запрос = Новый Запрос ;
Запрос.УстановитьПараметр ( "Ссылка" , Ссылка );
Запрос.Текст =
"ВЫБРАТЬ
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) КАК КоличествоДублей
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ТабЧасть.НомерСтроки) > 1" ;
РезЗапроса = Запрос.Выполнить ();
Если Не РезЗапроса.Пустой () Тогда
Сообщить ( "Имеются дубли строк. " );
КонецЕсли;

Здесь все достаточно просто. Обращаемся к данным табличной части документа, группируем по ключевым полям с использование агрегатной функции для подсчета количества номеров строк. Накладываем условие по вычисленному значению агрегатной функции. Все.

2) Классика жанра. Выведем в сообщении пользователю номера всех тех строк табличной части, которые являются дублями.

Запрос = Новый Запрос ;

Запрос.УстановитьПараметр ( "Ссылка" , Ссылка );

Запрос.Текст =
"ВЫБРАТЬ
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|;
| |////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.Качество КАК Качество,
| ТабЧасть.Номенклатура КАК Номенклатура,
| ТабЧасть.СерияНоменклатуры КАК СерияНоменклатуры,
| ТабЧасть.Склад КАК Склад,
| ТабЧасть.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ИЗ
| ВТ_ТабЧасть КАК ТабЧасть
|ГДЕ
| (ТабЧасть.Качество, ТабЧасть.Номенклатура, ТабЧасть.СерияНоменклатуры, ТабЧасть.Склад, ТабЧасть.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад";
РезЗапроса = Запрос.Выполнить () ;
Если Не РезЗапроса.Пустой () Тогда
Выб_Качество = РезЗапроса.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Качество.Следующий () Цикл
Выб_Номенклатура = Выб_Качество.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Номенклатура.Следующий () Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_СерияНоменклатуры.Следующий () Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Склад.Следующий() Цикл
Выборка = Выб_Склад.Выбрать ();
ТекстСообщения = "" ;
Пока Выборка.Следующий () Цикл
ТекстСообщения = ТекстСообщения + ?( ПустаяСтрока ( ТекстСообщения ) , "" , ", " ) + Выборка.НомерСтроки ;
КонецЦикла;
ТекстСообщения = "Обнаружено дублирование строк: " + ТекстСообщения ; Сообщить(ТекстСообщения);
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;

А теперь попробуем оценить перспективу доработки. Допустим, у нас изменился состав ключевых полей в сторону увеличения их количества: добавились ЕдиницаИзмерения и ЗаказПокупателя. Чтобы контроль дублей строк не перестал работать, нам нужно доработать запрос и обход результата запроса следующим образом:

Запрос = Новый Запрос ;
Запрос.УстановитьПараметр ( "Ссылка" , Ссылка );
Запрос.Текст =
" ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя,
| ТабЧасть.Качество,
| ТабЧасть.Номенклатура,
| ТабЧасть.СерияНоменклатуры,
| ТабЧасть.Склад,
| ТабЧасть.ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ПОМЕСТИТЬ ВТ_ТабЧасть
|ИЗ
| Документ.РеализацияТоваровУслуг.Товары КАК ТабЧасть
|ГДЕ
| ТабЧасть.Ссылка = &Ссылка
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ТабЧасть.ЕдиницаИзмерения КАК ЕдиницаИзмерения,
| ТабЧасть.ЗаказПокупателя КАК ЗаказПокупателя,
| ТабЧасть.Качество КАК Качество,
| ТабЧасть.Номенклатура КАК Номенклатура,
| ТабЧасть.СерияНоменклатуры КАК СерияНоменклатуры,
| ТабЧасть.Склад КАК Склад,
| ТабЧасть.ХарактеристикаНоменклатуры КАК ХарактеристикаНоменклатуры,
| ТабЧасть.НомерСтроки КАК НомерСтроки
|ИЗ
| ВТ_ТабЧасть КАК ТабЧасть
|ГДЕ
| (ТабЧасть.ЕдиницаИзмерения, ТабЧасть.ЗаказПокупателя, ТабЧасть.Качество, ТабЧасть.Номенклатура, ТабЧасть.СерияНоменклатуры, ТабЧасть.Склад, ТабЧасть.ХарактеристикаНоменклатуры) В
| (ВЫБРАТЬ
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИЗ
| ВТ_ТабЧасть КАК ВТ
| СГРУППИРОВАТЬ ПО
| ВТ.ЕдиницаИзмерения,
| ВТ.ЗаказПокупателя,
| ВТ.Качество,
| ВТ.Номенклатура,
| ВТ.СерияНоменклатуры,
| ВТ.Склад,
| ВТ.ХарактеристикаНоменклатуры
| ИМЕЮЩИЕ
| КОЛИЧЕСТВО(ВТ.НомерСтроки) > 1)
|
|УПОРЯДОЧИТЬ ПО
| НомерСтроки
|ИТОГИ ПО
| Качество,
| Номенклатура,
| СерияНоменклатуры,
| Склад,
| ХарактеристикаНоменклатуры,
| ЕдиницаИзмерения" ;
РезЗапроса = Запрос.Выполнить ();
Если Не РезЗапроса.Пустой () Тогда
Выб_Качество = РезЗапроса.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Качество.Следующий () Цикл
Выб_Номенклатура = Выб_Качество.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Номенклатура.Следующий () Цикл
Выб_СерияНоменклатуры = Выб_Номенклатура.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_СерияНоменклатуры.Следующий () Цикл
Выб_Склад = Выб_СерияНоменклатуры.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_Склад.Следующий () Цикл
Выб_ХарактеристикаНоменклатуры = Выб_Склад.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_ХарактеристикаНоменклатуры.Следующий () Цикл
Выб_ЕдиницаИзмерения = Выб_ХарактеристикаНоменклатуры.Выбрать ( ОбходРезультатаЗапроса.ПоГруппировкам );
Пока Выб_ЕдиницаИзмерения.Следующий () Цикл
ТекстСообщения = "" ;
Выборка = Выб_ЕдиницаИзмерения.Выбрать ();
Пока Выборка.Следующий () Цикл
ТекстСообщения = ТекстСообщения + ?( ПустаяСтрока ( ТекстСообщения ), " " , ", " ) + Выборка.НомерСтроки ;
КонецЦикла;
ТекстСообщения = "Обнаружено дублирование строк: " + ТекстСообщения ;
Сообщить ( ТекстСообщения );
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;
КонецЦикла;

3) Альтернативный вариант.

Реализация предыдущего варианта другим способом. Предлагаю использовать особенность запросов 1С, позволяющих обращаться к данным табличных частей, как к обычным полям выборки. Ну все-таки не совсем обычным, но все же полям выборки. Кроме того, нам придётся использовать не самый оптимальный способ соединения данных — декартово произведение. Почему так — опишу ниже.

Несколько комментариев по поводу запроса.

Работа с табличными частями в качестве полей выборки накладывает ряд ограничений на выполнение запросов. Во-первых, это работа с временными таблицами. Т.е. нельзя помещать такие объекты во временные таблицы, но никто не мешает использовать вложенные запросы. Во-вторых, это соединения таблиц. Мне требовалось написать такой запрос, который бы возвратил мне наборы ключевых полей по которым имеются дубли, и многострочный объект, содержащий все строки с таким же набором ключевых полей. Обычные соединения (ВНУТРЕННЕЕ, ЛЕВОЕ, ПРАВОЕ, ПОЛНОЕ) возвращают всю табличную часть, что, в общем, правильно – для части объекта условие соединения же выполняется? Выполняется. Ну тогда и получите всю табличную часть. Искомый результат, как оказалось, достигается декартовым произведением. Мне как-то претит видеть в тексте запроса перечисление таблиц через запятую, поэтому я все декартовы произведения всегда реализую через «. СОЕДИНЕНИЕ . ПО (ИСТИНА)». Чтобы ограничить мсье Декарта в аппетитах (и повысить производительность), применяются дополнительные ограничения.

Теперь о производительности. Производились тестовые замеры каждого из вариантов на документе с большим количеством строк в табличной части. Количество строк в тестируемом документе: 47 817, 4 комбинации ключевых полей с дублями по 2, 2, 3 и 4 строки. Результаты замеров:

Вариант 1) 0:00:00.078 сек.

Вариант 2) 0:00:00.265 сек.

Вариант 3) 0:00:01.513 сек.

Как видим, третий вариант, как и ожидалось, самый медленный, но он же является самым удобным в перспективе модификации.

Прилагаемая обработка является демонстратором третьего варианта. Работает она и в обычном, и в управляемом режимах. Внешний вид и функционал полностью одинаков.

1) Выбираем вид объекта: Документ или Справочник.

2) Выбираем тип объекта: Какой именно документ или справочник.

3) Выбираем табличную часть объекта.

4) Определяем состав ключевых полей в специальном диалоге

5) Если мы хотим, то можем указать ссылку на объект, чтобы проверить его на наличие дублей.

6) Если активен флажок «Сгенерировать и показать код для проверки на дубли», то будет сгенерирован программный код для выполнения проверки на дубли строк с имеющимися настройками.

Эксперт по технологическим вопросам ООО ЦБР ИнфоСофт

Оцените статью
Ремонт оргтехники
Добавить комментарий