Как проверить наличие родителя у субконто в 1С 7.7

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

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

Анализ проблемы и выбор стратегии

В системе 1С 7.7 субконто на счетах могут иметь различные типы: справочники, документы, перечисления, счета или даже конкретные значения базовых типов. Попытка получить БИ.Субконто(2).Родитель без предварительной проверки безопасна с точки зрения падения системы (1С вернет пустое значение), но логически она может быть неверной. Рассмотрим ситуацию: если субконто — это Документ или Перечисление, у него в принципе не может быть родителя в понимании иерархического справочника. Поэтому наша задача — построить многоуровневую проверку.

Шаг 1: Проверка типа значения субконто

Первым делом нам необходимо убедиться, что текущее значение субконто является справочником. В 1С 7.7 для этого существует два основных способа: использование числового кода типа и строкового представления.

Проанализируем вариант с использованием числового кода. Тип "Справочник" в семерке соответствует числу 11. Посмотрим на пример кода:


Если ТипЗначения(БИ.Субконто(2)) = 11 Тогда
    // Это справочник, можно пытаться работать с иерархией
    Элемент = БИ.Субконто(2);
КонецЕсли;

Однако более "читаемым" и надежным способом считается использование функции ТипЗначенияСтр(). Это позволяет избежать магических чисел в коде и делает алгоритм понятным для других разработчиков. Разберем этот подход подробнее:


ТекСубконто = БИ.Субконто(2);
Если ТипЗначенияСтр(ТекСубконто) = "Справочник" Тогда
    // Выполняем действия, специфичные для справочников
КонецЕсли;

Шаг 2: Проверка на «ПустоеЗначение»

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


ТекСубконто = БИ.Субконто(2);
Если ПустоеЗначение(ТекСубконто) = 0 Тогда
    Если ТипЗначенияСтр(ТекСубконто) = "Справочник" Тогда
        // Переходим к проверке родителя
    КонецЕсли;
КонецЕсли;

Шаг 3: Определение уровня иерархии

Даже если субконто является справочником, элемент может находиться на самом верхнем уровне (в корне). В этом случае свойство Родитель будет пустым. Чтобы понять, есть ли у элемента "вышестоящий" объект, мы используем метод Уровень(). Рассмотрим логику: если уровень равен 1, то родителя нет. Если уровень больше 1, мы можем смело обращаться к родителю.


Если ТекСубконто.Уровень() > 1 Тогда
    РодительСубконто = ТекСубконто.Родитель;
    КодРодителя = РодительСубконто.Код;
    НаименованиеРодителя = РодительСубконто.Наименование;
Иначе
    // Элемент находится в корне
    КодРодителя = "";
    НаименованиеРодителя = "Корневой элемент";
КонецЕсли;

Шаг 4: Обработка многоуровневых справочников (Рекурсия)

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


ВерхнийРодитель = "";
Если ТекСубконто.Уровень() > 1 Тогда
    ВремЭлемент = ТекСубконто.Родитель;
    Пока ВремЭлемент.Уровень() > 1 Цикл
        ВремЭлемент = ВремЭлемент.Родитель;
    КонецЦикла;
    ВерхнийРодитель = ВремЭлемент;
КонецЕсли;

Если ПустоеЗначение(ВерхнийРодитель) = 0 Тогда
    Сообщить("Верхняя группа: " + ВерхнийРодитель.Наименование);
КонецЕсли;

Особенности различных типов субконто

Важно помнить, что в 1С 7.7 план счетов может быть настроен так, что субконто имеет неопределенный тип. Рассмотрим ситуацию, упомянутую в обсуждении: счет 19.3, где субконто 2 — это "Счета-фактуры полученные". В типовых конфигурациях это обычно тип Документ. Попытка вызвать метод .Уровень() или свойство .Родитель у документа приведет к тому, что система не найдет такой метод.

Поэтому правильный алгоритм должен выглядеть так:

  1. Проверяем, что субконто не пустое через ПустоеЗначение().
  2. Проверяем тип через ТипЗначенияСтр().
  3. Если это Справочник, проверяем Уровень() и получаем Родитель.
  4. Если это Документ, выгружаем номер и дату, так как родителя у документов в иерархическом смысле нет.
  5. Если это Перечисление, выгружаем его идентификатор.

Использование метаданных для универсальности

Если вы пишете универсальную обработку, которая должна работать на разных конфигурациях (где план счетов мог быть изменен), стоит проверить, является ли справочник иерархическим вообще. Это можно сделать через объект Метаданные. Проанализируем пример кода:


ВидСправочника = ТекСубконто.Вид();
Если Метаданные.Справочник(ВидСправочника).Иерархический = 1 Тогда
    // Справочник поддерживает группы, можно искать родителя
Иначе
    // Справочник линейный, родителей быть не может
КонецЕсли;

Подводим итоги

Для надежной выгрузки родителя субконто в 1С 7.7 мы рекомендуем использовать следующую конструкцию, которая объединяет все вышеописанные проверки:


// Предположим, БИ - объект БухгалтерскиеИтоги
Для Номер = 1 По БИ.КоличествоСубконто() Цикл
    ТекСубконто = БИ.Субконто(Номер);
    
    Если ПустоеЗначение(ТекСубконто) = 0 Тогда
        Если ТипЗначенияСтр(ТекСубконто) = "Справочник" Тогда
            Если ТекСубконто.Уровень() > 1 Тогда
                // Выгружаем родителя
                РодительКод = ТекСубконто.Родитель.Код;
            Иначе
                РодительКод = "НЕТ_РОДИТЕЛЯ";
            КонецЕсли;
        Иначе
            // Обработка других типов (Документы, Счета и т.д.)
            РодительКод = "НЕ_СПРАВОЧНИК";
        КонецЕсли;
    КонецЕсли;
КонецЦикла;

Важный момент: Не путайте Родителя с Владельцем. Если ваш справочник подчинен другому справочнику (например, "Договоры" подчинены "Контрагентам"), то для получения связи нужно использовать свойство Владелец, а не Родитель. Проверка наличия владельца осуществляется аналогично через ПустоеЗначение(ТекСубконто.Владелец).

← На главную