Почему программно созданные складские ячейки в УТ 11 не видны в интерфейсе и как это исправить?

Программист 1С v8.3 (Управляемые формы) 1С:Управление торговлей Управленческий учет Торговля и дистрибуция
← На главную

При разработке механизмов автоматизации в конфигурации 1С:Управление торговлей 11 (или ERP 2.5) программисты часто сталкиваются с задачей тиражирования структуры складских ячеек с одного склада на другой. Казалось бы, задача тривиальна: прочитать данные запросом и создать новые объекты. Однако на практике возникают ситуации, когда объекты физически записываются в базу данных (их видно в консоли запросов), но они полностью отсутствуют в экранных формах списка или вызывают критическую ошибку «Обнаружено рассогласование при получении данных» (Расхождение товаров на складах и товаров организаций). Для устранения подобных расхождений в учете на уровне регистров можно использовать инструмент для исправления расхождений между регистрами «Товары на складах» и «Товары организаций».

В этой статье мы подробно разберем, почему так происходит, проанализируем типичные ошибки в коде и научимся правильно создавать иерархические структуры в справочниках, подчиненных владельцу. В дальнейшем, когда структура ячеек будет успешно перенесена, задействовать её на практике при сборке заказов поможет печатная форма задания на отбор с указанием ячеек хранения.

Причина №1: Копирование системного поля «Ссылка»

Рассмотрим фрагмент кода, который чаще всего становится источником проблем. Основная ошибка кроется в использовании универсального метода заполнения свойств объекта из выборки запроса. Посмотрим на этот участок:


НовЭл = Справочники.СкладскиеЯчейки.СоздатьГруппу(); 
ЗаполнитьЗначенияСвойств(НовЭл, Выборка); 
НовЭл.Владелец = Объект.СкладПриемник;
НовЭл.Записать();

Проанализируем ситуацию: в переменной Выборка содержатся данные, полученные из запроса по складу-источнику. Среди этих полей обязательно присутствует поле Ссылка. Когда мы вызываем ЗаполнитьЗначенияСвойств(НовЭл, Выборка), платформа пытается записать уникальный идентификатор (GUID) из старого объекта в новый.

Почему это критично:

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

Как сделать правильно: Всегда исключайте системные поля при использовании метода ЗаполнитьЗначенияСвойств. Код должен выглядеть так:


// Исключаем Ссылку, Родителя и Владельца, так как их нужно устанавливать отдельно
ЗаполнитьЗначенияСвойств(НовЭл, Выборка, , "Ссылка, Родитель, Владелец");

Причина №2: Нарушение иерархии (Связь Родитель — Владелец)

Справочник СкладскиеЯчейки имеет сложную структуру: он иерархический (группы и элементы) и одновременно подчинен владельцу (справочник Склады). В 1С существует незыблемое правило: Родитель и Владелец объекта должны принадлежать одному контексту.

Если мы программно копируем подгруппу и устанавливаем ей Родителя со старого склада (источника), а Владельца — с нового склада (приемника), мы получаем «логическую химеру». Такая запись пройдет (особенно если включен режим ОбменДанными.Загрузка = Истина), но в интерфейсе 1С:УТ 11 такая ячейка не отобразится. Система фильтрации в динамических списках работает по владельцу, а дерево иерархии строится по родителям. Если родитель не принадлежит текущему складу, ветка обрывается.

Разберем, как правильно переносить иерархию:

  1. Сначала создаем (или находим) аналогичную группу на складе-приемнике.
  2. Получаем ссылку на эту НОВУЮ группу.
  3. Назначаем эту ссылку в качестве Родителя для создаваемого элемента.

Причина №3: Использование режима «ОбменДанными.Загрузка = Истина»

Многие программисты используют флаг НовЭл.ОбменДанными.Загрузка = Истина, чтобы избежать лишних проверок и ускорить запись. Однако в типовой конфигурации УТ 11 на справочнике ячеек «висит» множество обработчиков в модуле объекта (события ПередЗаписью и ПриЗаписи).

Что мы теряем, включая этот режим:

Рассмотрим подробнее ситуацию с параметром ОтключитьМеханизмРегистрацииОбъектов. Это свойство полезно для исключения записи в таблицы регистрации изменений (для обменов), но оно никак не решает проблему корректности данных внутри самого объекта.

