В работе с конфигурациями 1С, особенно на управляемых формах (например, в УТ 11.2), мы часто сталкиваемся со стандартным поведением платформы: при вызове отчета "Структура подчиненности" из измененного, но еще не сохраненного документа, система автоматически записывает документ. Это происходит для обеспечения актуальности данных, отображаемых в отчете, так как связи строятся на основе информации, уже находящейся в базе данных. Однако такое поведение может быть нежелательным, приводя к случайному сохранению незавершенных изменений. Давайте разберем, как мы можем управлять этим процессом и предотвратить автоматическое сохранение.
Прежде чем приступить к решению, давайте поймем логику платформы. "Структура подчиненности" — это отчет, который анализирует связи между документами и другими объектами на основе критериев отбора, настроенных в конфигурации. Для того чтобы отчет отображал актуальную информацию, система ожидает, что все данные, формирующие эти связи, уже записаны в базу. Автоматическая запись помогает поддерживать целостность данных и гарантирует, что отчет строится на основе самых свежих, хотя и не всегда завершенных, изменений. Автоматическая запись движений при проведении документа способствует поддержанию строгого порядка блокировки таблиц движений, что помогает избежать взаимоблокировок при многопользовательской работе.
Наиболее эффективный и рекомендованный способ изменить стандартное поведение — это использовать расширение конфигурации. Расширения позволяют вносить изменения в типовой функционал, не снимая конфигурацию с поддержки, что значительно упрощает обновление конфигурации и ее сопровождение.
Суть подхода заключается в том, чтобы найти команду, отвечающую за вызов "Структуры подчиненности", и изменить ее свойство РежимЗаписи на "НеЗаписывать". Это явно указывает платформе, что при вызове данной команды автоматическая запись документа не требуется.
ПриОпределенииКомандПодключенныхКОбъекту. Эта процедура может находиться в различных общих модулях в зависимости от версии БСП и конфигурации, например:
СтруктураПодчиненностиСлужебныйПодключаемыеКомандыПереопределяемыйУправлениеПечатьюИнтеграцияПодсистемБСПНастройкаПорядкаЭлементовВариантыОтчетовВ нашем случае (УТ 11.2, БСП 3.1.10) мы скорее всего будем искать ее в одном из модулей, связанных с подключением команд. Мы можем начать поиск с ПодключаемыеКомандыПереопределяемый или СтруктураПодчиненностиСлужебный. Для точного определения модуля мы можем открыть конфигурацию, найти любой документ, перейти на вкладку "Команды", посмотреть свойства команды "Структура подчиненности" и затем использовать поиск в конфигураторе по имени этой процедуры.
ПриОпределенииКомандПодключенныхКОбъекту, мы добавим ее в наше расширение и изменим ее с помощью директивы &После. Это позволит нам выполнить наш код после стандартного выполнения процедуры, которая уже добавила команду на форму.
// Пример кода для расширения
&После("ПриОпределенииКомандПодключенныхКОбъекту")
Процедура Сек_ПриОпределенииКомандПодключенныхКОбъекту(НастройкиФормы, Источники, ПодключенныеОтчетыИОбработки, Команды) Экспорт
// Перебираем все команды, которые были определены для объекта
Для Каждого Команда Из Команды Цикл
// Ищем команду, которая соответствует "Структуре подчиненности"
// Ее Вид часто равен "СвязанныеДокументы" или "СтруктураПодчиненности"
// Также можно проверять по Представлению, но Вид более надежен для программного поиска
Если Команда.Вид = "СвязанныеДокументы" Или Команда.Представление = НСтр("ru = 'Связанные документы'") Тогда
// Устанавливаем режим записи "НеЗаписывать"
Команда.РежимЗаписи = "НеЗаписывать";
// Если команда найдена и изменена, можно прервать цикл для оптимизации
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Важные моменты при реализации:
&После, чтобы наш код выполнился после того, как типовая процедура уже добавила команду. Это гарантирует, что мы работаем с существующей командой.Команды, так как она может содержать не только одну команду "Структура подчиненности", но и другие подключаемые команды.Вид (часто "СвязанныеДокументы") или по Представлению ("Связанные документы"). Рекомендуется использовать Вид, так как он обычно уникален и не зависит от языковых настроек. Проверим в отладчике или в конфигураторе точное значение для вашей конфигурации.Команда.РежимЗаписи устанавливается в "НеЗаписывать". Это явно указывает платформе, что при вызове этой команды документ не должен автоматически сохраняться.РежимЗаписи = "Запись", платформа в некоторых случаях может проигнорировать это и выполнить проведение, если это предусмотрено логикой конфигурации (например, при попытке записать проведенный документ без указания режима проведения). В нашем случае "НеЗаписывать" работает корректно.Если мы не хотим вносить изменения в конфигурацию (даже через расширения) или просто нам нужно быстро просмотреть структуру без сохранения текущих правок, мы можем использовать обходной путь, который не требует никаких доработок.
Этот метод позволит нам просмотреть связи документа в его последнем записанном состоянии, не затрагивая текущие незавершенные изменения в открытой форме. Это безопасный и простой способ получить необходимую информацию, когда нам не нужна самая актуальная, но еще не сохраненная, версия документа.
Некоторые продвинутые подходы могут включать более тонкое управление тем, как команды добавляются на форму. Изначально команды добавляются в определенные группы, и их поведение может зависеть от этих групп или от типа параметра команды. Оптимальным вариантом иногда видится убрать команду из стандартной группы и закинуть ее в общую процедуру, чтобы создавалась кнопка и к ней привязывалась команда с индивидуальными настройками. Но при этом нужно как-то ограничить список документов, в которых эта кнопка будет появляться.
Если стандартный механизм добавления команды через ПриОпределенииКомандПодключенныхКОбъекту не подходит (например, если нам нужно, чтобы кнопка появлялась только для определенных документов или при определенных условиях), мы можем пойти по пути создания собственной команды и кнопки на форме.
&Вместо, но это значительно сложнее и может иметь побочные эффекты. Чаще всего достаточно просто переопределить ее поведение, как в Решении 1.РежимЗаписи и Видимость. Это потребует более глубокой доработки формы документа через расширение, включая переопределение процедуры ПриСозданииНаСервере формы документа.
// Пример добавления собственной команды на форму документа через расширение
// Этот код добавляется в общий модуль, связанный с формами документов, или
// непосредственно в модуль формы документа, который мы расширяем.
// Например, для формы документа "Реализация товаров и услуг" мы расширяем ее модуль.
// В расширении, в модуле формы документа (например, РеализацияТоваровУслугФормаДокумента)
// Переопределяем процедуру ПриСозданииНаСервере с директивой &После
&После("ПриСозданииНаСервере")
Процедура Сек_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// 1. Создаем новую команду формы.
// Уникальное имя команды в рамках формы.
НоваяКоманда = Команды.Добавить("Сек_ОткрытьМоюСтруктуруПодчиненности");
НоваяКоманда.Действие = "Сек_ОткрытьМоюСтруктуруПодчиненностиВыполнить"; // Имя процедуры-обработчика
НоваяКоманда.Представление = НСтр("ru = 'Моя структура подчиненности'"); // Текст кнопки
НоваяКоманда.Картинка = БиблиотекаКартинок.СтруктураПодчиненности; // Картинка для кнопки
НоваяКоманда.РежимЗаписи = "НеЗаписывать"; // Ключевое свойство для отключения автозаписи
НоваяКоманда.Использование = ТипИспользованияКоманды.КомандаФормы; // Указываем, что это команда формы
// 2. Добавляем элемент "Кнопка" на форму и связываем ее с нашей командой.
// Найдем группу, куда хотим добавить кнопку, например, КоманднаяПанель
// Или создадим новую группу, если это необходимо.
Если Элементы.Найти("КоманднаяПанель") Тогда
Кнопка = Элементы.Добавить("Сек_КнопкаМояСтруктураПодчиненности", Тип("КнопкаФормы"), Элементы.КоманднаяПанель);
Кнопка.Вид = ВидКнопкиФормы.ОбычнаяКнопка;
Кнопка.Команда = НоваяКоманда.Имя; // Привязываем кнопку к созданной команде
Кнопка.ПоложениеВГруппе = ПоложениеВГруппе.После; // Размещаем после существующих кнопок
// Можно попытаться скрыть стандартную кнопку, если она была добавлена.
// Например, если знаем имя стандартного элемента
Если Элементы.Найти("КомандаСвязанныеДокументы") Тогда
Элементы.КомандаСвязанныеДокументы.Видимость = Ложь;
КонецЕсли;
КонецЕсли;
// 3. Добавляем обработчик для нашей команды.
// Эта процедура будет вызываться, когда пользователь нажмет на кнопку.
ДобавитьОбработчик("Сек_ОткрытьМоюСтруктуруПодчиненностиВыполнить", "НаКлиенте", "Сек_ОткрытьМоюСтруктуруПодчиненностиНаКлиенте");
КонецПроцедуры
// Клиентская процедура для открытия структуры подчиненности
&НаКлиенте
Процедура Сек_ОткрытьМоюСтруктуруПодчиненностиНаКлиенте()
// Создаем структуру параметров для передачи в форму отчета.
// ОбъектОтбора должен содержать ссылку на текущий документ.
Параметры = Новый Структура;
Параметры.Вставить("ОбъектОтбора", Объект.Ссылка);
// Открываем форму отчета "Связанные документы".
// Полное имя формы может быть "ОбщаяФорма.СвязанныеДокументы"
// или другое, в зависимости от конфигурации.
ОткрытьФорму("ОбщаяФорма.СвязанныеДокументы", Параметры);
КонецПроцедуры
Важные моменты при использовании этого подхода:
Запись, ОтменаПроведения и Проведение. При записи документа вызывается последовательность событий (например, ПередЗаписью, ПриЗаписи, ПослеЗаписи), которые могут быть переопределены для изменения стандартного поведения. Однако в нашем случае изменение свойства команды является более прямым и менее инвазивным решением.