Каталог решений - Как определить дату последнего документа в 8ке.

Как определить дату последнего документа в 8ке.

Как определить дату последнего документа в 8ке.

В наличии

Решил записать в блог полезную мысль, чтобы не потерялась на форуме.

Категория:

Описание

Вот тут //sale.itcity.ru/forum/read.php?24,23382,23397#msg-23397 на форуме, спрашивали, как получить в восмерке дату последнего имеющегося в базе документа. В принципе тему можно расширить до вопроса «Как выбрать некоторое количество документов (возможно разного вида) по определенным критериям?».
Известно, что в восьмерке мы не можем выбирать все документы в одной выборке как в 7.7.

// Так не прокатит 
Док = СоздатьОбъект("Документ");
Док.ВыбратьДокументы();
Пока Док.ПолучитьДокумент()=1 Цикл
   // тут что  нибудь делаем
КонецЦикла;

Вместо этого теперь документы выбираются через объект ДокументМенеджер.<Имя документа>

Выборка = Документы.РасходнаяНакладная.Выбрать(ДатаНач, ДатаКон);
Пока Выборка.Следующий() Цикл
   // тут что  нибудь делаем
КонецЦикла;

При этом, имя документа необходимо указывать (читай — знать) перед вызовом метода Выбрать(). Следовательно, сначала необходимо все эти типы документов получить.
Чтобы в цикле получить все типы документов, можно воспользоваться коллекцией объектов Метаданные.Документы, и конкретным свойством Имя объекта коллекции, в котором храниться Вид документа, как он задан в конфигураторе. Немного подумав получаем примерно такой код:

            
	
ТекДата = '00010101'; //Переменная с пустой датой
	ЛастДок = Неопределено; //Здесь будет храниться документ с наибольшей датой
            //Перебираем все виды документов в метаданных
	Для каждого ТекДок из Метаданные.Документы Цикл
                        //имя текущего документа
		ТекИмя = ТекДок.Имя;
                        //Для создания выборки конкретного вида воспользуемся объектом
                        //ДокументМенеджер, для доспупа к конкретному виду используем 
                        //квадратные скобки и имя документа в них
		Выборка = Документы[ТекИмя].Выбрать(,,,"Дата Убыв");
                        // или Выборка = Документы[ТекИмя].Выбрать(ДатаНач,ДатаКон,Отбор,"Дата Убыв"); 
// Где Отбор это Структура, которая задает поле и значение отбора открываемой выборки. 
//Ключ структуры описывает имя поля, а значение структуры - 
//значение отбора по этому полю.

                        //Последним параметром мы поставили "Дата Убыв", то есть
                        //выбираться будут документы отсортированные по дате в порядке убывания, 
                        //самые большие даты - сначала
		Пока Выборка.Следующий() Цикл
                                    //В переменной ТекДата сохраняем наибольшую дату документа
			Если Выборка.Ссылка.Дата>ТекДата Тогда
                                                //в перенной ЛастДок - ссылку на документ с наибольшей датой
				ЛастДок = Выборка.Ссылка;
				ТекДата = ЛастДок.Дата;
			КонецЕсли;	
		        
			//При установленном порядке, первый документ в выборке
                                     // будет с напибольшей датой среди данного вида,
			//дальше можно не проверять
			Прервать;
		КонецЦикла;
	КонецЦикла;
	
	//Ну и собвтвенно выводим результаты
	Если ЛастДок <>Неопределено Тогда
		Сообщить(ЛастДок);
	Иначе
		Сообщить("Нет документов");
		
	КонецЕсли;

Второй способ получения информации о документах — язык запросов. Правда тут новички могут натолкнуться на те же самые грабли, потому что запросом можно выбрать только документа конкретного вида. Нет, к журналам документов тоже можно обращаться, но вот полного журнала, в котором регистрируются все документы по умолчанию, как в 7.7, нет, поэтому обращаться в запросе будем именно к конкретным документам. Как же будет выглядеть такой запрос? И не устанем ли мы перечислять в нем все документы?
Нет, не устанем, если будем формировать текст запроса автоматически по принципу описанному в первом примере.
Итак, как должен выглядеть текст запроса выбирающего документы одного вида? Примерно вот так:

"ВЫБРАТЬ
| ОприходованиеТоваров.Ссылка,
| ОприходованиеТоваров.ПометкаУдаления,
| ОприходованиеТоваров.Номер,
| ОприходованиеТоваров.Дата КАК Дата
|ИЗ
| Документ.ОприходованиеТоваров КАК ОприходованиеТоваров
|
|УПОРЯДОЧИТЬ ПО
| Дата УБЫВ"

Обратите внимание, документы сортируются в запросе по убыванию.

