Имя: Пароль:
1C
1С v8
Автонумерация при разделении данных
,
0 realret
 
29.10.13
11:23
Приветствую всех. Есть нетиповая база. Недавно добавил в ней общий реквизит с разделением данных по нему. После этого автонумерация всех документов пошла почему-то с 1, причем при записи возникает ошибка "номер не уникальный", что естественно. Исправил ситуация создав программно все виды документов с максимальным номером. Отработали день, сегодня опять нумерация слетела у одного вида документов - выдает вчерашний номер. Пользователям номер недоступен, обменов нет. Никто не знает, в чем может быть проблема?
1 realret
 
29.10.13
11:45
Да, забыл сказать, до введения разделения данных никаких проблем с автонумерацией не было за весь период использования. До ведения разделения во всех документах был реквизит "ВладелецТовара", я его удалил, добавил одноименный общий с разделением данных и заполнил в документах значения нового реквизита как был до разделения
2 realret
 
29.10.13
12:09
Неужели ни у кого не было ничего подобного? Или никто разделение данных не использует?
3 realret
 
29.10.13
23:39
Up?
4 realret
 
30.10.13
09:23
Сегодня ситуация повторилась. Стабильно утром слетает нумерация...
5 spleen
 
30.10.13
09:28
У тебя есть Нумератор?
Если да, то посмотри периодичность. Возможно она у тебя стоит в пределах дня, а проверка на уникальность на весь период написана
6 realret
 
30.10.13
10:06
(5) Нумератора нет. Периодичность в пределах года, как и была. Проблема появилась после введения общего реквизита с разделением данных по нему. Попробую сегодня в конфигурации убрать автоматическое высвобождение номеров, может поможет
7 realret
 
30.10.13
10:22
Проблема даже не в дне. Нумерация слетает когда все вышли из базы и снова зашли - хоть 10 раз на дню. Причем начинается в этом случае не с 1, а с первого номера предыдущего сеанса.
8 realret
 
30.10.13
10:46
Нашел точно в чем проблема.

Процедура ПриУстановкеНовогоНомера(СтандартнаяОбработка, Префикс)
    Если ЭтоНовый() Тогда
        Префикс = "0";
    КонецЕсли;    
КонецПроцедуры

Было сделано, чтобы созданные вручную документы не имели префикса (в базе предусмотрен обмен). до разделения данных работало корректно, после перестало.
9 realret
 
30.10.13
11:31
Если кому понадобится, то решилось так:
пришлось в ПриЗаписи добавлять вызов процедуры:


Процедура КонтрольНомера(ЭтотОбъект) Экспорт

    Мета            = ЭтотОбъект.Метаданные();
    Имя             = Мета.Имя;
    Номер            = ЭтотОбъект.Номер;
    ДлинаН            = Мета.ДлинаНомера;
    
    Запрос             = Новый Запрос;
    Запрос.Текст     =
        "ВЫБРАТЬ
        |    Док.Ссылка КАК Ссылка
        |ИЗ
        |    Документ."+Имя+" КАК Док
        |ГДЕ
        |    Док.Номер = &Номер";
    
    Запрос.УстановитьПараметр("Номер",Номер);
    //НайтиПоНомеру с разделителем данных не работает при сквозной нумерации
    Результат         = Запрос.Выполнить();
    Выборка         = Результат.Выбрать();
    ЕстьДубль        = Ложь;
    
    Пока Выборка.Следующий() Цикл
                
        Если Выборка.Ссылка = ЭтотОбъект.Ссылка Тогда
            Продолжить;
        КонецЕсли;
        
        ЕстьДубль    = Истина;
        
    КонецЦикла;

    Если НЕ ЕстьДубль Тогда
        Возврат;
    КонецЕсли;
    
    Преф            = "";
    Длина            = СтрДлина(Номер);
    
    Для Сч = 1 По Длина Цикл
        
        Сим    = Сред(Номер,Длина-Сч+1,1);
        
        Если ОбщегоНазначения.ПривестиСтрокуКЧислу(Сим,Истина) = Неопределено Тогда
            Преф    = Лев(Номер,Сим);
            Прервать;
        КонецЕсли;
        
    КонецЦикла;
    
    ДлинаП            = СтрДлина(Преф);
    МаксНомер        = 0;
    Запрос             = Новый Запрос;
    Запрос.Текст     =
        "ВЫБРАТЬ
        |    МАКСИМУМ(Док.Номер) КАК Номер
        |ИЗ
        |    Документ."+Имя+" КАК Док
        |ГДЕ
        |    Док.Номер ПОДОБНО &Преф+""%""";
    
    Запрос.УстановитьПараметр("Преф",Преф);
    
    Результат = Запрос.Выполнить();

    Выборка = Результат.Выбрать();

    Пока Выборка.Следующий() Цикл
        
        Если Выборка.Номер = Null Тогда
            Продолжить
        КонецЕсли;
        
        МаксНомер    = ОбщегоНазначения.ПривестиСтрокуКЧислу(Сред(Выборка.Номер,ДлинаП+1));
        
    КонецЦикла;

    ЭтотОбъект.Номер = Преф+Формат(МаксНомер+1, "ЧЦ="+(ДлинаН-ДлинаП)+"; ЧДЦ=0; ЧГ=0; ЧВН=")
    
КонецПроцедуры //


//Функция выполняет приведение строки к числу
// Параметры:
//  ЧислоСтрокой           - Строка - Строка приводимая к числу
//  ВозвращатьНеопределено - Булево - Если Истина и строка содержит некорректное значение, то возвращать Неопределено
//
// Возвращаемое значение:
//  Число
//
Функция ПривестиСтрокуКЧислу(ЧислоСтрокой, ВозвращатьНеопределено = Ложь) Экспорт
    
    ОписаниеТипаЧисла = Новый ОписаниеТипов("Число");
    ЗначениеЧисла = ОписаниеТипаЧисла.ПривестиЗначение(ЧислоСтрокой);
    
    Если ВозвращатьНеопределено И (ЗначениеЧисла = 0) Тогда
        
        Стр = Строка(ЧислоСтрокой);
        Если Стр = "" Тогда
            Возврат Неопределено;
        КонецЕсли;
        
        Стр = СтрЗаменить(СокрЛП(Стр), "0", "");
        Если (Стр <> "") И (Стр <> ".") И (Стр <> ",") Тогда
            Возврат Неопределено;
        КонецЕсли;
    КонецЕсли;
    
    Возврат ЗначениеЧисла;    
    
КонецФункции