Номер по порядку в запросе 1с


Ключевые слова: нумерация строк запроса, ПЕРВЫЕ, нумерация строк в построителе, пронумеровать

Иногда возникает необходимость добавить в запрос колонку с номерами строк, например, когда нужно вывести номера строк в отчет, а используется построитель отчета. Так же нумерация строк полезна когда необходимо для определенных группировок вывести ограниченное количество строк данных. Что-то типа ПЕРВЫЕ 5 документов для каждого контрагента.

Итак, есть код, выбирающий номенклатуру, отсортированный по наименованию:
ВЫБРАТЬ
Номенклатура.Ссылка
ИЗ

УПОРЯДОЧИТЬ ПО
Номенклатура.Наименование
исходный запрос

Требуется добавить сюда колонку с порядковыми номерами номенклатуры (в рамках данной сортировки).
ВЫБРАТЬ

ИЗ
Справочник.Номенклатура КАК Номенклатура
ПО Номенклатура.Наименование >= Номенклатура_1.Наименование // Условие сортировки для нумерации

УПОРЯДОЧИТЬ ПО
Номенклатура.Наименование
запрос с номерами строк

Соединяем таблицу саму с собой довольно хитрым способом. По правой таблице подсчитываем количество номенклатуры с наименованием меньше текущего левого, используя группировку.

Аналогичную технику можно применить, если нужно задавать нумерацию строк с учетом группировки по какому-то полю.
ВЫБРАТЬ
Номенклатура.Ссылка КАК Номенклатура,
Номенклатура.Родитель КАК Родитель,
КОЛИЧЕСТВО(Номенклатура_1.Ссылка) КАК Номер
ИЗ
Справочник.Номенклатура КАК Номенклатура
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.Номенклатура КАК Номенклатура_1
ПО Номенклатура.Наименование >= Номенклатура_1.Наименование
И Номенклатура.Родитель = Номенклатура_1.Родитель

СГРУППИРОВАТЬ ПО
Номенклатура.Родитель,
Номенклатура.Ссылка
запрос с номерами строк в рамках группировки

Это тот же самый запрос, в него просто добавлена группировка по полю "Родитель", нумерация для каждого родителя своя.

Быстродействие:
Если говорить о быстродействии, то запросы подобного рода естественно ресурсоемки (математически ложность порядка N^2). Для большинства повседневных задач их использование вполне приемлемо.
Кстати, второй запрос выполняется несколько быстрее первого, это связано с меньшим размером вспомогательных таблиц.

Пример реального использования:
Теперь немного о том, ради чего всё это делается, то-есть польза, которую можно извлечь из нумерации строк запроса.

Например, перед нами стоит задача получить для каждого контрагента пять последних документов поступления товаров и услуг:
ВЫБРАТЬ
ПоступлениеТоваровУслуг.Контрагент КАК Контрагент,
ПоступлениеТоваровУслуг.Ссылка КАК Ссылка,
КОЛИЧЕСТВО(ПоступлениеТоваровУслуг_1.Ссылка) КАК Номер
ИЗ
Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг_1
ПО ПоступлениеТоваровУслуг.Дата <= ПоступлениеТоваровУслуг_1.Дата
И ПоступлениеТоваровУслуг.Контрагент = ПоступлениеТоваровУслуг_1.Контрагент

СГРУППИРОВАТЬ ПО
ПоступлениеТоваровУслуг.Ссылка,
ПоступлениеТоваровУслуг.Контрагент

ИМЕЮЩИЕ
КОЛИЧЕСТВО(ПоступлениеТоваровУслуг_1.Ссылка) <= 5

УПОРЯДОЧИТЬ ПО
Контрагент,
Номер
запрос с номерами строк при наличии дублей интересующего поля(того,относительно которого строится счетчик)
ВЫБРАТЬ
КОЛИЧЕСТВО(ФизическиеЛица_1.Наименование) КАК Номер,
ФизическиеЛица.Ссылка КАК ФИО
ИЗ
Справочник.ФизическиеЛица КАК ФизическиеЛица
ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ФизическиеЛица КАК ФизическиеЛица_1
ПО (ФизическиеЛица.Наименование + ФизическиеЛица.Код >= ФизическиеЛица_1.Наименование + ФизическиеЛица_1.Код)

