Как найти запросом последний документ

 0 

   

Распечатать

1С 8.3 : Как запросом получить последний по дате документ?

Сортируем документы по убыванию даты и используем конструкцию «ВЫБРАТЬ ПЕРВЫЕ 1»:

Код 1C v 8.х

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

В результате запрос вернёт одну строку, с данными последнего документа по одному контрагенту.

А как сделать запрос, который вернёт последние документы по всем контрагентам, а не по одному конкретному?

Используем функцию МАКСИМУМ в запросе для решения данной задачи.

Код 1C v 8.х

 Запрос = Новый Запрос;
Запрос.Текст = "
|ВЫБРАТЬ
| ПоследниеДокументыКонтрагентов.Ссылка,
| ПоследниеДокументыКонтрагентов.Контрагент
|ИЗ Документ.РеализацияТоваровУслуг КАК ПоследниеДокументыКонтрагентов
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ
| (ВЫБРАТЬ
| Доки.Контрагент КАК Контрагент,
| МАКСИМУМ(Доки.Дата) КАК ДатаПоследнегоДокумента
| ИЗ Документ.РеализацияТоваровУслуг КАК Доки
|СГРУППИРОВАТЬ ПО Доки.Контрагент)
|КАК ДатыПоследнихДокументовКонтрагентов
|ПО ПоследниеДокументыКонтрагентов.Контрагент =
|ДатыПоследнихДокументовКонтрагентов.Контрагент
|И ПоследниеДокументыКонтрагентов.Дата =
|ДатыПоследнихДокументовКонтрагентов.ДатаПоследнегоДокумента";
РезультатЗапроса = Запрос.Выполнить();

Этот запрос выбирает последние документы по всем контрагентам.

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

Разберем на примере демо-базы УТ11, найдем последние документы прихода номенклатуры по регистру “ТоварыНаСкладе”. Под последним документом в контексте данной задачи может пониматься как документ с наибольшей датой документа, так и последний документ, введенный пользователем.

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

ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 ТоварыНаСкладахОбороты.Регистратор КАК Регистратор,
 ТоварыНаСкладахОбороты.ВНаличииПриход КАК ВНаличииПриход
ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

УПОРЯДОЧИТЬ ПО
 Регистратор УБЫВ
 АВТОУПОРЯДОЧИВАНИЕ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ ПЕРВЫЕ 1
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,      
 ТоварыНаСкладахОбороты.Регистратор КАК Регистратор,
 ТоварыНаСкладахОбороты.ВНаличииПриход КАК ВНаличииПриход
ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, Номенклатура = &Номенклатура) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

УПОРЯДОЧИТЬ ПО
 Регистратор УБЫВ
 АВТОУПОРЯДОЧИВАНИЕ 

Без автоупорядочивания сортировка произойдет без учета даты документа, по уникальному идентификатору. В этом случае, документы введенные позже приходного ордера ЦУ-33 задним числом встанут в начало выборки. Уберем “АВТОУПОРЯДОЧИВАНИЕ” из запроса и посмотрим результат.

Если воспользоваться методом получения даты создания объекта из GUID, то в первом случае 3339428b-6656-11e0-af2a-0015e9b8c48d создан 14.04.2011, во втором b2c7cfa2-6ca9-11e0-af30-0015e9b8c48d – 22.04.2011. То есть второй способ можно применять, если нужно определить последний документ прихода, введенный пользователем.

В случае, когда нужно определить последние документы для перечня номенклатуры конструкция “ВЫБРАТЬ ПЕРВЫЕ” нам уже не подходит. Поэтому, чтобы свернуть выборку по регистратору, будем использовать функцию МАКСИМУМ.

ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 ТоварыНаСкладахОбороты.Регистратор КАК Регистратор

ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

УПОРЯДОЧИТЬ ПО
 Номенклатура,
 Регистратор УБЫВ
 АВТОУПОРЯДОЧИВАНИЕ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 МАКСИМУМ(ТоварыНаСкладахОбороты.Регистратор) КАК Регистратор

ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

СГРУППИРОВАТЬ ПО
 ТоварыНаСкладахОбороты.Номенклатура

УПОРЯДОЧИТЬ ПО
 Номенклатура,
 Регистратор УБЫВ
 АВТОУПОРЯДОЧИВАНИЕ
;

