Работа с датами в системе 1С:Предприятие является фундаментальной задачей для любого разработчика, будь то написание сложного отчета или простая выгрузка остатков на складе. Понимание того, как правильно формулировать условия отбора по времени, напрямую влияет на скорость выполнения запроса и корректность получаемых данных. Ошибки в логике сравнения дат часто приводят к тому, что документы"теряются" или, наоборот, попадают в выборку дважды.

В языке запросов 1С существует несколько способов фильтрации записей по временной шкале: от простых операторов сравнения до использования специального ключевого слова ПЕРИОДЫ. Выбор конкретного метода зависит от типа используемого регистра (накопления, сведений или бухгалтерии) и требований к производительности. Важно не просто знать синтаксис, но и понимать, как платформа интерпретирует эти условия на уровне СУБД.

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

Базовый синтаксис отбора по дате

Самый распространенный способ фильтрации — использование оператора ВЫБОР в сочетании с условиями в блоке ГДЕ. Для полей типа Date стандартно применяются операторы сравнения: больше (>), меньше (<), больше или равно (>=) и меньше или равно (<=). Платформа 1С автоматически преобразует эти условия в оптимизированный SQL-код, соответствующий используемой системе управления базами данных.

При написании условий критически важно учитывать тип граничных значений. Если вы используете параметры в запросе, убедитесь, что их тип строго соответствует типу поля в таблице. Например, попытка сравнить дату с строкой без явного приведения типов может привести к ошибке выполнения или некорректному результату, если СУБД попытается выполнить неявное преобразование.

Часто возникает необходимость выбрать документы за конкретный день. В этом случае разработчики используют конструкцию"больше или равно начало дня" и"меньше конец дня". Это позволяет охватить все записи, включая те, у которых время установлено на 23:59:59. Такой подход является универсальным и работает одинаково стабильно независимо от настроек точности времени в конфигурации.

Обратите внимание на использование ключевого слова НАЧАЛОДНЯ и КОНЕЦДНЯ. Эти функции являются частью встроенного языка запросов и позволяют динамически вычислять границы временных интерсов прямо в тексте запроса, что избавляет от необходимости передавать лишние параметры из внешней среды.

⚠️ Внимание: Использование функций в условии отбора по индексируемому полю даты (например, НАЧАЛОДНЯ(Дата)) может привести к полному сканированию таблицы (table scan) и резкому падению производительности на больших объемах данных. Всегда старайтесь сравнивать само поле даты с вычисленным значением, а не применять функции к полю.

Использование ключевого слова ПЕРИОДЫ

Для регистров накопления и бухгалтерии в 1С предусмотрен специальный механизм — ключевое слово ПЕРИОДЫ. Оно позволяет выбирать срезы или обороты за определенный временной интервал без ручного написания сложных условий сравнения. Этот синтаксический сахар не только упрощает чтение кода, но и позволяет движку 1С применять специфические оптимизации для виртуальных таблиц.

При использовании ПЕРИОДЫ вы указываете начало и конец интервала, а система сама определяет, какие записи попадают в выборку. Это особенно удобно при работе с регистрами, где данные могут храниться с разной периодичностью или иметь сложную структуру разрезов. Синтаксис выглядит лаконично и интуитивно понятно для специалистов, знакомых с предметной областью.

💡

При работе с виртуальными таблицами регистров накопления всегда используйте параметр"Период" в свойствах таблицы в конструкторе запросов, если это возможно — это гарантирует использование оптимального плана выполнения.

Однако стоит помнить, что ПЕРИОДЫ работает только с виртуальными таблицами регистров. Если вы обращаетесь к физической таблице документа или справочника напрямую, этот синтаксис будет недоступен, и придется возвращаться к классическим операторам сравнения. Понимание этой границы важно для архитектурной целостности вашего кода.

В некоторых случаях, когда требуется получить данные на конкретную дату (срез), использование периода может быть избыточным. Тогда применяют параметр На в виртуальных таблицах, что является эквивалентом условия"меньше или равно дате отсечения" с учетом специфики проведения документов.

Работа с граничными условиями и временем

Одной из самых частых причин ошибок в отчетах является непонимание того, как 1С хранит время внутри типа Date. Дата всегда включает в себя временную составляющую. Если в документе время не указано явно, оно часто принимается равным 00:00:00 или текущему времени системы в момент записи, в зависимости от настроек объекта.

Рассмотрим ситуацию, когда нужно выбрать все документы за 25 октября 2023 года. Наивная попытка написать условие Где Дата = &Дата, где параметру передано значение"25.10.2023 00:00", вернет только те документы, у которых время тоже ровно ноль. Все документы, проведенные в 10:00 или 14:30, будут отфильтрованы, хотя логически они относятся к этому дню.

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

ВЫБРАТЬ

ДокументРеализацияТоваровУслуг.Ссылка КАК Ссылка,

ДокументРеализацияТоваровУслуг.Дата КАК Дата

ИЗ

Документ.РеализацияТоваровУслуг КАК ДокументРеализацияТоваровУслуг

ГДЕ

ДокументРеализацияТоваровУслуг.Дата >= НАЧАЛОДНЯ(&НачалоПериода)

И ДокументРеализацияТоваровУслуг.Дата < КОНЕЦДНЯ(&КонецПериода)

Использование конструкции < КОНЕЦДНЯ(...) является предпочтительным по сравнению с <= КОНЕЦДНЯ(...), так как функция КОНЕЦДНЯ возвращает время 23:59:59. Если в системе используется высокая точность времени (до миллисекунд), условие"меньше или равно" может пропустить документы, созданные в последние доли секунды дня.

