Вход | Регистрация
 
1С:Предприятие :: 1С:Предприятие 8 общая

Найти первый свободный артикул

Найти первый свободный артикул
Я
   sergqwert
 
13.08.21 - 13:41
Есть стандартный справочник номенклатуры, у которого есть реквизит – числовой артикул.
В справочнике большое количество элементов. Некоторые могут удаляться. Как найти первый свободный артикул (либо все незанятые артикулы). То число, которое не принадлежит ни одному из элементов справочника. Перебор использовать нельзя.
   ДенисЧ
 
1 - 13.08.21 - 13:42
   DrShad
 
2 - 13.08.21 - 13:43
собери в запросе таблицу чисел, потом соедини со своим справочником, где будет NULL там и свободно, выбрать минимум
   fisher
 
3 - 13.08.21 - 13:46
Если для целей "заполнения дырок" (т.е. реализации собственной нумерации без пропусков) - нужно вести учет дырок.
Если просто странная алгоритмическая задача, то можно проверять "куски" диапазонов с половинным делением - если количество элементов в куске "стыкуется" с первым и последним номером, значит в этом диапазоне дырок нет.
   Classic
 
4 - 13.08.21 - 13:50
ВЫБРАТЬ
    0 КАК Артикул
ПОМЕСТИТЬ Артикулы
ОБЪЕДИНИТЬ ВСЕ
ВЫБРАТЬ 
    СправочникНоменклатура.Артикул
ИЗ Справочник.Номенклатура КАК СправочникНоменклатура
;
ВЫБРАТЬ
    МИНИМУМ(Артикулы.Артикул) + 1
ИЗ Артикулы КАК Артикулы
   ЛЕВОЕ СОЕДИНЕНИЕ Артикулы КАК Артикулы.Следующий
   ПО Артикулы.Артикул + 1 = АртикулыСледующий.Артикул
ГДЕ
   АртикулыСледующий.Артикул ЕСТЬ NULL
   H A D G E H O G s
 
5 - 13.08.21 - 13:56
(4) У вас - перебор. Использовать нельзя, см (0)
   Kassern
 
6 - 13.08.21 - 13:57
(0) тестовое задание?
   Kassern
 
8 - 13.08.21 - 14:02
(0) посмотрите как в типовых новый ШК присваивается
   Garykom
 
9 - 13.08.21 - 14:03
(0) засунь в ТЗ и отсортируй, далее один проход
   серый КТУЛХУ
 
10 - 13.08.21 - 14:04
половинное деление с определением наличия дырок в интервале по не равенству дельты кон.артикула минус нач.артикула + 1 от количества значений в интервале.
   Classic
 
11 - 13.08.21 - 14:04
(5)
Артикул = СлучайноеЧисло();
Если ЗначениеЗаполнено(Справочник.Номенклатура.НайтиПоРеквизиту("Артикул", СлучайноеЧисло)) Тогда
    Сообщить("Объекты базы заблокированы бухгалтерией. Попробуйте еще раз позже");
КонецЕсли;

Так пойдет?
   Garykom
 
12 - 13.08.21 - 14:05
(10) не сильно лучше полного перебора
   серый КТУЛХУ
 
13 - 13.08.21 - 14:05
(10)+: конечно по отсортированной по возрастанию артикула выборке.
(12): в два раза лучше - это "сильно лучше"
   Garykom
 
14 - 13.08.21 - 14:07
(13) в два раза это идеальная нач ситуация
на практике на условиях и обращениях с вычислениями потеряешь больше чем банальный цикл со сравнением пар
   Garykom
 
15 - 13.08.21 - 14:08
и метод половинного хреново параллелится
в отличие от совмещения сортировки с определением интервалов
   серый КТУЛХУ
 
16 - 13.08.21 - 14:08
(14): нет, не идеальная.
   Classic
 
17 - 13.08.21 - 14:10
(15)
Половинное хреново параллелится?
   серый КТУЛХУ
 
18 - 13.08.21 - 14:10
(15): схреновли он "храново параллелится".
храново параллелится он у тех кто хреново параллетит. два потока - сразу четверное деление и ускорение по сравнению с перебором в 4 раза. четыре потока - ускорение по сравнению с перебором в 16 раз.
   Serg_1960
 
19 - 13.08.21 - 14:15
(0) Спасибо за интересный вопрос :)
    Запрос = Новый Запрос;
    Запрос.Текст =
    "ВЫБРАТЬ ПЕРВЫЕ 999999
    |    ВсеАртикулы.Артикул КАК Артикул,
    |    АВТОНОМЕРЗАПИСИ() КАК Номер
    |ПОМЕСТИТЬ ВТ
    |ИЗ
    |    Справочник.Номенклатура КАК ВсеАртикулы
    |ГДЕ
    |    ВсеАртикулы.Артикул <> 0
    |
    |УПОРЯДОЧИТЬ ПО
    |    Артикул
    |;
    |
    ////////////////////////////////////////////////////////////////////////////////

    |ВЫБРАТЬ ПЕРВЫЕ 1
    |    НеЗанятые.Номер КАК СвободныйНомер
    |ИЗ
    |    ВТ КАК НеЗанятые
    |ГДЕ
    |    НеЗанятые.Артикул <> НеЗанятые.Номер
    |
    |УПОРЯДОЧИТЬ ПО
    |    СвободныйНомер";
   Kassern
 
20 - 13.08.21 - 14:17
(19) артикул с кодом 1000000, ну да пошел я на*ер=))
   Serg_1960
 
21 - 13.08.21 - 14:20
(20) Добавь девяток столько, сколько длина артикула. Разрешаю.
   PLUT
 
22 - 13.08.21 - 14:22
(0) Артикул - тип Строка (50)  в ERP
   Garykom
 
23 - 13.08.21 - 14:23
(17) (18) распишите алгоритм распараллеливания половинного
   Kassern
 
24 - 13.08.21 - 14:26
(21) насколько мне известно, максимум вы сможете выбрать 1410065407. А артикул это 99% у ТС строка скорее всего длинной в 50символов.
   mistеr
 
25 - 13.08.21 - 14:35
(0) Как ни крути, а на уровне скуля все равно будет перебор. Препода, задавшего задачу, на мыло!

(24) Сказано же, число.
   Garykom
 
26 - 13.08.21 - 14:37
(25) именно перебор
   Kassern
 
27 - 13.08.21 - 14:37
(25) читайте внимательно: (0) "стандартный справочник номенклатуры, у которого есть реквизит – числовой артикул"
Насколько я понял, это значит, что в строковое поле Артикул стандартного справочника номенклатуры записывается число. Пример артикул "123456", полностью подходит под описание ТС
   Kassern
 
28 - 13.08.21 - 14:38
(27) в общем, как то двояко воспринимается его текст. Лучше бы написал, реквизит с типом таким то.
   Serg_1960
 
29 - 13.08.21 - 14:42
Это всего лишь игры разума :)
   серый КТУЛХУ
 
30 - 13.08.21 - 14:51
(23): ты идиот? (18) по слогам перечитай. немного подумай.
в каждом потоке - получение интервала, проверка на наличие в нем "дырки":
есть дырка - делим на количество "свободных" потоков (включая себя) и раздаем
нет дырки - отбрасываем интервал и переходим в статус "свободного".
на пальцах. 4 параллельных потока вычислений. начальный интервал 1-80 дырка в последнем проверяемом (пессимистический случай, полный перебор = 80 тактов)
1 такт.
1-й поток - получил интервал 1-20 проверил - дырок нет - освободился.
2-й поток - получил интервал 21-40 проверил - дырка есть - разделил на 4 интервала для раздачи...
3-й поток - получил интервал 41-60 проверил - дырок нет - освободился.
4-й поток - получил интервал 61-80 проверил - дырок нет - освободился.
2 такт.
1-й поток - получил интервал 21-25 проверил - дырок нет - освободился.
2-й поток - получил интервал 26-30 проверил - дырка есть - разделил на 4 интервала для раздачи...
3-й поток - получил интервал 31-35 проверил - дырок нет - освободился.
4-й поток - получил интервал 36-40 проверил - дырок нет - освободился.
3 такт - финиш. однозначное определение дырки.
3 такта (или пусть даже 5 при затрате на каждую раздачу по такту) а не 80 для перебора - при пессимистическом исходе.
 
 
   серый КТУЛХУ
 
