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

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

При разработке и доработке конфигураций на платформе 1С:Предприятие 7.7 часто возникает типовая задача: в документе присутствует реквизит с типом ссылки на другой документ (например, Документ.ТТН), и при нажатии на кнопку выбора в поле ввода пользователю открывается журнал. Однако по умолчанию платформа открывает так называемый обычный журнал, в котором отсутствуют привычные быстрые отборы. Попытка настроить свойства вида документа в конфигураторе показывает, что привязать документ можно только к обычному журналу, а общий журнал (например, «Полный») выбрать в свойствах нельзя.

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

Почему платформа 1С 7.7 открывает обычный журнал без отборов

Проанализируем архитектуру метаданных платформы 1С 7.7, чтобы понять истоки проблемы:

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

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

Способ 1. Использование метода Документ.Выбрать() в процедуре ПриНачалеВыбораЗначения()

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

Посмотрим на пример реализации в модуле формы документа:


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

Разберем по шагам, как работает данный алгоритм:

  1. Параметр ИдентЭлементаДиалога позволяет определить, в каком именно реквизите пользователь нажал кнопку выбора (в нашем случае проверяется имя реквизита диалога "ТТН").
  2. Установка флага ФлагСтандОбр = 0 прерывает платформенную обработку события и предотвращает открытие обычного журнала.
  3. Метод Выбрать(Подсказка, ИдентификаторЖурнала) переводит журнал в режим выбора и приостанавливает выполнение программного кода до тех пор, пока окно не будет закрыто пользователем. Второй строковый параметр ("Журнал.Полный") указывает платформе, какую именно форму журнала открыть.
  4. Если выбор подтвержден, метод возвращает 1, а переменная ВыбДок позиционируется на выбранном документе. После этого мы вызываем метод ТекущийДокумент() и записываем результат в нужный реквизит формы.

Способ 2. Создание специализированного общего журнала

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

  1. Открываем конфигуратор и создаем новый журнал документов.
  2. Устанавливаем для созданного журнала тип «Общий».
  3. В списке регистрируемых видов документов отмечаем только один документ — ТТН.
  4. Добавляем в этот журнал требуемые графы отбора (или используем общие реквизиты документов с признаком отбора, такие как контрагент, склад, организация).
  5. В коде формы документа через ПриНачалеВыбораЗначения() вызываем этот новый журнал:
    
    Процедура ПриНачалеВыбораЗначения(ИдентЭлементаДиалога, ФлагСтандОбр)
        Если ИдентЭлементаДиалога = "ТТН" Тогда
            ФлагСтандОбр = 0;
            ВыбДок = СоздатьОбъект("Документ.ТТН");
            Если ВыбДок.Выбрать("Выберите ТТН", "Журнал.ЖурналТТНОбщий") = 1 Тогда
                ТТН = ВыбДок.ТекущийДокумент();
            КонецЕсли;
        КонецЕсли;
    КонецПроцедуры
    

В итоге пользователь видит только документы вида ТТН, но при этом получает в распоряжение весь функционал отборов общего журнала платформы 1С 7.7.

Способ 3. Открытие журнала через ОткрытьФорму() с передачей параметров отбора

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

Посмотрим, как выглядит вызов из модуля документа:


Процедура ПриНачалеВыбораЗначения(ИдентЭлементаДиалога, ФлагСтандОбр)
    Если ИдентЭлементаДиалога = "ТТН" Тогда
        ФлагСтандОбр = 0;
        
        Парам = СоздатьОбъект("СписокЗначений");
        Парам.ДобавитьЗначение(Контрагент, "ОтборКонтрагент");
        Парам.ДобавитьЗначение(1, "РежимВыбора");
        
        ОткрытьФормуМодально("Журнал.Полный", Парам);
        
        Если Парам.Получить("ВыбранныйДокумент") <> ПолучитьПустоеЗначение("Документ") Тогда
            ТТН = Парам.Получить("ВыбранныйДокумент");
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

При таком подходе необходимо учесть важный нюанс платформы: журнал, открытый через ОткрытьФорму(), по умолчанию открывается для просмотра. Если пользователь дважды кликнет по строке, откроется форма самой ТТН, а не вернется значение. Поэтому в модуле формы открываемого журнала обязательно перехватывают предопределенные события ПриОткрытии() и ПриВыбореСтроки():


// В модуле формы журнала:
Процедура ПриОткрытии()
    Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
        // Устанавливаем программный отбор, если передан контрагент
        Если ПустоеЗначение(Форма.Параметр.Получить("ОтборКонтрагент")) = 0 Тогда
            УстановитьОтбор("Контрагент", Форма.Параметр.Получить("ОтборКонтрагент"));
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

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

← На главную