УПОРЯДОЧИТЬ ПО
Номер
Собственно говоря идея какова: использовать "составное поле" для получения возрастающего итога (при этом одно поле может содержать дубли, а второе в данном примере- нет.)
Родилось в голове НЕКРОН"а

Здравствуйте, уважаемые читатели блога сайт! В прошлой статье мы, . А сегодня в третьей из этой серии статей, мы рассмотрим порядок следования периодов роли поля компоновки данных , а также рассмотрим, как порядок ролей влияет на расчет остатка. Итак, приступим!

Давайте еще раз повторим порядок следования периодов, то есть какие периоды являются самыми младшими. Самый младший период – это номер строки набора записей регистра. Дело в том, что у нас есть некий набор записей, который принадлежит одной дате, одному регистратору. И соответственно самым детальным элементом этого набора записей является строка, после это идет по порядку регистратор, «ПериодСекунда» и дальше по возрастанию.

Рассмотрим какие еще есть настройки у роли «Период». Для этого сделаем следующие шаги:

  1. откроем отчет, который мы в прошлой статье. Если у вас его нет, то можете скачать .
  2. Нажмите на кнопку «Открыть схему компоновки данных».
  3. На закладке «Наборы данных» видим список полей.
  4. Двойным нажатием левой кнопки мыши откроем роль «ПериодМесяц».

Итак, мы видим, что у поля «ПериодМесяц» в роли «Период» есть еще такая настройка как «Доп.» это флажок «Дополнительный» в диалоге. У поля «ПериодСекунда» и у поля «Регистратор» в роли «Период» система такой флажок автоматически не выставила. На что он влияет?

Если флажок «Дополнительный» снят, то есть период является основным, то при включении дочерних записей, дочерних периодов к текущему, родительский обязательно включается в запрос. Это означает, что, если мы выводим остатки по регистратору, то в запрос будет обязательно включено поле «ПериодСекунда», ведь поле «ПериодСекунда» является родительским по отношению к полю «Регистратор».

А вот для поля «ПериодМесяц» такого не происходит. И если мы получаем остатки по полю «Регистратор» или по полю «ПериодСекунда», нет смысла разворачивать периодичность помесячно, если этого не требует настройка варианта отчета. По сути, этот значок предназначен для того, чтобы решить одну частную задачу, а именно, получение остатков по регистратору. Поставим флажок «Дополнительный» для поля «ПериодСекунда», и посмотрим, что произойдет.

Откроем наш отчет в режиме 1С:Предприятие и сформируем его. И видим, что ничего не изменилось. Остаток является неправильным, как и было . Почему? Потому что сейчас выводятся данные по полю «Регистратор», а поле «ПериодСекунда» в отчете не выводится и соответственно в запрос не включается. У поля «ПериодСекунда» в роли «Период» стоит флажок «Дополнительный», а значит этот период не является основным. Поэтому система компоновки данных правильный остаток рассчитать не может. Другое дело, если бы мы включили поле «ПериодСекунда» в выходные поля. Для этого:

  1. Зайдем в режим Конфигуратора.
  2. Добавим поле «ПериодСекунда» двойным нажатием левой кнопкой мыши на нем, как показано на изображении ниже.

Каков будет тогда результат работы отчета? Формируем отчет и видим, что сейчас все корректно. Но появляется лишнее поле, которое может ввести пользователя в заблуждение.

Поэтому удаляем это поле и снимаем флажок «Дополнительный» в роли поля «ПериодСекунда».

  1. Зайдем в режим Конфигуратора.
  2. Откроем отчет, откроем в нем схему компоновки данных на закладке «Настройки».
  3. Внизу откроем закладку «Выбранные поля».
  4. Удалим поле «ПериодСекунда», выделив его и нажав красный крестик в правой панели.

