При слиянии нескольких БД в одну, имеется ситуация когда некоторым справочникам желательно присваивать код по собственному алгоритму, так как автоматическая нумерация не подходит, нам неизвестно какие коды и с какими префиксами уже существуют в БД.
Принцип следующий: дополняем строку кода с изъятым префиксом до двойной длины, что бы исключить "пропавшие" нули(для них то и используется неудобная функция вычисления длины конкретного кода), выравнивая до длины кода, что то типа функции Прав("0*(ДлинаКода+ДлинаПрефикса)"+Сред(Код,ДлинаПрефикса),ДлинаКода) можно использовать любой символ вместо "0", но так проще потом собирать код, в этом случае сортировка по убыванию поднимет максимальное значение кода в первую позицию.
Вот функция которую можно применять независимо:
// Возвращает максимальный код справочника с заданным префиксом или без него,
// использовать для справочников с типом кода "строка"
// Параметры
// ВидСправочника - имя справочника как оно задано в конфигурации
// Префикс - префикс, который вы хотите использовать(например префикс организации), "0" - без префикса
Функция МаксимальныйКод(ВидСправочника,Префикс = "0")
Мета = Метаданные.Справочники.Найти(ВидСправочника);
ДлинаКода = Мета.ДлинаКода;
ДлинаПрефикса = СтрДлина(Префикс);
// можно использовать функцию одДополнитьСтроку в обработке КонвертацияОбъектовИнформационныхБаз
Дополнение = СтроковыеФункцииКлиентСервер.ДополнитьСтроку("0", ДлинаПрефикса + ДлинаКода - 1,"0");
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("ДлинаКода",ДлинаКода);
Запрос.УстановитьПараметр("Дополнение",Дополнение);
Запрос.УстановитьПараметр("Префикс",Префикс);
Запрос.УстановитьПараметр("ДлинаПрефикса",ДлинаПрефикса);
Запрос.Текст = "
|ВЫБРАТЬ ПЕРВЫЕ 1
| ПОДСТРОКА(&Дополнение + ПОДСТРОКА(Контрагенты.Код,&ДлинаПрефикса+1,&ДлинаКода), ВЫБОР";
// определение длины строки кода, ВЫБОР начался чуть раньше перед циклом, КОНЕЦ будет чуть позже после цикла
Для Инд = 1 По ДлинаКода Цикл
Запрос.Текст = Запрос.Текст + "
| КОГДА Контрагенты.Код = ПОДСТРОКА(Контрагенты.Код, 1," + Инд + ")
| ТОГДА " + Инд;
КонецЦикла;
Запрос.Текст = Запрос.Текст + "
| КОНЕЦ, &ДлинаКода) КАК Код
|ИЗ
| Справочник.Контрагенты КАК Контрагенты
|ГДЕ
| ПОДСТРОКА(Контрагенты.Код, 1, &ДлинаПрефикса) = &Префикс
|
|УПОРЯДОЧИТЬ ПО
| Код УБЫВ";
Запрос.Текст = СтрЗаменить(Запрос.Текст,"Контрагенты",ВидСправочника);
Результат = Запрос.Выполнить();
Если Результат = Неопределено Тогда
Результат = СтроковыеФункцииКлиентСервер.ДополнитьСтроку("1", ДлинаКода,"0");
Иначе
Результат = СтроковыеФункцииКлиентСервер.ДополнитьСтроку(Число(Результат.Выгрузить()[0].Код) + 1, ДлинаКода,"0");
КонецЕсли;
Результат = Префикс + Сред(Результат,ДлинаПрефикса + 1);
Возврат Результат;
КонецФункции // МаксимальныйКод()
Конечно не очень красивая функция определения длины строки в запросе, но наворачивать для этого СКД (там есть такая функция) не вижу смысла, длины кодов в конфигурациях не очень велики.
Приведена функция, чтоб ее можно было использовать в любом месте
Например:
Процедура СформироватьКод()
// Для другого справочника поменять ВидСправочника на имя вашего справочника, как оно задано в конфигураторе
ВидСправочника = "Контрагенты";
Префикс = Организация.Префикс;
Код = МаксимальныйКод(ВидСправочника,Префикс);
КонецПроцедуры
Однако для конвертации, требуется следующее:
Просто в требуемом месте (ОбъектыУчета/Справочники/Контрагенты) вставить код программы тела функции без оператора "Возврат" и явно задав значения ВидСправочника и Префикс и дополнить строкой - Объект.Код = Результат; , в закладке событий - после загрузки
или же, если функция используется в разных местах выполнить:
- Открыть, конвертацию (Бухгалтерский учет для Украины(293) -> Бухгалтерия для Украины 1.8.1)
- Перейти к правилам конвертации
- Открыть закладку Алгоритмы/Запросы
- Создать новый алгоритм
- Назвать его "МаксимальныйКод"
- Установить параметры - ВидСправочника,Префикс = "0"
- В окно алгоритма вставить код функции без строк Функция.. и КонецФункции
- В требуемом месте (ОбъектыУчета/Справочники/Контрагенты) вызывать эту функцию в закладке событий - после загрузки (Объект.Код = МаксимальныйКод("Контрагенты"))
В скобках указаны примеры, некоторые этапы показаны на скриншотах.
В моем случае данный алгоритм понадобился при слиянии нескольких БД Бухгалтерия 7.7 в одну БД Бухгалтерия 8.2, при работе с одинаковыми товарами но разными контрагентами и складами, общие контрагенты и склады обрабатывались по другим правилам.