Привет всем)
попросили меня бухи дописать одну простую вещь: чтоб когда они создавали контрагентов, была проверка по наименованию и инн+кпп на дубль.
Вроде и просто а уже мучаюсь хз сколько.
Сделала так:

```1c
    Функция ЕстьВБазеКонтрагент(ИНН = ", КПП = ", Наименование = ")

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | СпрКонтрагенты.Ссылка КАК Ссылка
    |ИЗ
    | Справочник.Контрагенты КАК СпрКонтрагенты
    |ГДЕ
    | ИСТИНА
    | И СпрКонтрагенты.ИНН = &ИНН
    | И СпрКонтрагенты.КПП = &КПП
    | И СпрКонтрагенты.Наименование = &Наименование";

    Если ИНН = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.ИНН = &ИНН", ");
    Иначе
    Запрос.УстановитьПараметр("ИНН", ИНН);
    КонецЕсли;
    Если КПП = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.КПП = &КПП", ");
    Иначе
    Запрос.УстановитьПараметр("КПП", КПП);
    КонецЕсли;
    Если Наименование = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.Наименование = &Наименование", ");
    Иначе
    Запрос.УстановитьПараметр("Наименование", Наименование);
    КонецЕсли;
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
    Возврат Ложь;
    КонецЕсли;
    Возврат Истина;
    КонецФункции

    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    Если ЭтоНовый() И ЕстьВБазеКонтрагент(ИНН, КПП, Наименование) Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Такой Контрагент уже есть в базе";
    Сообщение.Поле = "Объект.Наименование";
    Сообщение.Сообщить();
    КонецЕсли;
```

Но! Если одинаковое наименование записывать программа отказывается, а если одинкаовые инн и кпп, то проверка как будто не делается вообще.

Я тут ещё делала так, что если инн не заполнено, то проверку только по наименованию проводить, а оно инн как понла вообще отключило.
---
А уже не важно, сделала так:

```1c
    Функция ЕстьВБазеКонтрагент(ИНН, КПП, Наименование)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | СпрКонтрагенты.Ссылка КАК Ссылка
    |ИЗ
    | Справочник.Контрагенты КАК СпрКонтрагенты
    |ГДЕ
    | ИСТИНА
    | И СпрКонтрагенты.ИНН = &ИНН
    | И СпрКонтрагенты.КПП = &КПП
    | И СпрКонтрагенты.Наименование = &Наименование
    |";

    Если ИНН = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.ИНН = &ИНН", ");
    Иначе
    Запрос.УстановитьПараметр("ИНН", ИНН);
    КонецЕсли;
    Если КПП = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.КПП = &КПП", ");
    Иначе
    Запрос.УстановитьПараметр("КПП", КПП);
    КонецЕсли;
    Если Наименование = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.Наименование = &Наименование", ");
    Иначе
    Запрос.УстановитьПараметр("Наименование", Наименование);
    КонецЕсли;
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
    Возврат Ложь;
    КонецЕсли;
    Возврат Истина;
    КонецФункции

    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

    //Если ЭтоНовый() И ЗначениеЗаполнено (ИНН) И ЕстьВБазеКонтрагент(ИНН, КПП) И ЕстьВБазеКонтрагентНаим(Наименование) Тогда
    //Если ЭтоНовый() И ЕстьВБазеКонтрагент(СокрЛП(ИНН),СокрЛП(КПП),СокрЛП(Наименование)) Тогда
    //Если ЭтоНовый() И ЗначениеЗаполнено (ИНН) И (ЕстьВБазеКонтрагент(ИНН, КПП) ИЛИ ЕстьВБазеКонтрагентНаим(Наименование)) Тогда
    Если (ЭтоНовый() И ЕстьВБазеКонтрагент(ИНН,КПП,Наименование)) или (ЭтоНовый() И ЗначениеЗаполнено (ИНН) и ЕстьВБазеКонтрагент(ИНН,КПП,")) Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Такой Контрагент уже есть в базе";
    Сообщение.Поле = "Объект.Наименование";
    Сообщение.Сообщить();
    КонецЕсли;
```
---
А откуда берутся ИНН, КПП и Наименование в этом месте
```1c
    ЕстьВБазеКонтрагент(ИНН, КПП, Наименование)
```
 ?
---
пробовала так:

