Почему периодический реквизит в 1С 7.7 изменяется вручную при настройке «Только документами» и как это исправить?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Многие разработчики на платформе 1С:Предприятие 7.7 сталкиваются с ситуацией, когда для периодического реквизита справочника (например, «Цена» или «Оклад») в Конфигураторе жестко установлена опция «Только документами», но в режиме «Предприятие» в истории значений все равно появляются «ручные» записи. Это вызывает хаос в учете, так как становится невозможно отследить, на основании какого первичного документа изменился показатель. Разберем подробно, почему так происходит, как найти виновника и как очистить базу от некорректных данных.

Разбираем причину: почему настройка «Только документами» не является панацеей?

Первое и самое важное, что нам необходимо понять: настройка «Только документами» в 1С 7.7 ограничивает исключительно интерактивные действия пользователя. Это означает, что пользователь не сможет нажать кнопку «Новая строка» непосредственно в окне истории реквизита или изменить его значение прямо в форме элемента справочника. Однако эта настройка совершенно не защищает от программного вмешательства.

Проанализируем основные пути появления «ручных» записей:

  1. Программная запись через объект «Периодический»: Любая внешняя обработка или код внутри конфигурации может создать объект СоздатьОбъект("Периодический") и вызвать метод Записать(). Платформа при этом не проверяет установленный в метаданных флаг.
  2. Использование метода Установить(): Если в коде используется конструкция вида Спр.Реквизит.Установить(Дата, Значение), запись в историю будет создана без привязки к документу.
  3. Тестирование и исправление (ТиИ): Если документ, который создал периодическую запись, был поврежден или удален некорректно (на уровне таблиц СУБД), после выполнения процедуры ТиИ с очисткой ссылок запись в истории может остаться, но ссылка на документ-основание исчезнет, превратив запись в «ручную».
  4. Прямые SQL-запросы: В случае использования SQL-версии базы данных, записи могут вноситься напрямую в таблицу _1SCONST через внешние утилиты или компоненты (например, 1C++), минуя бизнес-логику платформы.

Как вычислить источник появления записей?

Чтобы понять, кто и когда «фигачит» цены или другие показатели, проанализируем ситуацию по шагам:

Шаг 1: Проверка журнала регистрации. Нам нужно установить фильтр по метаданным соответствующего справочника. Помните, что запись значения в историю может происходить не в тот день, который указан в истории (дата значения), а в момент запуска какой-то регламентной обработки. Проверьте события «Изменение справочника» за последние несколько дней.

Шаг 2: Глобальный поиск по конфигурации. Выполним поиск строк "Периодический" и ".Установить(". Особое внимание уделим модулям внешних отчетов и обработок, которые хранятся в папке ExtForms. Часто именно там скрыты инструменты для массовой корректировки данных, которые игнорируют правила учета.

Шаг 3: Контроль внешних обработок. Рассмотрим возможность установки запрета на запуск внешних обработок для обычных пользователей. Если обработка необходима для работы, ее следует включить в состав конфигурации — так ее действия будет легче контролировать и модифицировать.

Программная очистка «ручных» записей

Если в базе уже накопилось много некорректных записей, их нужно удалить, оставив только те, что привязаны к документам. Для этого мы воспользуемся объектом Периодический. Рассмотрим пример кода для очистки:


Процедура ОчиститьРучныеЗаписи(ТекЭлемент, ИмяРеквизита)
    История = СоздатьОбъект("Периодический");
    // Выбираем историю конкретного реквизита для конкретного элемента
    История.ИспользоватьОбъект(ИмяРеквизита, ТекЭлемент);
    История.ВыбратьЗначения();
    
    Пока История.ПолучитьЗначение() = 1 Цикл
        // Проверяем, есть ли документ-основание у этой записи
        Если История.ТекущийДокумент().Выбран() = 0 Тогда
            // Это ручная запись, удаляем её
            Попытка
                История.Удалить();
                Сообщить("Удалена ручная запись на дату: " + История.ДатаЗнач);
            Исключение
                Сообщить("Не удалось удалить запись: " + ОписаниеОшибки());
            КонецПопытки;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Важный нюанс: Обратите внимание, что в 1С 7.7 после вызова метода Удалить() у объекта Периодический нельзя вызывать метод Записать(). Метод Удалить() срабатывает мгновенно, а последующий вызов Записать() может привести к непредсказуемому восстановлению или перезаписи данных, на что жаловались участники обсуждения.

Работа с СУБД (для опытных администраторов)

Если ваша база работает на MS SQL Server, мы можем использовать более радикальные методы контроля. Все периодические реквизиты хранятся в таблице _1SCONST.

Посмотрим на структуру этой таблицы:

Проанализируем ситуацию через SQL-запрос. Если поле DOCID заполнено пробелами или нулями (в зависимости от типа), значит, запись является ручной. Для предотвращения появления таких записей в будущем, можно создать SQL-триггер на таблицу _1SCONST, который будет блокировать (делая ROLLBACK) любую вставку, где DOCID пуст для конкретных ID реквизитов.

Выясним, стоит ли делать ТиИ?

Рассмотрим совет по запуску «Тестирования и исправления». Как правильно заметили эксперты, ТиИ — это скорее диагностика, а не лечение в данном случае. Если у вас есть битые ссылки, ТиИ сделает записи «ручными», но не удалит их. Поэтому сначала рекомендуется выполнить программную очистку по алгоритму выше, а уже затем проводить регламентные работы с базой данных.

Резюме и рекомендации

Подведем итог нашему исследованию:

  1. Флаг «Только документами» — это интерфейсное ограничение, которое легко обходится любым программным кодом.
  2. Для обнаружения «ручных» записей используйте метод ТекущийДокумент().Выбран() объекта Периодический.
  3. Для очистки истории используйте метод Удалить() без последующего вызова Записать().
  4. Чтобы исключить повторение проблемы, рассмотрите возможность блокировки внешних обработок или внедрения триггеров на уровне SQL-сервера.

Помните, что чистота данных в периодических реквизитах — это залог правильного формирования отчетов «задним числом». Регулярно проверяйте историю критически важных показателей, чтобы избежать ошибок в расчетах.

← На главную