В практике разработки и администрирования 1С нередко возникают ситуации, когда служебный скрипт или внешняя обработка запускаются не в тестовом контуре, а в рабочей информационной базе. Одной из самых опасных и при этом распространенных ошибок является непреднамеренное обнуление независимого регистра сведений, например регистра Штрихкоды, что мгновенно парализует работу кассовых узлов и складов в торговых предприятиях. Разберем механику возникновения этой ошибки, методы быстрого возврата утерянных данных и способы программной защиты конфигурации от подобных инцидентов.
Проанализируем программный код, приведший к сбою в рабочей базе:
НаборЗаписей = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
НаборЗаписей.Записать();
Или его эквивалент в одну строку:
РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей().Записать();
Выясним причину такого поведения платформы. Метод СоздатьНаборЗаписей() инициализирует пустую выборку записей. При вызове метода Записать() платформа по умолчанию применяет параметр Замещать = Истина. Это означает, что текущие данные в таблице базы данных заменяются содержимым набора. Если в наборе записей не установлено ни одного отбора, то замещению подлежит абсолютно вся таблица регистра.
Важно подчеркнуть различие между типами регистров: в подчиненных регистрах (с режимом записи «Подчинение регистратору») платформа 1С на уровне ядра требует обязательной установки отбора по регистратору. Если попытаться записать пустой набор подчиненного регистра без указания ссылки на документ-регистратор, платформа сгенерирует исключение времени выполнения. В независимых же регистрах сведений таких системных ограничений нет, что делает их крайне уязвимыми для подобных случайных очисток.
Если бы программист указал второй параметр как Ложь:
НаборЗаписей = РегистрыСведений.Штрихкоды.СоздатьНаборЗаписей();
НаборЗаписей.Записать(Ложь);
Платформа отработала бы в режиме дозаписи и слияния, и существующие строки регистра остались бы нетронутыми.
Когда таблица регистра уже очищена в рабочей базе, полная перезаливка базы из бэкапа недопустима, так как это приведет к потере проведенных чеков, введенных документов и проводок за прошедшее с момента создания копии время. Разберем по шагам правильный алгоритм точечного восстановления.
COMConnector / веб-сервисы) считываем записи регистра сведений Штрихкоды из копии.Если на сервере СУБД (например, MS SQL Server или PostgreSQL) используется модель восстановления с логированием транзакций (Point-in-Time Recovery), то развертывание копии можно произвести с точностью до секунды, предшествующей моменту выполнения ошибочного скрипта. Также при наличии снимков базы (Database Snapshot) возможно мгновенно обратиться к теневой таблице и извлечь строки регистра без полной инициализации резервной копии.
Чтобы гарантированно обезопасить базу от случайных команд на очистку, внедрим программную проверку в модуль набора записей регистра. Рассмотрим правильную реализацию обработчика ПередЗаписью.
При разработке проверки важно учитывать системную особенность: свойство Отбор независимого регистра изначально содержит все измерения и период, но их свойство Использование по умолчанию имеет значение Ложь. Поэтому простая проверка количества элементов коллекции не сработает — необходимо анализировать именно активность фильтра.
Процедура ПередЗаписью(Отказ, Замещать)
// Если происходит не замещение, а добавление, полная очистка не угрожает
Если Не Замещать Тогда
Возврат;
КонецЕсли;
// Проверяем активность хотя бы одного установленного фильтра
ЕстьУстановленныйОтбор = Ложь;
Для Каждого ЭлементОтбора Из Отбор Цикл
Если ЭлементОтбора.Использование Тогда
ЕстьУстановленныйОтбор = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
// Блокируем запись пустого набора без условий
Если Не ЕстьУстановленныйОтбор И ЭтотОбъект.Количество() = 0 Тогда
ВызватьИсключение "Запрещена полная очистка регистра сведений без установки отбора!";
КонецЕсли;
КонецПроцедуры
В типовых конфигурациях, находящихся на поддержке без возможности изменения, данный функционал можно безопасно внедрить через механизм расширений конфигурации, применив аннотацию &Перед к событию модуля набора записей.
Рассмотрим комплексные меры, которые снижают вероятность ошибки разработчика при выполнении служебных операций:
УстановитьЗаголовокСистемы() при начале работы программы. Для тестовых баз заголовок должен содержать яркие маркеры («ТЕСТ», «КОПИЯ ДЛЯ РАЗРАБОТКИ»), что исключит путаницу в открытых окнах клиента 1С.ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок. Любые сервисные обработки должны регистрироваться через справочник «Дополнительные отчеты и обработки» с обязательным прохождением аудита и запуском в безопасном режиме.