Многие разработчики на платформе 1С:Предприятие 7.7 сталкиваются с ситуацией, когда для периодического реквизита справочника (например, «Цена» или «Оклад») в Конфигураторе жестко установлена опция «Только документами», но в режиме «Предприятие» в истории значений все равно появляются «ручные» записи. Это вызывает хаос в учете, так как становится невозможно отследить, на основании какого первичного документа изменился показатель. Разберем подробно, почему так происходит, как найти виновника и как очистить базу от некорректных данных.
Первое и самое важное, что нам необходимо понять: настройка «Только документами» в 1С 7.7 ограничивает исключительно интерактивные действия пользователя. Это означает, что пользователь не сможет нажать кнопку «Новая строка» непосредственно в окне истории реквизита или изменить его значение прямо в форме элемента справочника. Однако эта настройка совершенно не защищает от программного вмешательства.
Проанализируем основные пути появления «ручных» записей:
СоздатьОбъект("Периодический") и вызвать метод Записать(). Платформа при этом не проверяет установленный в метаданных флаг.Установить(): Если в коде используется конструкция вида Спр.Реквизит.Установить(Дата, Значение), запись в историю будет создана без привязки к документу._1SCONST через внешние утилиты или компоненты (например, 1C++), минуя бизнес-логику платформы.Чтобы понять, кто и когда «фигачит» цены или другие показатели, проанализируем ситуацию по шагам:
Шаг 1: Проверка журнала регистрации. Нам нужно установить фильтр по метаданным соответствующего справочника. Помните, что запись значения в историю может происходить не в тот день, который указан в истории (дата значения), а в момент запуска какой-то регламентной обработки. Проверьте события «Изменение справочника» за последние несколько дней.
Шаг 2: Глобальный поиск по конфигурации. Выполним поиск строк "Периодический" и ".Установить(". Особое внимание уделим модулям внешних отчетов и обработок, которые хранятся в папке ExtForms. Часто именно там скрыты инструменты для массовой корректировки данных, которые игнорируют правила учета.
Шаг 3: Контроль внешних обработок. Рассмотрим возможность установки запрета на запуск внешних обработок для обычных пользователей. Если обработка необходима для работы, ее следует включить в состав конфигурации — так ее действия будет легче контролировать и модифицировать.
Если в базе уже накопилось много некорректных записей, их нужно удалить, оставив только те, что привязаны к документам. Для этого мы воспользуемся объектом Периодический. Рассмотрим пример кода для очистки:
Процедура ОчиститьРучныеЗаписи(ТекЭлемент, ИмяРеквизита)
История = СоздатьОбъект("Периодический");
// Выбираем историю конкретного реквизита для конкретного элемента
История.ИспользоватьОбъект(ИмяРеквизита, ТекЭлемент);
История.ВыбратьЗначения();
Пока История.ПолучитьЗначение() = 1 Цикл
// Проверяем, есть ли документ-основание у этой записи
Если История.ТекущийДокумент().Выбран() = 0 Тогда
// Это ручная запись, удаляем её
Попытка
История.Удалить();
Сообщить("Удалена ручная запись на дату: " + История.ДатаЗнач);
Исключение
Сообщить("Не удалось удалить запись: " + ОписаниеОшибки());
КонецПопытки;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важный нюанс: Обратите внимание, что в 1С 7.7 после вызова метода Удалить() у объекта Периодический нельзя вызывать метод Записать(). Метод Удалить() срабатывает мгновенно, а последующий вызов Записать() может привести к непредсказуемому восстановлению или перезаписи данных, на что жаловались участники обсуждения.
Если ваша база работает на MS SQL Server, мы можем использовать более радикальные методы контроля. Все периодические реквизиты хранятся в таблице _1SCONST.
Посмотрим на структуру этой таблицы:
OBJID — идентификатор объекта (элемента справочника).ID — идентификатор самого реквизита.VALUE — значение.DOCID — идентификатор документа-регистратора.Проанализируем ситуацию через SQL-запрос. Если поле DOCID заполнено пробелами или нулями (в зависимости от типа), значит, запись является ручной. Для предотвращения появления таких записей в будущем, можно создать SQL-триггер на таблицу _1SCONST, который будет блокировать (делая ROLLBACK) любую вставку, где DOCID пуст для конкретных ID реквизитов.
Рассмотрим совет по запуску «Тестирования и исправления». Как правильно заметили эксперты, ТиИ — это скорее диагностика, а не лечение в данном случае. Если у вас есть битые ссылки, ТиИ сделает записи «ручными», но не удалит их. Поэтому сначала рекомендуется выполнить программную очистку по алгоритму выше, а уже затем проводить регламентные работы с базой данных.
Подведем итог нашему исследованию:
ТекущийДокумент().Выбран() объекта Периодический.Удалить() без последующего вызова Записать().Помните, что чистота данных в периодических реквизитах — это залог правильного формирования отчетов «задним числом». Регулярно проверяйте историю критически важных показателей, чтобы избежать ошибок в расчетах.