Показать вопрос в 1С 8.3 нужно перед действием, которое трудно отменить: заменить данные во всех строках, удалить строки, закрыть непроведённый документ, запустить обработку на сотни объектов. В управляемых формах модальная функция Вопрос() не годится: при отключённой модальности она завершается ошибкой, а в справке 8.3.27 у неё нет веб-клиента в списке доступности. Работают два немодальных метода: ПоказатьВопрос (с платформы 8.3.3) и ВопросАсинх (с 8.3.18).
Ниже один диалог — «Склад в шапке изменён. Заменить его во всех строках?» — написан тремя способами: ПоказатьВопрос с ОписаниеОповещения, ВопросАсинх с Ждать и свои кнопки из СписокЗначений. Дальше — вопрос перед закрытием формы, удалением строки и долгой операцией, флажок «Больше не спрашивать» из БСП и обычные формы. Обработчики событий назначают в палитре свойств, раздел «События».
Полный вызов: ПоказатьВопрос(ОписаниеОповещенияОЗавершении, ТекстВопроса, Кнопки, Таймаут, КнопкаПоУмолчанию, Заголовок, КнопкаТаймаута). Метод есть только на клиенте — тонком, толстом, веб- и мобильном. Он открывает окно и сразу возвращает управление, а ответ приходит позже в процедуру из первого параметра.
| Параметр | Тип | Что важно |
|---|---|---|
| ОписаниеОповещенияОЗавершении | ОписаниеОповещения | обязательный; обработчик — экспортная процедура (Результат, ДополнительныеПараметры) |
| ТекстВопроса | Строка, ФорматированнаяСтрока | ширина текста в окне ограничена 40 символами |
| Кнопки | РежимДиалогаВопрос, СписокЗначений | список не должен быть пустым |
| Таймаут | Число | секунды; 0 — без ограничения, отрицательное — исключение |
| КнопкаПоУмолчанию | КодВозвратаДиалога или значение из списка | выделена при открытии, её нажимает Enter |
| Заголовок | Строка | без него у окна нет заголовка |
| КнопкаТаймаута | КодВозвратаДиалога или значение из списка | на ней идёт обратный отсчёт; по истечении времени ответ — Таймаут |
Наборы кнопок задаёт РежимДиалогаВопрос, ответ сравнивают со значениями КодВозвратаДиалога:
| РежимДиалогаВопрос | Возможные ответы |
|---|---|
| ДаНет | Да, Нет |
| ДаНетОтмена | Да, Нет, Отмена |
| ОК | ОК |
| ОКОтмена | ОК, Отмена |
| ПовторитьОтмена | Повторить, Отмена |
| ПрерватьПовторитьПропустить | Прервать, Повторить, Пропустить |
При заданном таймауте к ответам любого набора добавляется Таймаут. Кнопки окна одной ширины — по самой длинной надписи, так что подписи лучше делать короткими.
Пример — документ со складом в шапке и в табличной части «Товары». ПриИзменении поля «Склад» задаёт вопрос, обработчик ответа меняет строки. В типовых так же: в УТ 11.4 команда «Закрыть заказ» в форме заказа клиента спрашивает через ПоказатьВопрос и продолжает в ЗакрытьЗаказЗавершение.
&НаКлиенте
Процедура СкладПриИзменении(Элемент)
КоличествоСтрок = Объект.Товары.Количество();
Если КоличествоСтрок = 0 Или Не ЗначениеЗаполнено(Объект.Склад) Тогда
Возврат; // менять нечего или склад очистили
КонецЕсли;
// Третий параметр придет в обработчик вторым параметром
Оповещение = Новый ОписаниеОповещения("СкладПриИзмененииЗавершение", ЭтотОбъект, КоличествоСтрок);
ТекстВопроса = СтрШаблон("Склад в шапке изменен. Заменить его во всех строках (%1)?", КоличествоСтрок);
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет, 30,
КодВозвратаДиалога.Да, "Смена склада", КодВозвратаДиалога.Нет);
// Управление вернется сюда сразу, ответ придет в СкладПриИзмененииЗавершение
КонецПроцедуры
&НаКлиенте
Процедура СкладПриИзмененииЗавершение(Ответ, КоличествоСтрок) Экспорт
// «Нет» или 30 секунд без ответа (КодВозвратаДиалога.Таймаут)
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Для Каждого СтрокаТоваров Из Объект.Товары Цикл
СтрокаТоваров.Склад = Объект.Склад;
КонецЦикла;
ПоказатьОповещениеПользователя("Склад заменен", ,
СтрШаблон("Изменено строк: %1", КоличествоСтрок));
КонецПроцедуры
ОписаниеОповещения передаёт в обработчик любое значение, здесь — число строк; несколько значений передают структурой. Конструктор и цепочки вызовов — в статье про ОписаниеОповещения.Экспорт и лежит в модуле из второго параметра: ЭтотОбъект — сама форма.Ответ <> КодВозвратаДиалога.Да отсекает и «Нет», и Таймаут.С платформы 8.3.18 тот же диалог пишется одной процедурой. ВопросАсинх принимает те же параметры, кроме описания оповещения, и возвращает Обещание, из которого ответ достаёт оператор Ждать. Процедуру с Ждать объявляют с модификатором Асинх.
&НаКлиенте
Асинх Процедура СкладПриИзменении(Элемент)
КоличествоСтрок = Объект.Товары.Количество();
Если КоличествоСтрок = 0 Или Не ЗначениеЗаполнено(Объект.Склад) Тогда
Возврат; // менять нечего или склад очистили
КонецЕсли;
ТекстВопроса = СтрШаблон("Склад в шапке изменен. Заменить его во всех строках (%1)?", КоличествоСтрок);
// Здесь процедура приостановится и продолжится, когда пользователь ответит
Ответ = Ждать ВопросАсинх(ТекстВопроса, РежимДиалогаВопрос.ДаНет, 30,
КодВозвратаДиалога.Да, "Смена склада", КодВозвратаДиалога.Нет);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Для Каждого СтрокаТоваров Из Объект.Товары Цикл
СтрокаТоваров.Склад = Объект.Склад;
КонецЦикла;
ПоказатьОповещениеПользователя("Склад заменен", ,
СтрШаблон("Изменено строк: %1", КоличествоСтрок));
КонецПроцедуры
Асинх пишется после директивы компиляции, перед словом Процедура. Асинхронным может быть обработчик команды или события вроде ПриИзменении.Ждать процедура отдаёт управление вызвавшему коду, а после ответа продолжается с того же места со всеми локальными переменными.Что выбрать: в новом коде ВопросАсинх короче, особенно при нескольких вопросах подряд. ПоказатьВопрос нужен при старом режиме совместимости и в обработчиках с Отказ (см. закрытие формы).
Когда выбор не сводится к «Да/Нет», вместо РежимДиалогаВопрос передают список значений: значение элемента вернётся в обработчик, представление станет надписью на кнопке. Тот же диалог с тремя кнопками: заменить склад во всех строках, только в незаполненных или не менять.
&НаКлиенте
Процедура СкладПриИзменении(Элемент)
Если Объект.Товары.Количество() = 0 Или Не ЗначениеЗаполнено(Объект.Склад) Тогда
Возврат;
КонецЕсли;
// Значение вернется в обработчик, представление станет надписью на кнопке
Кнопки = Новый СписокЗначений;
Кнопки.Добавить("Все", "Во всех строках");
Кнопки.Добавить("Пустые", "Только в пустых");
Кнопки.Добавить(КодВозвратаДиалога.Отмена, "Не менять");
Оповещение = Новый ОписаниеОповещения("СкладПриИзмененииЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Склад в шапке изменен. В каких строках его заменить?", Кнопки, 60,
"Все", "Смена склада", КодВозвратаДиалога.Отмена);
КонецПроцедуры
&НаКлиенте
Процедура СкладПриИзмененииЗавершение(Ответ, ДополнительныеПараметры) Экспорт
Если Ответ <> "Все" И Ответ <> "Пустые" Тогда
Возврат; // «Не менять», Esc или таймаут
КонецЕсли;
Изменено = 0;
Для Каждого СтрокаТоваров Из Объект.Товары Цикл
Если Ответ = "Пустые" И ЗначениеЗаполнено(СтрокаТоваров.Склад) Тогда
Продолжить;
КонецЕсли;
СтрокаТоваров.Склад = Объект.Склад;
Изменено = Изменено + 1;
КонецЦикла;
ПоказатьОповещениеПользователя("Склад заменен", ,
СтрШаблон("Изменено строк: %1", Изменено));
КонецПроцедуры
КодВозвратаДиалога.Отмена со своей надписью (без надписи платформа подставит стандартную). По справке к Вопрос() с кнопкой «Отмена» связана клавиша Esc, а без неё в веб-клиенте закрытие окна крестиком открывает вопрос заново."Все" и КодВозвратаДиалога.Отмена.Событие ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка) выполняется на клиенте, а ответ на вопрос приходит уже после выхода из обработчика. Поэтому схема одна: сразу отказаться от закрытия, спросить, а в обработчике ответа закрыть форму повторно, запомнив, что пользователь ответил. Пример для формы документа: непроведённый документ предлагаем провести перед закрытием.
&НаКлиенте
Перем ЗакрытиеПодтверждено; // Истина, когда пользователь уже ответил
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если ЗакрытиеПодтверждено = Истина Или Не НужноПредложитьПроведение() Тогда
Возврат;
КонецЕсли;
// Отказ ставим до вопроса: ответ придет уже после выхода из обработчика
Отказ = Истина;
Если ЗавершениеРаботы Тогда
// Закрывается вся программа: окна открывать нельзя, текст покажет платформа
ТекстПредупреждения = "Документ не проведен.";
Возврат;
КонецЕсли;
Оповещение = Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Документ не проведен. Провести перед закрытием?",
РежимДиалогаВопрос.ДаНетОтмена, , КодВозвратаДиалога.Да);
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытиемЗавершение(Ответ, ДополнительныеПараметры) Экспорт
Если Ответ = КодВозвратаДиалога.Да Тогда
ПараметрыЗаписи = Новый Структура("РежимЗаписи", РежимЗаписиДокумента.Проведение);
Если Не Записать(ПараметрыЗаписи) Тогда
Возврат; // не провелся: причины уже в сообщениях, форма остается открытой
КонецЕсли;
ИначеЕсли Ответ <> КодВозвратаДиалога.Нет Тогда
Возврат; // Отмена — остаемся в документе
КонецЕсли;
ЗакрытиеПодтверждено = Истина;
Закрыть();
КонецПроцедуры
&НаКлиенте
Функция НужноПредложитьПроведение()
// Новый документ, который даже не начали заполнять, закрываем молча
Если Объект.Ссылка.Пустая() И Не Модифицированность Тогда
Возврат Ложь;
КонецЕсли;
Возврат Не Объект.Проведен И Не Объект.ПометкаУдаления И Не ТолькоПросмотр;
КонецФункции
ЗакрытиеПодтверждено нужен потому, что Закрыть() снова вызывает ПередЗакрытием: без него вопрос появится опять.ЗавершениеРаботы = Истина пользователь выходит из программы, и по справке окна и вызовы сервера в этот момент запрещены. Хватает отказа и текста в ТекстПредупреждения: платформа сама покажет его и предложит остаться или уйти без сохранения.Модифицированность, а вместо Записать() вызывают свою процедуру сохранения.В БСП (УТ 11.4, КА 2.5) есть готовые ОбщегоНазначенияКлиент.ПоказатьПодтверждениеЗакрытияФормы — вопрос «Данные были изменены. Сохранить изменения?» с записью через ваше оповещение — и ПоказатьПодтверждениеЗакрытияПроизвольнойФормы со своим текстом и признаком в реквизите формы.
Строки табличной части платформа удаляет без подтверждения. Чтобы спросить, назначьте таблице формы обработчик ПередУдалением: стандартное удаление отменяется всегда, а выделенные строки удаляет код после ответа «Да».
&НаКлиенте
Процедура ТоварыПередУдалением(Элемент, Отказ)
// Стандартное удаление отменяем всегда: строки удалим сами после ответа «Да»
Отказ = Истина;
Идентификаторы = Новый Массив;
Для Каждого Идентификатор Из Элемент.ВыделенныеСтроки Цикл
Идентификаторы.Добавить(Идентификатор);
КонецЦикла;
Если Идентификаторы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
Если Идентификаторы.Количество() = 1 Тогда
ДанныеСтроки = Объект.Товары.НайтиПоИдентификатору(Идентификаторы[0]);
ТекстВопроса = СтрШаблон("Удалить строку %1 «%2»?", ДанныеСтроки.НомерСтроки, ДанныеСтроки.Номенклатура);
Иначе
ТекстВопроса = СтрШаблон("Удалить выделенные строки (%1)?", Идентификаторы.Количество());
КонецЕсли;
Оповещение = Новый ОписаниеОповещения("ТоварыПередУдалениемЗавершение", ЭтотОбъект, Идентификаторы);
ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
КонецПроцедуры
&НаКлиенте
Процедура ТоварыПередУдалениемЗавершение(Ответ, Идентификаторы) Экспорт
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Для Каждого Идентификатор Из Идентификаторы Цикл
ДанныеСтроки = Объект.Товары.НайтиПоИдентификатору(Идентификатор);
Если ДанныеСтроки <> Неопределено Тогда
Объект.Товары.Удалить(ДанныеСтроки);
КонецЕсли;
КонецЦикла;
// ПослеУдаления при удалении из кода не вызывается: все, что было там, делаем здесь
Модифицированность = Истина;
ОбновитьИтоги();
КонецПроцедуры
&НаКлиенте
Процедура ОбновитьИтоги()
// ИтогоСумма — реквизит формы, выведенный под таблицей
ИтогоСумма = Объект.Товары.Итог("Сумма");
КонецПроцедуры
Элемент.ВыделенныеСтроки — массив идентификаторов строк, а не индексов. Строку по нему находит НайтиПоИдентификатору, поэтому порядок удаления не важен.ПослеУдаления при удалении из кода не вызывается: итоги пересчитываются явно, Модифицированность ставится вручную.ПередУдалением нельзя вызывать серверные методы формы с &НаСервере; вопрос и удаление на клиенте этого правила не нарушают.Перед операцией на несколько минут вопрос заодно предупреждает о времени. Здесь удобен ВопросАсинх: вопрос, вызов сервера и итог идут подряд в одной процедуре. Пример — обработка с табличной частью «Документы» (колонка «Документ»), которая проводит все документы списка.
&НаКлиенте
Асинх Процедура ПровестиДокументы(Команда)
Документы = Новый Массив;
Для Каждого СтрокаСписка Из Объект.Документы Цикл
Если ЗначениеЗаполнено(СтрокаСписка.Документ) Тогда
Документы.Добавить(СтрокаСписка.Документ);
КонецЕсли;
КонецЦикла;
Если Документы.Количество() = 0 Тогда
Возврат;
КонецЕсли;
ТекстВопроса = СтрШаблон("Будет проведено документов: %1.
|Это может занять несколько минут. Начать?", Документы.Количество());
Ответ = Ждать ВопросАсинх(ТекстВопроса, РежимДиалогаВопрос.ОКОтмена, 60,
КодВозвратаДиалога.ОК, "Проведение документов", КодВозвратаДиалога.Отмена);
Если Ответ <> КодВозвратаДиалога.ОК Тогда
Возврат; // Отмена или минута без ответа
КонецЕсли;
Состояние("Проведение документов...");
Ошибки = ПровестиДокументыНаСервере(Документы);
Состояние();
Если Ошибки.Количество() = 0 Тогда
ПоказатьОповещениеПользователя("Документы проведены", ,
СтрШаблон("Всего: %1", Документы.Количество()));
Возврат;
КонецЕсли;
Для Каждого ТекстОшибки Из Ошибки Цикл
Сообщить(ТекстОшибки);
КонецЦикла;
ПоказатьПредупреждение(, СтрШаблон("Не проведено документов: %1 из %2.
|Причины — в окне сообщений.", Ошибки.Количество(), Документы.Количество()));
КонецПроцедуры
&НаСервереБезКонтекста
Функция ПровестиДокументыНаСервере(Знач Документы)
Ошибки = Новый Массив;
Для Каждого Ссылка Из Документы Цикл
Попытка
ДокументОбъект = Ссылка.ПолучитьОбъект();
ДокументОбъект.Записать(РежимЗаписиДокумента.Проведение);
Исключение
Ошибки.Добавить(СтрШаблон("%1: %2", Ссылка,
КраткоеПредставлениеОшибки(ИнформацияОбОшибке())));
КонецПопытки;
КонецЦикла;
Возврат Ошибки;
КонецФункции
&НаСервереБезКонтекста получает только массив ссылок. Ошибка одного документа не останавливает остальные; массовое проведение подробнее — в статье про перепроведение.ПоказатьПредупреждение: у ПредупреждениеАсинх в справке 8.3.27 нет веб-клиента в списке доступности.Платформенное окно вопроса флажков не умеет. В БСП (сверено по УТ 11.4 и КА 2.5) есть СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю: общая форма «Вопрос» с флажком «Больше не задавать этот вопрос». Настройки окна дают ПараметрыВопросаПользователю(), а выбор пользователя запоминают сами.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// ЗаменятьСкладБезВопроса — реквизит формы типа Булево
ЗаменятьСкладБезВопроса = ОбщегоНазначения.ХранилищеОбщихНастроекЗагрузить(
"СменаСклада", "ЗаменятьБезВопроса", Ложь);
КонецПроцедуры
&НаКлиенте
Процедура СкладПриИзменении(Элемент)
Если Объект.Товары.Количество() = 0 Или Не ЗначениеЗаполнено(Объект.Склад) Тогда
Возврат;
КонецЕсли;
Если ЗаменятьСкладБезВопроса Тогда
ЗаменитьСкладВСтроках();
Возврат;
КонецЕсли;
ПараметрыВопроса = СтандартныеПодсистемыКлиент.ПараметрыВопросаПользователю();
ПараметрыВопроса.Заголовок = "Смена склада";
ПараметрыВопроса.КнопкаПоУмолчанию = КодВозвратаДиалога.Да;
Оповещение = Новый ОписаниеОповещения("СкладПриИзмененииЗавершение", ЭтотОбъект);
СтандартныеПодсистемыКлиент.ПоказатьВопросПользователю(Оповещение,
"Заменить склад во всех строках?", РежимДиалогаВопрос.ДаНет, ПараметрыВопроса);
КонецПроцедуры
&НаКлиенте
Процедура СкладПриИзмененииЗавершение(Результат, ДополнительныеПараметры) Экспорт
// Структура (Значение, БольшеНеЗадаватьЭтотВопрос) или Неопределено
Если Результат = Неопределено Или Результат.Значение <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
// Флажок запоминаем только вместе с ответом «Да»
Если Результат.БольшеНеЗадаватьЭтотВопрос Тогда
ЗаменятьСкладБезВопроса = Истина;
ОбщегоНазначенияВызовСервера.ХранилищеОбщихНастроекСохранить(
"СменаСклада", "ЗаменятьБезВопроса", Истина);
КонецЕсли;
ЗаменитьСкладВСтроках();
КонецПроцедуры
&НаКлиенте
Процедура ЗаменитьСкладВСтроках()
Для Каждого СтрокаТоваров Из Объект.Товары Цикл
СтрокаТоваров.Склад = Объект.Склад;
КонецЦикла;
КонецПроцедуры
В обработчик приходит структура с полями Значение и БольшеНеЗадаватьЭтотВопрос. Форма «Вопрос» отдаёт её только по кнопке или таймауту, поэтому результат сначала проверяют на Неопределено. Со стандартной надписью флажок виден только пользователям с правом «Сохранение данных пользователя».
В обычных формах толстого клиента вопрос задают модальной функцией Вопрос() с теми же параметрами, что у ВопросАсинх. Она останавливает код до ответа и сразу возвращает результат, поэтому ПередЗакрытием(Отказ, СтандартнаяОбработка) обычной формы обходится без оповещений.
// Модуль обычной формы документа (толстый клиент, обычное приложение)
Процедура СкладПриИзменении(Элемент)
Если Товары.Количество() = 0 Или Не ЗначениеЗаполнено(Склад) Тогда
Возврат;
КонецЕсли;
// Модальный вызов: следующая строка выполнится только после ответа
Ответ = Вопрос("Склад в шапке изменен. Заменить его во всех строках?",
РежимДиалогаВопрос.ДаНет, 30, КодВозвратаДиалога.Да, "Смена склада", КодВозвратаДиалога.Нет);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
Для Каждого СтрокаТоваров Из Товары Цикл
СтрокаТоваров.Склад = Склад;
КонецЦикла;
КонецПроцедуры
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Если Проведен Или ЭтоНовый() Тогда
Возврат;
КонецЕсли;
// Ответ известен сразу, поэтому Отказ ставится прямо здесь
Ответ = Вопрос("Документ не проведен. Закрыть его без проведения?",
РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Если «Режим использования модальности» в свойствах конфигурации установлен в «Не использовать», Вопрос() завершится ошибкой и код придётся переписать — см. статью «Использование модальных окон в данном режиме запрещено».
Вопрос() в конфигурации без модальности. Замените на ПоказатьВопрос или ВопросАсинх.&НаСервере. Диалоги есть только на клиенте, см. статью про директивы компиляции.Экспорт, с опечаткой в имени или не в том модуле, что передан в ОписаниеОповещения.ПоказатьВопрос не ждёт пользователя: всё, что зависит от ответа, переносите в обработчик.Если Ответ = КодВозвратаДиалога.Нет Тогда Возврат пропускает Таймаут дальше. С таймаутом сравнивайте ответ с кнопкой, разрешающей действие.ПередЗакрытием объявили с Асинх и спрашивают через Ждать. Параметры асинхронных процедур передаются только по значению, и Отказ = Истина до платформы не доходит. Обработчик события оставьте обычным: выставьте Отказ, затем вызовите асинхронную процедуру с вопросом.ПередЗакрытием не вызывается, если форму во вспомогательном окне закрыли системным крестиком или Alt+F4.Нет, диалоги есть только на клиенте. Сервер возвращает признак, что нужен вопрос (например, «есть строки без цены»), клиент спрашивает и следующим вызовом передаёт ответ. В фоновом задании спрашивать некого — делайте это до запуска.
Наборы РежимДиалогаВопрос не переименовываются. Передайте список со стандартными кодами и своими надписями: Кнопки.Добавить(КодВозвратаДиалога.Да, "Провести"), Кнопки.Добавить(КодВозвратаДиалога.Нет, "Не проводить"). Обработчик по-прежнему сравнивает ответ с КодВозвратаДиалога.Да.
Обработчик ответа кладут в клиентский неглобальный общий модуль, объявляют экспортным и передают модуль вторым параметром: Новый ОписаниеОповещения("ПослеОтвета", МойМодульКлиент). С ВопросАсинх проще: экспортная Асинх Функция модуля возвращает ответ, форма получает его через Ждать.
Да, ТекстВопроса у обоих методов принимает ФорматированнаяСтрока. Как её собрать, разобрано в статье про форматированную строку.
Подтверждения обычно нужны сразу в нескольких типовых документах, и ставить их лучше в расширении, чтобы не мешать обновлениям. Если разбираться с ПередЗакрытием и оповещениями в чужой конфигурации некогда, разместите задачу на 1c-only.ru: оценка бесплатная, ответ в течение рабочего дня. Доработка обработок — в разделе отчёты и обработки 1С.
Станьте частью сообщества!
Войдите или зарегистрируйтесь, и вы сможете участвовать в обсуждениях.