Имя: Пароль:
1C
1С v8
Если "номер не ункален", тогда +1
0 citruss87
 
30.04.20
14:52
Доброго времени суток всем!
Давно читаю форум, но зарегаться решил только сегодня.
В общем давайте ближе к теме. Есть 1с БП 8.3, есть обработка которая разбивает указанную сумму на множество документов (реализаций) в заданном интервале даты и и диапазоне сумм документа и указания начального номера, который меняется таким образом: в один день создается 7 документов попорядку начиная от начального номера (х), далее пропускает 20 номеров, и уже на следующую дату продолжает создавать документы попорядку.
Суть вопроса следующая, обработка иногда останавливается с сообщением "Значение "префикс-номер" поля "номер" не уникально". Думаю можно дописать код проверки уникальности, т.е. какое-то условие типа: Если значение поля номер не уникально, тогда +1. Кто может помочь?
Ах да еще вопрос как выложить код сюда?
1 Fish
 
30.04.20
14:59
" как выложить код сюда?" - Скопировать и вставить в сообщение. Неожиданно, правда?
2 NorthWind
 
30.04.20
15:00
ну и в чем конкретно проблема? Обрабатываем исключение, добавляем номер. Для семерки делал когда-то в лохматых годах, работало.
3 Ray Zexter
 
30.04.20
15:00
Попытка
    Записать документ
Исключение
    Номер документа +1
    Записать документ
КонецПопытки;

Хотя не вижу смысл таких наворотов.
4 NorthWind
 
30.04.20
15:03
(3) если обработка создает множество документов и при этом такие же документы создаются человеками, то бывает что сбивается нумерация, соответственно, робат-ипопат должен как-то эту историю обойти
5 citruss87
 
30.04.20
15:09
(1) Спасибо, реально не ожиданно
(2) Я не программист 1с, в юнешестве программировал на бейсике и паскале, небольшой опыт программирования есть, обработку поправил под себя (мелочи всякие).
(3) Спасибо, может подскажите в какую часть кода надо это вставить?

Сам код генератора:

