Помощь - Поиск - Пользователи - Календарь
Полная версия: Сквозная нумерация элементов нескольких справочников.
1C-PRO - Форум по 1С > Форумы по платформе "1С:Предприятие 8.x" > (8.х) Конфигурирование на платформе "1С:Предприятие 8.x"
Пользователь 1С
cowboy.gif
Есть два справочника "Частные лица" и "Организации".
Одним словом - "Корреспонденты".
Хочу чтобы каждый корреспондент имел собственный уникальный номер.
Как это сделать? aua.gif

В один справочник объединять разные типы корреспондентов не хочу. excl.gif
То, что можно использовать "счётчик", это и ежу понятно...
Как добиться ГАРАНТИРОВАННОЙ УНИКАЛЬНОСТИ при многопользовательской работе? rtfm.gif
Подскажите... cry_1.gif





Пользователь 1С
aua.gif

Написал вот такую функцию:

Функция УникальныйКодЧастныхЛицИОрганизаций() Экспорт
Запрос = Новый Запрос("
|ВЫБРАТЬ ЕСТЬNULL(МАКСИМУМ(Корреспонденты.Код),0) КАК Код
|ИЗ
| (ВЫБРАТЬ МАКСИМУМ(Справочник.спрЧастныеЛица.Код) КАК Код
| ОБЪЕДИНИТЬ
| ВЫБРАТЬ МАКСИМУМ(Справочник.спрОрганизации.Код))
|КАК Корреспонденты");
МаксимальныйНомер = Запрос.Выполнить().Выгрузить()[0].Код;
Возврат (МаксимальныйНомер + 1);
КонецФункции

При тестировании она иногда вызывает конфликт блокировок - проверено. mad.gif
Stack_G
Я бы сделал так:
создаем новый документ "НомерКорреспондента" (хотя можно и справочник)
При создании элемента того или иного справочника ("Частные лица" или "Организации") создаешь новый документ (Элемент справочника) "НомерКорреспондента"... и присваиваем его номер (код) коду нашего нового элемента...
Таким образом уникальность 100% будет обеспечена уникальностью номера документа (кода справочника) "НомерКорреспондента".
имхо
Пользователь 1С
Спасибо Stack_G!
Честно говоря, я так раньше и сделал...
Завёл справочник "СчётчикКорреспондентов", каждый раз когда создавался настоящий корреспондент, я создавал новый объект в справочнике счётчик и код этого объекта присваивал новому корреспонденту. Более того, чтобы не засорять базу, я сразу же удалял все накопившиеся объекты из справочника "СчётчикКорреспондентов" кроме только что созданного. И это - работает!!! Работает хорошо!!!

Просто я относительно недавно занялся программированием в 1С. И этот подход мне показался "любительским", не серьёзным, во всяком случае - не очень красивым (возможно ошибаюсь, лучшего способа пока нет!). И я стал искать более профессиональный подход. Такие дела...

Всё-равно СПАСИБО! clap1.gif
Stack_G
подобным образом реализуется функциональность присвоения номера договору контрагента - созданием документа, там можно учесть и префикс организации....
Не знаю, может есть и способ получше... но этот точно обеспечивает уникальность.
Пользователь 1С
Решил остановиться на таком варианте:

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

Каждый отдельный счётчик будет представлен в этом справочнике отдельным предопределённым элементом.

Чтобы прочитать значение нужного счётчика, обращаюсь к предопределённому элементу по коду и считываю значение его реквизита "ПорядковыйНомер" используя вот эту функцию, где ИмяСправочника - имя, моего единственного справочника "спрСчетчики" (вдруг, будет ещё один подобный справочник счётчиков, хотя вряд ли) , а Код - код предопределённого элемента (код счётчика из которого буду читать "ПорядковыйНомер");

Функция ПолучитьСчётчик(ИмяСправочника, Код) Экспорт
ИмяСправочника = "Справочник." + ИмяСправочника;

Запрос = Новый Запрос("ВЫБРАТЬ " + ИмяСправочника + ".Ссылка
|ГДЕ
| " + ИмяСправочника + ".Код = &Код
|ДЛЯ ИЗМЕНЕНИЯ
| " + ИмяСправочника);
Запрос.УстановитьПараметр("Код", Код);

Счётчик = Запрос.Выполнить().Выгрузить()[0].Ссылка.ПолучитьОбъект();

НовыйПорядковыйНомер = (Счётчик.ПорядковыйНомер + 1);
Счётчик.ПорядковыйНомер = НовыйПорядковыйНомер;

Счётчик.Записать();

Возврат НовыйПорядковыйНомер;
КонецФункции


Цепляю вызов функции в модуле объекта:

Процедура ПриУстановкеНовогоКода(СтандартнаяОбработка, Префикс)
СтандартнаяОбработка = Ложь;
ЭтотОбъект.Код = омСправочники.ПолучитьСчётчик("спрСчётчики", 1);
КонецПроцедуры

Использую файловый вариант базы данных.
Тестировал два дня... параллельно записывал значения в разные справочники из 6-10 отдельных подключений и каждый, в цикле, одновременно записывали по 5000 новых объектов - счётчик всегда оставался уникальным.

В функции сознательно не использовал вызов НачатьТранзакцию() т.к. она увеличивает (в этом случае) количество исключительных ситуаций связанных с взаимными блокировками - если один пользователь получал код более 20сек. у остальных выскакивает сообщение об ошибке. Убрал "НачатьТранзакцию()" всё стало нормально. Уникальность кода сохраняется, даже как-то, параллельность работы пользователей улучшилась. Ещё проверю конечно...

Можно было бы и константы использовать, но как-то не захотелось. Смущает конструкция "ДЛЯ ИЗМЕНЕНИЯ".

Короче, если у кого есть лучше предложения... (или здоровая критика всех выше изложенных) sample.gif


cool.gif

MaxxaM
ИМХО Записывать номер надо при записи а не при открытии , так как иначе ты можешь получить пропуски в нумерации будет где то так 1 контр ; 2 физ лицо; 4 контр; 6 контр и т.д. cowboy.gif
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.
Русская версия Invision Power Board © 2001-2009 Invision Power Services, Inc.