При переходе с платформы 1С:Предприятие 7.7 на современную версию 8.3 (например, в конфигурации Управление торговлей 11.4) многие разработчики сталкиваются с отсутствием прямой возможности просмотреть список всех созданных документов одной кнопкой, как это было реализовано в старых интерфейсах. В этой статье мы подробно разберем, как решить эту задачу программно и с помощью стандартных средств системы — также для этого подойдёт групповая обработка документов с гибким отбором.
Прежде чем приступать к написанию кода, проанализируем штатные возможности УТ 11.4. В современных конфигурациях на управляемых формах существует инструмент под названием Общий журнал документов. Чтобы его найти, выполним следующие действия:
Этот способ удобен для быстрого просмотра (также можно использовать Полный журнал документов), но если нам нужно программно обработать эти данные или вывести их в специфический отчет, придется воспользоваться средствами встроенного языка.
Рассмотрим наиболее эффективный программный метод. Основная сложность заключается в том, что каждый вид документа (например, РеализацияТоваровУслуг, ПоступлениеТоваровУслуг и т.д.) хранится в своей физической таблице базы данных. Чтобы собрать их воедино, мы воспользуемся коллекцией Метаданные.Документы и сформируем текст запроса динамически (помочь в этом может обработка для получения текста запроса).
Проанализируем следующий алгоритм:
ТекстЗапросаПоДокументу =
"ВЫБРАТЬ
| Документ.Ссылка КАК Ссылка,
| Документ.МоментВремени КАК МоментВремени
|ИЗ
| Документ.ТипДокумента КАК Документ
|ГДЕ
| Документ.Дата МЕЖДУ &ДатаНач И &ДатаКон";
ТекстЗапроса = "";
Для Каждого ДокументМД Из Метаданные.Документы Цикл
// Пропускаем документы, которые не записываются в БД (если такие есть)
ТекстЗапроса = ТекстЗапроса + ?(ПустаяСтрока(ТекстЗапроса), "", " ОБЪЕДИНИТЬ ВСЕ ")
+ СтрЗаменить(ТекстЗапросаПоДокументу, "ТипДокумента", ДокументМД.Имя);
КонецЦикла;
ТекстЗапроса = ТекстЗапроса + " УПОРЯДОЧИТЬ ПО МоментВремени";
Запрос = Новый Запрос(ТекстЗапроса);
Запрос.УстановитьПараметр("ДатаНач", НачалоДня(Объект.ДатаНачала));
Запрос.УстановитьПараметр("ДатаКон", КонецДня(Объект.ДатаОкончания));
Результат = Запрос.Выполнить();
Важное замечание: При использовании оператора ОБЪЕДИНИТЬ ВСЕ следует помнить о технических ограничениях SQL Server. Если в вашей конфигурации более 256 или 512 видов документов (что встречается в крупных ERP-системах), такой запрос может вызвать ошибку переполнения стека парсера SQL. В этом случае рекомендуется выполнять запросы порциями или обращаться к предопределенным журналам документов.
Если документов слишком много или требуется избежать построения гигантского текста запроса, разберем вариант с выполнением запроса для каждого метаданного по отдельности. Мы будем выводить результат сразу в окно сообщений или заполнять таблицу значений.
Для каждого ДокМД из Метаданные.Документы Цикл
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Ссылка
|ИЗ
| Документ." + ДокМД.Имя + "
|ГДЕ
| Дата МЕЖДУ &Дата1 И &Дата2";
Запрос.УстановитьПараметр("Дата1", НачалоДня(Объект.ДатаНачала));
Запрос.УстановитьПараметр("Дата2", КонецДня(Объект.ДатаОкончания));
РезультатЗапроса = Запрос.Выполнить().Выбрать();
Пока РезультатЗапроса.Следующий() Цикл
Сообщить("Найден документ: " + Строка(РезультатЗапроса.Ссылка));
КонецЦикла;
КонецЦикла;
Этот метод более "безопасен" для системы, так как нагрузка на память сервера БД распределена. Однако он не позволяет легко отсортировать общий список всех документов по дате, так как данные выводятся группами по типам.
Выясним, как получить данные без использования языка запросов. У каждого менеджера документов есть метод Выбрать(). Это может быть полезно для простых обработок, запускаемых в консоли кода (для разработки и тестирования которых поможет универсальная консоль запросов и кода 1С).
Д1 = НачалоДня(Объект.ДатаНачала);
Д2 = КонецДня(Объект.ДатаОкончания);
Для каждого МД из Метаданные.Документы Цикл
Выборка = Документы[МД.Имя].Выбрать(Д1, Д2);
Пока Выборка.Следующий() Цикл
// Здесь можно выполнять действия с объектом
Сообщить(Выборка.Ссылка);
КонецЦикла;
КонецЦикла;
Важный нюанс: Метод Выбрать() работает медленнее, чем Запрос, так как он считывает объект целиком со всеми реквизитами и табличными частями в память сервера приложений. Если вам нужны только ссылки и даты, используйте Запрос.
Проанализируем ситуацию, когда автор сообщения спрашивает: "какие документы внесены в базу". В 1С Дата документа — это реквизит, который пользователь может установить вручную (даже "задним числом"). Если ваша цель — увидеть документы, физически созданные в определенный день (независимо от того, какая дата стоит в самом документе), обычный запрос к таблицам документов не поможет.
В этом случае необходимо обращаться к Журналу регистрации — фиксировать эти события автоматически поможет обработка логирования изменений и удалений документов. Рассмотрим пример кода, который выгружает события создания новых документов за период:
Фильтр = Новый Структура;
Фильтр.Вставить("ДатаНачала", НачалоДня(Объект.ДатаНачала));
Фильтр.Вставить("ДатаОкончания", КонецДня(Объект.ДатаОкончания));
// Указываем событие - добавление данных
МассивСобытий = Новый Массив;
МассивСобытий.Добавить("_$Data$_.New");
Фильтр.Вставить("Событие", МассивСобытий);
ТаблицаСобытий = Новый ТаблицаЗначений;
ВыгрузитьЖурналРегистрации(ТаблицаСобытий, Фильтр, "Дата, Данные, ИмяПользователя");
Для Каждого СтрокаСобытия Из ТаблицаСобытий Цикл
// Проверяем, что измененные данные являются документом
Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(СтрокаСобытия.Данные)) Тогда
Сообщить("Документ " + СтрокаСобытия.Данные + " создан пользователем " + СтрокаСобытия.ИмяПользователя);
КонецЕсли;
КонецЦикла;
Как справедливо замечено в обсуждении, если документов в выборке будет "100500+", использование метода Сообщить() может привести к зависанию интерфейса. Посмотрим на альтернативные варианты вывода:
ТаблицаЗначений, и заполняйте её. Это позволит пользователю сортировать и фильтровать результат.Выбор конкретного метода зависит от ваших задач: для разовой проверки подойдет консоль запросов и динамический текст, а для постоянной работы лучше использовать отчет на базе СКД (Системы компоновки данных), который будет обращаться к общему журналу документов для обеспечения максимальной производительности.