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

Программист 1С v7.7
← На главную

В процессе разработки на платформе 1С:Предприятие 7.7 часто возникает задача предоставить пользователю возможность выбрать документ не из общего списка, а из отфильтрованного — например, только те, которые подчинены текущему открытому документу. Попытка решить эту задачу "в лоб" часто приводит к ошибке "Объект - документ определенного вида!". Разберем, почему она возникает и как правильно организовать такой выбор.

Анализ исходной задачи и типичной ошибки

Проанализируем ситуацию, с которой столкнулся автор. Есть основной документ, и ему подчинены документы вида "Приходный кассовый ордер" (ПрихОрдерТБ). Задача — по нажатию кнопки в основном документе открыть окно выбора, в котором будут показаны только подчиненные ему ПКО.

Интуитивно начинающий разработчик может написать следующий код:


ПКО=СоздатьОбъект("Документ.ПрихОрдерТБ");
ПКО.ВыбратьПодчиненныеДокументы(,,ТекущийДокумент());
ПКО.Выбрать("Выберите ПКО:","");

Такой код не будет работать и на второй строке вызовет ошибку "Объект - документ определенного вида!". Давайте выясним причину. Дело в фундаментальном различии методов и объектов, которые здесь используются:

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

Таким образом, исходный код пытается смешать два совершенно разных механизма: подготовку к программному перебору и запуск интерактивного выбора. Это и есть корень проблемы.

Правильное решение: использование специальной формы журнала

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

Вот как выглядит правильный и рабочий код:


ПКО = СоздатьОбъект("Документ.ПрихОрдерТБ");
ПКО.Выбрать("Выберите ПКО:", "Журнал.Подчиненные", ТекущийДокумент());

Разберем этот код по шагам:

  1. ПКО = СоздатьОбъект("Документ.ПрихОрдерТБ");
    Здесь мы, как и ранее, создаем объект нужного нам вида. Это важно, так как именно этот вид будет использоваться для фильтрации в форме выбора.
  2. ПКО.Выбрать("Выберите ПКО:", "Журнал.Подчиненные", ТекущийДокумент());
    Вся магия происходит здесь, в параметрах метода Выбрать():
    • Первый параметр: "Выберите ПКО:" — это просто заголовок, который увидит пользователь в окне выбора.
    • Второй параметр: "Журнал.Подчиненные" — это ключевой элемент. Мы указываем системе, что нужно открыть не стандартную форму выбора документов, а специальную системную форму "Журнал подчиненных документов".
    • Третий параметр: ТекущийДокумент() — это контекст. Мы передаем в открываемую форму тот документ, для которого нужно показать подчиненные. Форма "Журнал.Подчиненные" примет этот параметр и автоматически отфильтрует список, показав только те документы, у которых в реквизите "Документ-основание" указан наш ТекущийДокумент().

В результате такого вызова система откроет стандартное окно со списком подчиненных документов для ТекущийДокумент() и, поскольку метод был вызван от объекта Документ.ПрихОрдерТБ, в этом списке останутся только документы вида "Приходный кассовый ордер". Именно то, что и требовалось.

Альтернативные способы для более сложных задач

Найденное решение идеально для простого выбора. Однако в некоторых случаях может потребоваться более сложная логика. Рассмотрим другие подходы.

1. Формирование СпискаЗначений для выбора

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

Посмотрим на пример:


// Создаем пустой список для наших документов
СписокПКО = СоздатьОбъект("СписокЗначений");

// Для перебора нужен общий, нетипизированный объект Документ
Док = СоздатьОбъект("Документ");

// Готовим выборку всех подчиненных документов для ТекущегоДокумента()
Если Док.ВыбратьПодчиненныеДокументы(,,ТекущийДокумент()) = 1 Тогда
    // Перебираем найденные документы в цикле
    Пока Док.ПолучитьДокумент() = 1 Цикл
        // Проверяем, что текущий документ в выборке - это ПКО
        Если Док.Вид() = "ПрихОрдерТБ" Тогда
            // Добавляем документ в список. В качестве представления можно
            // сформировать удобную строку с номером и датой
            Представление = "ПКО №" + Док.НомерДок + " от " + Формат(Док.ДатаДок, "ДД.ММ.ГГГГ");
            СписокПКО.ДобавитьЗначение(Док.ТекущийДокумент(), Представление);
        КонецЕсли;
    КонецЦикла;
КонецЕсли;

// Проверяем, нашлись ли документы
Если СписокПКО.РазмерСписка() > 0 Тогда
    ВыбранныйПКО = 0;
    // Открываем стандартное окно выбора из списка
    Если СписокПКО.ВыбратьЗначение(ВыбранныйПКО, "Выберите ПКО:") = 1 Тогда
        // Если пользователь что-то выбрал, переменная ВыбранныйПКО
        // будет содержать ссылку на выбранный документ
        Сообщить("Выбран документ: " + ВыбранныйПКО);
    КонецЕсли;
Иначе
    Предупреждение("Подчиненные ПКО не найдены!");
КонецЕсли;

Плюсы: полный контроль над списком, возможность добавить любую логику отбора.

Минусы: при большом количестве подчиненных документов может работать медленнее, так как требует полного перебора.

2. Использование собственной формы подбора

Этот способ является самым гибким и мощным. Он применяется, когда требуется сложный интерфейс выбора — например, с множественным выбором, дополнительными колонками информации, поиском и т.д.

Принцип работы:

  1. Создается специальная обработка с формой.
  2. На форме размещается табличная часть или таблица значений, куда будут выводиться нужные документы.
  3. Из документа-основания эта форма открывается в модальном режиме или в режиме подбора (ОткрытьПодбор()). В качестве параметра ей передается документ-основание.
  4. Форма подбора при открытии получает документ-основание, формирует список подчиненных документов и заполняет свою таблицу.
  5. Пользователь выбирает нужную строку (или строки), нажимает кнопку "Выбрать", и форма возвращает выбранное значение в исходный документ через процедуру ОбработкаПодбора() или через механизм оповещения (ОповеститьОВыборе()).

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

← На главную