Причина №4: Настройки склада-приемника

Выясним причину, по которой ячейки могут быть видны в запросе, но не в интерфейсе, с точки зрения настроек программы. В 1С:УТ 11 отображение ячеек в форме списка склада зависит от функциональных опций самого склада:

  1. Откройте карточку Склада-приемника.
  2. Проверьте раздел «Настройки складских ячеек». Если там установлено «Не использовать», то список ячеек будет пуст, даже если вы создали их миллион.
  3. Если склад использует помещения, убедитесь, что в каждой созданной группе и ячейке заполнен реквизит Помещение. Без привязки к помещению ячейки «адресного склада» в стандартных формах часто скрываются фильтрами по умолчанию.

Правильный алгоритм программного создания ячеек

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


// Пример корректного создания группы ячеек
Запрос = Новый Запрос;
Запрос.Текст = 
    "ВЫБРАТЬ
    |   СкладскиеЯчейки.Наименование КАК Наименование,
    |   СкладскиеЯчейки.Код КАК Код,
    |   СкладскиеЯчейки.Родитель КАК СтарыйРодитель
    |ИЗ
    |   Справочник.СкладскиеЯчейки КАК СкладскиеЯчейки
    |ГДЕ
    |   СкладскиеЯчейки.Владелец = &СкладИсточник И СкладскиеЯчейки.ЭтоГруппа";

Запрос.УстановитьПараметр("СкладИсточник", Объект.СкладИсточник);
Выборка = Запрос.Выполнить().Выбрать();

Пока Выборка.Следующий() Цикл
    // Проверяем, нет ли уже такой группы на новом складе
    НоваяГруппаСсылка = Справочники.SkladскиеЯчейки.НайтиПоНаименованию(Выборка.Наименование, Истина, , Объект.СкладПриемник);
    
    Если НоваяГруппаСсылка.Пустая() Тогда
        ОбъектГруппа = Справочники.СкладскиеЯчейки.СоздатьГруппу();
        
        // ВАЖНО: Исключаем Ссылку при копировании!
        ЗаполнитьЗначенияСвойств(ОбъектГруппа, Выборка, , "Ссылка, Родитель");
        
        ОбъектГруппа.Владелец = Объект.СкладПриемник;
        
        // Логика поиска нового родителя (упрощенно)
        Если ЗначениеЗаполнено(Выборка.СтарыйРодитель) Тогда
             // Здесь должна быть логика поиска соответствия родителя на новом складе
             // Например, через НайтиПоНаименованию среди уже созданных групп
             ИмяРодителя = Выборка.СтарыйРодитель.Наименование;
             ОбъектГруппа.Родитель = Справочники.СкладскиеЯчейки.НайтиПоНаименованию(ИмяРодителя, Истина, , Объект.СкладПриемник);
        КонецЕсли;
        
        Попытка
            // Не используем Загрузка = Истина, чтобы сработали типовые проверки
            ОбъектГруппа.Записать();
        Исключение
            Сообщить("Ошибка при создании группы: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецЦикла;

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

Если после исправления кода ячейки всё равно не видны, проанализируем ситуацию по следующим шагам:

  1. Проверка через консоль запросов: Выполните запрос ВЫБРАТЬ Ссылка, Владелец, Родитель, Помещение ИЗ Справочник.СкладскиеЯчейки ГДЕ Владелец = &СкладПриемник. Убедитесь, что все поля заполнены ссылками, принадлежащими новому складу.
  2. Тестовое создание вручную: Создайте одну группу через интерфейс 1С в том же складе. Сравните в консоли запросов реквизиты «ручной» группы и «программной». Обратите особое внимание на скрытые реквизиты, такие как ПорядокОбхода, Склад (в некоторых релизах УТ 11 это отдельный реквизит помимо Владельца) и ТипЯчейки.
  3. Очистка кэша: Если вы столкнулись с ошибкой рассогласования, обязательно перезапустите сеанс 1С, а в идеале — очистите кэш конфигурации на локальном компьютере, так как «битые» ссылки часто застревают в памяти клиента.

Подведем итог: программное создание объектов в сложных типовых конфигурациях требует не просто копирования данных, а соблюдения бизнес-логики. Главными правилами являются исключение ссылки при заполнении свойств и строгое соблюдение контекста Владельца для всей иерархии Родителей.

← На главную