Как видно из результата, функция МАКСИМУМ сворачивает выборку по GUID объекта. То есть, этот способ не подходит для случая, когда нам нужно получить последний документ, исходя из даты документа. Получать перечень номенклатуры и потом в цикле для каждой позиции получать последний документ тоже не наш вариант, замедляется быстродействие. Поэтому перепишем запрос, добавим временную таблицу, в которой свернем выборку по максимуму даты регистратора. Эту дату и будем использовать для соединения с основной выборкой. В последнем запросе так же сворачиваем выборку по максимуму регистратора, но теперь мы получим последний введенный документ с учетом последней даты документа.

ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 ТоварыНаСкладахОбороты.Регистратор КАК Регистратор,
 ТоварыНаСкладахОбороты.ВНаличииПриход КАК ВНаличииПриход
ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

УПОРЯДОЧИТЬ ПО
 Номенклатура,
 Регистратор УБЫВ
 АВТОУПОРЯДОЧИВАНИЕ
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 МАКСИМУМ(ТоварыНаСкладахОбороты.Регистратор.Дата) КАК Дата
ПОМЕСТИТЬ времДата
ИЗ
 РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК ТоварыНаСкладахОбороты
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

СГРУППИРОВАТЬ ПО
 ТоварыНаСкладахОбороты.Номенклатура
;
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
 ТоварыНаСкладахОбороты.Номенклатура КАК Номенклатура,
 МАКСИМУМ(ТоварыНаСкладахОбороты.Регистратор) КАК Регистратор
ИЗ
 времДата КАК времДата
  ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Обороты(, , Регистратор, ) КАК ТоварыНаСкладахОбороты
  ПО времДата.Номенклатура = ТоварыНаСкладахОбороты.Номенклатура
   И времДата.Дата = ТоварыНаСкладахОбороты.Регистратор.Дата
ГДЕ
 ТоварыНаСкладахОбороты.ВНаличииПриход > 0

СГРУППИРОВАТЬ ПО
 ТоварыНаСкладахОбороты.Номенклатура

УПОРЯДОЧИТЬ ПО
 Номенклатура
 АВТОУПОРЯДОЧИВАНИЕ 

UPD: как правильно заметили в комментариях, механизм генерации ГУИД обеспечивает только уникальность, но не возрастающую последовательность. На момент написания статьи проведенные тесты давали необходимый результат. Но гарантии, что выявленная закономерность сохранится в последующих версиях платформы, нет. Поэтому, если необходимо фиксировать момент создания документов, то лучше реализовать свой механизм. Например, с использованием регистра сведений.

как в запросе выбрать самый последний документ

Я
   AugustBlack

23.11.12 – 08:38

привет, подскажите в запросе есть ссылка на документ и дата, как выбрать самый последний док из кучи строк регистра бухгалтерии, функция МАКСИМУМ?

   Нуф-Нуф

1 – 23.11.12 – 08:43

В поиск епта. Через день такое спрашивают

   AugustBlack

2 – 23.11.12 – 10:00

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

   Промежуточная_ТЗ.Контрагент,

   Промежуточная_ТЗ.Счет,

   МАКСИМУМ(ХозрасчетныйОбороты.Регистратор) КАК Документ,

   СУММА(Промежуточная_ТЗ.Дебет) КАК Дебет,

   СУММА(Промежуточная_ТЗ.Кредит) КАК Кредит

ИЗ

   Промежуточная_ТЗ КАК Промежуточная_ТЗ,

   РегистрБухгалтерии.Хозрасчетный.Обороты(, &ДатаКон, Регистратор, Счет В ИЕРАРХИИ (&СписокСчетов), , Организация = &Организация, КорСчет В ИЕРАРХИИ (&СписокСчетов), ) КАК ХозрасчетныйОбороты

ГДЕ

   (Промежуточная_ТЗ.Документ ЕСТЬ NULL

           ИЛИ Промежуточная_ТЗ.Документ = НЕОПРЕДЕЛЕНО)

   И Промежуточная_ТЗ.Счет = ХозрасчетныйОбороты.Счет

   И Промежуточная_ТЗ.Контрагент = ХозрасчетныйОбороты.Субконто1

СГРУППИРОВАТЬ ПО

   Промежуточная_ТЗ.Контрагент,

   Промежуточная_ТЗ.Счет

УПОРЯДОЧИТЬ ПО

   Документ УБЫВ

   AugustBlack

3 – 23.11.12 – 10:01

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

   mikecool

4 – 23.11.12 – 10:02

(3) ну ты по дате попробуй упорядочить чтоле

   Cube

5 – 23.11.12 – 10:06

(0) Нажми большую красную букву “Я” справа от заголовка темы…

   AugustBlack

6 – 23.11.12 – 10:07

