При выполнении синхронизации данных между конфигурациями «Торговля для Казахстана» и «Бухгалтерия для Казахстана» (аналогично для российских редакций УТ 11 и БП 3.0) специалисты часто сталкиваются с критической ошибкой на этапе загрузки объектов в базу-приемник. Система внезапно прекращает работу, выдавая сообщение: Ошибка при вызове метода контекста (ПолучитьСписокВышеСтоящихГруппЭлементов): Превышен максимальный расход памяти сервера за один вызов. Рассмотрим подробно, почему это происходит и как устранить проблему по шагам.
Прежде всего, проанализируем ситуацию. Ошибка возникает в общем модуле ПроцедурыБухгалтерскогоУчета при обработке документа Поступление ТМЗ и услуг (ПТУ). В этот момент система пытается выполнить стандартную процедуру — определить счета учета номенклатуры для загружаемых позиций. В типовых решениях счета учета могут задаваться не только для конкретных позиций, но и для целых групп справочника Номенклатура.
Для корректного подбора счета программа должна «пройтись» вверх по дереву иерархии от текущего элемента до самого корня. Метод ПолучитьСписокВышеСтоящихГруппЭлементов выполняет рекурсивный обход, собирая список всех родителей. Ошибка «Превышен максимальный расход памяти» однозначно указывает на то, что рекурсия стала бесконечной. Это происходит из-за зацикливания иерархии: когда Группа А является родителем для самой себя, или Группа А входит в Группу Б, которая в свою очередь входит в Группу А.
Поскольку стандартные отчеты и списки в интерфейсе 1С часто скрывают циклические зависимости (они просто не отображают такие элементы или отображают их некорректно), нам потребуется использовать технические средства. Проанализируем три основных способа поиска «петли» в справочнике.
Это самый быстрый метод, если у вас есть подозрение, что один из элементов справочника Номенклатура (или Статьи затрат, что также актуально для ПТУ) ссылается сам на себя. Рассмотрим текст запроса, который поможет выявить прямое зацикливание:
ВЫБРАТЬ
Номенклатура.Ссылка КАК Ссылка,
Номенклатура.Наименование КАК Наименование,
Номенклатура.Код КАК Код
ИЗ
Справочник.Номенклатура КАК Номенклатура
ГДЕ
Номенклатура.Родитель = Номенклатура.Ссылка
И Номенклатура.Ссылка <> ЗНАЧЕНИЕ(Справочник.Номенклатура.ПустаяСсылка)
Если этот запрос вернул хотя бы одну строку — вы нашли виновника. Вам необходимо программно или через групповую обработку очистить поле Родитель у этого объекта или переподчинить его корректной группе.
Иногда цикл бывает «длинным» (через несколько уровней вложенности). В этом случае простой запрос к полю Родитель не поможет. Напишем небольшой алгоритм, который можно запустить во внешней обработке. Мы будем имитировать обход иерархии и проверять количество итераций.
Выборка = Справочники.Номенклатура.Выбрать();
Пока Выборка.Следующий() Цикл
ТекущийРодитель = Выборка.Родитель;
СчетчикУровней = 0;
МаксимальноДопустимыйУровень = 50; // В нормальной базе иерархия редко глубже 10
Пока НЕ ТекущийРодитель.Пустая() Цикл
СчетчикУровней = СчетчикУровней + 1;
Если СчетчикУровней > МаксимальноДопустимыйУровень Тогда
Сообщить("Обнаружено зацикливание для элемента: " + Выборка.Наименование + " (Код: " + Выборка.Код + ")");
Прервать;
КонецЕсли;
ТекущийРодитель = ТекущийРодитель.Родитель;
КонецЦикла;
КонецЦикла;
Проанализируем результаты выполнения этого кода. Если сообщение появилось, значит, данный элемент (или одна из его родительских групп) участвует в циклической зависимости. Обратите внимание, что проверять нужно базу именно на стороне Бухгалтерии, так как ошибка падает при загрузке.
Если вы не хотите писать код, можно воспользоваться штатным механизмом платформы 1С. В конфигураторе перейдем в меню Администрирование — Тестирование и исправление. Посмотрим на критически важные настройки:
Платформа при проверке иерархии автоматически разорвет циклы, очистив некорректных родителей. После завершения ТиИ обязательно попробуйте повторить синхронизацию.
Почему ошибка возникает именно при синхронизации? Рассмотрим механизм сопоставления. Часто бывает так, что в базе УТ элемент находится в одной группе, а в базе Бухгалтерии — в другой. При загрузке документа система пытается обновить информацию об объекте. Если в правилах обмена настроено обновление полей родителя, и при этом в Бухгалтерии уже существует сложная структура групп, загрузка может случайно создать «петлю».
Важный нюанс: Если в документе ПТУ присутствуют услуги, обязательно проверьте справочник Статьи затрат. Метод ПолучитьСписокВышеСтоящихГруппЭлементов часто используется и для поиска счетов затрат по иерархии статей. Проверьте зацикливание в этом справочнике по тем же алгоритмам, что описаны выше для номенклатуры.
В редких случаях зацикливания может не быть, но иерархия просто слишком глубокая, а серверные настройки слишком жесткие. Если вы уверены, что циклов нет, проанализируем параметры рабочего процесса сервера 1С. Параметр Max memory consumption per call (Максимальный расход памяти за один вызов) ограничивает объем памяти, который может занять один сеанс для выполнения одной операции. Однако, для функции ПолучитьСписокВышеСтоящихГруппЭлементов, которая оперирует небольшими объемами данных (просто ссылки на группы), превышение лимита в 99% случаев свидетельствует именно о бесконечной рекурсии, а не о реальной нехватке памяти.
Для успешного решения задачи выполните следующие действия:
Родитель = Ссылка.Номенклатура, но и Статьи затрат, а также Подразделения.После устранения логических ошибок в иерархии справочников метод ПолучитьСписокВышеСтоящихГруппЭлементов начнет отрабатывать мгновенно, и синхронизация пройдет без ошибок.