31 - 13.08.21 - 14:54
если неймется - можно попробовать сыграть на четырех сеансах и одном регистре сведений.
   Garykom
 
32 - 13.08.21 - 14:54
(30) >проверка на наличие в нем "дырки"

каким образом выполняется?
   серый КТУЛХУ
 
33 - 13.08.21 - 14:56
(32): см.(10) "по не равенству дельты кон.артикула минус нач.артикула + 1 от количества значений в интервале."
(ты вообще читаешь на что отвечаешь и прямо к нему относящееся?)
   Garykom
 
34 - 13.08.21 - 14:57
(33) как найдется конечный и начальный артикулы в интервале?
с чего взял что у тебя артикулы отсортированы?
   серый КТУЛХУ
 
35 - 13.08.21 - 14:58
ЗЫ: вообщек надо Ваню Guk-а позвать - он и про это разжует и еще более оптимальных алгоритмов может быть отсыпет. с точным определением их сложности.
   Йохохо
 
39 - 13.08.21 - 15:15
(14) добавь проверку что свободные не макс +1, получишь ускорение на два порядка)
   Garykom
 
40 - 13.08.21 - 15:20
(39) тут есть всего два вида перебора

перебирать весь интервал (проверяя каждое число от 1 до N есть ли оно в артикулах в справочнике) и перебирать все занятые (артикулы из справочника, размещая/сортирую а затем проверяя попарно нет ли разрыва)

все

все методы прочие это вариации этих двух по совмещению
   nodrama
 
41 - 13.08.21 - 15:50
(0) Если Артикул числовой. Значит база не типовая. в типовых он вроде "строка" ))

Вообще артикулы так себе штука.. помню был интернет магаз большой. у них УТ была. Они покупали кууууеву тучу товаров у поставщиков
И что. один и тот де товар у разных поставщиков может быть с разными артикулами в прайсах.
один и тот же артикул у тебя в базе у разных поставщиков может использоваться в разных товаров

У тебя Отвертка артикул 123456
А у поставщика артикул 123456 это Шуруп а ты у этого поставщика покупаешь 10к+ позиций по прайсу каждый месяц.
Получается к артикулу привязываться уже нельзя при таких объемах и продажах и количестве поставщиков.

А в свой интернет магаз ты выгружаешь со своими артикулами те которые загрузились с прайсов ранее и были свободными. Либо у тебя будет два разных товара с одним артикулом что не верно

В общем Артикулы так себе реквизит
   nodrama
 
42 - 13.08.21 - 15:51
(41) И получается что бы загрузить этот шуруп из прайса с 10к позициями. тебе не нужно привязываться к артиклу что логично.
Только у тебя может быть точно такой же Шуруп только чуть другое название. СРазу нужно делать "Аналоги номенклатуры" в общем.. напомнили мне геморой ))
   Garykom
 
43 - 13.08.21 - 15:53
(41) думаю это внешние id фактически, которые просто а артикулах в конфе хранят
   Kassern
 
44 - 13.08.21 - 15:56
(41) вы не поверите, есть такой справочник, как НоменклатураКонтрагентов (раньше НоменклатураПоставщиков была). Вот он и юзается для таких задач
   МихаилМ
 
45 - 13.08.21 - 18:29
   Злопчинский
 
46 - 13.08.21 - 19:01
(3) "то можно проверять "куски" диапазонов с половинным делением"
- это вариант перебора, а перебор - нельзя
   Вафель
 
47 - 13.08.21 - 19:53
Для каждого найти следующий (а ля срез последних)
Если слнд не равен +1, тогда вот он свободный номер
   Garykom
 
48 - 13.08.21 - 19:55
(47) это самый дебильный вариант запроса в цикле перебора
   Вафель
 