(4) упорядочил:

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

   Промежуточная_ТЗ.Контрагент,

   Промежуточная_ТЗ.Счет,

   МАКСИМУМ(ХозрасчетныйОбороты.Регистратор.Дата) КАК ДокументДата,

   МАКСИМУМ(ХозрасчетныйОбороты.Регистратор) КАК Документ,

   СУММА(Промежуточная_ТЗ.Дебет) КАК Дебет,

   СУММА(Промежуточная_ТЗ.Кредит) КАК Кредит

ИЗ

   Промежуточная_ТЗ КАК Промежуточная_ТЗ,

   РегистрБухгалтерии.Хозрасчетный.Обороты(, &ДатаКон, Регистратор, Счет В ИЕРАРХИИ (&СписокСчетов), , Организация = &Организация, КорСчет В ИЕРАРХИИ (&СписокСчетов), ) КАК ХозрасчетныйОбороты

ГДЕ

   (Промежуточная_ТЗ.Документ ЕСТЬ NULL

           ИЛИ Промежуточная_ТЗ.Документ = НЕОПРЕДЕЛЕНО)

   И Промежуточная_ТЗ.Счет = ХозрасчетныйОбороты.Счет

   И Промежуточная_ТЗ.Контрагент = ХозрасчетныйОбороты.Субконто1

СГРУППИРОВАТЬ ПО

   Промежуточная_ТЗ.Контрагент,

   Промежуточная_ТЗ.Счет

УПОРЯДОЧИТЬ ПО

   ДокументДата УБЫВ

поля:

датадокумента         документ

31.10.2012 23:59:59  операция 00001 от 31.01.2012:23 59 59

   Reset

7 – 23.11.12 – 10:09

(6) Регистратор в Сгруппировать

   Cube

8 – 23.11.12 – 10:09

(6) И что тебя удивляет? Смотри (5)

   Reset

9 – 23.11.12 – 10:09

(7) Не читать, не проснулся еще

   dk

10 – 23.11.12 – 10:10

МАКСИМУМ(ХозрасчетныйОбороты.Регистратор.Дата)

и

МАКСИМУМ(ХозрасчетныйОбороты.Регистратор)

вообще-то не связаны др/др

   salvator

11 – 23.11.12 – 10:10

(6) ДатаКон чему равно?

   Irbis

12 – 23.11.12 – 10:10

Выбрать первый с конца

   Serg_1960

13 – 23.11.12 – 10:15

»    AugustBlack

14 – 23.11.12 – 10:16

(11) 01.11.2012

   Нуф-Нуф

15 – 23.11.12 – 10:17

Максимум по ссылке – это не последний документ.

   zippygrill

16 – 23.11.12 – 10:21

(15) а если сначала выбрать макс(дата) и потом макс(Ссылка)?

   Irbis

17 – 23.11.12 – 10:23

(16) Фигня получится, МАКС(ПоСсылке)<> МАКС(ПоДате)

   Serg_1960

18 – 23.11.12 – 10:27

»    Нуф-Нуф

19 – 23.11.12 – 10:27

сначала получаются максимальные даты и уже для этих дат находятся документы

   Diose

20 – 23.11.12 – 10:28

может так

ВЫБРАТЬ ПЕРВЫЕ 1

ИЗ

   
ГДЕ

   

УПОРЯДОЧИТЬ ПО

   Дата УБЫВ

   zippygrill

21 – 23.11.12 – 10:29

(17) я ж говорю сначала получает документы по максимальной даты и потом из этой даты выбирает макс(Ссылка). почему фигня?

   Serg_1960

22 – 23.11.12 – 10:30

»    Нуф-Нуф

23 – 23.11.12 – 10:31

(22) а номер то причем?

   zippygrill

24 – 23.11.12 – 10:31

(22) моя ветка дошла до 100 постов точно по этому вопросу 🙂

   Serg_1960

25 – 23.11.12 – 10:32

»    Нуф-Нуф

26 – 23.11.12 – 10:34

(25) помент времени? в запросе?

   Serg_1960

27 – 23.11.12 – 10:37

»    Serg_1960

28 – 23.11.12 – 10:42

Ладно уж, сорри тс, – потрите мои посты – это тяпница виновата 🙂

Если “без шуток”, то в запросе “скрытая” ошибка. Желая получить дату и ссылку на последний документ – нельзя использовать максимум по дате и максимум по ссылке. Вы можете получить дату из одного документа и ссылку на другой документ.

   Нуф-Нуф

29 – 23.11.12 – 10:52

