При создании внешних обработок в 1С мы часто сталкиваемся с задачами, требующими группового изменения данных. Давайте вместе разберем, как создать такую обработку, которая позволит отобрать документы по заданному периоду, изменить в них определенный реквизит (например, статус) и затем провести их.
Представим, что нам поручено разработать внешнюю обработку, которая будет выполнять следующие действия:
Рассмотрим весь процесс создания такой обработки по шагам, начиная с основных элементов формы и заканчивая логикой изменения и проведения документов.
Прежде всего, нам необходимо создать основу для нашей работы – новый файл внешней обработки. Мы будем работать в режиме Конфигуратора 1С.
После создания файла обработки, мы увидим окно свойств обработки. Нам нужно создать форму, с которой будет взаимодействовать пользователь. Для этого:
Перед нами откроется редактор формы, где мы будем размещать все необходимые элементы управления.
Теперь, когда у нас есть пустая форма, давайте добавим на неё элементы, которые позволят пользователю задавать параметры отбора и видеть список документов.
Период отбора документов
Для того чтобы пользователь мог задать период, нам понадобятся два реквизита формы типа Дата.
Табличное поле для отображения документов
Чтобы вывести отобранные документы, нам потребуется табличное поле. Оно будет связано с реквизитом формы типа ТаблицаЗначений.
Кнопки команд
Нам нужны кнопки для управления обработкой:
Создайте эти команды в окне Команды формы, а затем перетащите их на форму, чтобы автоматически создать соответствующие кнопки. Для каждой команды необходимо создать обработчик на сервере или клиенте в зависимости от требуемых операций.
После того как форма готова, переходим к основной логике – отбору документов. Эту логику мы реализуем в модуле формы. Предполагаем, что у нас есть команда ОтобратьДокументы, привязанная к кнопке Отобрать.
Для взаимодействия с базой данных (выборки документов) нам необходимо использовать объект Запрос. Все операции с базой данных должны выполняться на сервере, поэтому наш обработчик команды будет вызывать серверную процедуру.
Начнем с обработчика команды ОтобратьДокументы на клиенте, который вызывает серверную процедуру:
&НаКлиенте
Процедура ОтобратьДокументы(Команда)
ОтобратьДокументыНаСервере();
КонецПроцедуры
&НаСервере
Процедура ОтобратьДокументыНаСервере()
// Очищаем текущие данные в таблице перед новым отбором
ТаблицаДокументов.Очистить();
Запрос = Новый Запрос;
Запрос.Текст = "ВЫБРАТЬ
| ПоступлениеТоваровУслуг.Ссылка,
| ПоступлениеТоваровУслуг.Дата,
| ПоступлениеТоваровУслуг.Номер,
| ПоступлениеТоваровУслуг.Статус
|ИЗ
| Документ.ПоступлениеТоваровУслуг КАК ПоступлениеТоваровУслуг
|ГДЕ
| ПоступлениеТоваровУслуг.Дата МЕЖДУ &НачДата И &КонДата";
// Устанавливаем параметры запроса из реквизитов формы
Запрос.УстановитьПараметр("НачДата", НачалоПериода);
Запрос.УстановитьПараметр("КонДата", КонецПериода);
Попытка
РезультатЗапроса = Запрос.Выполнить();
Исключение
Сообщить("Ошибка выполнения запроса: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Выборка = РезультатЗапроса.Выбрать();
// Заполняем табличное поле на форме
Пока Выборка.Следующий() Цикл
НоваяСтрока = ТаблицаДокументов.Добавить();
НоваяСтрока.Отмечен = Ложь; // По умолчанию документы не отмечены
НоваяСтрока.Ссылка = Выборка.Ссылка;
НоваяСтрока.Дата = Выборка.Дата;
НоваяСтрока.Номер = Выборка.Номер;
НоваяСтрока.Статус = Выборка.Статус;
КонецЦикла;
КонецПроцедуры
В этом коде мы сначала объявляем клиентскую процедуру ОтобратьДокументы, которая вызывает серверную процедуру ОтобратьДокументыНаСервере. В серверной процедуре мы создаем объект Запрос, формируем текст запроса для выбора документов ПоступлениеТоваровУслуг (замените на актуальный тип документа в вашей конфигурации) в заданном диапазоне дат. Параметры &НачДата и &КонДата устанавливаются из реквизитов формы НачалоПериода и КонецПериода.
После выполнения запроса мы перебираем полученную Выборку и для каждой строки создаем новую строку в реквизите формы ТаблицаДокументов, заполняя её данными из запроса. Важно, что колонка Отмечен по умолчанию устанавливается в Ложь.
Реализуем также команды для групповой отметки/снятия отметок:
&НаКлиенте
Процедура ОтметитьВсе(Команда)
УстановитьОтметкуДляВсех(Истина);
КонецПроцедуры
&НаКлиенте
Процедура СнятьОтметки(Команда)
УстановитьОтметкуДляВсех(Ложь);
КонецПроцедуры
&НаКлиенте
Процедура УстановитьОтметкуДляВсех(ЗначениеОтметки)
Для Каждого СтрокаТЗ Из ТаблицаДокументов Цикл
СтрокаТЗ.Отмечен = ЗначениеОтметки;
КонецЦикла;
КонецПроцедуры
Эти процедуры клиентские, так как они работают только с данными на форме (ТаблицаДокументов) и не взаимодействуют напрямую с базой данных.
Это центральная часть нашей обработки. Мы должны перебрать все отмеченные документы в ТаблицаДокументов, получить их объекты, изменить статус и провести.
Эта логика также должна выполняться на сервере, так как включает запись в базу данных.
Начнем с обработчика команды ИзменитьИПровести на клиенте:
&НаКлиенте
Процедура ИзменитьИПровести(Команда)
Если Не ИзменитьИПровестиНаСервере() Тогда
Сообщить("Операция завершена с ошибками. Подробности в журнале регистрации.");
Иначе
Сообщить("Операция успешно завершена.");
// После проведения, возможно, имеет смысл обновить данные на форме
ОтобратьДокументыНаСервере();
КонецЕсли;
КонецПроцедуры
Теперь рассмотрим серверную процедуру ИзменитьИПровестиНаСервере. Здесь мы будем использовать транзакции, чтобы обеспечить целостность данных. Если в процессе изменения и проведения множества документов произойдет ошибка, мы сможем отменить все изменения, чтобы база данных осталась в согласованном состоянии. Также будем формировать реестр выполненных изменений, чтобы пользователь видел результат по каждому документу.
Для реестра изменений нам понадобится еще один реквизит формы типа ТаблицаЗначений, назовем его, например, РеестрРезультатов, с колонками: Документ (тип Строка), Результат (тип Строка), ОписаниеОшибки (тип Строка). Можем также добавить его на форму в виде табличного поля.
&НаСервере
Функция ИзменитьИПровестиНаСервере()
// Очищаем реестр результатов перед началом новой операции
РеестрРезультатов.Очистить();
Если ТаблицаДокументов.Количество() = 0 Тогда
Сообщить("Нет документов для обработки.", СтатусСообщения.Важное);
Возврат Истина;
КонецЕсли;
// Проверяем, есть ли отмеченные документы
ЕстьОтмеченные = Ложь;
Для Каждого СтрокаТЗ Из ТаблицаДокументов Цикл
Если СтрокаТЗ.Отмечен Тогда
ЕстьОтмеченные = Истина;
Прервать;
КонецЕсли;
КонецЦикла;
Если Не ЕстьОтмеченные Тогда
Сообщить("Не выбрано ни одного документа для обработки.", СтатусСообщения.Важное);
Возврат Истина;
КонецЕсли;
// Начинаем транзакцию
НачатьТранзакцию();
ВсеУспешно = Истина;
Для Каждого СтрокаТЗ Из ТаблицаДокументов Цикл
Если Не СтрокаТЗ.Отмечен Тогда
Продолжить; // Пропускаем неотмеченные
КонецЕсли;
НоваяСтрокаРеестра = РеестрРезультатов.Добавить();
НоваяСтрокаРеестра.Документ = СтрокаТЗ.Ссылка; // Или СтрокаТЗ.Ссылка.Представление()
Попытка
// Получаем объект документа по ссылке
ДокОбъект = СтрокаТЗ.Ссылка.ПолучитьОбъект();
Если ДокОбъект = Неопределено Тогда
НоваяСтрокаРеестра.Результат = "Ошибка";
НоваяСтрокаРеестра.ОписаниеОшибки = "Объект документа не найден (возможно, удален).";
ВсеУспешно = Ложь;
Продолжить;
КонецЕсли;
// Изменяем реквизит "Статус"
// Важно: замените "Статус" и "Перечисления.СтатусыДокументовПоступления.Принят"
// на актуальные реквизиты и значения в вашей конфигурации.
// Например, для документа "ПоступлениеТоваровУслуг" статус может быть "Состояние"
// и перечисление "Перечисления.СостоянияДокументовПоступления"
ДокОбъект.Статус = Перечисления.СтатусыДокументовПоступления.Принят;
// Проводим документ
ДокОбъект.Записать(РежимЗаписиДокумента.Проведение);
НоваяСтрокаРеестра.Результат = "Успешно";
НоваяСтрокаРеестра.ОписаниеОшибки = "Документ изменен и проведен.";
Исключение
НоваяСтрокаРеестра.Результат = "Ошибка";
НоваяСтрокаРеестра.ОписаниеОшибки = ОписаниеОшибки();
ВсеУспешно = Ложь;
// Можно логировать ошибки в журнал регистрации 1С
ЗаписатьВЖурналРегистрации("Массовое изменение документов",
УровеньЖурналаРегистрации.Ошибка,
Метаданные.Документы.ПоступлениеТоваровУслуг,
СтрокаТЗ.Ссылка,
"Ошибка при изменении/проведении документа: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
// Завершаем транзакцию
Если ВсеУспешно Тогда
ЗафиксироватьТранзакцию();
Сообщить("Все отмеченные документы успешно изменены и проведены.", СтатусСообщения.Информация);
Иначе
ОтменитьТранзакцию();
Сообщить("Обнаружены ошибки. Транзакция отменена. Ни один документ не был изменен/проведен.", СтатусСообщения.Важное);
КонецЕсли;
Возврат ВсеУспешно;
КонецФункции
Давайте подробнее проанализируем этот код:
После того как вы завершили разработку и отладку обработки в Конфигураторе, её можно использовать в режиме 1С:Предприятие.
Пользовательский интерфейс: Помимо основной функциональности, уделите внимание удобству использования. Четкие подписи к полям, интуитивно понятное расположение кнопок, информативные сообщения для пользователя – все это значительно повышает ценность обработки. Продумайте, что пользователь должен видеть в процессе работы и по её завершении.
Проверка прав: В реальных условиях работы с 1С всегда необходимо учитывать права доступа пользователей. Убедитесь, что у пользователя, запускающего обработку, есть достаточные права для чтения документов поступления, изменения их реквизитов и проведения.
Особенности проведения: При работе с документами, которые имеют проводки (например, ПоступлениеТоваровУслуг), важно понимать разницу между оперативным и неоперативным проведением. Обычно, метод Записать(РежимЗаписиДокумента.Проведение) выполняет неоперативное проведение, если не указано иное. Если требуется именно оперативное проведение, то нужно будет дополнительно управлять режимом проведения.
Встроенные возможности: Помните, что в типовых конфигурациях 1С уже существует мощная встроенная обработка Групповое изменение реквизитов. В некоторых случаях, если задача сводится только к изменению статуса и не требует сложной логики отбора или проведения, эту обработку можно использовать или изучить как пример для реализации собственных решений. Она находится в разделе Администрирование -> Обслуживание -> Корректировка данных.
Таким образом, мы рассмотрели полный цикл создания внешней обработки для массового изменения статуса и проведения документов в 1С. Следуя этим шагам и рекомендациям, вы сможете успешно реализовать подобную задачу, даже если вы только начинаете осваивать разработку на платформе 1С.