А запрос с несколькими видами документов?
Смотрим:

"ВЫБРАТЬ
| ОприходованиеТоваров.Ссылка,
| ОприходованиеТоваров.ПометкаУдаления,
| ОприходованиеТоваров.Номер,
| ОприходованиеТоваров.Дата КАК Дата
|ИЗ
| Документ.ОприходованиеТоваров КАК ОприходованиеТоваров
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| СписаниеТоваров.Ссылка,
| СписаниеТоваров.ПометкаУдаления,
| СписаниеТоваров.Номер,
| СписаниеТоваров.Дата
|ИЗ
| Документ.СписаниеТоваров КАК СписаниеТоваров
|
|УПОРЯДОЧИТЬ ПО
| Дата УБЫВ"

И теперь, имея все необходимы части запроса, можно приступать к автоматическому формированию текста.
В 

	
ТекстЗапроса = "";
	
	Для каждого МетаданныеДокумента Из Метаданные.Документы Цикл
		
		
		ИмяДокумента = МетаданныеДокумента.Имя;
		
		
		ТекстЗапроса = ?(ПустаяСтрока(ТекстЗапроса), "Выбрать разрешенные первые 1 ", ТекстЗапроса + Символы.ПС + "Объединить Все Выбрать");
		
		ТекстЗапроса = ТекстЗапроса + "
		|	__Документ.Ссылка,
		|	__Документ.ПометкаУдаления,
		|	" + ?(МетаданныеДокумента.ДлинаНомера, "__Документ.Номер","NULL") + " КАК Номер,
		|	__Документ.Дата,
		|	__Документ.Проведен,
		|	""" + МетаданныеДокумента.Представление() + """  КАК ВидДокумента,";
		
		Если МетаданныеДокумента.Проведение = Метаданные.СвойстваОбъектов.Проведение.Разрешить Тогда
			ТекстЗапроса = ТекстЗапроса + "
			|	ВЫБОР КОГДА __Документ.Проведен ТОГДА 0 ИНАЧЕ ВЫБОР КОГДА __Документ.ПометкаУдаления ТОГДА 2 ИНАЧЕ 1 КОНЕЦ КОНЕЦ КАК Иконка";
		Иначе
			ТекстЗапроса = ТекстЗапроса + "
			|	ВЫБОР КОГДА __Документ.ПометкаУдаления ТОГДА 3 ИНАЧЕ 0 КОНЕЦ КАК Иконка";
		КонецЕсли;
		
		ТекстЗапроса = ТекстЗапроса + "
		|ИЗ Документ." + ИмяДокумента + " КАК __Документ
		|ГДЕ 
		|	__Документ.Дата >= НАЧАЛОПЕРИОДА(&ДатаНачалаПериодаЖурнала, ДЕНЬ)
		|	И (__Документ.Дата <= КОНЕЦПЕРИОДА(&ДатаОкончанияПериодаЖурнала, ДЕНЬ) или &ДатаОкончанияПериодаЖурнала = ДатаВремя(1,1,1))
		|";
		
	КонецЦикла;
	
	ТекстЗапроса = ТекстЗапроса + " 
	|УПОРЯДОЧИТЬ ПО Дата УБЫВ";
	
	ЗапросЛастДок = Новый Запрос(ТекстЗапроса);
	ЗапросЛастДок.УстановитьПараметр("ДатаНачалаПериодаЖурнала",'00010101');
	ЗапросЛастДок.УстановитьПараметр("ДатаОкончанияПериодаЖурнала",'00010101');
	
	Рез = ЗапросЛастДок.Выполнить();
	Если не Рез.Пустой() Тогда
		Сообщить(Рез.Выгрузить()[0].Ссылка);
	Иначе
		Сообщить("Нет документов");
	КонецЕсли;

Сразу оговорюсь, что практически всю вышеописанныую процедуру (автоматического формирования текста запроса) я выдрал с типовой обработки «Универсальный журнал документов», которая использует нужный нам принцип:)
Итак, на что необходимо обратить внимание в этом коде:
— датами начала и конца запроса устанавливается пустая дата, это означает, что документы будут выбираться за весь период;
— документы отсортированы по убыванию;
— таблица результат запроса ограничена количеством строк равным ЕДИНИЦЕ — нам ведь нужем был только ОДИН последний документ;
— ну и кроме ссылки тут выбирается еще кое какая полезная информация: дата, номер, номер пиктограммы для отображения и т.д.
— вариант с запросом более правильный с методологической точки зрения.

Вот в принципе и все на сегодня, если кто то еще знает другие способы решения поставленной задачи — прошу в комменты:).

has been added to your cart:
Оформление заказа