ВЫБРАТЬ

   ТоварыНаСкладах.Номенклатура КАК Номенклатура,

   ТоварыНаСкладах.Регистратор КАК Регистратор,

   ТоварыНаСкладах.Регистратор.Дата КАК Дата

ПОМЕСТИТЬ ТаблицаДвижений

ИЗ

   РегистрНакопления.ТоварыНаСкладах КАК ТоварыНаСкладах

ГДЕ

   ТоварыНаСкладах.Номенклатура = &Номенклатура

;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

   ТаблицаДвижений.Номенклатура,

   МАКСИМУМ(ТаблицаДвижений.Дата) КАК Дата

ПОМЕСТИТЬ ТаблицаДат

ИЗ

   ТаблицаДвижений КАК ТаблицаДвижений

СГРУППИРОВАТЬ ПО

   ТаблицаДвижений.Номенклатура

;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

   ТаблицаДат.Номенклатура,

   МАКСИМУМ(ТаблицаДвижений.Регистратор) КАК Регистратор

ИЗ

   ТаблицаДат КАК ТаблицаДат

       ЛЕВОЕ СОЕДИНЕНИЕ ТаблицаДвижений КАК ТаблицаДвижений

       ПО ТаблицаДат.Дата = ТаблицаДвижений.Дата

СГРУППИРОВАТЬ ПО

   ТаблицаДат.Номенклатура

   zippygrill

30 – 23.11.12 – 11:06

(29) это ответ на (28) что так можно? 🙂

   Serg_1960

31 – 23.11.12 – 11:13

(29) Грац – у меня мозг взорвался от просветления при чтении поста.

PS: я говорил про конкретный запрос, а не “в общем виде”.

   AugustBlack

32 – 23.11.12 – 11:51

(19)(29) вы гений,спасибо!:) переделал под свой запрос все получилось!!

   Нуф-Нуф

33 – 23.11.12 – 12:12

хотя на самом деле в (29) все равно используется максимум по ссылке. что не дает гарантию, что из двух документов с одинаковой датой выберется самый последний.

имхо самый правильный вариант:

получить в запросе  отсортированную по Номенклатуре и МоментуВремени (убыв) таблицу ТАБЛ1

Номенклатура Регистратор МоментВремени

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

Полученную ТАБЛ1 сгруппировать по Номенклатуре и Максимум по НомеруСтроки и сунуть в ТАБЛ2

Соединить ТАБЛ2 и ТАБЛ1 по номеру строки и получить регистратор (напримере соединения в (29))

   Нуф-Нуф

34 – 23.11.12 – 12:18

хотя гоню. вариант в (33) ничем не отличается от (29) 🙂

   Serg_1960

35 – 23.11.12 – 12:39

Нуф-Нуф, не парься. Регистратором в регистре накопления могут быть документы различного вида и тогда сортировка или максимум по ссылке  – информация “не об чём” в контексте поиска последнего документа.

   AugustBlack

36 – 23.11.12 – 13:05

(33) да нашлась строка результата запроса в которой некорректно вывелся последний документ, в осв это документ не последний а предпоследний т.е даты у 2х документов совпадают 31.10.2012 23 59 59

   Serg_1960

37 – 23.11.12 – 13:14

(между прочим)

Момент времени – это дата документа + номер таблицы вида документа + уникальный идентификатор документа. Ссылка – это номер таблицы + идентификатор. Так?

Имхо: сортировки по дате и ссылке с отбором первых/последних (от сортировки зависит) – достаточно.

Я не прав?

  

AugustBlack

38 – 13.12.12 – 10:05

(37) получилось так

ВЫБРАТЬ

   МАКСИМУМ(ХозрасчетныйОбороты.Регистратор.Дата) КАК РегистраторДата,

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1

ПОМЕСТИТЬ ПоследниеДокументыНаДату

ИЗ

   РегистрБухгалтерии.Хозрасчетный.Обороты(, &КонДата, Регистратор, Счет = &Счет, , , , ) КАК ХозрасчетныйОбороты

СГРУППИРОВАТЬ ПО

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1

;

////////////////////////////////////////////////////////////////////////////////

ВЫБРАТЬ

   МАКСИМУМ(ХозрасчетныйОбороты.Регистратор) КАК Регистратор,

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1 КАК Субконто1