Процедура СформироватьНаСервере()
    КоличествоДней = (Объект.Дата2 - Объект.Дата1) / 60 / 60 / 24;
    СредняяСумма = Объект.min+(Объект.max-Объект.min)/2;
    КоличествоДокументов = Объект.Сумма/СредняяСумма;
    КоличествоДокументовДень = Объект.Сумма/КоличествоДней/СредняяСумма;
    флаг=1;
    ГрадиенСуммы=(Объект.max-Объект.min)/КоличествоДокументов+0.01;
    min=99999999999999;
    Пока флаг=1  Цикл
        ГрадиенСуммы=ГрадиенСуммы-0.01;
        СуммаДок=ОКР(Объект.max-ГрадиенСуммы,2);
        флаг=0;
        СчетчикСуммы=0;
        для сч=1 по 9999999999999 Цикл
            
            СуммаДок=ОКР(СуммаДок-ГрадиенСуммы,2);
            Если (СчетчикСуммы+СуммаДок>Объект.Сумма) или (СуммаДок>Объект.max) или (СуммаДок<Объект.min) тогда
                флаг=1;
                прервать;
            ИначеЕсли     (ОКР(СчетчикСуммы+СуммаДок,2)=Объект.Сумма) и (СуммаДок<=Объект.max) тогда
                флаг=2;
                прервать;
            КонецЕсли;
            
            СчетчикСуммы=ОКР(СчетчикСуммы+СуммаДок,2);
        КонецЦикла;    
        //Если флаг=1 тогда
        //    СуммаДок=Объект.Сумма-СчетчикСуммы;
        //КонецЕсли;    
        если СчетчикСуммы<>Объект.Сумма тогда
            флаг=1;
        КонецЕсли;    
        Если флаг=2 тогда
            прервать;
        КонецЕсли;    
        Если Объект.Сумма-СчетчикСуммы<min тогда
           min=Объект.Сумма-СчетчикСуммы;
           ГрадиенСуммыMIN=ГрадиенСуммы;
           Если min<(Объект.max-Объект.min)/2 тогда
                СуммаДок = СуммаДок+min;
                Прервать;
           КонецЕсли;      
       КонецЕсли;
   КонецЦикла;
  
   СуммаДок=ОКР(Объект.max-ГрадиенСуммыMIN,2);
   СчетчикСуммы=0;
   НомерДок=Объект.НачНом;
   //НомерДок=Формат(НомерДок1, "ЧГ=0");
   //Формат(НомерДок, "ЧГ=0");
   ДатаДок=Объект.Дата1;
   док=0;
   КоличествоДокументовДень=0;
  
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ОсновныеДоговорыКонтрагента.Договор КАК Договор
   |ИЗ
   |    РегистрСведений.ОсновныеДоговорыКонтрагента КАК ОсновныеДоговорыКонтрагента
   |ГДЕ
   |    ОсновныеДоговорыКонтрагента.Организация = &Организация
   |    И ОсновныеДоговорыКонтрагента.Контрагент = &Контрагент";
  
   Запрос.УстановитьПараметр("Контрагент", Объект.Контрагент);
   Запрос.УстановитьПараметр("Организация", Объект.Организация);
  
   РезультатЗапроса = Запрос.Выполнить();
  
   ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
  
   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
       Договор = ВыборкаДетальныеЗаписи.Договор;
   КонецЦикла;
  
  
   Запрос = Новый Запрос;
   Запрос.Текст =
   "ВЫБРАТЬ
   |    ДоговорыКонтрагентов.Ссылка КАК Договор
   |ИЗ
   |    Справочник.ДоговорыКонтрагентов КАК ДоговорыКонтрагентов
   |ГДЕ
   |    ДоговорыКонтрагентов.Владелец = &Контрагент
   |    И ДоговорыКонтрагентов.ВидДоговора = &ВидДоговора";
  
   Запрос.УстановитьПараметр("Контрагент", Справочники.Контрагенты.НайтиПоРеквизиту("ИНН",объект.Организация.ИНН));
   Запрос.УстановитьПараметр("ВидДоговора",  Перечисления.ВидыДоговоровКонтрагентов.СПоставщиком);
  
  
   РезультатЗапроса = Запрос.Выполнить();
  
   ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
  
   Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
       ДоговорСПоставщиком = ВыборкаДетальныеЗаписи.Договор;
   КонецЦикла;

  
  
   для  сч2=1 по сч-2 цикл
      
       Если НачалоДня(ДатаДок)<>НачалоДня(Объект.Дата2) тогда
           Если  КоличествоДокументовДень<7 тогда//ЦЕЛ((сч-1)/КоличествоДней)  тогда                    
               КоличествоДокументовДень = КоличествоДокументовДень+1;
           иначе
               ДатаДок=Дата(ДатаДок + 86400);
               КоличествоДокументовДень=1;
                НомерДок=номерДок+20;
                //номерДок=формат(номерДок, "ЧГ=0");
           КонецЕсли;
       КонецЕсли;
          
      
    СуммаДок=ОКР(СуммаДок-ГрадиенСуммыMIN,2);

    СчетчикСуммы=ОКР(СчетчикСуммы+СуммаДок,2);
    флаг=1;
    
    пока флаг=1 ЦИкл
        флаг = 0;
            Запрос = новый Запрос;
        Запрос.Текст =
        "ВЫБРАТЬ
        |    РеализацияТоваровУслуг.Ссылка КАК Ссылка
        |ИЗ
        |    Документ.РеализацияТоваровУслуг КАК РеализацияТоваровУслуг
        |ГДЕ
        |    РеализацияТоваровУслуг.Дата МЕЖДУ &НачГода И &КонГода
        |    И РеализацияТоваровУслуг.Номер = &НомерДок";
        
        Запрос.УстановитьПараметр("НомерДок", Строка(НомерДок));
        Запрос.УстановитьПараметр("НачГода", НачалоГода(Объект.Дата1));
        Запрос.УстановитьПараметр("КонГода", КонецГода(Объект.Дата2));
        
        РезультатЗапроса = Запрос.Выполнить();
        
        ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
        
        Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
            флаг=1;          
             НомерДок=НомерДок+1;
             //НомерДок=формат(НомерДок, "ЧГ=0");
            продолжить;
        КонецЦикла;    
        
    КонецЦикла;    
    
        
        Реализация=Документы.РеализацияТоваровУслуг.СоздатьДокумент();
        Если Объект.Номенклатура.ВидНоменклатуры.Услуга тогда
            Реализация.ВидОперации=Перечисления.ВидыОперацийРеализацияТоваров.Услуги;    
        иначе
            Реализация.ВидОперации=Перечисления.ВидыОперацийРеализацияТоваров.Товары;
        КонецЕсли;    
        Реализация.Организация=Объект.Организация;
        Реализация.ДоговорКонтрагента=Договор;
        Реализация.Дата=ДатаДок;
        //Реализация.Номер=Объект.Префикс+Формат(НомерДок,"ЧГ=0");
        Реализация.Номер=Объект.Префикс+Прав("0000000000000000000000000000" + Формат(НомерДок,"ЧГ=0"), 6);  
        Реализация.Контрагент=Объект.Контрагент;
        Реализация.СпособЗачетаАвансов = Перечисления.СпособыЗачетаАвансов.Автоматически;
        Реализация.СуммаВключаетНДС=Истина;
        Реализация.ВалютаДокумента = Константы.ВалютаРегламентированногоУчета.Получить();
        Реализация.КурсВзаиморасчетов=1;
        Реализация.КратностьВзаиморасчетов=1;
        Если Объект.Номенклатура.ВидНоменклатуры.Услуга тогда
            СтрокаРеализации=Реализация.Услуги.Добавить();
        иначе
            СтрокаРеализации=Реализация.Товары.Добавить();
            СтрокаРеализации.Количество=1;
        КонецЕсли;    
        
        СтрокаРеализации.Номенклатура=Объект.Номенклатура;
        СтрокаРеализации.СтавкаНДС=Перечисления.СтавкиНДС.НДС20;
        СтрокаРеализации.Цена=СуммаДок;
        СтрокаРеализации.Сумма=СуммаДок;
        СтрокаРеализации.СуммаНДС=СуммаДок/120*20;
        
        ЗаполнитьЗначенияСвойств(Реализация, НалоговыйУчетУСН.ДеятельностьНаПатентеПоУмолчанию(Реализация.Организация, Реализация.Дата));
        ОтветственныеЛицаБП.УстановитьОтветственныхЛиц(Реализация);
        СчетаУчетаВДокументах.ЗаполнитьПередОтображениемПользователю(Реализация);
        
       Реализация.Записать();
