Имя: Пароль:
1C
1С v8
Ошибка арифметического переполнения при проведении Расчета себестоимости
0 al_zzz
 
19.05.16
09:19
Конфигурация УП2.0.Перестал проводиться документ "Расчет себестоимости". При проведении получаю такую ошибку: "Microsoft OLE DB Provider for SQL Server: Ошибка арифметического переполнения при преобразовании numeric к типу данных numeric.
HRESULT=80040E57, SQLSrvr: SQLSTATE=22003, state=8, Severity=10, native=8115, line=1".
В интернете нашел описание решения подобной проблемы: увеличить количество символов для оператора "Выразить".
Нашел запрос, при выполнении которого происходит ошибка. Он расположен в модуле документа, в функции "РешитьСЛУ". Там порядка 20 вызовов оператора "Выразить". Я для всех увеличил длину до 30 символов(там по-умолчанию 23). При этом после расчета получил удвоенную себестоимость, а за предыдущий месяц она вообще не рассчиталась. На другой копии базы поставил количество символов в Выразить по-максимуму и получил какие-то дикие цифры по себестоимости. В итоге сейчас вернул код как раньше, но не работает.
Подскажите, если кто-нибудь сталкивался, как найти ошибку в данных или как поправить код, чтоб заработало? Заранее спасибо!
1 al_zzz
 
19.05.16
10:04
Сам дошел до того, что причина в том, что в цикле, в котором выполняется запрос решения СЛУ отклонение, вместо того, чтоб уменьшаться, растет. На 22-ой итерации оно переваливает за 23 символа и происходит ошибка.
2 al_zzz
 
19.05.16
10:04
Не могу только докопаться, из каких данных оно собирается.
3 al_zzz
 
19.05.16
11:31
Ап!
4 al_zzz
 
