Имеется справочник с строковым кодом длиной 9 символов, например, Контрагенты, необходимо чтобы при присвоении кода код не совпадал с кодом в другом справочнике, где код так же строковый, например, Сотрудники. Подскажите пожалуйста запрос который бы возвращал свободный следующий номер из двух справочников. В справочнике Сотрудники коды могут идти не по порядку. Известен код который присвоится при записи нового элемента Контрагента.
Нумерация Сотрудников очень плохая в том плане что и пробелов много и нумерация есть без лидирующих нулей, поэтому в начале её привожу к одному виду
Функция ВернутьКодБезДубляПоСотрудникам(Код)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА ПОДСТРОКА(Сотрудники.Код, 9, 1) <> """"
| ТОГДА СОКРЛП(Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 8, 1) <> """"
| ТОГДА СОКРЛП(""0"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 7, 1) <> """"
| ТОГДА СОКРЛП(""00"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 6, 1) <> """"
| ТОГДА СОКРЛП(""000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 5, 1) <> """"
| ТОГДА СОКРЛП(""0000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 4, 1) <> """"
| ТОГДА СОКРЛП(""00000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 3, 1) <> """"
| ТОГДА СОКРЛП(""000000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 2, 1) <> """"
| ТОГДА СОКРЛП(""0000000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 1, 1) <> """"
| ТОГДА СОКРЛП(""00000000"" + Сотрудники.Код)
| КОНЕЦ КАК КодСотрудника
|ПОМЕСТИТЬ ВТ_КодыСотрудников
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПРАВ(ВТ_КодыСотрудников.КодСотрудника, 6) КАК Код
|ПОМЕСТИТЬ ВТ_Дано
|ИЗ
| ВТ_КодыСотрудников КАК ВТ_КодыСотрудников
|ГДЕ
| ПОДСТРОКА(ПРАВ(ВТ_КодыСотрудников.КодСотрудника, 6), 1, 2) = ПОДСТРОКА(ПРАВ(&Код, 6), 1, 2)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 6, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 5, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 10 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 4, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 100 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 3, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 1000 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 2, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 10000 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 1, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 100000 КАК Х
|ПОМЕСТИТЬ Числа
|ИЗ
| ВТ_Дано КАК ВТ_Дано
|
|ДЛЯ ИЗМЕНЕНИЯ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Числа.Х КАК Х,
| ЛОЖЬ КАК Свободен
|ПОМЕСТИТЬ ЧислаПлюс
|ИЗ
| Числа КАК Числа
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| Числа.Х + 1,
| ИСТИНА
|ИЗ
| Числа КАК Числа
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 1
| ЧислаПлюс.Х КАК ПервыйСвободныйАртикул
|ИЗ
| ЧислаПлюс КАК ЧислаПлюс
|
|СГРУППИРОВАТЬ ПО
| ЧислаПлюс.Х
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(*) = 1 И
| МАКСИМУМ(ЧислаПлюс.Свободен) = ИСТИНА";
Запрос.УстановитьПараметр("Код", СокрЛП(Код));
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Код;
Иначе
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
ВыборкаДетальныеЗаписи.Следующий();
Если ВыборкаДетальныеЗаписи.ПервыйСвободныйАртикул > Число(Код) Тогда
Возврат "000" + Формат(ВыборкаДетальныеЗаписи.ПервыйСвободныйАртикул,"ЧГ=0");
Иначе
Возврат Код;
КонецЕсли;
КонецЕсли;
КонецФункции
ВЫБРАТЬ
Контрагенты.Код КАК Код
ИЗ
Справочник.Контрагенты КАК Контрагенты
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
Сотрудники.Код
ИЗ
Справочник.Сотрудники КАК Сотрудники
УПОРЯДОЧИТЬ ПО
Код
АВТОУПОРЯДОЧИВАНИЕ
(2)Подойдет только в том случае, если коды будут идентичные и пользаки не влезут в нумерацию руками и нет обмена, т.к. обмен может свои префиксы притащить.
(3) Тогда одним запросом не сделать. В цикле удалять символы отличные от цифр. Потом сортировку к таблице применить. Ну и к получившемуся числу прибавить префикс.
Я сделал через генерацию числовой последовательности, преобразования кодов сотрудников в числа и связь между ними, думал может есть что то более лаконичное и всё в запросе
Создать объект второго справочника, дернуть у него УстановитьНовыйКод, присвоить полученный код первому справочнику, объект второго справочника не записывать. Не?
(8)классное решение, но у меня нарушение в нумерации у справочника Сотрудники, много неиспользованных кодов, хотел нумерацию продолжать в номерах Контрагентов
ВЫБРАТЬ
ВложенныйЗапрос.Код КАК Код
ИЗ
(ВЫБРАТЬ ПЕРВЫЕ 1
Контрагенты.Код КАК Код
ИЗ
Справочник.Контрагенты КАК Контрагенты
УПОРЯДОЧИТЬ ПО
Код УБЫВ) КАК ВложенныйЗапрос
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ
ВложенныйЗапрос.Код
ИЗ
(ВЫБРАТЬ ПЕРВЫЕ 1
Сотрудники.Код КАК Код
ИЗ
Справочник.Сотрудники КАК Сотрудники
УПОРЯДОЧИТЬ ПО
Сотрудники.Код УБЫВ) КАК ВложенныйЗапрос
УПОРЯДОЧИТЬ ПО
Код УБЫВ
(1) Вам это зачем запросом в 1С делать?
Представьте 100 пользователей выполнили запрос примерно в одно и то же время, мгновение и стали один и тот же номер куда-то присваивать.
Есть нумератор. Его и используйте. Только номер надо не в код справочника сувать, а отдельным реквизитом. А какой код у справочника будет не важно.
Но если честно, ума не приложу зачем у справочников коды разводить на разные. Тип справочника и так дает понять кто есть где. Коды же не обязательно должны идти подряд.
Физлица: "Ф" + 9 символов кода, или "1" + 9 символов кода.
Контрагенты: "К" + 9 символов кода, или "2" + 9 символов кода.
(10) в дальшейшем коды импортируются в другую систему, где нельзя использовать буквы для префикса потому что только числа принимает система, для числового префикса тоже не хватает длины и нумерация потом нарушится
(11) Проще поправить систему приема данных. Расширить длину кода, до необходимого. Либо вообще код не переносить. Пусть принимающая система свои генерит. Добавить внешний ключ из базы источника куда прописать GUID из 1С и усё. Какая разница какой там код.
В общем, по моему, не с той стороны задачу решаете.
Нумерация Сотрудников очень плохая в том плане что и пробелов много и нумерация есть без лидирующих нулей, поэтому в начале её привожу к одному виду
Функция ВернутьКодБезДубляПоСотрудникам(Код)
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ВЫБОР
| КОГДА ПОДСТРОКА(Сотрудники.Код, 9, 1) <> """"
| ТОГДА СОКРЛП(Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 8, 1) <> """"
| ТОГДА СОКРЛП(""0"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 7, 1) <> """"
| ТОГДА СОКРЛП(""00"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 6, 1) <> """"
| ТОГДА СОКРЛП(""000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 5, 1) <> """"
| ТОГДА СОКРЛП(""0000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 4, 1) <> """"
| ТОГДА СОКРЛП(""00000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 3, 1) <> """"
| ТОГДА СОКРЛП(""000000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 2, 1) <> """"
| ТОГДА СОКРЛП(""0000000"" + Сотрудники.Код)
| КОГДА ПОДСТРОКА(Сотрудники.Код, 1, 1) <> """"
| ТОГДА СОКРЛП(""00000000"" + Сотрудники.Код)
| КОНЕЦ КАК КодСотрудника
|ПОМЕСТИТЬ ВТ_КодыСотрудников
|ИЗ
| Справочник.Сотрудники КАК Сотрудники
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ПРАВ(ВТ_КодыСотрудников.КодСотрудника, 6) КАК Код
|ПОМЕСТИТЬ ВТ_Дано
|ИЗ
| ВТ_КодыСотрудников КАК ВТ_КодыСотрудников
|ГДЕ
| ПОДСТРОКА(ПРАВ(ВТ_КодыСотрудников.КодСотрудника, 6), 1, 2) = ПОДСТРОКА(ПРАВ(&Код, 6), 1, 2)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 6, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 5, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 10 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 4, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 100 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 3, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 1000 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 2, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 10000 + ВЫБОР ПОДСТРОКА(ВТ_Дано.Код, 1, 1)
| КОГДА ""1""
| ТОГДА 1
| КОГДА ""2""
| ТОГДА 2
| КОГДА ""3""
| ТОГДА 3
| КОГДА ""4""
| ТОГДА 4
| КОГДА ""5""
| ТОГДА 5
| КОГДА ""6""
| ТОГДА 6
| КОГДА ""7""
| ТОГДА 7
| КОГДА ""8""
| ТОГДА 8
| КОГДА ""9""
| ТОГДА 9
| ИНАЧЕ 0
| КОНЕЦ * 100000 КАК Х
|ПОМЕСТИТЬ Числа
|ИЗ
| ВТ_Дано КАК ВТ_Дано
|
|ДЛЯ ИЗМЕНЕНИЯ
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
| Числа.Х КАК Х,
| ЛОЖЬ КАК Свободен
|ПОМЕСТИТЬ ЧислаПлюс
|ИЗ
| Числа КАК Числа
|
|ОБЪЕДИНИТЬ
|
|ВЫБРАТЬ
| Числа.Х + 1,
| ИСТИНА
|ИЗ
| Числа КАК Числа
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 1
| ЧислаПлюс.Х КАК ПервыйСвободныйАртикул
|ИЗ
| ЧислаПлюс КАК ЧислаПлюс
|
|СГРУППИРОВАТЬ ПО
| ЧислаПлюс.Х
|
|ИМЕЮЩИЕ
| КОЛИЧЕСТВО(*) = 1 И
| МАКСИМУМ(ЧислаПлюс.Свободен) = ИСТИНА";
Запрос.УстановитьПараметр("Код", СокрЛП(Код));
РезультатЗапроса = Запрос.Выполнить();
Если РезультатЗапроса.Пустой() Тогда
Возврат Код;
Иначе
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
ВыборкаДетальныеЗаписи.Следующий();
Если ВыборкаДетальныеЗаписи.ПервыйСвободныйАртикул > Число(Код) Тогда
Возврат "000" + Формат(ВыборкаДетальныеЗаписи.ПервыйСвободныйАртикул,"ЧГ=0");
Иначе
Возврат Код;
КонецЕсли;
КонецЕсли;
КонецФункции
(15) В 10 написал: "Есть нумератор. Его и используйте. Только номер надо не в код справочника сувать, а отдельным реквизитом. А какой код у справочника будет не важно."
Рассматривали такой вариант? Что бы при одновременном создании элементов уникальность номера сама платформа 1С отслеживала.
(16) Такой вариант не рассматривался из-за того что основная цель для чего создавалась нумерация это выгрузка в стороннюю систему где соответсвие по коду сотрудника, если добавлю нумератор, нужно как то с системой решить вопрос как идентифицировать уже созданные и переданные данные. Нужно будет присваивать текущий код? А как потом будет работать нумератор, не очень представляю.