Как программно очистить регистр сведений в 1С и исправить ошибку недостаточности фактических параметров

Программист 1С v8.3 (Управляемые формы) Сфера услуг, туризм и социальный сектор
← На главную

При разработке внешних обработок в 1С:Предприятие 8.3 программисты часто сталкиваются с необходимостью программной очистки или выборочного удаления записей из регистров сведений. На первый взгляд задача кажется тривиальной, однако она скрывает в себе нюансы, связанные с типами регистров (независимые или подчиненные регистратору), контекстом выполнения кода (Клиент/Сервер) и правильной передачей параметров в процедуры. Разберем по шагам, как эффективно управлять данными в регистрах и избегать типичных ошибок.

Разбор ошибки «Недостаточно фактических параметров»

Рассмотрим ситуацию, когда при вызове серверной процедуры из клиентской команды система выдает ошибку: Недостаточно фактических параметров. Проанализируем причину. Если процедура на сервере описана с формальным параметром, например ОчиститьЗаписи(Пациент), то при ее вызове на клиенте обязательно нужно передать значение в скобках. В 1С:Предприятие нельзя просто вызвать процедуру по имени, если в ее заголовке указаны обязательные переменные.

Посмотрим на пример правильного вызова команды:


&НаКлиенте
Процедура Команда1(Команда)
    // Передаем ссылку на конкретного пациента в качестве параметра
    ОчиститьЗаписиВНезависимомРегистреСведенийСОтбором(Объект.НужныйПациент);
КонецПроцедуры

&НаСервере
Процедура ОчиститьЗаписиВНезависимомРегистреСведенийСОтбором(Пациент)
    // Код удаления
КонецПроцедуры

Важно помнить: если параметр не является обязательным, в описании процедуры его можно инициализировать значением по умолчанию, например Пациент = Неопределено. В этом случае ошибка при вызове без скобок исчезнет.

Удаление одной записи через МенеджерЗаписи

Если нам нужно удалить одну конкретную запись в независимом регистре сведений, удобнее всего использовать объект СоздатьМенеджерЗаписи. Этот объект имитирует работу с одной строкой регистра. Чтобы удаление сработало, необходимо заполнить значения всех измерений, которые составляют ключ записи.

Выясним, как это выглядит в коде:


Запись = РегистрыСведений.ДанныеПациентов.СоздатьМенеджерЗаписи();
Запись.Пациент = ПараметрПациент; // Указываем измерение
Запись.Прочитать(); // Пытаемся найти запись в базе
Если Запись.Выбран() Тогда
    Запись.Удалить();
КонецЕсли;

Важный момент: использование менеджера записи оправдано только для точечного удаления. Для массовой очистки данных этот метод крайне неэффективен, так как порождает отдельный SQL-запрос на каждую строку.

Массовое удаление записей через НаборЗаписей

Для удаления группы записей или полной очистки регистра мы используем объект НаборЗаписей. Принцип его работы прост: мы создаем набор, устанавливаем фильтры (отборы) и записываем пустой набор. Система автоматически удалит из базы данных все записи, попадающие под установленный отбор.

Разберем пример удаления записей по конкретному измерению:


Набор = РегистрыСведений.ДанныеПациентов.СоздатьНаборЗаписей();
Набор.Отбор.Пациент.Установить(ПараметрПациент);
Набор.Записать(); // По умолчанию Записать(Истина), что перезаписывает данные на пустой набор

Если же стоит задача полностью очистить весь независимый регистр, мы просто не устанавливаем никаких фильтров:


&НаСервере
Процедура ПолнаяОчисткаРегистра()
    Набор = РегистрыСведений.ДанныеПациентов.СоздатьНаборЗаписей();
    // Отборы не устанавливаем
    Набор.Записать(); // Все данные в регистре будут удалены
КонецПроцедуры

Особенности регистров, подчиненных регистратору

Проанализируем ситуацию, если регистр сведений является подчиненным (в свойствах стоит «Режим записи: Подчинение регистратору»). В этом случае попытка записать набор записей без отбора по регистратору приведет к ошибке платформы.

Для таких регистров обязательным является наличие отбора по полю Регистратор. Чтобы очистить такой регистр полностью, придется перебирать документы-регистраторы. Однако, если регистр хранит данные пациентов, привязанные к документам (например, «Прием врача»), удаление записей напрямую в регистре может нарушить логику системы. Обычно в таких случаях очищают движения самих документов.

Взаимодействие с PostgreSQL на уровне СУБД

Рассмотрим, что происходит «под капотом» при выполнении команды Набор.Записать(), особенно если база работает на PostgreSQL. Платформа 1С транслирует этот метод в SQL-команду DELETE.

Нужно учитывать два важных фактора:

  1. Транзакционный лог: При массовом удалении миллионов строк лог транзакций PostgreSQL может значительно вырасти. Рекомендуется удалять данные порциями, если объем превышает сотни тысяч записей.
  2. Освобождение места: После удаления данных физический размер базы в PostgreSQL не уменьшится сразу. Удаленные строки помечаются как «мертвые кортежи» (dead tuples). Для физического освобождения места на диске СУБД должна выполнить процедуру VACUUM. В большинстве случаев это делает autovacuum, но при экстренной очистке огромных объемов может потребоваться ручной VACUUM FULL.

Интеграция медицинских систем: «1С:Больница» и «1С:Лаборатория»

В контексте обсуждения данных пациентов часто возникает вопрос интеграции специализированных решений. Если вы настраиваете обмен между 1С:Больница (МИС) и 1С:Лаборатория (ЛИС), помните следующие правила:

Во-первых, обмен чаще всего строится на использовании веб-сервисов или стандартов HL7. Данные о пациентах должны быть синхронизированы по уникальным идентификаторам (UID), чтобы исключить дублирование при очистке или обновлении регистров.

Во-вторых, в медицинских конфигурациях данные в регистрах часто связаны с Электронными Медицинскими Картами (ЭМК). Простое удаление записей из регистра ДанныеПациентов может привести к тому, что в интерфейсе врача пропадут результаты анализов или анамнез, хотя сами документы останутся в базе. Перед массовой очисткой всегда проверяйте структуру метаданных и наличие связей с другими объектами через «Поиск ссылок на объект».

Подведем итог: для корректного удаления данных всегда выбирайте между МенеджеромЗаписи (для одной строки) и НаборомЗаписей (для группы строк). Всегда проверяйте тип регистра и следите за контекстом вызова процедур с параметрами, чтобы не сталкиваться с досадными синтаксическими ошибками.

← На главную