Как создать табличную часть в справочнике на платформе 1С 7.7?

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

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

Метод 1. Классический подход: подчиненный справочник + Таблица Значений на форме

Это самый популярный, надежный и архитектурно правильный способ, который используется в большинстве типовых конфигураций (например, связка справочников «Контрагенты» и «Договоры» в «1С:Бухгалтерии 7.7»).

Суть метода заключается в создании дополнительного справочника, который в метаданных объявляется подчиненным основному справочнику. Для удобства пользователя данные этого подчиненного справочника выводятся прямо на форму элемента основного справочника с помощью элемента диалога Таблица Значений (ТЗ).

Разберем по шагам, как это реализовать:

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

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

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

    Добавляем вызов нашей процедуры в предопределенный обработчик событий формы:

    
    Процедура ПриОткрытии()
        ЗаполнитьТабличнуюЧасть();
    КонецПроцедуры
    
  5. Реализация интерактивного редактирования:

    Стандартная Таблица Значений в 1С 7.7 не позволяет пользователю напрямую редактировать ячейки «на месте» так же легко, как в 1С 8. Чтобы организовать редактирование, мы можем использовать двойной клик по строке ТЗ для открытия формы подчиненного элемента:

    
    Процедура ПриВыбореСтрокиТЗ()
        // Проверяем, что кликнули по заполненной строке
        Если ТЗ_Услуги.ТекущаяСтрока() > 0 Тогда
            // Открываем форму подчиненного элемента для редактирования
            ОткрытьФорму(ТЗ_Услуги.ЭлементСсылка);
            // После закрытия формы редактирования обновляем данные на форме
            ЗаполнитьТабличнуюЧасть();
        КонецЕсли;
    КонецПроцедуры
    

    Чтобы связать эту процедуру с двойным кликом по таблице, в свойствах элемента диалога ТЗ_Услуги в поле «Формула» пишем имя нашей процедуры: ПриВыбореСтрокиТЗ().

Метод 2. Трюк с перенаправлением: подчиненный справочник + документ

Это оригинальный и очень удобный метод, упомянутый опытными разработчиками на форуме. Он позволяет использовать полноценную встроенную табличную часть документа, полностью избавив программиста от ручного проектирования интерфейса ТЗ на форме.

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

Рассмотрим детальную реализацию этого алгоритма:

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

Процедура ПриОткрытии()
    // Если это новый элемент справочника, которого еще нет в базе
    Если Выбран() = 0 Тогда
        // Создаем новый документ программно
        ДокОбъект = СоздатьОбъект("Документ.ОказанныеУслуги");
        ДокОбъект.Новый();
        ДокОбъект.Контрагент = Владелец; // Передаем владельца-контрагента в документ
        
        // Записываем документ, чтобы получить на него ссылку
        ДокОбъект.Записать();
        
        // Записываем ссылку на документ в наш подчиненный справочник
        ДокументСсылка = ДокОбъект.ТекущийДокумент();
        Записать();
    КонецЕсли;
    
    // Открываем форму связанного документа для редактирования его ТЧ
    ОткрытьФорму(ДокументСсылка);
    
    // Отменяем открытие формы самого элемента подчиненного справочника!
    СтатусВозврата(0); 
КонецПроцедуры

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

Метод 3. Сериализация Таблицы Значений в строку неограниченной длины

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

Для этого в структуре основного справочника создается всего один реквизит, например, ХранилищеТЧ с типом Строка (неограниченной длины). На форме элемента размещается визуальная Таблица Значений ТЗ_Экран.

Проанализируем программную реализацию этого механизма:


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

// Процедура сохраняет данные ТЗ обратно в текстовый реквизит перед записью элемента
Процедура ПриЗаписи()
    ТЗ = СоздатьОбъект("ТаблицаЗначений");
    // Забираем текущие данные с экрана
    ТЗ_Экран.Выгрузить(ТЗ);
    
    // Сериализуем объект ТЗ в системную строку 1С и пишем в реквизит справочника
    ХранилищеТЧ = ЗначениеВСтрокуВнутр(ТЗ);
КонецПроцедуры

Преимущества метода: Высочайшая скорость разработки. Нет необходимости создавать новые справочники и забивать метаданные конфигурации. Данные всегда перемещаются и копируются вместе с элементом справочника.

Недостатки: Информация хранится в закодированном текстовом виде внутри системного формата 1С. Получить к ней доступ через SQL-запросы или стандартные отчеты без предварительного открытия каждого элемента невозможно.

Метод 4. Профессиональное решение с использованием внешних компонент (FormEx и 1С++)

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

Резюме: какой метод выбрать?

Выбор конкретного метода реализации табличной части зависит от бизнес-требований к вашей задаче:

  1. Если по данным этой табличной части нужно будет строить отчеты, делать отборы или выгрузки в другие системы — используйте Метод 1 (Подчиненный справочник). Это классический, поддерживаемый всеми типовыми решениями стандарт.
  2. Если вам требуется сложный функционал табличной части (например, расчет скидок, налогов, подчиненные цепочки документов) — используйте Метод 2 (Подчиненный документ). Это сэкономит вам массу времени на проектировании интерфейса.
  3. Если данные нужны исключительно для локального хранения справочной информации внутри элемента и не будут задействованы в глобальных отчетах — смело выбирайте Метод 3 (Сериализация ТЗ в строку).
← На главную