Работа с регистрами сведений в 1С:Предприятие 8.3 — одна из самых востребованных задач среди разработчиков и администраторов. Часто требуется не просто прочитать данные, а именно выявить новые записи, которые появились с последней проверки: будь то обновление курсов валют, изменение цен номенклатуры или добавление новых параметров системы. Без правильного подхода эта задача может превратиться в рутинный перебор тысяч строк или, хуже того, привести к ошибкам в бизнес-логике.

В этой статье мы разберём 5 практических методов определения новых записей — от элементарных (с использованием стандартных отборов) до продвинутых (с триггерами и внешними обработками). Особое внимание уделим типичным ошибкам при работе с датами записей и независимыми регистрами, которые могут свести на нет все усилия по оптимизации. Материал будет полезен как начинающим программистам , так и опытным специалистам, ищущим нестандартные решения.

1. Метод отбора по дате: простой, но эффективный

Самый очевидный способ — использовать отбор по полю "Период" (или "Дата") в запросе. Этот метод работает для большинства регистров сведений, где записи имеют временную привязку. Например, для регистра КурсыВалют можно выбрать все записи, добавленные после определенной даты:

Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ

| КурсыВалют.Валюта КАК Валюта,

| КурсыВалют.Курс КАК Курс,

| КурсыВалют.Период КАК Период

|ИЗ

| РегистрСведений.КурсыВалют КАК КурсыВалют

|ГДЕ

| КурсыВалют.Период > &ПоследняяПроверка";

Запрос.УстановитьПараметр("ПоследняяПроверка", ПоследняяДатаПроверки);

Результат = Запрос.Выполнить();

Плюсы метода:

  • 🔹 Простота реализации — не требует сложных конструкций.
  • 🔹 Быстродействие — индексирование по полю "Период" ускоряет выполнение.
  • 🔹 Универсальность — работает в большинстве типовых конфигураций.

⚠️ Внимание: Если регистр сведений непериодический (например, АдресаОбъектов), поле "Период" отсутствует. В этом случае придётся использовать другие подходы, о которых пойдёт речь далее.

💡

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

2. Сравнение с последней известной версией данных

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

  1. Сохраняем текущее состояние регистра в временную таблицу или файл.
  2. При следующем запуске сравниваем актуальные данные с сохранёнными.
  3. Выявляем различия — это и будут новые или изменённые записи.

Пример кода для сохранения хэша записей:

Процедура СохранитьХэшРегистра(РегистрИмя)

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ ХэшДанных(*, ""SHA1"") КАК Хэш ИЗ РегистрСведений." + РегистрИмя;

Результат = Запрос.Выполнить();

ХэшТаблица = Новый ТаблицаЗначений;

ХэшТаблица.Колонки.Добавить("Хэш");

Пока Результат.Следующий() Цикл

ХэшТаблица.Добавить();

ХэшТаблица.Хэш = Результат.Хэш;

КонецЦикла;

ЗаписатьХэшВФайл(ХэшТаблица, РегистрИмя + ".hash");

КонецПроцедуры

🔍 Когда применять:

  • 📌 Для регистров без явной периодичности.
  • 📌 Когда важны даже минимальные изменения (например, корректировка цены на 0.01 копейку).
  • 📌 При работе с распределёнными базами, где даты могут не совпадать.
📊 Какой метод отслеживания новых записей вы используете чаще?
По дате
Сравнение хэшей
Триггеры
Внешние обработки
Другой

3. Использование триггеров "ПриЗаписи"

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

Пример кода для триггера:

Процедура ПриЗаписи(Отказ, РежимЗаписи, РежимПроводки)

Если РежимЗаписи = РежимЗаписиРегистра.Добавление Тогда

// Логируем новую запись

ЖурналРегистрации.Записать(

"РегистрСведений.ИмяРегистра",

НСтр("ru = 'Добавлена новая запись'"),

УровеньЖурналирования.Информация,

,

ПодробноеПредставлениеОбъекта(ЭтотОбъект)

);

КонецЕсли;

КонецПроцедуры

⚠️ Внимание: Триггеры ПриЗаписи срабатывают до фактической записи в базу. Если в логике обработчика возникнет ошибка, это может прервать транзакцию и привести к потере данных. Всегда тестируйте такие решения на копии базы!

Что делать, если триггер не срабатывает?

Если триггер ПриЗаписи не работает, проверьте:

1. Права пользователя на модификацию метаданных.

2. Наличие галочки "Использовать стандартные обработки" в свойствах регистра.

3. Возможные ошибки в коде (например, отсутствие ключевого слова Экспорт для процедуры).

4. Режим совместимости базы — в некоторых версиях триггеры могут вести себя иначе.

4. Внешние обработки и фоновые задания

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

Алгоритм работы:

  1. Создаём обработку с формой, где указываем интересующий регистр и дату последней проверки.
  2. Запускаем запрос к регистру с отбором по дате/периоду.
  3. Выгружаем результаты в табличный документ или файл Excel.

📥 Где взять готовые решения:

  • 🛠 Инфостарт — множество бесплатных и платных обработок для работы с регистрами.
  • 🛠 1С:ИТС — типовые отчёты для анализа изменений.
  • 🛠 GitHub — открытые репозитории с примерами кода.

Создать новую обработку в конфигураторе

Добавить реквизит "ДатаПоследнейПроверки" типа Дата

Написать запрос к регистру сведений с отбором по дате

Добавить команду выгрузки результатов в Excel

Протестировать на тестовой базе-->

5. Работа с независимыми регистрами сведений

Независимые регистры сведений (например, ПараметрыСистемы или НастройкиПользователей) не имеют поля "Период", что усложняет поиск новых записей. Здесь поможет:

  1. Отбор по реквизиту "ПометкаУдаления" — если запись помечена на удаление, её можно исключить из анализа.
  2. Сравнение с предыдущей выборкой — сохраняем идентификаторы записей и сравниваем их при следующем запуске.
  3. Использование служебных полей — некоторые регистры имеют скрытые поля вроде ДатаСоздания или ВерсияДанных.

Пример запроса для независимого регистра:

Запрос.Текст =

"ВЫБРАТЬ

| НастройкиПользователей.Пользователь КАК Пользователь,

| НастройкиПользователей.Параметр КАК Параметр,

| НастройкиПользователей.Значение КАК Значение

|ИЗ

| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей

|ГДЕ

| НЕ НастройкиПользователей.ПометкаУдаления

| И НастройкиПользователей.Пользователь = &ТекущийПользователь";

Тип регистра Метод определения новых записей Пример регистра в 1С
Периодический Отбор по полю "Период" КурсыВалют, ЦеныНоменклатуры
Независимый Сравнение с предыдущей выборкой ПараметрыСистемы, АдресаОбъектов
Подчинённый Отбор по владельцу + дата СебестоимостьТоваров (подчинён документу)
Виртуальный Триггеры или внешние обработки Регистры расчёта (например, НачисленияЗарплаты)

Типичные ошибки и как их избежать

Даже опытные разработчики сталкиваются с подводными камнями при работе с регистрами сведений. Вот самые распространённые:

  • Игнорирование транзакций — если не обернуть чтение/запись в транзакцию, можно получить "грязные" данные при параллельной работе пользователей.
    ⚠️ Внимание: Всегда используйте НачатьТранзакцию() и ЗафиксироватьТранзакцию() при массовых операциях с регистрами.
  • Неправильный отбор по дате — если указать Период >= &Дата вместо Период > &Дата, в результаты попадёт лишняя запись с граничной датой.
  • Забывают про права доступа — пользователь может не иметь прав на чтение регистра, что приведёт к пустому результату запроса.

🔧 Как тестировать:

  1. Проверяйте логику на тестовой базе с копией реальных данных.
  2. Имитируйте параллельную работу нескольких пользователей.
  3. Убедитесь, что обработка корректно работает при обновлении конфигурации.
💡

Самая частая ошибка — сравнение дат без учёта временной зоны. В распределённых системах это может привести к пропуску записей. Всегда используйте универсальное время (UTC) или явно указывайте часовой пояс.

FAQ: Ответы на частые вопросы

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

Да, но с оговорками. Регистры накопления имеют поле "Регистратор" (ссылка на документ), что упрощает отбор по дате документа. Однако для них чаще используют отчёты типа "Анализ субконто" или "Обороты между регистраторами".

Как быть, если в регистре миллионы записей, и запрос выполняется слишком долго?

Для больших регистров:

  1. Используйте постраничную выборку (параметр Позиция в запросе).
  2. Добавьте индексы по полям отбора.
  3. Рассмотрите вариант выгрузки данных в SQL и обработки на стороне СУБД.
Можно ли отслеживать, кто именно добавил новую запись?

В стандартных регистрах сведений информация о пользователе не сохраняется. Решения:

  • Добавить реквизит "Пользователь" в регистр (требует изменения конфигурации).
  • Использовать журнал регистрации 1С для отслеживания изменений.
  • Настроить аудит на уровне СУБД (например, SQL Server Audit).
Что делать, если новые записи добавляются ретроактивно (с прошлой датой)?

В этом случае отбор по дате не сработает. Альтернативы:

  • Сравнивать текущую выборку с предыдущей (метод хэширования).
  • Использовать версионность данных (например, добавлять поле "Версия").
  • Настроить триггеры на уровне СУБД, если 1С работает в режиме управляемого приложения.
Как автоматизировать проверку новых записей по расписанию?

Варианты автоматизации:

  • 🕒 Регламентные задания в 1С (настройка в "Администрирование → Регламентные задания").
  • 🤖 Внешние скрипты на Python + COM-соединение с 1С.
  • Планировщик задач Windows для запуска обработок по расписанию.

Пример кода для регламентного задания:

Процедура ВыполнитьПроверкуНовыхЗаписей() Экспорт

// Ваш код проверки

Сообщить("Проверка новых записей завершена!");

КонецПроцедуры