Имя: Пароль:
1C
1С v8
Генерация уникального числа
,
0 avlav
 
24.08.12
06:55
Добрый день.
Нужна идея, как сгенерировать уникальное 5-ти значное число в пределах дня. Сейчас работает регистр сведений (счетчик), жуткие тормоза и проблема с параллельностью работы.
Полученное значение нужно для обмена документами со спец. оборудованием.

Всю голову уже сломал, придумал генерацию из секунды в дне и номера сеанса пользователя, но числа получаются очень большие.
52 Ursus maritimus
 
24.08.12
09:00
(0) Случайное число от уникального отличаешь?
Новый УникальныйИдентификатор() используй
53 avlav
 
24.08.12
09:01
(52) Отличаю, с легкостью. Смотри ограничение - 5 цифр
54 acsent
 
24.08.12
09:04
чем гуид то не подошел?
55 avlav
 
24.08.12
09:06
Там как бэ число больше получается, цифр 15
56 H A D G E H O G s
 
24.08.12
09:08
(55) И что?
57 vde69
 
24.08.12
09:09
сложный но быстрый вариант решения

1. делается РС где хранятся ВСЕ уже использованые номера
2. делается регистр для текущего разделения по диапазонам между сеансами
 измерения ID_Сеанса, реквизиты стартовый_номер, ФинишныйНомер
2. делается параметр сеанса

при начале сеанса
1. блокируем регистр 2 (что-бы нельзя было получить уже занятый планируемый диапазон)
2. получаем список сеансов, по этому списку из регистра 2 получаем список занятых диапазонов, джойним его с регистром 1 и находим свободный диапазон
3. записываем свободный диапазон в регистр 2 и сохраняем параметры в параметр сеанса

при необходимости получения номера тупо инкремируем нижнюю границу лежащую в параметре сеанса и для фиксации - пишем в регист 1

если сеансов много - можно немного оптимизировать процесс выделения диапазона

плюсы - скорость, медленные операции выполняются при инициализации сеанса
минусы - резерв номеров
58 Sserj
 
24.08.12
09:09
Чего то я не понял, если нужно просто уникальное в дне, зачем регистры?
Просто константа и увеличивать ее на 1
59 avlav
 
24.08.12
09:14
(56)->(0) 5 цифр надо
60 Cube
 
24.08.12
09:15
Мой вариант:

   ГСЧ = Новый ГенераторСлучайныхЧисел();
   СлучайноеЧисло = (ТекущаяДата() - НачалоДня(ТекущаяДата())) + ГСЧ.СлучайноеЧисло(0, 9999);


В обработке со следующим кодом:

   МассивЧисел = Новый Массив;
   КоличествоЧисел = 0;
   ВремяНачала = ТекущаяДата();
   
   ГСЧ = Новый ГенераторСлучайныхЧисел();
   СлучайноеЧисло = (ТекущаяДата() - НачалоДня(ТекущаяДата())) + ГСЧ.СлучайноеЧисло(0, 9999);
   
   Пока МассивЧисел.Найти(СлучайноеЧисло) = Неопределено Цикл
       ОбработкаПрерыванияПользователя();
       МассивЧисел.Добавить(СлучайноеЧисло);
       КоличествоЧисел = КоличествоЧисел + 1;
       СлучайноеЧисло = (ТекущаяДата() - НачалоДня(ТекущаяДата())) + ГСЧ.СлучайноеЧисло(0, 9999);
   КонецЦикла;
   
   Сообщить("За " + (ТекущаяДата() - ВремяНачала) + " сек. выбрано " + КоличествоЧисел + " уничальных пятизначных чисел.");


Получаем результат (кнопку нажимал активно, раза 3 в секунду):