ИЗ

   РегистрБухгалтерии.Хозрасчетный.Обороты(, , Регистратор, , , , , ) КАК ХозрасчетныйОбороты

       ВНУТРЕННЕЕ СОЕДИНЕНИЕ ПоследниеДокументыНаДату КАК ПоследниеДокументыНаДату

       ПО ХозрасчетныйОбороты.Счет = ПоследниеДокументыНаДату.Счет

           И ХозрасчетныйОбороты.Субконто1 = ПоследниеДокументыНаДату.Субконто1

           И ХозрасчетныйОбороты.Регистратор.Дата = ПоследниеДокументыНаДату.РегистраторДата

СГРУППИРОВАТЬ ПО

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1

УПОРЯДОЧИТЬ ПО

   Субконто1,

   Регистратор

но почему-то этот запрос медленее отрабатывает по сравнению с тем если получить все документы по оборотам 60.01(в случае с программной обработкой результата запроса)

ВЫБРАТЬ

   ХозрасчетныйОбороты.Регистратор КАК Регистратор,

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1 КАК Субконто1

ИЗ

   РегистрБухгалтерии.Хозрасчетный.Обороты(, &КонДата, Регистратор, , , , , ) КАК ХозрасчетныйОбороты

ГДЕ

   ХозрасчетныйОбороты.Счет = &Счет

СГРУППИРОВАТЬ ПО

   ХозрасчетныйОбороты.Счет,

   ХозрасчетныйОбороты.Субконто1,

   ХозрасчетныйОбороты.Регистратор

УПОРЯДОЧИТЬ ПО

   Субконто1,

   Регистратор

на моих тестовых базах разница в 3-5 сек.

В данной статье рассмотрено предложение ВЫБРАТЬ, его место и роль в языке запросов 1С:Предприятия 8.

Предложение ВЫБРАТЬ является единственным обязательным элементом любого запроса, поэтому изучение языка запросов начинается именно с него. Основная цель предложения ВЫБРАТЬ заключается в том, чтобы указать поля выборки, которые должны попасть в результат запроса.

Ниже рассмотрены следующие темы:

Место предложения ВЫБРАТЬ в структуре запроса

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

Из приведенной схемы можно сделать следующие выводы:

  • В любом запросе должно быть хотя бы одно предложение ВЫБРАТЬ.
  • В списке полей выборки должно быть описание хотя бы одного поля выборки, которое в общем случае является выражением.

Примеры запросов с предложением ВЫБРАТЬ

1. Выборка всех полей (кроме виртуальных) из таблиц

Вместо перечисления списка полей можно указать звездочку (“*”) и тогда в результат запроса попадут все поля таблицы-источника, кроме виртуальных. Например:

//обращение к таблице справочника
ВЫБРАТЬ * ИЗ Справочник.Номенклатура

//обращение к таблице документа
ВЫБРАТЬ * ИЗ Документ.РасходныйКассовыйОрдер

//обращение к основной таблице регистра накопления
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании

//обращение к виртуальной таблице регистра накопления
ВЫБРАТЬ * ИЗ РегистрНакопления.ПродажиКомпании.Обороты

Замечание: В языке запросов есть возможность обойтись без предложения ИЗ, если описание поля содержит полный путь к нему с указанием таблицы-источника, например,

//выборка всех невиртуальных полей из таблицы справочника
ВЫБРАТЬ Справочник.Номенклатура.*

//выборка определенных полей из таблицы справочника
ВЫБРАТЬ
Справочник.Номенклатура.Код,
Справочник.Номенклатура.Наименование,
Справочник.Номенклатура.Представление //виртуальное поле

2. Выборка только определенных полей из таблиц

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

//обращение к таблице справочника
ВЫБРАТЬ Код, Наименование, Артикул, СтранаПроисхождения
ИЗ Справочник.Номенклатура

//обращение к таблице документа
ВЫБРАТЬ Номер, Дата, ПодразделениеКомпании, СуммаДокумента
ИЗ Документ.РасходныйКассовыйОрдер

3. Виртуальные поля

Некоторые поля в таблицах-источниках виртуальные, например, поле «Представление» для таблицы справочника и документа, или поле «МоментВремени» для документа. Это значит, что они не хранятся в базе данных, а генерируются «на лету». Виртуальные поля не включаются в результат запроса, когда вместо списка полей указана звездочка («*»), их нужно указывать явно, например «ВЫБРАТЬ *, Представление ИЗ Справочник.Товары». Такое решение было принято для ускорения выполнения классического запроса «ВЫБРАТЬ * ИЗ. ». В этом случае не требуется генерировать представления для элементов справочников и документов, следовательно запросы будут выполняться быстрее.

