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

 0 

   

Распечатать

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

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

Код 1C v 8.х

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

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

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

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

Код 1C v 8.х

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

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

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

Т.е. нужно через запрос получить список контрагентов и дату или ссылку на документ Реализация товаров и услуг.

Нашел этот замечательный запрос тут.

Сам запрос:

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

Содержание:

1.       Получение последних документов в 1С

2.       Запрос с временной таблицей

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

1.      Получение последних документов в 1С

У многих разработчиков в 1С часто возникает вопрос: как получать последние (либо первые) документы из конкретной выборки? Данную задачу можно решить не одним, но несколькими способами.

Рассмотрим пример. Пусть есть некоторая первоначальная база 1С:Управление торговлей, редакция 11, из которой необходимо получить последнюю документацию по номенклатурному приходу по специальному регистру «ТоварыНаСкладе». Последним документом в этом контексте имеется ввиду тот документ, который имеет максимальную дату, а именно: последний документ, в котором работал пользователь системы 1С.

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

Далее представлены примеры запросов:

Рис. 1 Запрос для поиска последнего документа в 1С

Результат будет выведен в виде следующей таблицы с последними сохраненными документами – номенклатурой по регистраторам:

Рис. 2 Таблица с последними сохраненными документами – номенклатура по регистраторам

В таком случае сортировка по умолчанию будет происходить без учета даты документации – учитывается только персональный идентификатор. Таким образом документация, которая была зарегистрирована позже некоторого времени в приходной ордер ЦУ-33, будет в самом начале нашей выборки. Рассмотрим вариант, когда сортировки по порядку не будет:

Рис. 3 Таблица без сортировки по порядку последних документов в 1С

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

Рис. 4 Запрос для поиска последних открытых документов

А результат данного запроса будет следующим:

Рис. 5 Результат поиска последних открытых документов

В данном случае конструкция «МАКСИМУМ» разбивает избранную выборку по «GUID» объекта. Данным способом можно воспользоваться в 1С 8 УТ 11 в случае, когда необходимо получить последний сохраненный документ, опираясь на его дату. Так мы получаем список с номенклатурой и, при помощи цикла для всех позиций по отдельности, последний документ в 1С 8 «Управление торговлей» 11. Но данный способ занимает довольно много времени и уменьшает производительность.  

2. Запрос с временной таблицей

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

Рис. 6 Запрос с временной таблицей

Результат будет следующим:

Рис. 7 Результат запроса с временной таблицей

Специалист компании «Кодерлайн»

Айдар Фархутдинов

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

Разберем на примере демо-базы УТ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: как правильно заметили в комментариях, механизм генерации ГУИД обеспечивает только уникальность, но не возрастающую последовательность. На момент написания статьи проведенные тесты давали необходимый результат. Но гарантии, что выявленная закономерность сохранится в последующих версиях платформы, нет. Поэтому, если необходимо фиксировать момент создания документов, то лучше реализовать свой механизм. Например, с использованием регистра сведений.

Приветсвую вас, уважаемые читатели блога SoftMaker.kz! Использование запросов в 1С помогает справляться с различными задачами, которые возникают на практике. Мы уже рассматривали примеры запросов, связанных с соединением и объединением, а также пакетные запросы. Еще есть целая статья, которая посвящена теме запросов. А сегодня, с помощью примеров, мы рассмотрим, как получить последние документы в 1С запросе. Давайте начнем!

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

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

В результате запрос вернёт одну строку, с данными последнего документа по одному контрагенту. Мы берем не дату, так как в одну секунду может быть много документов, поэтому нельзя быть уверенным, что будет взят последний из этих документов. Поэтому в запросе нужно сортировать по моменту времени и отбор первого документа. Такой запрос вернет последний документ. Момент времени это сочитание даты документа и ссылки, поэтому можно написать и так:

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

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

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

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

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

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

ПОДПИСКА

Понравилась статья? Поделить с друзьями:
  • Как исправить перекус у щенка чихуахуа
  • Как найти середину строки в питоне
  • Как найти задать критерий в excel
  • Как найти в телефоне видео экрана
  • Асимметрия губ после увеличения как исправить видео