```1c
    Функция ЕстьВБазеКонтрагент(ИНН = ", КПП = ", Наименование = ")
```

ничего не поменялось.

И как понять откуда береться? идет же вызов функции? или что-то не так делаю?
---
Я имел ввиду вот

```1c
    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)
    Если ЭтоНовый() И ЕстьВБазеКонтрагент(ИНН, КПП, Наименование) Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Такой Контрагент уже есть в базе";
    Сообщение.Поле = "Объект.Наименование";
    Сообщение.Сообщить();
    КонецЕсли;
```
тут ОТКУДА 1С знает чему равны ИНН, КПП, Наименование.
У вас они ВСЕГДА неопределены, и потому запрос всегда выдает всех контрагентов в базе...
---
А уже не важно, сделала так:

```1c
    Функция ЕстьВБазеКонтрагент(ИНН, КПП, Наименование)

    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ
    | СпрКонтрагенты.Ссылка КАК Ссылка
    |ИЗ
    | Справочник.Контрагенты КАК СпрКонтрагенты
    |ГДЕ
    | ИСТИНА
    | И СпрКонтрагенты.ИНН = &ИНН
    | И СпрКонтрагенты.КПП = &КПП
    | И СпрКонтрагенты.Наименование = &Наименование
    |";

    Если ИНН = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.ИНН = &ИНН", ");
    Иначе
    Запрос.УстановитьПараметр("ИНН", ИНН);
    КонецЕсли;
    Если КПП = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.КПП = &КПП", ");
    Иначе
    Запрос.УстановитьПараметр("КПП", КПП);
    КонецЕсли;
    Если Наименование = " Тогда
    Запрос.Текст = СтрЗаменить(Запрос.Текст, "И СпрКонтрагенты.Наименование = &Наименование", ");
    Иначе
    Запрос.УстановитьПараметр("Наименование", Наименование);
    КонецЕсли;
    РезультатЗапроса = Запрос.Выполнить();
    Если РезультатЗапроса.Пустой() Тогда
    Возврат Ложь;
    КонецЕсли;
    Возврат Истина;
    КонецФункции

    Процедура ОбработкаПроверкиЗаполнения(Отказ, ПроверяемыеРеквизиты)

    //Если ЭтоНовый() И ЗначениеЗаполнено (ИНН) И ЕстьВБазеКонтрагент(ИНН, КПП) И ЕстьВБазеКонтрагентНаим(Наименование) Тогда
    //Если ЭтоНовый() И ЕстьВБазеКонтрагент(СокрЛП(ИНН),СокрЛП(КПП),СокрЛП(Наименование)) Тогда
    //Если ЭтоНовый() И ЗначениеЗаполнено (ИНН) И (ЕстьВБазеКонтрагент(ИНН, КПП) ИЛИ ЕстьВБазеКонтрагентНаим(Наименование)) Тогда
    Если (ЭтоНовый() И ЕстьВБазеКонтрагент(ИНН,КПП,Наименование)) или (ЭтоНовый() И ЗначениеЗаполнено (ИНН) и ЕстьВБазеКонтрагент(ИНН,КПП,")) Тогда
    Отказ = Истина;
    Сообщение = Новый СообщениеПользователю;
    Сообщение.Текст = "Такой Контрагент уже есть в базе";
    Сообщение.Поле = "Объект.Наименование";
    Сообщение.Сообщить();
    КонецЕсли;
```
---
Лучше сделайте без наименования (только ИНН+КПП), ведь инн и кпп должны быть уникальными, а наименования можно и обойти(специально или случайно). Например "ооо фирма" / "фирма ооо" /"ооо фирма" / " ооо фирма" / "ооо фирма" / "ооо фирма" и тд...

+ группы вы никак не отделили? у групп только наименование, нельзя будет назвать 2 группы одинаково в любых уровнях иерархии.
---
да тут в любом случае идёт проверка и по инн тоже. Просто безопаснее будет если и по наименованию не пройдёт
---
да тут в любом случае идёт проверка и по инн тоже. Просто безопаснее будет если и по наименованию не пройдёт

Я Вам говорю немного о другом. Если у вас в базе есть клиент с инн 111, кпп 222 и наим ооо фирм, а вы создаете нового с инн 111, кпп 222 и наим фирм ооо, то ваша проверка не сработает, хотя очевидно, что это дубль.