//обращение к таблице справочника (выбрать два обычных поля и одно виртуальное)
ВЫБРАТЬ Код, Наименование, Представление
ИЗ Справочник.Номенклатура

//обращение к таблице документа (выбрать все невиртуальные поля и два виртуальных)
ВЫБРАТЬ *, Представление, МоментВремени
ИЗ Документ.РасходныйКассовыйОрдер

4. Разыменование ссылочных полей

В 1С:Предприятии 8 допускается обращение к свойствам объектов через одну или несколько точек, например, «Номенклатура.Поставщик.Страна». Это позволяет значительно упростить написание запросов. Рекомендуется всегда пользоваться разыменованием полей там, где это возможно, чтобы не усложнять запросы лишними конструкциями.

//обращение к свойству объекта через одну точку
ВЫБРАТЬ
Ссылка,
ЮрФизЛицоКонтрагента . ИНН,
ПодразделениеКомпании . Код
ИЗ Документ.РасходныйКассовыйОрдер

//обращение к свойствам объектов через несколько точек
ВЫБРАТЬ
Ссылка,
Ответственный . ОсновнойБанковскийСчет . Банк . КоррСчет
ИЗ Документ.АвансовыйОтчет

5. Псевдонимы полей (ключевое слово КАК / AS)

Для поля может быть назначен псевдоним с помощью ключевого слова КАК. Это позволяет обращаться к полю по псевдониму при указании итогов и порядка сортировки, а также при обходе выборки из результата запроса, например:

ВЫБРАТЬ
Ссылка КАК Документ,
Ответственный КАК МатериальноОтветственный
ИЗ Документ.АвансовыйОтчет
УПОРЯДОЧИТЬ ПО МатериальноОтветственный

Ключевое слово КАК является необязательным, то есть вышеприведенный запрос можно записать так:

ВЫБРАТЬ
Ссылка Документ,
Ответственный МатериальноОтветственный
ИЗ Документ.АвансовыйОтчет

6. Обращение к табличной части как вложенной таблице

В этом случае поле результата запроса будет иметь тип РезультатЗапроса, то есть содержать вложенный результат запроса, сформированный на основе табличной части.

//получение табличной части как вложенной таблицы результата запроса
ВЫБРАТЬ Номер, Дата, Товары
ИЗ Документ.АвансовыйОтчет

//получение нескольких колонок табличной части как вложенной таблицы
ВЫБРАТЬ Номер, Дата, Товары.(Номенклатура, Количество)
ИЗ Документ.АвансовыйОтчет

Обратите внимание, что если выполнить следующий запрос, то в результате запроса будет две вложенные таблицы: в первой — одна колонка Номенклатура, а во второй — колонка Количество:

ВЫБРАТЬ Номер, Дата, Товары.Номенклатура, Товары.Количество
ИЗ Документ.АвансовыйОтчет

7. Обращение к табличной части как таблице-источнику

При таком способе обращения имя вложенной таблицы фигурирует в имени таблицы-источника (предложение ИЗ или полные имена полей) и в результате запроса нет вложенных таблиц.

//выборка всех полей из табличной части
ВЫБРАТЬ * ИЗ Документ.АвансовыйОтчет.Товары

// выборка определенных полей из табличной части
ВЫБРАТЬ Номенклатура, Количество, Цена, Сумма
ИЗ Документ.АвансовыйОтчет.Товары

//задание псевдонимов для полей табличной части
ВЫБРАТЬ Документ.АвансовыйОтчет.Товары.(Номенклатура, Сумма КАК СуммаПоСтроке)

//обращение к реквизитам документа и реквизитам табличной части (поле Ссылка)
ВЫБРАТЬ
Ссылка.Номер, Ссылка.Дата, Ссылка.Ответственный, //реквизиты документа
Номенклатура, Количество, Цена, Сумма //реквизиты табличной части
ИЗ Документ.АвансовыйОтчет.Товары

8. Ключевое слово РАЗЛИЧНЫЕ / DISTINCT

Ключевое слово РАЗЛИЧНЫЕ позволяет оставить в результате запроса только отличающиеся строки.

ВЫБРАТЬ РАЗЛИЧНЫЕ Ответственный
ИЗ Документ.АвансовыйОтчет

9. Ключевое слово ПЕРВЫЕ / TOP

Данное ключевое слово позволяет ограничить выборку несколькими первыми записями. Часто это ключевое слово применяется в комбинации с сортировкой (предложение УПОРЯДОЧИТЬ ПО).