49 - 13.08.21 - 20:34
(48) в каком цикле?
   Вафель
 
50 - 13.08.21 - 20:35
Там не перебор, мердж скорее всего будет
   Йохохо
 
51 - 13.08.21 - 20:39
вариант Сердж_1960 через ИМЕЮЩИЕ не будет иметь цикла даже в трансляции скуля
   Йохохо
 
52 - 13.08.21 - 20:42
хотя цикла фор там все равно будет минимум 4)
   DJ Anthon
 
53 - 13.08.21 - 20:45
(8) берется последнее в каждом поддиапазоне, там не поиск дырок
   Кирпич
 
54 - 13.08.21 - 21:13
(0)Ну так можно. Выбрать начала всех дырок
ВЫБРАТЬ
   А.Код + 1
   ИЗ Справочник.Товары КАК А
   ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Товары КАК Б 
        ПО А.Код = Б.Код - 1
   ГДЕ Б.Код - 1 IS NULL;

   ДедМорроз
 
55 - 14.08.21 - 12:17
Только выбрать первые 1 и упорядочить по коду,чтобы скуль не шарил всю таблицу.
   ДедМорроз
 
56 - 14.08.21 - 12:19
Печаль этого действа в том,что если дырок нет,то будет полное сканирование всец таблицы,точнее индекса,нл все равно это долго.
   mistеr
 
57 - 14.08.21 - 16:00
(56) Другими словами, будет перебор.
   Garykom
 
58 - 14.08.21 - 16:17
(57) Задаче без перебора решается только если при удалении артикула (очистка/изменение реквизита у элемента справочника или удаление элемента) писать его в РС свободных
   серый КТУЛХУ
 
59 - 14.08.21 - 17:42
с терминологией сначала определиться бы. а то в интертрепации некоторых оппонентов реребором можно назвать любой выбор элементов, более одного: аааа, выбрал второй элемент - перебооорррр...
ну или бинарный поиск (например) - не перебор. ))))
   Garykom
 
60 - 14.08.21 - 17:51
(59) чтобы индекс построить сначала нужен полный перебор
 
 
   MyNick
 
61 - 14.08.21 - 18:12
(0) в рег сведений писать дырки, при занятости удалять
   MyNick
 
62 - 14.08.21 - 18:14
+ (61) работать будет одинаково эффективно хоть на тыще записей, хоть на миллионе. В отличие от всяких переборов и прочих вангований.
   Кирпич
 
63 - 14.08.21 - 18:54
Так без перебора не получится никак. Это невозможно сделать без перебора. Только если создавать специальный индекс.
   Aleksey
 
64 - 14.08.21 - 18:57
А зачем артикул, который не уникален?
   Кирпич
 
65 - 14.08.21 - 19:21
(64) Да это просто задачка наверное
   Lexandr
 
66 - 14.08.21 - 19:34
(63) Ну или добавить в базу новый объект с помощью которого будет искаться нужный артикул за одно обращение. Если задача синтетическая, то можно добавлять окружение, как вот прям захочется.
   VS-1976
 
67 - 14.08.21 - 20:48
Что бы сократить ресурсы на поиск теоретически можно сделать так:

Вызывать в цикле запрос отбирая окнами артикула, пока не найдёшь разрыв. К примеру по 100-500 артикулов за раз.
Ну а потом в этом диапазоне вытащив на клиент, уже можно найти разрыв.

ВЫБРАТЬ
    1 КАК Группа,
    Истина КАК ЕстьРазрывы
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Артикул МЕЖДУ &НачАртикул И &КонАртикул

СГРУППИРОВАТЬ ПО
    1
ИМЕЮЩИЕ
    КОЛИЧЕСТВО( Артикул ) < &КоличествоАртикулов// КонАртикул - НачАртикул
   VS-1976
 
68 - 14.08.21 - 20:50
(67) После нахождения свободного артикула, можно куда нибудь записывать его значение, чтобы в последующем стартовать от него + 1
   VS-1976
 
69 - 14.08.21 - 20:51
(68) Хотя если освободиться может любой... то пожалуй нет
   VS-1976
 
70 - 14.08.21 - 20:56
(67) Так красивее немного

оЗапрос = Новый Запрос( "ВЫБРАТЬ
    Истина КАК ЕстьРазрывы
ИЗ
    Справочник.Номенклатура КАК Номенклатура
ГДЕ
    Артикул МЕЖДУ &НачАртикул И &КонАртикул

СГРУППИРОВАТЬ ПО
    1
ИМЕЮЩИЕ
    КОЛИЧЕСТВО( Артикул ) < &КоличествоАртикулов" );

...

Если Не оЗапрос.Выполнить().Пустой() Тогда

    // Выбираем диапазон и ищем на клиенте разрыв или с помощью запроса, предложенного ранее с +1 к артикулу.


КонецЕсли;
   Garykom
 
71 - 14.08.21 - 21:24
Странные люди, не понимающие что никакие запросы кроме как получения всех артикулов тут не нужны
Затем берется "массив" (в кавычках потому что на 1С массивы не совсем они и лучше что то иное) длиной в максимальный артикул, изначально заполненный 0
И тупо туда пишутся 1 по адресам = артикулам

Далее останется только пробежаться по "массиву" и вот пустые артикулы где 0 остался
   Кирпич
 
72 - 14.08.21 - 22:00
(71) Бухаешь?
   Garykom
 
73 - 14.08.21 - 22:07
(72) мне бухать здоровье не позволяет
остается только флудить и троллить на форумах
   Вафель
 
74 - 14.08.21 - 22:08
(71) уж лучше делением пополам
   VS-1976
 
75 - 14.08.21 - 22:13
(71) Думаю проще как у меня сделать, окнами вынимать данные. Если артикулов много то I/O будет большой. А так как мой запрос не пересоздаётся, а подкидываются свежие параметры, то и запрос отрабатывает быстро, так как не нужен парсинг запроса и построение плана исполнения, тупо выбираются только данные. Далее данные которые уже в кэше ( последнее окно ) быстро вытаскиваются на свет, при их анализе.
   VS-1976
 
76 - 14.08.21 - 22:15
(75) К примеру артикулов миллион, если брать окна по 1000 то будет 1000 запросов. Количество окон можно регулировать. К примеру хотим максимум 100 запросов, тогда 1 000 000 / 100 - окно = 10 000 артикулов
   VS-1976
 
77 - 14.08.21 - 22:19
(76) К стати МАКСИМУМ( Артикул ) отрабатывает мгновенно, так как это упорядоченный "массив" - есть индекс. И таблица в шапке содержит ссылку на последний элемент, для последующей вставки в таблицу
   Garykom
 
78 - 14.08.21 - 22:21
(74) Не поможет тут никакое деление кроме как на потоки
   Garykom
 
79 - 14.08.21 - 22:23
(76) а сообразить что все эти запросы будут к одной табличке?

(77) индекса на поле Артикул может не быть, он может быть строковым в этом случае какой в жпо максимум?
   VS-1976
 
80 - 14.08.21 - 22:26
(79) Читай заголовок:
Есть стандартный справочник номенклатуры, у которого есть реквизит – числовой артикул.
У номенклатуры артикул в индексе, так как поиск по артикулу - "Будь готов, всегда готов"

И что, что запросы к одной таблице? Даже индекс читается кусками )

PS: Зачем фантазировать то?
   Garykom
 
81 - 14.08.21 - 22:28
(80) артикул то числовой а вот реквизит не факт
   Garykom
 
82 - 14.08.21 - 22:29
(81)+ Логично что если это типовая конфа то там Артикул по дефолту строка, просто они туда id пишут числовые
   VS-1976
 
83 - 14.08.21 - 22:31
(82) Число, строка какая для бинарного сравнения разница ). Это для тебя строка, а для процессора поток битов )
   Garykom
 
84 - 14.08.21 - 22:31
(80) И насчет запросов.
Самое быстро это один запрос который полные данные выдаст а не куча кусочных одновременно
И далее полученные обрабатываем по (71)

Вот я готов на поспорить что мой метод самый быстрый чем ваши с кучей запросов, на одинаковом железе и базе
   Garykom
 
85 - 14.08.21 - 22:31
(83) ыыы
   Garykom
 
86 - 14.08.21 - 22:32
меня иногда удивляет как люди с подобным незнанием основ умудряются работать да еще и зарплату получать
   VS-1976
 
87 - 14.08.21 - 22:33
(84) Как бы всё зависит от количества и от того, как часто в "окнах" появляются пробелы
   VS-1976
 
88 - 14.08.21 - 22:34
(86) Хотя бы приводил про кого речь ведёшь, а то я тоже могу абстрактно пукать не хуже )
   Garykom
 
89 - 14.08.21 - 22:48
(88) >Число, строка какая для бинарного сравнения разница ). Это для тебя строка, а для процессора поток битов

процессоры давным-давно уже не битами оперируют а большими объемами
обработка чисел, строк, дат, булевых, ссылочных и т.д. отличается
в случае строк переменной длины (тип varchar) особенно
   VS-1976
 
90 - 14.08.21 - 22:58
(89) Да ладно, честно что ли ), 64-ре бит, да не ужели... ты открыл истину для человека, который писал на assembler-е
   Garykom
 
91 - 14.08.21 - 23:03
(90) ничего страшного что забыл это просто возрастное, попей ривастигмин или аналоги
но пора уже программирование и ИТ бросать, да
   VS-1976
 
92 - 14.08.21 - 23:05
(90) Скажи а SSE позволяет параллельно обрабатывать 8 байт без переноса знака в старший разряд для мультимедиа, это же куруть! Прикинь сложение и т.д. сразу 8-ми чисел, я не говорю о сопроцессоре i87. Ты мой бог, присылай фото, рамку для иконы я уже вытачиваю )
   VS-1976
 
93 - 14.08.21 - 23:06
(91) Хоре курить, понимаю что не пьёшь, но дурь тоже не полезна )
   Garykom
 
94 - 14.08.21 - 23:09
(92) ты уже сам с собой разговариваешь? у себя спрашиваешь?
   VS-1976
 
95 - 14.08.21 - 23:11
(94) Да мне то что с тобой разговаривать то ). Смысл? Ты как бы капитан очевидность, но непонятно как это относится к конкретной задаче? Я понимаю что выкуривая штакетник тянет на абстракции )
   ДедМорроз
 
96 - 15.08.21 - 08:28
Индекс по артикулу строится в процессе работы,так как по нему идет поиск.
Поиск свободного - это,по сути,перебор,то есть полное сканирование индекса.
Таблица индекса - это артикул и кластерный инндекс записи таблицы - для справочника - это уникальный идентификатор.
То есть,перебор индекса не требует перебора записей,а индекс явно занимает меньше места в страницах.
Однако,операция все равно ресурсоемкая.
Поэтому,в реальности,проще хранить где-то свободные артикулы.

Но,если у пользователя на форме есть кнопка СвободныйАртикул,то время его поиска будет не критично,т.к.открытие и заполнение формы руками - это долго,и подьзователь ничего не заметит.

Если же пакетно идет добавление записей и нужны свободные артикулы,то проще одним запросом ввбрать их все,которые меньше максимального и из подготовленной таблицы уже доставать в процессе заполнения.
Но,тут нужно помнить про синхронизацию
Свободный артикул свободен,пока не создана запись с ним,поэтому несколько одновременных процессов получат один и тот же список свободных артикулов - это очень важно понимать,т.к.в процесс поиска и лбработки нужно будет добавить синхронизацию,чтобы один поток,получив артикул,мог его записать в базу,не боясь,что его кто-то другой запишет раньше него.
В 1с номера документов работают примерно так,но там есть таблица занятых номеров,хотя,номер присваивается при записи.


Список тем форума
 
ВНИМАНИЕ! Если вы потеряли окно ввода сообщения, нажмите Ctrl-F5 или Ctrl-R или кнопку "Обновить" в браузере.