gifts2017

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

Опубликовал kitt al;dskjf;ldasjkf (kitt) в раздел Программирование - Практика программирования

Решил записать в блог полезную мысль, чтобы не потерялась на форуме.
Вот тут http://infostart.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].Ссылка);
	Иначе
		Сообщить("Нет документов");
	КонецЕсли;


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

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

См. также

Подписаться Добавить вознаграждение

Комментарии

1. kitt al;dskjf;ldasjkf (kitt) 01.10.08 19:27
Ну конечно, потом чувак на форуме уточнил, что ему надо дату только одного вида документа - Приходного кассового ордера, но, я со свойственной для русских широтой души быстро наклепал пару универсальных алгоритмов для всех документов:)
2. Андрей Скляров (coder1cv8) 02.10.08 09:31
Про выборку всех документов я уже писал здесь...
3. Igоr Sаulеviсh (gutentag) 15.10.08 17:03
А не проще ли открыть журнал общих документов, переместить курсор в конц журнала и посмотреть дату последнего документа... Или я во что-то не въехал? :)
4. kitt al;dskjf;ldasjkf (kitt) 15.10.08 18:21
gutentag здесь подразумевается "Программно". Интерективно конечно проще в журнале, но общий журнал в 8ке использует описанный в этой статье механизм с запросом.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа