Имя: Пароль:
1C
1С v8
Программная установка номеров УТ 10.3 ☑
0 unknown181538
 
21.02.18
✎
00:18
Пользователи сбили нумерацию. Чтобы не переименовывать, решили сделать программную установку номеров, которая игнорировала бы неправильные номера.
В модуле объекта дописал процедуру установки номера:

Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    
    ГодДаты = Год(Дата);
    Если ГодДаты <> 2018 Тогда
        Возврат;
    КонецЕсли;
    
    Запрос = Новый Запрос;
    Запрос.Текст =
        "ВЫБРАТЬ ПЕРВЫЕ 1
        |    РеализацияТоваровУслуг.Номер КАК Номер
        |ИЗ
        |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |ГДЕ
        |    НАЧАЛОПЕРИОДА(РеализацияТоваровУслуг.Дата, ГОД) = &НачалоГода
        |    И НЕ ПОДСТРОКА(РеализацияТоваровУслуг.Номер, 7, 2) = ""43""
        |    И НЕ ПОДСТРОКА(РеализацияТоваровУслуг.Номер, 7, 2) = ""44""
        |
        |ДЛЯ ИЗМЕНЕНИЯ
        |
        |УПОРЯДОЧИТЬ ПО
        |    Номер УБЫВ";
    
    Запрос.УстановитьПараметр("НачалоГода", НачалоГода(Дата));
    
    РезультатЗапроса = Запрос.Выполнить();
    
    Выборка = РезультатЗапроса.Выбрать();
    
    Если Выборка.Следующий() Тогда
        ЧислоМаксНомер = Число(Выборка.Номер);
        НужноеЧисло = ЧислоМаксНомер + 1;
        Номер = Прав("0000000000000"+Формат(НужноеЧисло,"ЧГ="),11);
        СтандартнаяОбработка = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Контроль уникальности номеров включен, и даже иногда выдает ошибки. Но тем не менее, периодически возникает задвоение номеров.
Как удается записаться в базу документам с одинаковыми нумерами, и что с этим сделать можно?
1 youalex
 
21.02.18
✎
00:20
обмен?
2 unknown181538
 
21.02.18
✎
00:32
(1) нету. Создаются вручную, когда время близкое. т.е. как-то почти одновременно.
Была проблема, когда номер присваивался, но документы не записывался из-за ошибки заполнения. Но я сделал, чтобы номер заново присваивался в этом случае.
Даже сделал доп проверку в "ПриЗаписи", но все равно задвоения возникают изредка.
3 Джексон
 
21.02.18
✎
00:45
Режим блокировок какой?
Ну и периодичность нумерации и контроль уникальности.
4 unknown181538
 
21.02.18
✎
00:48
(3)Автоматический, в пределах года, автонумерация = истина, контроль уникальности = истина. Все стандартно в этом плане для ут10.3
5 Джексон
 
21.02.18
✎
00:55
(4) А установка нового номера у тебя всегда в неявной транзакции?
6 Джексон
 
21.02.18
✎
00:56
Наложи вручную, я порядок событий навскидку не помню
7 unknown181538
 
21.02.18
✎
02:42
(5) оно в предопределенной процедуре... казалось бы, должно быть в транзакции. Возможно, надо проверить это.
(6) А как тут вручную наложить? на что?
8 unknown181538
 
21.02.18
✎
04:29
(6) v8: Как установить новый номер документа с префиксом из этого обсуждения следует, что внутри транзакции все происходит.
9 Soul771
 
21.02.18
✎
06:00
(0) - помню, было что-то такое в Далионе.. к сожалению, нет сейчас базы посмотреть, забылось...
В УТ 10.3 + БИТ CRM8 была немного другая задача (для разных видов документов сделать по разным алгоритмам),  но тоже косяки с нумерацией до этого случались, сейчас вот такой код, наверняка, не самое грамотное решение, но работает...
Писала в процедуру ПередЗаписью модуля формы документа, в конец.

Если ЭтоНовый() Тогда
        
                
        тГод  = Прав(Год(Дата),2);
        тМес  = Месяц(Дата);
        
        если стрДлина(тмес)<2 тогда
            тМес = "0"+тМес;
        КонецЕсли;
        
        тДень = День(Дата);
        
        если стрДлина(тДень)<2 тогда
            тДень = "0"+тДень;
        КонецЕсли;

        
        Если НЕ ЗначениеЗаполнено(Документы.ЗаказПокупателя.НайтиПоНомеру("ТКЗ"+тГод+тМес+тДень+"01",Дата)) Тогда
            ЭтотОбъект.Номер = "ТКЗ"+тГод+тМес+тДень+"01";
        иначе
            
            Запрос = Новый Запрос;
            Запрос.Текст =
            "ВЫБРАТЬ
            |    МАКСИМУМ(ЗаказПокупателя.Номер) КАК Номер,
            |    ЗаказПокупателя.Организация
            |ИЗ
            |    Документ.ЗаказПокупателя КАК ЗаказПокупателя
            |ГДЕ
            |    ЗаказПокупателя.Дата МЕЖДУ &дата1 И &дата2
            |
            |СГРУППИРОВАТЬ ПО
            |    ЗаказПокупателя.Организация";
            
            
            Запрос.УстановитьПараметр("дата1", НачалоДня(ЭтотОбъект.Дата));
            Запрос.УстановитьПараметр("дата2", КонецДня(ЭтотОбъект.Дата));
            
            
            
            РезультатЗапроса = Запрос.Выполнить();
            
            ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
            
            Если  ВыборкаДетальныеЗаписи.Количество()>0 тогда
                Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
                    максНом = ВыборкаДетальныеЗаписи.Номер;
                    хвост =Число(Прав(максНом,2))+1;
                    если хвост<10 тогда
                        хвост= "0"+строка(хвост);
                        ЭтотОбъект.Номер=Лев(ВыборкаДетальныеЗаписи.Номер,9) +хвост;
                    КонецЕсли;
                    
                КонецЦикла;
            иначе
                ЭтотОбъект.Номер = "ТКЗ"+тГод+тМес+тДень+"01";
            КонецЕсли;
            
                    
        КонецЕсли;
    иначе
        ЭтотОбъект.Номер =Номер;
    конецЕсли;
    
    
    Если День(ЭтотОбъект.Дата)<>День(ТекущаяДата()) тогда
     ЭтотОбъект.ДополнениеКАдресуДоставки = "Данный документ был создан\изменен "+ТекущаяДата() +" "+ ЭтотОбъект.ДополнениеКАдресуДоставки;
    КонецЕсли;
10 Джексон
 
21.02.18
✎
06:55
(8) Оно работает при записи нового, а никак не при перезаписи исправленного существуюшего. Короче. Отставляя в стороне вопрос о проскакивании платформенного контроля уникальносьи пока. Переноси свой запрос и присваивание исправленного номера в призаписи. Там у тебя и транзакция для блокировки будет и возможность переприсвоить исправленный номер... И свой текущий документ из запроса выбросить не забудь
11 unknown181538
 
22.02.18
✎
04:05
(10) а зачем при перезаписи существующего? К тому же, как я буду из "ПриЗаписи" узнавать, нужен ли новый номер или нет? Если стандартнаяОбработка при присвоении номер ложь будет, то номер не присвоится, и он не запишется просто, как я понимаю
Разве что если это поможет с транзакцией? Логичнее тогда уж в ПередЗаписью()...
12 Сияющий в темноте
 
22.02.18
✎
09:31
Перед записью нет транзакции,если мы меняем свой номер,то кио тоо параллельно может поставить такой же,и потом транзакция записи уже отработает на двух документах,и будет два одинаковых номера
13 unknown181538
 
22.02.18
✎
16:27
(12) Мне кажется, ты ошибаешься.
http://catalog.mista.ru/public/153748/
вот описание. ПередЗаписью() модуля объекта уже в транзации, так же, как и присвоение номера.
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший