Работа с регистрами сведений в 1С:Предприятие 8.3 — одна из самых востребованных задач среди разработчиков и администраторов. Часто требуется не просто прочитать данные, а именно выявить новые записи, которые появились с последней проверки: будь то обновление курсов валют, изменение цен номенклатуры или добавление новых параметров системы. Без правильного подхода эта задача может превратиться в рутинный перебор тысяч строк или, хуже того, привести к ошибкам в бизнес-логике.
В этой статье мы разберём 5 практических методов определения новых записей — от элементарных (с использованием стандартных отборов) до продвинутых (с триггерами и внешними обработками). Особое внимание уделим типичным ошибкам при работе с датами записей и независимыми регистрами, которые могут свести на нет все усилия по оптимизации. Материал будет полезен как начинающим программистам 1С, так и опытным специалистам, ищущим нестандартные решения.
1. Метод отбора по дате: простой, но эффективный
Самый очевидный способ — использовать отбор по полю "Период" (или "Дата") в запросе. Этот метод работает для большинства регистров сведений, где записи имеют временную привязку. Например, для регистра КурсыВалют можно выбрать все записи, добавленные после определенной даты:
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| КурсыВалют.Валюта КАК Валюта,
| КурсыВалют.Курс КАК Курс,
| КурсыВалют.Период КАК Период
|ИЗ
| РегистрСведений.КурсыВалют КАК КурсыВалют
|ГДЕ
| КурсыВалют.Период > &ПоследняяПроверка";
Запрос.УстановитьПараметр("ПоследняяПроверка", ПоследняяДатаПроверки);
Результат = Запрос.Выполнить();
✅ Плюсы метода:
- 🔹 Простота реализации — не требует сложных конструкций.
- 🔹 Быстродействие — индексирование по полю "Период" ускоряет выполнение.
- 🔹 Универсальность — работает в большинстве типовых конфигураций.
⚠️ Внимание: Если регистр сведений непериодический (например, АдресаОбъектов), поле "Период" отсутствует. В этом случае придётся использовать другие подходы, о которых пойдёт речь далее.
Для ускорения работы с большими регистрами всегда добавляйте индексы по полям, используемым в отборах. Это можно сделать в конфигураторе на закладке "Индексы" у объекта регистра сведений.
2. Сравнение с последней известной версией данных
Если вам нужно отслеживать изменения не по дате, а по фактическому содержимому (например, изменение цены товара независимо от даты), можно использовать механизм хэширования или сравнения с сохранённым снимком данных. Алгоритм следующий:
- Сохраняем текущее состояние регистра в временную таблицу или файл.
- При следующем запуске сравниваем актуальные данные с сохранёнными.
- Выявляем различия — это и будут новые или изменённые записи.
Пример кода для сохранения хэша записей:
Процедура СохранитьХэшРегистра(РегистрИмя)
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ ХэшДанных(*, ""SHA1"") КАК Хэш ИЗ РегистрСведений." + РегистрИмя;
Результат = Запрос.Выполнить();
ХэшТаблица = Новый ТаблицаЗначений;
ХэшТаблица.Колонки.Добавить("Хэш");
Пока Результат.Следующий() Цикл
ХэшТаблица.Добавить();
ХэшТаблица.Хэш = Результат.Хэш;
КонецЦикла;
ЗаписатьХэшВФайл(ХэшТаблица, РегистрИмя + ".hash");
КонецПроцедуры
🔍 Когда применять:
- 📌 Для регистров без явной периодичности.
- 📌 Когда важны даже минимальные изменения (например, корректировка цены на 0.01 копейку).
- 📌 При работе с распределёнными базами, где даты могут не совпадать.
3. Использование триггеров "ПриЗаписи"
Для автоматического отслеживания новых записей прямо в момент их добавления можно задействовать триггеры ПриЗаписи в модуле регистра сведений. Этот метод требует прав на модификацию конфигурации, но даёт максимальную оперативность.
Пример кода для триггера:
Процедура ПриЗаписи(Отказ, РежимЗаписи, РежимПроводки)
Если РежимЗаписи = РежимЗаписиРегистра.Добавление Тогда
// Логируем новую запись
ЖурналРегистрации.Записать(
"РегистрСведений.ИмяРегистра",
НСтр("ru = 'Добавлена новая запись'"),
УровеньЖурналирования.Информация,
,
ПодробноеПредставлениеОбъекта(ЭтотОбъект)
);
КонецЕсли;
КонецПроцедуры
⚠️ Внимание: Триггеры ПриЗаписи срабатывают до фактической записи в базу. Если в логике обработчика возникнет ошибка, это может прервать транзакцию и привести к потере данных. Всегда тестируйте такие решения на копии базы!
Что делать, если триггер не срабатывает?
Если триггер ПриЗаписи не работает, проверьте:
1. Права пользователя на модификацию метаданных.
2. Наличие галочки "Использовать стандартные обработки" в свойствах регистра.
3. Возможные ошибки в коде (например, отсутствие ключевого слова Экспорт для процедуры).
4. Режим совместимости базы — в некоторых версиях триггеры могут вести себя иначе.
4. Внешние обработки и фоновые задания
Если модифицировать конфигурацию нельзя (например, в облачных решениях или типовых базах), на помощь приходят внешние обработки. Они позволяют запускать проверку новых записей по расписанию или вручную, не затрагивая основную логику системы.
Алгоритм работы:
- Создаём обработку с формой, где указываем интересующий регистр и дату последней проверки.
- Запускаем запрос к регистру с отбором по дате/периоду.
- Выгружаем результаты в табличный документ или файл Excel.
📥 Где взять готовые решения:
- 🛠 Инфостарт — множество бесплатных и платных обработок для работы с регистрами.
- 🛠 1С:ИТС — типовые отчёты для анализа изменений.
- 🛠 GitHub — открытые репозитории с примерами кода.
Создать новую обработку в конфигураторе
Добавить реквизит "ДатаПоследнейПроверки" типа Дата
Написать запрос к регистру сведений с отбором по дате
Добавить команду выгрузки результатов в Excel
Протестировать на тестовой базе-->
5. Работа с независимыми регистрами сведений
Независимые регистры сведений (например, ПараметрыСистемы или НастройкиПользователей) не имеют поля "Период", что усложняет поиск новых записей. Здесь поможет:
- Отбор по реквизиту "ПометкаУдаления" — если запись помечена на удаление, её можно исключить из анализа.
- Сравнение с предыдущей выборкой — сохраняем идентификаторы записей и сравниваем их при следующем запуске.
- Использование служебных полей — некоторые регистры имеют скрытые поля вроде
ДатаСозданияилиВерсияДанных.
Пример запроса для независимого регистра:
Запрос.Текст =
"ВЫБРАТЬ
| НастройкиПользователей.Пользователь КАК Пользователь,
| НастройкиПользователей.Параметр КАК Параметр,
| НастройкиПользователей.Значение КАК Значение
|ИЗ
| РегистрСведений.НастройкиПользователей КАК НастройкиПользователей
|ГДЕ
| НЕ НастройкиПользователей.ПометкаУдаления
| И НастройкиПользователей.Пользователь = &ТекущийПользователь";
| Тип регистра | Метод определения новых записей | Пример регистра в 1С |
|---|---|---|
| Периодический | Отбор по полю "Период" | КурсыВалют, ЦеныНоменклатуры |
| Независимый | Сравнение с предыдущей выборкой | ПараметрыСистемы, АдресаОбъектов |
| Подчинённый | Отбор по владельцу + дата | СебестоимостьТоваров (подчинён документу) |
| Виртуальный | Триггеры или внешние обработки | Регистры расчёта (например, НачисленияЗарплаты) |
Типичные ошибки и как их избежать
Даже опытные разработчики сталкиваются с подводными камнями при работе с регистрами сведений. Вот самые распространённые:
- ❌ Игнорирование транзакций — если не обернуть чтение/запись в транзакцию, можно получить "грязные" данные при параллельной работе пользователей.
⚠️ Внимание: Всегда используйте
НачатьТранзакцию()иЗафиксироватьТранзакцию()при массовых операциях с регистрами. - ❌ Неправильный отбор по дате — если указать
Период >= &ДатавместоПериод > &Дата, в результаты попадёт лишняя запись с граничной датой. - ❌ Забывают про права доступа — пользователь может не иметь прав на чтение регистра, что приведёт к пустому результату запроса.
🔧 Как тестировать:
- Проверяйте логику на тестовой базе с копией реальных данных.
- Имитируйте параллельную работу нескольких пользователей.
- Убедитесь, что обработка корректно работает при обновлении конфигурации.
Самая частая ошибка — сравнение дат без учёта временной зоны. В распределённых системах это может привести к пропуску записей. Всегда используйте универсальное время (UTC) или явно указывайте часовой пояс.
FAQ: Ответы на частые вопросы
Можно ли отслеживать новые записи в регистре накопления теми же методами?
Да, но с оговорками. Регистры накопления имеют поле "Регистратор" (ссылка на документ), что упрощает отбор по дате документа. Однако для них чаще используют отчёты типа "Анализ субконто" или "Обороты между регистраторами".
Как быть, если в регистре миллионы записей, и запрос выполняется слишком долго?
Для больших регистров:
- Используйте постраничную выборку (параметр
Позицияв запросе). - Добавьте индексы по полям отбора.
- Рассмотрите вариант выгрузки данных в SQL и обработки на стороне СУБД.
Можно ли отслеживать, кто именно добавил новую запись?
В стандартных регистрах сведений информация о пользователе не сохраняется. Решения:
- Добавить реквизит "Пользователь" в регистр (требует изменения конфигурации).
- Использовать журнал регистрации 1С для отслеживания изменений.
- Настроить аудит на уровне СУБД (например, SQL Server Audit).
Что делать, если новые записи добавляются ретроактивно (с прошлой датой)?
В этом случае отбор по дате не сработает. Альтернативы:
- Сравнивать текущую выборку с предыдущей (метод хэширования).
- Использовать версионность данных (например, добавлять поле "Версия").
- Настроить триггеры на уровне СУБД, если 1С работает в режиме управляемого приложения.
Как автоматизировать проверку новых записей по расписанию?
Варианты автоматизации:
- 🕒 Регламентные задания в 1С (настройка в "Администрирование → Регламентные задания").
- 🤖 Внешние скрипты на Python + COM-соединение с 1С.
- ⏰ Планировщик задач Windows для запуска обработок по расписанию.
Пример кода для регламентного задания:
Процедура ВыполнитьПроверкуНовыхЗаписей() Экспорт
// Ваш код проверки
Сообщить("Проверка новых записей завершена!");
КонецПроцедуры