За 0 сек. выбрано 63 уничальных пятизначных чисел.
За 0 сек. выбрано 148 уничальных пятизначных чисел.
За 0 сек. выбрано 64 уничальных пятизначных чисел.
За 0 сек. выбрано 132 уничальных пятизначных чисел.
За 0 сек. выбрано 178 уничальных пятизначных чисел.
За 0 сек. выбрано 88 уничальных пятизначных чисел.
За 0 сек. выбрано 94 уничальных пятизначных чисел.
За 0 сек. выбрано 125 уничальных пятизначных чисел.
За 0 сек. выбрано 127 уничальных пятизначных чисел.
За 0 сек. выбрано 85 уничальных пятизначных чисел.
За 0 сек. выбрано 85 уничальных пятизначных чисел.
За 0 сек. выбрано 103 уничальных пятизначных чисел.
За 0 сек. выбрано 109 уничальных пятизначных чисел.
За 0 сек. выбрано 154 уничальных пятизначных чисел.
За 0 сек. выбрано 115 уничальных пятизначных чисел.
За 0 сек. выбрано 205 уничальных пятизначных чисел.
За 0 сек. выбрано 92 уничальных пятизначных чисел.
За 0 сек. выбрано 71 уничальных пятизначных чисел.
За 0 сек. выбрано 214 уничальных пятизначных чисел.
За 0 сек. выбрано 22 уничальных пятизначных чисел.
За 0 сек. выбрано 157 уничальных пятизначных чисел.
За 0 сек. выбрано 116 уничальных пятизначных чисел.
За 0 сек. выбрано 107 уничальных пятизначных чисел.
За 0 сек. выбрано 194 уничальных пятизначных чисел.
За 0 сек. выбрано 255 уничальных пятизначных чисел.
За 0 сек. выбрано 25 уничальных пятизначных чисел.
За 0 сек. выбрано 111 уничальных пятизначных чисел.
За 0 сек. выбрано 77 уничальных пятизначных чисел.
За 0 сек. выбрано 73 уничальных пятизначных чисел.
За 0 сек. выбрано 251 уничальных пятизначных чисел.
За 0 сек. выбрано 292 уничальных пятизначных чисел.
За 0 сек. выбрано 89 уничальных пятизначных чисел.
За 0 сек. выбрано 215 уничальных пятизначных чисел.
За 0 сек. выбрано 70 уничальных пятизначных чисел.
За 0 сек. выбрано 223 уничальных пятизначных чисел.
За 0 сек. выбрано 18 уничальных пятизначных чисел.
За 0 сек. выбрано 64 уничальных пятизначных чисел.
За 0 сек. выбрано 70 уничальных пятизначных чисел.
За 0 сек. выбрано 192 уничальных пятизначных чисел.
За 0 сек. выбрано 91 уничальных пятизначных чисел.
За 0 сек. выбрано 134 уничальных пятизначных чисел.
За 0 сек. выбрано 115 уничальных пятизначных чисел.
За 0 сек. выбрано 124 уничальных пятизначных чисел.
За 0 сек. выбрано 44 уничальных пятизначных чисел.
За 0 сек. выбрано 90 уничальных пятизначных чисел.
За 0 сек. выбрано 181 уничальных пятизначных чисел.
За 0 сек. выбрано 66 уничальных пятизначных чисел.
За 0 сек. выбрано 42 уничальных пятизначных чисел.
За 0 сек. выбрано 31 уничальных пятизначных чисел.
За 0 сек. выбрано 176 уничальных пятизначных чисел.
За 0 сек. выбрано 74 уничальных пятизначных чисел.
За 0 сек. выбрано 104 уничальных пятизначных чисел.
За 0 сек. выбрано 101 уничальных пятизначных чисел.
За 0 сек. выбрано 108 уничальных пятизначных чисел.
За 0 сек. выбрано 113 уничальных пятизначных чисел.
За 0 сек. выбрано 90 уничальных пятизначных чисел.
За 0 сек. выбрано 84 уничальных пятизначных чисел.
За 0 сек. выбрано 99 уничальных пятизначных чисел.
За 0 сек. выбрано 163 уничальных пятизначных чисел.
За 0 сек. выбрано 119 уничальных пятизначных чисел.
За 0 сек. выбрано 88 уничальных пятизначных чисел.
За 0 сек. выбрано 167 уничальных пятизначных чисел.
За 0 сек. выбрано 94 уничальных пятизначных чисел.
За 0 сек. выбрано 164 уничальных пятизначных чисел.
За 0 сек. выбрано 106 уничальных пятизначных чисел.
За 0 сек. выбрано 107 уничальных пятизначных чисел.
За 0 сек. выбрано 38 уничальных пятизначных чисел.
За 0 сек. выбрано 194 уничальных пятизначных чисел.
За 0 сек. выбрано 143 уничальных пятизначных чисел.
За 0 сек. выбрано 180 уничальных пятизначных чисел.
За 0 сек. выбрано 179 уничальных пятизначных чисел.
За 0 сек. выбрано 52 уничальных пятизначных чисел.
За 0 сек. выбрано 43 уничальных пятизначных чисел.
За 0 сек. выбрано 136 уничальных пятизначных чисел.
За 0 сек. выбрано 167 уничальных пятизначных чисел.
За 0 сек. выбрано 230 уничальных пятизначных чисел.
За 0 сек. выбрано 118 уничальных пятизначных чисел.
За 0 сек. выбрано 34 уничальных пятизначных чисел.
За 0 сек. выбрано 123 уничальных пятизначных чисел.
За 0 сек. выбрано 11 уничальных пятизначных чисел.
За 0 сек. выбрано 189 уничальных пятизначных чисел.
За 0 сек. выбрано 66 уничальных пятизначных чисел.