Теперь независимо от варианта настройки отчета поле «ПериодСекунда» будет включено в этот отчет, если младший период, то есть поле «Регистратор», представлен в выходных полях. Итак, мы увидели, как настройки роли «Период» влияют на вывод остатка в отчете СКД .

В конце статьи хочу посоветовать вам бесплатный от Сотникова Анатолия. Это курс от опытного программиста. Он на отдельной базе покажет вам, как строить отчеты в СКД. Вам только нужно внимательно слушать и запоминать! Вы получите ответы на такие вопросы:
  • Как создать простой отчет в виде списка?
  • Для чего нужны колонки Поле, Путь и Заголовок на закладке «Поля»?
  • Какие существуют ограничения для полей компоновки?
  • Как правильно настраивать роли?
  • Какие существуют роли для полей компоновки?
  • Где найти закладку компоновка данных в запросе?
  • Как настраивать параметры в СКД?
  • Дальше еще интереснее...
Наверное, не стоит самому стараться бороздить интернет в поисках нужной информации? Тем более все готово для применения. Только начните! Все подробности о том, что есть в бесплатных видеоуроках

Вот один из уроков о закладке компоновки данных в запросе:

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

В принципе, задача легко бы решалась, если список документов мы бы получали в отчете. Но тут дела обстоят иначе.

В отчетах - не проблема!

Создав отчет на системе компоновки данных с получением списка документов, задача решалась бы очень просто. В поля отчета нужно было бы всего-навсего добавить специальное поле "Номер по порядку".

В результате пользователь увидит подобный результат формирования отчета:

Но как быть, если нумерацию нужно получить непосредственно в запросе? Например, это может понадобиться для получения порядкового номера записи в динамическом списке.

Нумерация в запросе

Изменим запрос динамического списка журнала документов следующим образом:

" ВЫБРАТЬ | Т. НомерПоПорядку, | Т. Ссылка, | Т. Дата, | Т. ПометкаУдаления, | Т. Номер, | Т. Проведен, | Т. Тип |ИЗ | (ВЫБРАТЬ " + // Получаем количество присоединенных ссылок в поле "НомерПоПорядку" " КОЛИЧЕСТВО(РАЗЛИЧНЫЕ ЖурналДокументовЖурналДокументов. Ссылка) КАК НомерПоПорядку, | ЖурналДокументов. Ссылка КАК Ссылка, | ЖурналДокументов. Дата КАК Дата, | ЖурналДокументов. ПометкаУдаления КАК ПометкаУдаления, | ЖурналДокументов. Номер КАК Номер, | ЖурналДокументов. Проведен КАК Проведен, | ЖурналДокументов. Тип КАК Тип | ИЗ | ЖурналДокументов. ЖурналДокументов КАК ЖурналДокументов | ЛЕВОЕ СОЕДИНЕНИЕ ЖурналДокументов. ЖурналДокументов КАК ЖурналДокументовЖурналДокументов " + // Соединим таблицу журнала документов к самой себе по ссылке на документ. Количество присоед. // ссылок и есть порядковый номер " ПО ЖурналДокументов. Ссылка > = ЖурналДокументовЖурналДокументов. Ссылка / | | СГРУППИРОВАТЬ ПО | ЖурналДокументов. Ссылка, | ЖурналДокументов. Дата, | ЖурналДокументов. ПометкаУдаления, | ЖурналДокументов. Номер, | ЖурналДокументов. Проведен, | ЖурналДокументов. Тип) КАК Т "

При открытии динамического списка в режиме 1С:Предприятия получаем следующий результат:

Примечание: в примере показан лишь принцип нумерации строк непосредственно в запросе. Если Вы обратили внимание, то на скриншоте выше документы в списке, отсортированные по порядковому номеру строки, "идут" в порядке типов (сначала приходные ордера, затем расходные и т.д.). Это происходит, потому что, используя ссылку для соединения, мы не можем гарантировать, что GUID"ы ссылок будут уникальными. Также нельзя сравнивать ссылки разных типов документов - это приведет к некорректному результату. Можно использовать момент времени или другие поля, определяющие конкретное положение документа с общем списке журнала.

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

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