Как восстановить розничные цены в 1С 7.7 после ошибочного запуска обработки Формирование цен

Программист 1С v7.7 Управленческий учет Торговля и дистрибуция
← На главную

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

Почему цены стали нулевыми и как это работает

Прежде чем приступать к исправлению, проанализируем причину проблемы. В типовых конфигурациях (например, «Торговля и Склад») механизм получения себестоимости обращается к регистрам остатков. Если товара нет в наличии, функция возвращает 0. Обработка записывает этот ноль в периодический реквизит справочника Цены на текущую дату. Чтобы вернуть состояние цен к моменту «до обработки», нам необходимо найти в истории периодических реквизитов все записи, сделанные конкретной датой, и удалить их.

Подготовительный этап: Безопасность данных

Любые манипуляции с историей значений и прямым удалением записей из базы данных несут риски. Обязательно сделайте резервную копию базы данных (файл 1Cv7.77 или SQL-бэкап) перед запуском любых корректирующих обработок.

Способ 1. Программное удаление записей через объект Периодический

Основным инструментом для работы с историей изменений в 1С 7.7 является объект Периодический. Разберем по шагам алгоритм, который позволит нам найти и удалить записи на определенную дату. Основная сложность здесь заключается в том, что записи могут быть установлены как «вручную» (через карточку или программно), так и «документами».

Рассмотрим пример кода для обработки, которая обходит справочник номенклатуры и чистит историю цен:


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

Разбор ключевых функций и методов

Проанализируем используемые методы, чтобы понять, как работает очистка:

  1. Метод ИспользоватьОбъект(ИмяРеквизита, Ссылка) — связывает объект Периодический с конкретным полем справочника. Важно помнить, что в 1С 7.7 цены часто хранятся в подчиненном справочнике Цены, поэтому сначала нужно выбрать элемент этого справочника.
  2. Метод НайтиЗначение(Дата, Режим) — позволяет быстро позиционироваться на нужной дате в истории. Использование этого метода гораздо эффективнее, чем полный перебор истории через ВыбратьЗначения().
  3. Свойство ТекущийДокумент() — это критически важная проверка. Если метод Выбран() возвращает 1, это означает, что запись в истории порождена проведением документа (например, «Установка цен»). Платформа 7.7 запрещает удаление таких записей методом Удалить() — это вызовет фатальную ошибку.

Способ 2. Обработка ситуаций с документами

Если вы выяснили, что цены были установлены не просто обработкой «вручную», а путем автоматического формирования документа «Установка цен ТМЦ», то метод Удалить() не сработает. В этом случае у вас есть два пути:

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

Способ 3. Восстановление «поверх» ошибочных данных

Иногда вместо удаления записей проще создать новую «правильную» запись той же датой. Если вы знаете, что до запуска обработки цены были корректными, можно написать скрипт, который:

Это не удалит историю, но «перекроет» нулевые значения актуальными данными. Для этого используется метод Значение объекта Периодический и метод Записать().

Рекомендации по оптимизации

При работе с большими справочниками (десятки тысяч позиций) работа через объект Периодический может быть медленной. Чтобы ускорить процесс, мы рекомендуем обернуть цикл обработки в транзакцию:


НачатьТранзакцию();
// ... ваш код цикла ...
ЗафиксироватьТранзакцию();

Это позволит платформе 1С 7.7 выполнить все операции с файлом 1SCONST.DBF (где хранится история периодических реквизитов) за один проход, что сократит время выполнения с часов до нескольких минут.

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

← На главную