ВЫБРАТЬ ПЕРВЫЕ 10 Номер, Дата, СуммаДокумента
ИЗ Документ.АвансовыйОтчет
УПОРЯДОЧИТЬ ПО СуммаДокумента УБЫВ

10. Выражения в списке полей выборки

В качестве описания поля выборки может быть выражение, использующее следующие элементы:

  • Литералы типов: число, строка (в кавычках), булево (значения Истина и Ложь), Null, Неопределено. [ Замечание : Чтобы указать литерал типа “дата”, можно воспользоваться ключевым словом языка запросов ДАТАВРЕМЯ или передать дату через параметр запроса].
  • Параметры запроса (со знаком &)
  • Имя поля
  • Имя табличной части
  • Разыменование ссылочного поля (через одну или несколько точек)
  • Арифметические операции (+, -, /, *) [ Замечание : операция получения остатка % в языке запросов не поддерживается]
  • Операция конкатенации строк (+) [ Замечание : операцию конкатенации нельзя использовать для виртуальных полей]
  • Встроенные функции языка запросов (ДЕНЬ, МЕСЯЦ, ГОД и т.д.)
  • Агрегатные функции (СУММА, МИНИМУМ, МАКСИМУМ, СРЕДНЕЕ, КОЛИЧЕСТВО)
  • Операция выбора ВЫБОР / CASE — позволяет получить одно из возможных значений в соответствии с указанными условиями.
  • Операция приведения типов ВЫРАЗИТЬ / CAST

Ниже приведено несколько примеров с выражениями в списке полей выборки:

//арифметические операции
ВЫБРАТЬ
Номенклатура,
Количество * Цена КАК РасчСумма1,
Сумма / Количество КАК РасчСумма2
ИЗ Документ.АвансовыйОтчет.Товары

//литералы типа “булево”, “число”, “строка”, “дата”
ВЫБРАТЬ Истина, Ложь, 10.5, “Текст”, ДАТАВРЕМЯ(2003,12,25)

//конкатенация строк
ВЫБРАТЬ “Сотрудник ” + Ответственный.Наименование
ИЗ Документ.АвансовыйОтчет

//агрегатные функции
ВЫБРАТЬ
ПодразделениеКомпании,
СУММА(СуммаДокумента),
МАКСИМУМ(СуммаДокумента),
МИНИМУМ(СуммаДокумента),
СРЕДНЕЕ(СуммаДокумента),
КОЛИЧЕСТВО(*)
ИЗ Документ.АвансовыйОтчет
СГРУППИРОВАТЬ ПО ПодразделениеКомпании

//операция выбора
ВЫБРАТЬ Наименование,
ВЫБОР
КОГДА СтранаПроисхождения.Наименование = “КИТАЙ” ТОГДА “Азия”
КОГДА СтранаПроисхождения.Наименование = “ТАЙВАНЬ” ТОГДА “Азия”
КОГДА СтранаПроисхождения.Наименование = “США” ТОГДА “Америка”
КОГДА СтранаПроисхождения.Наименование = “КАНАДА” ТОГДА “Америка”
ИНАЧЕ “Другое”
КОНЕЦ КАК Страна
ИЗ Справочник.Номенклатура

//операция приведения типов
ВЫБРАТЬ
Ссылка,
Номенклатура,
ВЫРАЗИТЬ(Сумма / 3 КАК Число(5,2)) КАК ТретьСуммы
ИЗ Документ.АвансовыйОтчет.Товары

Таким образом, предложение ВЫБРАТЬ является важнейшим элементом языка запросов, поскольку позволяет указать требуемые поля результата запроса. Гибкие возможности предложения ВЫБРАТЬ позволяют использовать язык запросов для решения самых разнообразных задач.

Сортируем документы по убыванию даты и используем конструкцию «ВЫБРАТЬ ПЕРВЫЕ 1»:
Код 1C v 8.х
В результате запрос вернёт одну строку, с данными последнего документа по одному контрагенту.

А как сделать запрос, который вернёт последние документы по всем контрагентам, а не по одному конкретному?

Используем функцию МАКСИМУМ в запросе для решения данной задачи.
Код 1C v 8.х
Этот запрос выбирает последние документы по всем контрагентам.

Имеется таблица, содержащая, например, колонки Ф, К1, К2, К3, К4. Для каждого значения Ф в тоблице может быть несколько записей.

Ф К1 К2 К3 К4
Петя 1 1 1 1
Петя 2 0 0 0
Петя 3 0 0 0
Вася 5 5 5 5
Женя 4 4 4 4

Требуется получить таблицу, включающую по одной (любой) записи для каждого значения Ф.

