Как обеспечить уникальность реквизита в справочнике?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Как обеспечить уникальность реквизита в справочнике
Обеспечение уникальности реквизита — это важный вопрос при разработке в 1С, так как нарушение уникальности данных может привести к ошибкам, потере целостности информации и проблемам в отчётах. Существует несколько подходов, каждый из которых имеет свои преимущества и ограничения.
Методы обеспечения уникальности
1. Встроенная функция реквизита — флаг "Уникальность"
В конфигураторе 1С при создании реквизита справочника можно установить свойство "Уникальный" (Unique) на значение "Истина". Это самый простой способ.
Преимущества:
- Простота реализации
- Автоматическая проверка при сохранении
- Работает на уровне базы данных
Ограничения:
- Работает только для одного реквизита
- Не позволяет учитывать пустые значения
- Не работает для иерархических справочников с разделением по группам
Пример в конфигураторе:
Справочник "Номенклатура"
├── Реквизит "Артикул"
│ ├── Тип: Строка
│ ├── Длина: 50
│ └── Уникальный: Да
2. Валидация на уровне программного кода
Проверка уникальности перед сохранением справочника через обработчик события ПередЗаписью.
// В модуле справочника
Процедура ПередЗаписью(Отмена)
// Проверка уникальности артикула
Запрос = Новый Запрос();
Запрос.Текст =
"Выбрать КОЛИЧЕСТВО(*) КАК Количество
Из Справочник.Номенклатура
Где Артикул = &Артикул
И Ссылка <> &Ссылка
И НЕ ЭтоГруппа";
Запрос.УстановитьПараметр("Артикул", ЭтотОбъект.Артикул);
Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка.Прочитать();
Если Выборка.Количество > 0 Тогда
Отмена = Истина;
ВызватьИсключение "Артикул '" + ЭтотОбъект.Артикул + "' уже существует!";
КонецЕсли;
КонецПроцедуры
Преимущества:
- Гибкость: можно добавить дополнительную логику
- Можно проверять несколько реквизитов одновременно
- Контролировать сообщение об ошибке
- Работает с иерархическими справочниками
Ограничения:
- Требует написания кода
- Может быть медленнее при большом объёме данных
- Нужно учитывать порядок проверок
3. Составная уникальность (по нескольким реквизитам)
Для обеспечения уникальности по комбинации нескольких реквизитов используется только программная валидация.
Процедура ПередЗаписью(Отмена)
// Проверка уникальности пары "Контрагент + Договор"
Запрос = Новый Запрос();
Запрос.Текст =
"Выбрать КОЛИЧЕСТВО(*) КАК Количество
Из Справочник.СчётаКонтрагента
Где Контрагент = &Контрагент
И Договор = &Договор
И Ссылка <> &Ссылка";
Запрос.УстановитьПараметр("Контрагент", ЭтотОбъект.Контрагент);
Запрос.УстановитьПараметр("Договор", ЭтотОбъект.Договор);
Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка.Прочитать();
Если Выборка.Количество > 0 Тогда
Отмена = Истина;
ВызватьИсключение "Для этого контрагента и договора счёт уже существует!";
КонецЕсли;
КонецПроцедуры
4. Ограничение уникальности в пределах группы
Для иерархических справочников можно обеспечить уникальность внутри конкретной группы.
Процедура ПередЗаписью(Отмена)
// Проверка уникальности в пределах группы
Запрос = Новый Запрос();
Запрос.Текст =
"Выбрать КОЛИЧЕСТВО(*) КАК Количество
Из Справочник.Подразделения
Где Родитель = &Родитель
И Наименование = &Наименование
И Ссылка <> &Ссылка
И НЕ ЭтоГруппа";
Запрос.УстановитьПараметр("Родитель", ЭтотОбъект.Родитель);
Запрос.УстановитьПараметр("Наименование", ЭтотОбъект.Наименование);
Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка.Прочитать();
Если Выборка.Количество > 0 Тогда
Отмена = Истина;
ВызватьИсключение "В этой группе элемент с таким названием уже существует!";
КонецЕсли;
КонецПроцедуры
5. Ограничение уникальности без учёта пустых значений
Частый кейс: нужна уникальность, но пустое значение может быть в нескольких элементах.
Процедура ПередЗаписью(Отмена)
// Проверка уникальности только если значение не пусто
Если ЭтотОбъект.Артикул <> "" Тогда
Запрос = Новый Запрос();
Запрос.Текст =
"Выбрать КОЛИЧЕСТВО(*) КАК Количество
Из Справочник.Номенклатура
Где Артикул = &Артикул
И Артикул <> ""
И Ссылка <> &Ссылка";
Запрос.УстановитьПараметр("Артикул", ЭтотОбъект.Артикул);
Запрос.УстановитьПараметр("Ссылка", ЭтотОбъект.Ссылка);
Результат = Запрос.Выполнить();
Выборка = Результат.Выбрать();
Выборка.Прочитать();
Если Выборка.Количество > 0 Тогда
Отмена = Истина;
ВызватьИсключение "Артикул '" + ЭтотОбъект.Артикул + "' уже существует!";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Таблица сравнения методов
| Метод | Простота | Гибкость | Производительность | Когда использовать |
|---|---|---|---|---|
| Флаг "Уникальный" | Высокая | Низкая | Отличная | Простые кейсы |
| Программная валидация | Средняя | Высокая | Хорошая | Сложные условия |
| Составная уникальность | Средняя | Высокая | Хорошая | Несколько полей |
| В пределах группы | Средняя | Средняя | Хорошая | Иерархические справочники |
Лучшие практики
- Всегда проверяй на null: Убедись, что реквизит заполнен перед проверкой уникальности
- Исключи сам объект: При проверке используй "Ссылка <> &Ссылка", чтобы не считать сам себя
- Информативные сообщения об ошибке: Пользователь должен понять, что неправильно
- Тестирование: Всегда тестируй граничные случаи (пустые значения, спецсимволы)
- Производительность: Для больших справочников добавь индексы в базе данных
Выбор метода зависит от сложности требований и размера справочника. Для простых случаев используй встроенный флаг, для сложных — программную валидацию с детальной обработкой ошибок.