В практике сопровождения старых систем на платформе 1С:Предприятие 7.7 (особенно конфигурации «Торговля и Склад» версии 9.2) встречается крайне специфическая проблема. Суть её заключается в следующем: пользователь строит стандартный отчет Остатки ТМЦ по фирме в оптовых ценах и получает определенную итоговую сумму (например, 95 млн рублей). Однако после переноса одной позиции номенклатуры из одной группы справочника в другую, итог отчета внезапно увеличивается (например, до 108 млн рублей), хотя ни цены, ни количество товара не менялись. Самое странное, что если сохранить этот отчет в Excel и пересчитать сумму строк вручную, она окажется верной (95 млн), в то время как в печатной форме 1С итог отображается неверно.
Проанализируем эту ситуацию, выясним технические причины такого поведения системы и разберем по шагам методы исправления этой ошибки.
Разберем, как работает механизм построения отчета в 1С 7.7. Большинство типовых отчетов используют встроенный язык запросов. Когда мы строим отчет с группировкой по иерархии, запрос использует конструкцию Группировка Номенклатура По Группам. Рассмотрим подробнее, что происходит внутри:
ParentID), объект Запрос может дважды включить одну и ту же ветку в расчет внутренних итогов.Именно поэтому при выгрузке в Excel сумма строк сходится — там мы считаем фактически выведенные данные, а итог в 1С берется из переменной запроса Запрос.Итого(), которая уже содержит ошибку накопления.
Выясним, откуда берутся «фантомные» данные. В файловых версиях 1С 7.7 информация хранится в таблицах .dbf. Каждая запись имеет уникальный идентификатор ID и идентификатор родителя ParentID. При интерактивном переносе элемента в другую группу система должна корректно обновить ParentID и перестроить индексы в файле .cdx.
Проанализируем ситуацию возникновения ошибки:
В конфигурации «Торговля и Склад» цены являются периодическими реквизитами. Отчет Остатки ТМЦ может брать цену на определенную дату. Рассмотрим ситуацию, когда алгоритм получения цены завязан на свойства группы. Если у новой группы установлены иные параметры (например, категория цен или признаки наценки), отчет при обходе может применять разные формулы для вывода строки и для расчета общего итога.
Проверим наличие дописок в конфигурации. Часто программисты вносят изменения в модуль отчета, добавляя условия типа:
Если Номенклатура.ПринадлежитГруппе(ГруппаАкций) = 1 Тогда
Цена = Цена * 0.9;
КонецЕсли;
Если такой код написан неаккуратно и переменная цены не очищается или не пересчитывается правильно при переходе от одной группы к другой в цикле обхода запроса, итоговые суммы «поплывут».
Первым делом необходимо исключить влияние «мусора» в индексах. Выполним следующие действия:
.cdx.%TEMP%), так как 1С 7.7 кэширует результаты запросов во временных .tmp файлах, которые могут содержать старые пути иерархии.Рассмотрим вероятность влияния кастомного кода. В 1С 7.7 существует предопределенная процедура ПриПереносеЭлементаВДругуюГруппу. Она может располагаться в модуле формы списка справочника Номенклатура.
Проанализируем процедуру на наличие лишних действий. Откроем конфигуратор, найдем справочник Номенклатура, откроем форму списка и вызовем поиск по названию процедуры. Если она найдена, проверим, не меняет ли она какие-либо периодические реквизиты или остатки в момент переноса. Если процедура пуста или отсутствует — значит, проблема чисто техническая (в данных), а не программная.
Если переиндексация не помогла, выполним полное Тестирование и исправление ИБ (Администрирование -> Тестирование и исправление). В настройках важно отметить пункты:
Особое внимание обратим на сообщения о «битых» ссылках или объектах без владельца. Если система найдет такие объекты, их нужно либо восстановить, либо очистить.
Если ошибка сохраняется только для одной конкретной позиции, это подтверждает теорию о поврежденном внутреннем ID или записи в DBF. Разберем метод «пересоздания»:
ID).Поиск и замена значений (стандартная для ТиС) заменим все вхождения старой номенклатуры в документах на новую.Этот метод позволяет полностью избавиться от «фантомных» связей в базе данных, которые не видят штатные средства проверки.
Проанализируем размеры файлов базы данных. Хотя автор утверждает, что база небольшая, стоит помнить об ограничениях DBF в 1С 7.7:
RG* или RA*) могут приводить к ошибкам адресации в индексах.Если файлы близки к этим значениям, единственным надежным решением будет либо свертка базы (удаление старых периодов), либо переход на SQL-версию 1С 7.7.
Мы выяснили, что расхождение итогов в отчете Остатки ТМЦ при переносе группы чаще всего связано не с ошибкой в алгоритме отчета, а с нарушением структуры индексов или физическим дублированием записей в таблицах справочника. Объект Запрос крайне чувствителен к иерархическим связям, и любое нарушение в ParentID приводит к задвоению итогов. Последовательное выполнение переиндексации, очистки кэша и, в крайнем случае, пересоздание проблемной позиции позволяют полностью устранить данную ошибку.