Ф К1 К2 К3 К4
Петя 1 1 1 1
Вася 5 5 5 5
Женя 4 4 4 4

Несмотря на простоту формлировки, у задачи нет простого решения, если только не использовать коррелированный запрос. С использованием коррелированного запроса решение получается очень простым:
ВЫБРАТЬ РАЗЛИЧНЫЕ Ф , К1 , К2 , К3 , К4
ИЗ Дано
ГДЕ ( Ф , К1 , К2 , К3 , К4 )
В ( ВЫБРАТЬ ПЕРВЫЕ 1 * ИЗ Дано КАК ВС Ё ГДЕ ВС Ё . Ф = Дано . Ф )
При использовании коррелированных запросов нельзя забывать о подводных камнях этого механизма, в частности о том, что он может служить причиной падения производительности запроса. Кроме того, в некоторых версиях файлового варианта условие ГДЕ из-за ошибки платформы 8.2 не срабатывает.

На чтение 3 мин. Просмотров 484 Опубликовано 15.12.2019

Сортируем документы по убыванию даты и используем конструкцию «ВЫБРАТЬ ПЕРВЫЕ 1»:
Код 1C v 8.х
В результате запрос вернёт одну строку, с данными последнего документа по одному контрагенту.

А как сделать запрос, который вернёт последние документы по всем контрагентам, а не по одному конкретному?

Используем функцию МАКСИМУМ в запросе для решения данной задачи.
Код 1C v 8.х
Этот запрос выбирает последние документы по всем контрагентам.

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

Мы попытаемся как можно подробнее рассказать вам об тех запросах, которые связанны с соединением, объединением, а также с соединением запросов. Давайте с помощью примеров попытаемся ответить на вопрос: каким образом можно получить последние документы в 1С запросе. Итак, давайте все таки начнем.

Для начала следует сортировать документы по убыванию даты, для этого вам понадобится воспользоватся конструкцией «ВЫБРАТЬ ПЕРВЫЕ 1»:

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

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

Каким образом можно сделать запрос, таким образом, чтобы он вернул документы по всем контрагентам, а не по одному конкретному?
Для решение данной задачи нужно будет воспользоватся функцией МАКСИМУМ.

Запрос = Новый Запрос;
Запрос.Текст = »
|ВЫБРАТЬ
| ПоследниеДокументыКонтрагентов.Ссылка,
| ПоследниеДокументыКонтрагентов.Контрагент
|ИЗ Документ.РеализацияТоваровУслуг КАК ПоследниеДокументыКонтрагентов
|ВНУТРЕННЕЕ СОЕДИНЕНИЕ
| (ВЫБРАТЬ
| Доки.Контрагент КАК Контрагент,
| МАКСИМУМ(Доки.Дата) КАК ДатаПоследнегоДокумента
| ИЗ Документ.РеализацияТоваровУслуг КАК Доки
|СГРУППИРОВАТЬ ПО Доки.Контрагент)
|КАК ДатыПоследнихДокументовКонтрагентов
|ПО ПоследниеДокументыКонтрагентов.Контрагент =
|ДатыПоследнихДокументовКонтрагентов.Контрагент
|И ПоследниеДокументыКонтрагентов.Дата =
|ДатыПоследнихДокументовКонтрагентов.ДатаПоследнегоДокумента»;
РезультатЗапроса = Запрос.Выполнить();

Этот запрос способен выбрать последние документы по всем контрагентам.

Примеры по программированию в 1с 7.7, 8.1, 8.2

пятница, 21 марта 2014 г.

Запрос 1с: Получить цену последненего прихода по всем номенклатурам на дату

1)Получим список номенклатур
2)По этому списку получим максимальную дату поступления
3)По максимальной дате поступления и номенклатуре — получим из документа (дата которого равна максимальной дате) цену.

ВЫБРАТЬ РАЗЛИЧНЫЕ
Номенклатура_.Ссылка КАК Номенклатура,
Поступления.Цена
ИЗ
Справочник.Номенклатура КАК Номенклатура_
ЛЕВОЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
МАКСИМУМ(ПоступлениеТоваровТовары.Ссылка.Дата) КАК Дата,
ПоступлениеТоваровТовары.Номенклатура КАК Номенклатура
ИЗ
Документ.ПоступлениеТоваров.Товары КАК ПоступлениеТоваровТовары
ГДЕ
ПоступлениеТоваровТовары.Ссылка.Проведен
И ПоступлениеТоваровТовары.Ссылка.Дата

Добавить комментарий