6 Ray Zexter
 
30.04.20
15:12
Документ у тебя записывает последняя строка. Вот от неё и пляши.
7 citruss87
 
30.04.20
15:17
(6) Это я понял что Реализация.Записать(); и есть ключ, но я так понимаю между скобками нужно что-то вписать.
Я со строкой Реализация.Номер=Объект.Префикс+Прав("0000000000000000000000000000" + Формат(НомерДок,"ЧГ=0"), 6); парился почти неделю не знал как оформить изначально было Реализация.Номер=НомерДок; и все номера записывались без нулей префикса, да еще и с разделителем разрядов:)
8 vova1122
 
30.04.20
15:35
Перед этой строкой Реализация.Номер=Объект.Префикс+Прав("0000000000000000000000000000" + Формат(НомерДок,"ЧГ=0"), 6);
9 vova1122
 
30.04.20
15:43
Перед этой строкой написать поиск документа по номеру.
НомерДляПроверки=Объект.Префикс+Прав("0000000000000000000000000000" + Формат(НомерДок,"ЧГ=0"), 6);
СсылкаНаДокумент=Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(НомерДляПроверки?ДатаДок);
Пока СсылкаНаДокумент<>Документы.ПоступлениеТоваровУслуг.ПустаяССылка() цикл
НомерДок=НомерДок+1;
СсылкаНаДокумент=Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(НомерДляПроверки?ДатаДок);
НомерДляПроверки=Объект.Префикс+Прав("0000000000000000000000000000" + Формат(НомерДок,"ЧГ=0"), 6);
КонецЦикла
// и свою строку заменить на
Реализация.Номер=НомерДляПроверки;
10 VladZ
 
30.04.20
15:44
(0) К чему эти нелепые телодвижения?
11 VladZ
 
30.04.20
15:45
Оставьте номер документа в покое. Пусть формируется по порядку.
12 vova1122
 
30.04.20
15:45
Очепятка
СсылкаНаДокумент=Документы.ПоступлениеТоваровУслуг.НайтиПоНомеру(НомерДляПроверки,ДатаДок);
13 citruss87
 
30.04.20
15:53
(9) Спасибо за подсказку буду пробовать
(11) Я бы сам не против оставить по умолчанию, но так надо
14 vova1122
 
30.04.20
15:55
Строки в цикле СсылкаНаДокумент=    и  НомерДляПроверки=   нужно поменять местами
15 VladZ
 
30.04.20
16:04
(13) Кому надо?
16 citruss87
 
30.04.20
16:26
(14) Спасибо большое вы упростили мне работу своей подсказкой. Благодарю от всей души!
(15) Нужно в первую очередь мне, так как бывает, когда надо разбить 5000000 на весь квартал, и если оставить нумерацию по порядку, то когда надо будет выписать реализацию вручную в середине квартала, то мне нужно будет продолжать нумерацию по порядку, т.е. получится реализация №236 от 10.02.2020, дальше реализация №237 от 11.02.2020 и т.д. до конца периода к примеру реализация №3046 от 30.04.2020, а теперь допустим нужно в ручную добавить реализацию допустим 11.02.2020 и как вы думаете с каким номером у меня добавиться реализация? Да правильно получится реализация №3047 от 11.02.2020, хотя на 10 число и тут же 11 нумерация была 236 и 237. Я думаю достаточно подробно объяснил.

Всем еще раз спасибо. Тему можно закрыть. Если кому нужна данная обработка, могу поделиться бесплатно.
17 Ray Zexter
 
30.04.20
17:20
(16)Предлагаю вариант проще. Тупо вбиваете все подряд, не обращая внимания на нумерацию. В конце месяца, когда уже точно новых документов не будет, причесывать нумерацию обработкой.
18 Сергиус
 
30.04.20
17:30
(17) +100, намного проще будет.
19 breezee
 
30.04.20
18:37
Если юзерам нужна нумерация - добавляете новый реквизит. Номер нужно получать через "УстановитьНовыйНомер()"
20 citruss87
 
30.04.20
19:49
(17) Спасибо, сам так и хотел сделать изначально, но номера контрагенты запрашивают сразу, т.е. конца месяца я не могу ждать. Ну в общем работает все, все устраивает, спасибо большое
Ошибка? Это не ошибка, это системная функция.