При разработке и доработке конфигураций на платформе 1С:Предприятие 7.7 часто возникает типовая задача: в документе присутствует реквизит с типом ссылки на другой документ (например, Документ.ТТН), и при нажатии на кнопку выбора в поле ввода пользователю открывается журнал. Однако по умолчанию платформа открывает так называемый обычный журнал, в котором отсутствуют привычные быстрые отборы. Попытка настроить свойства вида документа в конфигураторе показывает, что привязать документ можно только к обычному журналу, а общий журнал (например, «Полный») выбрать в свойствах нельзя.
Разберем причины такого поведения платформы и детально рассмотрим способы реализации выбора документа через журнал с необходимыми фильтрами и отборами.
Проанализируем архитектуру метаданных платформы 1С 7.7, чтобы понять истоки проблемы:
УстановитьОтбор() для фильтрации по общим реквизитам и графам отбора поддерживается только в журналах типа «Общий». Если попытаться вызвать метод УстановитьОтбор() в модуле формы обычного журнала, система выдаст ошибку времени выполнения Неверное имя реквизита!. Единственный отбор, который платформенно доступен в обычном журнале, — это фильтрация по подчинению с помощью метода ПодчинениеДокументу().Таким образом, для получения функционала отборов при выборе реквизита нам необходимо программно перехватить стандартный процесс выбора и открыть нужный журнал.
Рассмотрим наиболее надежный и правильный способ с точки зрения архитектуры платформы 1С 7.7. В форме документа, где пользователь заполняет реквизит, существует предопределенная процедура ПриНачалеВыбораЗначения(). С ее помощью мы можем отключить штатное открытие обычного журнала и запустить интерактивный выбор из любого журнала конфигурации с помощью метода Выбрать() объекта Документ.
Посмотрим на пример реализации в модуле формы документа:
Процедура ПриНачалеВыбораЗначения(ИдентЭлементаДиалога, ФлагСтандОбр)
Если ИдентЭлементаДиалога = "ТТН" Тогда
// Отключаем стандартный вызов привязанного журнала
ФлагСтандОбр = 0;
// Создаем объект документа для вызова модального выбора
ВыбДок = СоздатьОбъект("Документ.ТТН");
// Открываем модальное окно выбора с указанием нужного журнала
Если ВыбДок.Выбрать("Выберите ТТН для заполнения", "Журнал.Полный") = 1 Тогда
// Если пользователь нажал "Выбрать" (или Enter), присваиваем значение реквизиту
ТТН = ВыбДок.ТекущийДокумент();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Разберем по шагам, как работает данный алгоритм:
ИдентЭлементаДиалога позволяет определить, в каком именно реквизите пользователь нажал кнопку выбора (в нашем случае проверяется имя реквизита диалога "ТТН").ФлагСтандОбр = 0 прерывает платформенную обработку события и предотвращает открытие обычного журнала.Выбрать(Подсказка, ИдентификаторЖурнала) переводит журнал в режим выбора и приостанавливает выполнение программного кода до тех пор, пока окно не будет закрыто пользователем. Второй строковый параметр ("Журнал.Полный") указывает платформе, какую именно форму журнала открыть.1, а переменная ВыбДок позиционируется на выбранном документе. После этого мы вызываем метод ТекущийДокумент() и записываем результат в нужный реквизит формы.Нередко возникает ситуация, когда при открытии журнала «Полный» пользователю мешают документы других видов (например, накладные, счета, кассовые ордера), а в обычном журнале нет возможности настроить отбор. В этом случае мы можем применить архитектурный прием разделения журналов:
ТТН.ПриНачалеВыбораЗначения() вызываем этот новый журнал:
Процедура ПриНачалеВыбораЗначения(ИдентЭлементаДиалога, ФлагСтандОбр)
Если ИдентЭлементаДиалога = "ТТН" Тогда
ФлагСтандОбр = 0;
ВыбДок = СоздатьОбъект("Документ.ТТН");
Если ВыбДок.Выбрать("Выберите ТТН", "Журнал.ЖурналТТНОбщий") = 1 Тогда
ТТН = ВыбДок.ТекущийДокумент();
КонецЕсли;
КонецЕсли;
КонецПроцедуры
В итоге пользователь видит только документы вида ТТН, но при этом получает в распоряжение весь функционал отборов общего журнала платформы 1С 7.7.
Если требуется открыть форму журнала и сразу программно установить в ней отбор на основании текущих данных документа (например, ограничить выборку только тем контрагентом, который уже выбран в шапке), используют метод ОткрытьФорму() или ОткрытьФормуМодально() с передачей контекста или списка значений.
Посмотрим, как выглядит вызов из модуля документа:
Процедура ПриНачалеВыбораЗначения(ИдентЭлементаДиалога, ФлагСтандОбр)
Если ИдентЭлементаДиалога = "ТТН" Тогда
ФлагСтандОбр = 0;
Парам = СоздатьОбъект("СписокЗначений");
Парам.ДобавитьЗначение(Контрагент, "ОтборКонтрагент");
Парам.ДобавитьЗначение(1, "РежимВыбора");
ОткрытьФормуМодально("Журнал.Полный", Парам);
Если Парам.Получить("ВыбранныйДокумент") <> ПолучитьПустоеЗначение("Документ") Тогда
ТТН = Парам.Получить("ВыбранныйДокумент");
КонецЕсли;
КонецЕсли;
КонецПроцедуры
При таком подходе необходимо учесть важный нюанс платформы: журнал, открытый через ОткрытьФорму(), по умолчанию открывается для просмотра. Если пользователь дважды кликнет по строке, откроется форма самой ТТН, а не вернется значение. Поэтому в модуле формы открываемого журнала обязательно перехватывают предопределенные события ПриОткрытии() и ПриВыбореСтроки():
// В модуле формы журнала:
Процедура ПриОткрытии()
Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
// Устанавливаем программный отбор, если передан контрагент
Если ПустоеЗначение(Форма.Параметр.Получить("ОтборКонтрагент")) = 0 Тогда
УстановитьОтбор("Контрагент", Форма.Параметр.Получить("ОтборКонтрагент"));
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Процедура ПриВыбореСтроки()
Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
Если Форма.Параметр.Получить("РежимВыбора") = 1 Тогда
// Записываем текущий документ в параметр и закрываем форму
Форма.Параметр.Установить("ВыбранныйДокумент", ТекущийДокумент);
Форма.Закрыть(0);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Проанализировав все три способа, можно сделать вывод: если не требуется передавать жесткие начальные параметры фильтрации, наиболее простым и быстрым в реализации является Способ 1 с вызовом метода ВыбДок.Выбрать(). Если же отбор должен быть ограничен конкретным видом документов или инициализироваться автоматически из реквизитов документа-владельца, оптимально применять специализированный общий журнал или передачу параметров через СписокЗначений.