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