📊 Как вы обычно фильтруете документы за день?
Использую = ДАТАВРЕМЯ(...)
Использую диапазон >= и <=
Использую диапазон >= и <
Использую виртуальные таблицы

Оптимизация запросов с отбором по дате

Производительность запросов в 1С напрямую зависит от того, как построены условия отбора. Движок платформы старается использовать индексы по полям даты, но только если условия сформулированы определенным образом. Нарушение правил формирования предикатов может привести к тому, что база данных будет перебирать миллионы записей вместо использования быстрого поиска по индексу.

Главное правило оптимизации: поле даты в условии ГДЕ должно стоять"в чистом виде". Нельзя оборачивать его в функции, выполнять над ним арифметические операции или приводить типы непосредственно в условии. Любое действие над полем слева от знака сравнения часто ломает возможность использования индекса.

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

Тип условия Пример кода Использование индекса Рекомендация
Оптимальное Где Дата >= &Начало Да (полное) Использовать всегда
Допустимое Где Год(Дата) = 2023 Нет (сканирование) Избегать на больших таблицах
Ошибочное Где Дата + 1 = &Завтра Нет Переписать через сравнение
С функцией Где НАЧАЛОДНЯ(Дата) = &День Нет (часто) Заменить на диапазон

Также стоит учитывать селективность выборки. Если вы выбираете данные за 10 лет из таблицы, где хранится история за 15 лет, использование индекса по дате может оказаться менее эффективным, чем полное сканирование, так как СУБД решит, что проще прочитать всё подряд, чем прыгать по индексной структуре. В таких случаях иногда полезно добавить дополнительный отбор по организации или контрагенту.

⚠️ Внимание: В распределенных информационных базах (РИБ) отбор по дате может работать медленнее из-за необходимости синхронизации данных между узлами. Планируйте выгрузку данных в часы наименьшей нагрузки.

Специфика работы с регистрами накопления

Регистры накопления имеют свою уникальную логику хранения данных, разделенную на таблицы движений и итогов. При выборе данных"на дату" (остатки) система обращается к таблице итогов, если она построена для нужного периода. Если же требуется оборот за период, запрос идет к таблице движений.

При формировании запроса к виртуальной таблице Остатки важно правильно указывать параметры периода. Ошибка в один день может привести к тому, что система будет рассчитывать остатки"на лету", суммируя все движения с начала времен, что крайне ресурсоемко. Убедитесь, что в конфигурации разрешено ведение итогов для используемых разрезов.

Почему запрос к остаткам работает медленно?

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

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

Используйте модификаторы АКТУАЛЬНОСТЬ или ПОСЛЕДНИЕ при работе с такими таблицами, если ваша цель — получить только самое свежее значение свойства на момент времени. Это избавит от необходимости писать сложные вложенные запросы для фильтрации дублей.

Частые ошибки и методы отладки

Даже опытные разработчики иногда допускают логические ошибки при работе с временными интервалами. Самая коварная из них — ошибка"один день". Она возникает, когда программист забывает, что конец периода должен быть исключен из выборки (оператор <), и использует <=, получая лишнюю запись следующего дня, или наоборот, теряет последнюю запись текущего дня.

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

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

☑️ Чек-лист проверки запроса по дате

Выполнено: 0 / 5

Не забывайте про обработку пустых значений. Если поле даты может быть не заполнено (NULL), стандартные операторы сравнения могут вести себя непредсказуемо в зависимости от настроек СУБД. Явно указывайте условие И Дата ЕСТЬ NULL, если такая ситуация возможна в вашей предметной области, чтобы избежать потери данных.

⚠️ Внимание: Интерфейс и возможности конструктора запросов могут меняться в разных версиях платформы 1С. Всегда сверяйте доступные поля и параметры виртуальных таблиц в вашей конкретной конфигурации, так как обновления могут добавлять или изменять свойства регистров.

💡

Правильная работа с датами в 1С требует понимания разницы между физическим хранением данных (Date + Time) и логическим представлением периода. Всегда используйте диапазон [Начало, Конец) для фильтрации по дням.

FAQ: Вопросы и ответы

Как выбрать документы строго за вчерашний день?

Используйте конструкцию: Где Дата >= НАЧАЛОДНЯ(СЕГОДНЯ - 1) И Дата < НАЧАЛОДНЯ(СЕГОДНЯ). Это гарантирует, что вы захватите все секунды вчерашних суток, но не захватите ни одной секунды сегодняшнего дня.

Почему запрос с НАЧАЛОДНЯ(Дата) работает медленно?

Потому что применение функции к полю в условии ГДЕ запрещает использование индекса по этому полю. Базе данных приходится вычислять функцию для каждой строки таблицы. Перепишите условие, вычисляя начало дня для параметра, а не для поля таблицы.

В чем разница между ПЕРИОДЫ и обычным ГДЕ?

ПЕРИОДЫ — это специальный синтаксис для виртуальных таблиц регистров, который позволяет платформе применять внутренние оптимизации для расчета оборотов и остатков. Обычное ГДЕ работает на уровне стандартных SQL-условий и не знает о специфике регистров.

Как учесть часовой пояс в запросе?

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

Можно ли использовать переменные в условии даты?

Да, это стандартная практика. Передавайте параметры через объект Запрос.УстановитьПараметр. Это защищает от SQL-инъекций и позволяет переиспользовать текст запроса для разных периодов без его перекомпоновки.