При разработке внешних обработок в 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью программной очистки или выборочного удаления записей из регистров сведений. На первый взгляд задача кажется тривиальной, однако она скрывает в себе нюансы, связанные с типами регистров (независимые или подчиненные регистратору), контекстом выполнения кода (Клиент/Сервер) и правильной передачей параметров в процедуры. Разберем по шагам, как эффективно управлять данными в регистрах и избегать типичных ошибок.
Рассмотрим ситуацию, когда при вызове серверной процедуры из клиентской команды система выдает ошибку: Недостаточно фактических параметров. Проанализируем причину. Если процедура на сервере описана с формальным параметром, например ОчиститьЗаписи(Пациент), то при ее вызове на клиенте обязательно нужно передать значение в скобках. В 1С:Предприятие нельзя просто вызвать процедуру по имени, если в ее заголовке указаны обязательные переменные.
Посмотрим на пример правильного вызова команды:
&НаКлиенте
Процедура Команда1(Команда)
// Передаем ссылку на конкретного пациента в качестве параметра
ОчиститьЗаписиВНезависимомРегистреСведенийСОтбором(Объект.НужныйПациент);
КонецПроцедуры
&НаСервере
Процедура ОчиститьЗаписиВНезависимомРегистреСведенийСОтбором(Пациент)
// Код удаления
КонецПроцедуры
Важно помнить: если параметр не является обязательным, в описании процедуры его можно инициализировать значением по умолчанию, например Пациент = Неопределено. В этом случае ошибка при вызове без скобок исчезнет.
Если нам нужно удалить одну конкретную запись в независимом регистре сведений, удобнее всего использовать объект СоздатьМенеджерЗаписи. Этот объект имитирует работу с одной строкой регистра. Чтобы удаление сработало, необходимо заполнить значения всех измерений, которые составляют ключ записи.
Выясним, как это выглядит в коде:
Запись = РегистрыСведений.ДанныеПациентов.СоздатьМенеджерЗаписи();
Запись.Пациент = ПараметрПациент; // Указываем измерение
Запись.Прочитать(); // Пытаемся найти запись в базе
Если Запись.Выбран() Тогда
Запись.Удалить();
КонецЕсли;
Важный момент: использование менеджера записи оправдано только для точечного удаления. Для массовой очистки данных этот метод крайне неэффективен, так как порождает отдельный SQL-запрос на каждую строку.
Для удаления группы записей или полной очистки регистра мы используем объект НаборЗаписей. Принцип его работы прост: мы создаем набор, устанавливаем фильтры (отборы) и записываем пустой набор. Система автоматически удалит из базы данных все записи, попадающие под установленный отбор.
Разберем пример удаления записей по конкретному измерению:
Набор = РегистрыСведений.ДанныеПациентов.СоздатьНаборЗаписей();
Набор.Отбор.Пациент.Установить(ПараметрПациент);
Набор.Записать(); // По умолчанию Записать(Истина), что перезаписывает данные на пустой набор
Если же стоит задача полностью очистить весь независимый регистр, мы просто не устанавливаем никаких фильтров:
&НаСервере
Процедура ПолнаяОчисткаРегистра()
Набор = РегистрыСведений.ДанныеПациентов.СоздатьНаборЗаписей();
// Отборы не устанавливаем
Набор.Записать(); // Все данные в регистре будут удалены
КонецПроцедуры
Проанализируем ситуацию, если регистр сведений является подчиненным (в свойствах стоит «Режим записи: Подчинение регистратору»). В этом случае попытка записать набор записей без отбора по регистратору приведет к ошибке платформы.
Для таких регистров обязательным является наличие отбора по полю Регистратор. Чтобы очистить такой регистр полностью, придется перебирать документы-регистраторы. Однако, если регистр хранит данные пациентов, привязанные к документам (например, «Прием врача»), удаление записей напрямую в регистре может нарушить логику системы. Обычно в таких случаях очищают движения самих документов.
Рассмотрим, что происходит «под капотом» при выполнении команды Набор.Записать(), особенно если база работает на PostgreSQL. Платформа 1С транслирует этот метод в SQL-команду DELETE.
Нужно учитывать два важных фактора:
VACUUM. В большинстве случаев это делает autovacuum, но при экстренной очистке огромных объемов может потребоваться ручной VACUUM FULL.В контексте обсуждения данных пациентов часто возникает вопрос интеграции специализированных решений. Если вы настраиваете обмен между 1С:Больница (МИС) и 1С:Лаборатория (ЛИС), помните следующие правила:
Во-первых, обмен чаще всего строится на использовании веб-сервисов или стандартов HL7. Данные о пациентах должны быть синхронизированы по уникальным идентификаторам (UID), чтобы исключить дублирование при очистке или обновлении регистров.
Во-вторых, в медицинских конфигурациях данные в регистрах часто связаны с Электронными Медицинскими Картами (ЭМК). Простое удаление записей из регистра ДанныеПациентов может привести к тому, что в интерфейсе врача пропадут результаты анализов или анамнез, хотя сами документы останутся в базе. Перед массовой очисткой всегда проверяйте структуру метаданных и наличие связей с другими объектами через «Поиск ссылок на объект».
Подведем итог: для корректного удаления данных всегда выбирайте между МенеджеромЗаписи (для одной строки) и НаборомЗаписей (для группы строк). Всегда проверяйте тип регистра и следите за контекстом вызова процедур с параметрами, чтобы не сталкиваться с досадными синтаксическими ошибками.