Как видно, самое маленькое значение - 18 уникальных значений в секунду.
Код можно и модернизировать, добиваясь большей уникальности, но идея, я думаю всем понятна.
61 avlav
 
24.08.12
09:16
(60) Нет гарантированной уникальности.
62 sTOd
 
24.08.12
09:17
(42) Стопудово будет! Уже проверено.
63 Sserj
 
24.08.12
09:18
Ну так скажите мне пожалуйста, почему просто константа не подходит, обнуляющаяся в полночь???
64 Cube
 
24.08.12
09:18
(61) У тебя при любом раскладе, даже если ты будешь ГУИДы использовать, не будет 100% гарантии. Есть допустимая вероятность, отсюда и надо плясать.
65 avlav
 
24.08.12
09:19
(48), (57) Похоже, что ничего другого не остается, разделителем диапазонов будет Пользователь (спр. Пользователи). Единственный минус, исключительная блокировка на всю таблицу, когда диапазон у пользователя заканчивается.
66 jenny_tea
 
24.08.12
09:20
я бы сделала 2 константы: 1 дата, 2 число

Если НачалоДня(ТекущаяДата())<>Константа.ДатаДня.Получить() Тогда
  Константа.ДатаДня.Установить(НачалоДня(ТекущаяДата()));
  УникальноеЧисло = 10000;
Иначе
  УникальноеЧисло = Константа.УникальноеЧисло.Получить()+1;
конецесли;
Константа.УникальноеЧисло.Установить(УникальноеЧисло);
67 avlav
 
24.08.12
09:21
(64) Я ГУИДы не собирался использовать, нужна 100 % уникальность. см (42)
68 avlav
 
24.08.12
09:21
(66) Константы нельзя, при записи заблокируются все константы.
69 jenny_tea
 
24.08.12
09:23
Тогда РС, и брать срез последних
70 MSII
 
24.08.12
09:25
(69) все варианты, предполагающие работу с таблицами БД - медленные
71 avlav
 
24.08.12
09:25
(43) Ок, ограничение на колво обменов - 5ти значное
72 avlav
 
24.08.12
09:26
(70) Согласен, потому и задал вопрос (0) как уйти от запись в  БД.
73 MSII
 
24.08.12
09:27
(67) Кстати, не думал считать номер секунды не от начала реального дня, а от начала "условного рабочего дня"? Высвобождаются 2 бита.
74 avlav
 
24.08.12
09:27
(73) Номер секунды в чистом виде не походит, и еще, нужна уникальность в пределах дня, поэтому считать от начала дня - нормально
75 Cube
 
24.08.12
09:28
(67) Тогда смотри (10) + регистр сведений в который пишется время последнего обмена, а при обмене проверку: если текущее время совпадает с временем последнего обмена, то подождать секунду.
76 avlav
 
24.08.12
09:28
(73) Про высвобождению 2-х бит не понял
77 avlav
 
24.08.12
09:29
(75) А как работает нумерация сообщений, полагаю там тот же регистр сведений (условно) от которого я хочу уйти
78 Cube
 
24.08.12
09:30
(77) Ты про (13) что ли? Нет, там своя таблица.
79 avlav
 
24.08.12
09:31
(78) Таблица своя, но принцип тот же. Я ж написал - условно в скобках
80 Cube
 
24.08.12
09:31
(76) Наверное, он имеет ввиду, что если считать секунды не от 00:00:00, а от 08:00:00, то освобождается 28800 значений (8*60*60).
81 Cube
 
24.08.12
09:33
(0) Ладно, задам главный вопрос - зачем тебе это надо?)) В смысле, опиши всю картину, как это число применяешь потом?
82 avlav
 
24.08.12
09:33
(80) Понятно.
83 Ursus maritimus
 
24.08.12
09:33
Сдается мне, что (0) где-то 3,14здит. 5значное число предполагает не более 100 тыс. записей в регистре сведений в сутки (В СУТКИ!!!!). При этом автор умудряется получить какие-то бешеные тормоза??? Может в руках проблема?
84 avlav
 
24.08.12
09:36
см (42) Пользователь вносит док-т Обращение пациента, в документ записывается уникальный в дне номер. По этому номеру происходит обмен с медицинским оборудованием.
85 Cube
 
24.08.12
09:37
(84) Капец, приехали... А чем тебе номер документа не угодил?
86 Ursus maritimus
 
24.08.12
09:38
(85)+100500
87 avlav
 
24.08.12
09:38
(83) Может и в руках, вот код, не знаю как тут правильно вставлять:
ПередЗаписью

//Проверки

Менеджер=РегистрСведений.Нумератор.ПолучитьМенеджерЗаписи();
Менеджер.Период = Дата;
Менеджер.Прочитать()

ТекНомер=Менеджер.Номер+1;
Менеджер.Номер=ТекНомер;
Менеджер.Период=Дата;
Менеджер.Записать()
КонецПроцедуры
88 Sserj
 
24.08.12
09:39
(84) Что то мне сдается обмен с медицинским оборудованием никак не чиселками производится а битами, а там поле для полета фантазии безгранично и использовать можно не 10-ричную систему :)
89 avlav
 
24.08.12
09:39
(87) ЦУП показывает ожидание блокировок на строке Менеджер.Прочитать() - доходит до 25 секунд. Большая интенсивность ввода документов
90 avlav
 
24.08.12
09:40
(85) В БД несколько организаций, нумерация в каждой своя.
91 Ursus maritimus
 
24.08.12
09:40
Судя по (84) и (87). В (83) я был прав...
92 avlav
 
24.08.12
09:40
(88) На входе оборудование хавает xml
93 Ursus maritimus
 
24.08.12
09:41
(90) И Что?
94 Sserj
 
24.08.12
09:43
(87) а зачем тебе переодический регистр? Если история видимо нафик не нужна, зачем ее хранить в регистре и тем самым увеличивать расчеты?
95 Cube
 
24.08.12
09:43
(90) Да ё маё! В документ добавь реквизит, тип - число 5 символов. При присвоении документу нового номера (подписка на событие) присваивай реквизиту следующее по текущему дню значение. При выгрузке используй этот реквизит.
96 avlav
 
24.08.12
09:44
(95) Счас именно так и работает, как предлагаешь получить следующее значение?
97 Cube
 
24.08.12
09:45
(90) К тому же, каждой организации можно присвоить номер и добавлять его в качестве префикса к номеру документа...
98 Cube
 
24.08.12
09:45
(96) Запросом. Не нужно никаких регистров.
И сейчас совсем не так работает, не звизди :)
99 Ursus maritimus
 
24.08.12
09:45
(95) НАХЕРА??
(90) Поставить в соответсвие буквенному префиксу число И ВСЕ
АА=1
АБ=2

АА001 = 1001
АБ001 = 2001
АБ002 = 2002
100 Cube
 
24.08.12
09:47
(99) Опоздал)) См. (97).
Сотка!
101 avlav
 
24.08.12
09:47
Номер документа - строка, длина 10 символов, нумерация уникальная в пределах года.
102 qeos
 
24.08.12
09:47
а если просто константу завести и инкрементировать просто?
103 Ursus maritimus
 
24.08.12
09:48
(100) Не. Ты предлагаешь менять префикс в номере документа, а я нет.
104 avlav
 
24.08.12
09:48
Номер документа - строка, длина 10 символов, нумерация в пределах года.
105 Reset
 
24.08.12
09:48
А чем не подходит поле код в справочнике?
106 Ursus maritimus
 
24.08.12
09:49
(101) И че? Поставь 5 символов и в пределах дня.
107 Reset
 
24.08.12
09:49
*или номер документа с периодичностью день
108 Ursus maritimus
 
24.08.12
09:49
(106)+Вернее 5 символов можно не ставить
109 Cube
 
24.08.12
09:49
(101) Нумерацию можно и в пределах дня настроить, если что... Но и без этого можно обойтись, если в год документов меньше, чем 9999.
110 Reset
 
24.08.12
09:50
Автор изобретает велосипед какойто имхо
111 Ненавижу 1С
 
гуру
24.08.12
09:50
внешним запросом выбирать значение последовательности (SEQUENCE) в какой нибудь СУБД
112 Cube
 
24.08.12
09:50
(103) Я предлагаю заменять префикс. То же самое, что и ты предложил :)
113 Ursus maritimus
 
24.08.12
09:50
(110) Причем крайне кривоопый
114 Ursus maritimus
 
24.08.12
09:51
(112) возьми пирожок
115 avlav
 
24.08.12
09:51
(111) Те же грабли с блокировкой таблицы
116 Reset
 
24.08.12
09:53
(115) Какие еще грабли?
117 Ненавижу 1С
 
гуру
24.08.12
09:53
(115) там ничего не блокируется, именно для этого SEQUENCE и были придуманы
118 LobS
 
24.08.12
09:53
(0) Как работает генератор случайных чисел
http://habrahabr.ru/post/128666/#habracut
119 Reset
 
24.08.12
09:54
Игра в угадайку. Понравится автору/не понравится
120 avlav
 
24.08.12
09:54
(119) Ты о чем?
121 avlav
 
24.08.12
09:57
(117) Можно потестировать, только я не понимаю, как записи могут не блокироваться и при этом соблюдается уникальность
122 Cube
 
24.08.12
09:58
(101) Вот ещё вариант, примерно такой же, как и (95):
Номер документа делай 5 символов в пределах дня (тип число) и добавляй реквизит "Номер документа" длиной 10 символов (тип строка). При записи документа делай номер документа (наш новый реквизит) по принципу:
ПрефиксОрганизации + ДеньГода(НашДокумент.Дата) + НашДокумент.Номер.
123 Ненавижу 1С
 
гуру
24.08.12
09:59
(121) конечно блокируется в общем-то, но вне транзакций, в своей маленькой транзакции
именно поэтому последовательности гарантируют уникальность, но не гарантируют пропущенных номеров
124 avlav
 
24.08.12
10:03
(122) Нумерация док-тов внутри каждой организации должна быть своя по идеологическим соображениям
125 Reset
 
24.08.12
10:05
(120)
(110) -> (105) -> (107)
126 Cube
 
24.08.12
10:06
(124) Ну сделай номер документа 8 символов, три из которых префикс организации, уговорил...
127 avlav
 
24.08.12
10:08
(107)->(124), (105)- Уникальность в дне нужна. (110) - других вариантов не вижу
128 avlav
 
24.08.12
10:09
(126) Даже не думал уговаривать.
129 Reset
 
24.08.12
10:09
(127) Это никак не исключает возможностей как того, так и другого
130 Reset
 
24.08.12
10:11
(127) Двадцать раз уже сказали, что документ может нумероваться в предалах дня. Спрвочник может быть подчиненным и можно иметь сколь угодно параллельную нумерацию в пределах владельцев.
131 avlav
 
24.08.12
10:12
Двадцать раз уже ответил, что нумерация документов уникальна в каждой организации.
132 Reset
 
24.08.12
10:13
(131) 21 раз пояснили, что для разный организаций придумали префиксы
133 avlav
 
24.08.12
10:14
(132) И?
134 avlav
 
24.08.12
10:14
Попробуй на листочке пронумеровать два столбика от 1 до 10 - получишь уникальность?
135 Cube
 
24.08.12
10:16
(133) Ты что такой упоротый? Тебе уже 130 сообщений говорят, что не нужно тебе ничего, кроме номера документа... Если уникальность будет без учета организаций, то в разрезе организаций точно будет всё уникально...
136 Reset
 