19.05.16
14:49
Почти докопался до сути, но немного не хватает.
В общем, переписал код процедуры так, чтоб можно было смотреть временные таблицы а так же записи с максимальным отклонением:
Процедура РешитьСЛУ(МенеджерВременныхТаблиц)

    Запрос = Новый Запрос;
    Запрос.МенеджерВременныхТаблиц = МенеджерВременныхТаблиц;

    МаксКоличествоИтераций = мМаксКоличествоИтераций;
    СчетчикИтераций        = 1;
    ТекущееОтклонение      = 1;
    ТребуемаяТочность      = мТребуемаяТочность;

    Пока ТекущееОтклонение > ТребуемаяТочность И СчетчикИтераций <= МаксКоличествоИтераций Цикл

        Запрос.Текст =
        "ВЫБРАТЬ
        |    УзлыКорректировки.НомерУзла КАК НомерУзла,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.Стоимость) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициент,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.СтоимостьБезНДС) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициентБезНДС,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.ПостояннаяРазница) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициентПостояннаяРазница,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.ВременнаяРазница) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициентВременнаяРазница,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.СтоимостьДопРасходы) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициентДопрасходы,
        |    ВЫРАЗИТЬ(МАКСИМУМ(УзлыКорректировки.СтоимостьДопРасходыБезНДС) КАК ЧИСЛО(23, 10)) КАК СвободныйКоэффициентДопрасходыБезНДС,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.Стоимость, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК Стоимость,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.СтоимостьБезНДС, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК СтоимостьБезНДС,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.ПостояннаяРазница, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК ПостояннаяРазница,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.ВременнаяРазница, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК ВременнаяРазница,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.СтоимостьДопРасходы, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК СтоимостьДопРасходы,
        |    (ВЫРАЗИТЬ(СУММА(ЕСТЬNULL(ВтТаблицаРешений.СтоимостьДопРасходыБезНДС, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0)) КАК ЧИСЛО(23, 10))) / УзлыКорректировки.Количество КАК СтоимостьДопРасходыБезНДС
        |ПОМЕСТИТЬ ВременнаяТаблицаРешений
        |ИЗ
        |    ВтУзлыКорректировки КАК УзлыКорректировки
        |        ЛЕВОЕ СОЕДИНЕНИЕ ВтПеремещенияСписания КАК ПеремещенияСписания
        |        ПО УзлыКорректировки.НомерУзла = ПеремещенияСписания.НомерУзлаПриемник
        |        ЛЕВОЕ СОЕДИНЕНИЕ ВтТаблицаРешений КАК ВтТаблицаРешений
        |        ПО (ПеремещенияСписания.НомерУзлаИсточник = ВтТаблицаРешений.НомерУзла)
        |ГДЕ
        |    УзлыКорректировки.Количество <> 0
        |    И ЕСТЬNULL(ВтТаблицаРешений.Стоимость, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0) > -999999999.999999999
        |    И ЕСТЬNULL(ВтТаблицаРешений.Стоимость, 0) * ЕСТЬNULL(ПеремещенияСписания.Количество, 0) < 9999999999999.999999999
        |
        |СГРУППИРОВАТЬ ПО
        |    УзлыКорректировки.НомерУзла,
        |    УзлыКорректировки.Количество
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    НомерУзла
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0)))
        |            КОНЕЦ), 0) КАК Отклонение,
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьБезНДС, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентБезНДС + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьБезНДС, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьБезНДС, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентБезНДС + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьБезНДС, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.СтоимостьБезНДС, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентБезНДС + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьБезНДС, 0)))
        |            КОНЕЦ), 0) КАК ОтклонениеБезНДС,
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.ПостояннаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентПостояннаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ПостояннаяРазница, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.ПостояннаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентПостояннаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ПостояннаяРазница, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.ПостояннаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентПостояннаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ПостояннаяРазница, 0)))
        |            КОНЕЦ), 0) КАК ОтклонениеПостояннаяРазница,
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.ВременнаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентВременнаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ВременнаяРазница, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.ВременнаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентВременнаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ПостояннаяРазница, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.ВременнаяРазница, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентВременнаяРазница + ЕСТЬNULL(ВременнаяТаблицаРешений.ВременнаяРазница, 0)))
        |            КОНЕЦ), 0) КАК ОтклонениеВременнаяРазница,
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0)))
        |            КОНЕЦ), 0) КАК ОтклонениеДопрасходы,
        |    ЕСТЬNULL(МАКСИМУМ(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.СтоимостьДопРасходы, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ЕСТЬNULL(ВременнаяТаблицаРешений.СтоимостьДопРасходы, 0)))
        |            КОНЕЦ), 0) КАК ОтклонениеДопрасходыБезНДС
        |ПОМЕСТИТЬ _0_
        |ИЗ
        |    ВременнаяТаблицаРешений КАК ВременнаяТаблицаРешений
        |        ЛЕВОЕ СОЕДИНЕНИЕ ВтТаблицаРешений КАК ТаблицаРешений
        |        ПО ВременнаяТаблицаРешений.НомерУзла = ТаблицаРешений.НомерУзла
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ВременнаяТаблицаРешений.НомерУзла,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициент,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициентБезНДС,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициентПостояннаяРазница,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициентВременнаяРазница,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы,
        |    ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходыБезНДС,
        |    ВременнаяТаблицаРешений.Стоимость,
        |    ВременнаяТаблицаРешений.СтоимостьБезНДС,
        |    ВременнаяТаблицаРешений.ПостояннаяРазница,
        |    ВременнаяТаблицаРешений.ВременнаяРазница,
        |    ВременнаяТаблицаРешений.СтоимостьДопРасходы,
        |    ВременнаяТаблицаРешений.СтоимостьДопРасходыБезНДС
        |ПОМЕСТИТЬ РоковойУзел
        |ИЗ
        |    ВременнаяТаблицаРешений КАК ВременнаяТаблицаРешений
        |        ЛЕВОЕ СОЕДИНЕНИЕ ВтТаблицаРешений КАК ТаблицаРешений
        |        ПО ВременнаяТаблицаРешений.НомерУзла = ТаблицаРешений.НомерУзла
        |ГДЕ
        |    ЕСТЬNULL(ВЫБОР
        |                КОГДА ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0)) > 0
        |                    ТОГДА ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0))
        |                ИНАЧЕ -(ЕСТЬNULL(ТаблицаРешений.Стоимость, 0) - (ВременнаяТаблицаРешений.СвободныйКоэффициент + ЕСТЬNULL(ВременнаяТаблицаРешений.Стоимость, 0)))
        |            КОНЕЦ, 0) В
        |            (ВЫБРАТЬ
        |                _0_.Отклонение
        |            ИЗ
        |                _0_ КАК _0_)
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |УНИЧТОЖИТЬ ВтТаблицаРешений
        |;
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    ВременнаяТаблицаРешений.НомерУзла КАК НомерУзла,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициент + ВременнаяТаблицаРешений.Стоимость КАК ЧИСЛО(23, 10)) КАК Стоимость,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициентБезНДС + ВременнаяТаблицаРешений.СтоимостьБезНДС КАК ЧИСЛО(23, 10)) КАК СтоимостьБезНДС,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициентПостояннаяРазница + ВременнаяТаблицаРешений.ПостояннаяРазница КАК ЧИСЛО(23, 10)) КАК ПостояннаяРазница,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициентВременнаяРазница + ВременнаяТаблицаРешений.ВременнаяРазница КАК ЧИСЛО(23, 10)) КАК ВременнаяРазница,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходы + ВременнаяТаблицаРешений.СтоимостьДопРасходы КАК ЧИСЛО(23, 10)) КАК СтоимостьДопРасходы,
        |    ВЫРАЗИТЬ(ВременнаяТаблицаРешений.СвободныйКоэффициентДопрасходыБезНДС + ВременнаяТаблицаРешений.СтоимостьДопРасходыБезНДС КАК ЧИСЛО(23, 10)) КАК СтоимостьДопРасходыБезНДС
        |ПОМЕСТИТЬ ВтТаблицаРешений
        |ИЗ
        |    ВременнаяТаблицаРешений КАК ВременнаяТаблицаРешений
        |
        |ИНДЕКСИРОВАТЬ ПО
        |    НомерУзла
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |УНИЧТОЖИТЬ ВременнаяТаблицаРешений
        |;
        |
        |////////////////////////////////////////////////////////////////////////////////
        |ВЫБРАТЬ
        |    _0_.Отклонение,
        |    _0_.ОтклонениеБезНДС,
        |    _0_.ОтклонениеПостояннаяРазница,
        |    _0_.ОтклонениеВременнаяРазница,
        |    _0_.ОтклонениеДопрасходы,
        |    _0_.ОтклонениеДопрасходыБезНДС
        |ИЗ
        |    _0_ КАК _0_
        |;";
        Выборка = Запрос.ВыполнитьПакет()[6].Выбрать();
        Если Выборка.Следующий() Тогда
            
            ТекущееОтклонение = Макс(Выборка.Отклонение, Выборка.ОтклонениеБезНДС, Выборка.ОтклонениеДопрасходы, Выборка.ОтклонениеДопрасходыБезНДС);

        Иначе

            ТекущееОтклонение = 0;//Отклонений нет

        КонецЕсли;

        СчетчикИтераций = СчетчикИтераций + 1;

        Запрос.Текст =      
            "////////////////////////////////////////////////////////////////////////////////
            |УНИЧТОЖИТЬ РоковойУзел
            |;
            |////////////////////////////////////////////////////////////////////////////////
            |УНИЧТОЖИТЬ _0_
            |;";
        Запрос.ВыполнитьПакет();
    КонецЦикла;

КонецПроцедуры

В отладке посмотрел - отклонение возникает всё время по одной и той же позиции и складу. Сформировал ведомость по себестоимости за период по данной позиции и стал по очереди помечать доки на удаление и пытаться провести Расчет себестоимости. В итоге выяснил, что причина заключается в документе: Возврат товаров между организациями. В виде эксперимента удалил строку с проблемной позицией, провел и попытался провести документ РС. Та же ошибка появилась, но уже на другой позиции.
  В общем, данный док я удалить не могу и не могу понять, что же с ним не так...
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший