Работало через поиск Макс. значения в Регистре сведений и записи туда нового значения.
В принципе данный функционал можно использовать для создания уникальныхзначений.
Решение созрело такое:
1. Создается табличка прямо в БД 1С вида:
(для MS SQL Server)
CREATE TABLE [dbo].[zbarcodes](
[ID] [bigint] IDENTITY([НАЧАЛЬНОЕЗНАЧЕНИЕСЧЕТЧИКА],1) NOT NULL,
CONSTRAINT [PK_zbarcodes] PRIMARY KEY CLUSTERED
(
[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
[НАЧАЛЬНОЕЗНАЧЕНИЕСЧЕТЧИКА] — заменить на число, например 20000000000 — первый шк в системе (или другое число — последнее в Вашей учетной системе, если хочется продолжить текущую нумерацию)
2. Создаем Процедурку в общем модуле с выполнением на сервере (для УФ)
//Процедура получения уникального штрихкода (у нас используется Code 128 — без контрольных символов)
//Параметры:
//Организация — можно сделать таблицы на каждую организацию — и получать по организации имя таблицы в БД из ЗначенияСвойствОбъектов
//СтруктураПараметров — параметры подключения к БД SQL через ADO
Функция ПолучитьНовыйШтрихкод(Организация, СтруктураПараметров) Экспорт
Соединение= Новый COMObject(«ADODB.Connection»);
Соединение.ConnectionString = «Driver={SQL Server};Server=» + СокрЛП(СтруктураПараметров.Сервер)
+ «;UID=» + СокрЛП(СтруктураПараметров.Логин)
+ «;pwd=» + СокрЛП(СтруктураПараметров.Пароль)
+ «;Database=» + СокрЛП(СтруктураПараметров.БД);
Соединение.ConnectionTimeOut = 40;
Соединение.CommandTimeout = 0;
Соединение.CursorLocation = 3;
Попытка
Соединение.Open();
Исключение
#Если Клиент Тогда
Сообщить(«Возникла ошибка подключения к базе»);
#КонецЕсли
Соединение=»»;
Возврат Неопределено;
КонецПопытки;
ТекстЗапроса=»INSERT into zbarcodes DEFAULT VALUES»;
Соединение.Execute(ТекстЗапроса);
ТекстЗапроса=»SELECT @@IDENTITY»;
Выборка=Соединение.Execute(ТекстЗапроса);
НовыйШтрихкод=Выборка.Fields(0).Value;
Выборка.Close();
Выборка =»»
Соединение = «»;
Возврат НовыйШтрихкод;
КонецФункции
В итоге все забыли что такое блокировки при присвоении новых штрихкодов, и обеспечена уникальность штрихкода, + скорость получения значения!
Так можно вообще не заморачиваться с базой данных и т.п.
ага, только ручками очень тяжко потом это всё набирать в случае отказа сканера ШК
(2) serferian,
Если интересует без тормозов, то лучше создать массив уникальных значений а потом лишь их использовать. Не думаю что регистр сведений для этого лучшая реализация. Ведь требуется всего 3 поля, 1 — ID, 2 — значение, 3 — уже используется. Если вам подойдет на таблице SQL, то можете создать такую таблицу, заполнить ее значениями от 1 до 1000 000 000 и пользоваться ими.
(3) pvase, обычно штрих-коды генерируют с целью записи в базу, так что тут только какая-то структура в ОЗУ на вкус разработчика (проиндексированная ТаблицаЗначений, Структура, соответствие. А вот при инициализации этого механизна и при окончании работы лучше всего ХранилищеЗначения. Ну еще может что-то быть для сохранения промежуточных результатов работы в базе.
(3) pvase,
Не согласен что так лучше. Все-таки Identity — 100% уникальность, а галочки используется и прочее — это во первых поиск «без галочки», а во-вторых блокировки «на запись данного значения»! Да и цифры «чисто теоретически» могут закончится)))
(4) kostyaomsk,
С константой вариант тоже не прошел — по причине блокировок! Пробовали!
С Кэшем интересно будет попробовать.
Про уникальность по методу
с дальнейшей любой обработкой даже незначительно снижающей разрядность полученного числа.
Я представлял задачу по-другому:
1. Где-то сидят 20 операторов (по всему городу и набивают номенклатуру, а заодно и штрихкоды
2. В 1С из различных источников загружается что-попало из номенклатуры и все это надо «пометить» штрихкодами
3. Комбинация 1 и 2 + еще все что угодно + уже вышедшая из употребления (продажи, обработки) номенклатура
Причем, в длинных штрихкодах (не EAN13) нужно и тип товара проклассифицировать (весовой, штучный) и кучу «префиксов» предусмотреть (код региона, магазина, оператора). Еще и дополнительные штрих-коды могут быть для отличия своего товара от чужого (при попытке недобросовестного покупателя вернуть товар).
Причем, еще требование на сквозную нумерацию в пределах региона-магазина-оператора (было такое в практике по учету основных средств холдинга в консолидированной отчетности).
Это что касается «пометки».
А вот чтение должно осуществляться максимально быстро. Для этого по ночам регламентные задания должны перезаписывать блоками в порядке возрастания нужные штрихкода, и обновлять индексы для поиска по регионам-магазинам как для аппаратуры POS-терминала, так и для консолидированного товарного отчета.
Такой вот гипотетический пример, который все в себя включает.
Для поиска тут только оптимизированный запрос на SQL сервер. А вот для модификации: перед записью на компьютере «оператора штрихкодов» уже должны в ОЗУ быть прочитаны и его часть сложной структуры данных к которой должен быть доступ без блокировок с возможностью записи, т.к. тут предусмотрена нумерация в пределах сегмента.
Иначе как-то так:
Показать
От задачи зависит.
Задумка хороша. Вижу явное ограничение в следующем.
Запись идет во внешний источник данных.
Использование транзакции для сохранение целостности данных между 1с(таблицами sql связанные с 1с) и sql(независимая таблица от 1с) невозможно. При получении штрихкода
НовыйШтрихкод=Выборка.Fields(0).Value
транзакция в сиквел завершена, транзакция в 1с(если была начата) не завершена.
При аварийном завершении программы(возможны разные причины) счетчик будет увеличен только в сиквел.
Если задача по сквозной нумерации не стоит то задача решена на 5)).
(9) danila_inf,
При аварийных завершениях 1С — просто получаем пропуск данного ШК.
Идея использования сервера SQL опять не по назначению (или сначала не по назначению для поиска максимального значения во внутренней таблице соответствующей на низком уровне регистру сведений 1С 8 путем вставки новой строки и последующего автоинкремента +1
Насчет скорости исполнения вопрос:
И везде (раз подняли тему блокировок) SQL сервер атакую со всех сторон из 1С данная функция, каждый раз: создание COM-объекта, логин, пароль, авторизация, максимальный таймаут? А еще у комовских объектов бывает метод Close() не срабатывает.
А если нужно массив сгенерировать штрихкодов и записать. Вот то, что запрос через Опять цикл вызова функции ПолучитьНовыйШтрихкод?
А еще вызов самого метода COM-объекта? Для получения одного-единственного значения.
Мы в свое время использовали запросы 1С в SQL-серверном варианте вида:
Показать
Если нужно записать за раз много данных, то получим последнее максимальное значение в нужной группе, а дальше генерация кодом таблицы значений для записи (примитивный алгоритм +1 с преобразованиями в строку) и дальше блокировка регистра и запись опять через 1С.
А в Вашем алгоритме получается полное отсутствие блокировок в момент записи строки что плюс, но вот сразу идет запись в базу нового штрихкода самим SQL-сервером. А если произойдет ошибка уже дальше в коде. Запрос то в транзакции записи и тот и другой уже отработал?
Или потом блок
. Как сработает пропуск штрихкода?
(9) danila_inf, более точно по-научному написал суть проблем. Хотелось бы узнать, можно ли как то усовершенствовать алгоритм чтоб, допустим сом-процесс был один и уже пусть на него идут запросы со всех сторон. Вернее будет хоть какая-то очередь транзакций со стороны 1С.
Вот нашел в статьеСпускаемся в 1С 8.2 на уровень Базы Данных (Часть2) подробно про доступ посредством СУБД MS SQL Server, и в частности про оптимизацию подключения:
.
Мне кажется некорректным сравнение производительности между полноценным регистром сведений, который хранит явно больше информации с голой таблицей из цифр.
Регистр сведений:
-хранит еще ссылки на номенклатуру, характеристики, иногда серии. Плюс индексы по этому всему, которые ускоряют поиск, но замедляют запись (и, соответственно, блокировку)
-отлично работает с РИБ (да, у вас не получится с РИБ единой нумерации при одновременной работе пользователей в разных узлах, но сам обмен информацией работает на пять)
-Не стоит забывать о резервных копиях — сделав голую таблицу, вы добавили головной боли сисадмину — ему теперь все это нужно помнить и заодно делать бекап вместе с базой 1с. Опоздал на несколько минут — получай рассинхронизированную копию базы 1с и таблицы. А что делать, если нужно развернуть копию? Забыли про это — и она тоже будет увеличивать счетчик в таблице для боевой?
-В базе, возможно, куча подписок на события, сквозь которые тоже проходит выполнение при записи в этот регистр.
Наверно, для сравнения лучше подойдет объект попроще — константу, например, предлагали в комментариях. Или 1 элемент справочника — его блокировать, увеличивать реквизит на 1 и записывать.
Да и избыточная по времени блокировка как правило получается из-за того, что между получением значения и записью вставляют массу другой логики. Например, выбрали для изменения записи регистра, затем проводимся по кучи других регистров, масса проверок и вот в конце снимаем блокировку при фиксации транзакции. Так приближаем максимально чтение, запись и снятие блокировки — вот и нет их.
угу еще один недостаток — когда идет обмен РС полностью уходит в блокировку!!! и спрашивается — зачем оно нам?
(правда этот механизм нужен только в центральной базе!)
ну и выход для РИБ тоже есть через префиксы — их никто не отменял.
тут уж как настроите подключение к БД — если копия — то данные о БДSQL можно получать из настроек БД 1C
а копии однозначно и давно создаются при помощи SQL Backup. вряд ли я смогу 300Gb выгрузкой — загрузко данных копировать)) — так что табличка в ажуре и актуальна!
Константа отпала сразу на основе начала реальной работы!
(15) serferian, верно, поэтому я предлагаю использовать объект попроще, чем РС именно для задачи быстрого получения следующего номера. Пусть это будет 1 элемент справочника, в реквизите которого хранится последнее выданное число. Раз пропуски в номерах возможны => можно не связывать эту транзакцию с остальной логикой => читаем значение, делаем инкремент, записываем без пауз, а уже потом используем записанное значение. Я думаю, будет ненамного медленнее и особых блокировок не возникнет, зато все сделано средствами платформы и не добавляет мучений сисадминам, легко используется в остальных механизмах платформы.
Если вы хотите создавать таблицу внутри базы 1с — недостатков тоже порядочно: нарушаем лицензию 1с + конфигуратор легко может стереть нашу таблицу при загрузке.