24.08.12
10:16
(134) Я тебя не понимаю. Ладно, здесь есть более терпеливые, может поймут что тебе надо
137 Cube
 
24.08.12
10:16
(126) Этого делать нельзя, кстати. Я поторопился.
138 avlav
 
24.08.12
10:17
(135) см. (124) Нумерация док-тов внутри орг. должна быть СВОЯ, по идеологическим соображениям.
139 Cube
 
24.08.12
10:18
(138) Что значит СВОЯ? По порядку? Че за бред... Не счет-фактуры же нумеруешь...
140 avlav
 
24.08.12
10:20
(139) Ты с Заказчиками также разговариваешь? Ну вот уперся он, грит внутри организации должна быть своя непрерывная нумерация. Я ж не буду говорить ему, что он лох.
141 Cube
 
24.08.12
10:25
(140) Самый производительный для тебя вариант это либо (95), либо (122). Принцип я объяснил. Тебе осталось его понять и подпилить под свою задачу. Можно сделать так, что и волки сыты будут и овцы целы, но ты этого пока не понимаешь, т.к. уперся...
142 Reset
 
24.08.12
10:28
(140) Ты не заказчик, ты пришел помощи просить
143 avlav
 
24.08.12
10:45
Всем спасибо за помощь!
Резюмирую: нормальный вариант, предложен в (48),(57). (123) - тут повышаются затраты на подключение к внешней СУБД, можно потестить скорость работы, если приемлема, тоже вариант.
Вариант (122) имеет место быть, при условии отсутствия необходимости сплошной нумерации доков внутри организации.
Закрываю ветку.
144 Ursus maritimus
 
24.08.12
10:47
Лол. А потом приходится за ними это гуано разгребать...
145 Cube
 
24.08.12
10:49
(143) С вариантом (122), как и с вариантом (95) можно иметь непрерывную нумерацию в разрезе организаций, ващета...
146 Torquader
 
26.08.12
01:38
когда мне нужен был уникальный номер в многопроцессорной системе-мне пришлось создавать файлы с номерами,и пока происходила ошибка создания-номер был занят-при больших номерах,конечно,существовала задержка,но вместо создания можно было просто прочитать директорию,чтобы отсеить заведомо занятые.
147 mistеr
 
26.08.12
02:30
(84) Механизм нумерации есть в платформе, и работает он эффективно, без блокировок "до 25 секунд". В этом топике же его неумело пытаются изобрести заново.

У тебя, как я понял, проблема в том, что док. Обращение пациента имеет свою нумерацию для разных организаций. А оборудование у них одно на всех, и обмены с ним также должны регистрироваться и нумероваться, уникально в пределах дня. Что отсюда следует? Сущность "обмен", или "анализ", или что там у вас, нужно выделить в отдельный документ. Настроить ему нумерацию в пределах дня, без префикса организации. В доке Обращение пациента вместо номера ссылку на док. Анализ. При программном его создании получаем уникальный номер.
148 КонецЦикла
 
26.08.12
04:39
Ужос, 200 постов обсуждать ЭТО
Переходите на 8.3 штоле, там уж точно все реализовано :)
149 Torquader
 
26.08.12
20:45
(147) Оно работает эффективно, если не пытаются в несколько десятков процессов создавать документы пачками.
Вообще-то, в нормальных SQL-серверах есть такое понятие, как генератор, которое специально для этого придумано, чтобы независимо от транзакций или параллельности выполнения выдавать уникальные значения на каждый вызов.
И ситуация сильно зависит от того, сколько номеров нужно нагенерить - если это нумерация обращения пациента в устройство, то стандартная нумерация 1С вполне справится, если же нумерация нужна для передаваемых в устройство пакетов, а передаваться они будут несколько сот штук в секунду, то можно очень даже сильно подвесить 1С.
150 mistеr
 
27.08.12
01:03
(149) >в несколько десятков процессов создавать документы пачками

Никогда еще не встречал реальную необходимость в подобном. В нише 1С естественно.
151 МишКа
 
27.08.12
01:32
(0) ЭтаФорма.УникальныйИдентификатор чем не устраивает?
Оптимист верит, что мы живем в лучшем из миров. Пессимист боится, что так оно и есть.