Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Контроль Остатков на складе
Украинский 1С форум: всё про 1С 8.3, 1С 8.2, 1С 8.1, 1С 8.0, 1С 7.7 > Программисту > Программирование в 1С Предприятие 8.2 > Программирование управляемых форм 1С 8.2
Stiff
Пробую на примере учебника Радченко сделать контроль товара на складе. Но что-то не получается. Помогите пожалуйста
Процедура ОбработкаПроведения(Отказ, Режим)
    Движения.ТоварыНаСкладах.Записывать = Истина;


    // Создать менеджер временных таблиц
    МенеджерВТ = Новый МенеджерВременныхТаблиц;
    Запрос = Новый Запрос;
    
    // Укажем, какой менеджер временных таблиц использует этот запрос
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

    Запрос.Текст = "ВЫБРАТЬ
                   |    РеализацияМатериалы.Номенклатура,
                   |    РеализацияМатериалы.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
                   |    СУММА(РеализацияМатериалы.Количество) КАК КоличествоВДокументе
                   |ПОМЕСТИТЬ НоменклатураДокумента
                   |ИЗ
                   |    Документ.Реализация.Материалы КАК РеализацияМатериалы
                   |ГДЕ
                   |    РеализацияМатериалы.Ссылка = &Ссылка
                   |
                   |СГРУППИРОВАТЬ ПО
                   |    РеализацияМатериалы.Номенклатура,
                   |    РеализацияМатериалы.Номенклатура.ВидНоменклатуры";

    Запрос.УстановитьПараметр("Ссылка", Ссылка);
    Результат = Запрос.Выполнить();
    
    
    Движения.ТоварыНаСкладах.Записать();

    Для Каждого ТекСтрокаМатериалы Из Материалы Цикл
        Движение = Движения.ТоварыНаСкладах.Добавить();
        Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
        Движение.Период = Дата;
        Движение.Материал = ТекСтрокаМатериалы.Номенклатура;
        Движение.Склад = Склад;
        Движение.Штрихкод = ТекСтрокаМатериалы.Штрихкод;
        Движение.Количество = ТекСтрокаМатериалы.Количество;
    КонецЦикла;
   Движения.Записать();

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

    
    
КонецПроцедуры
logist
Цитата(Stiff @ 14.06.12, 10:45) необходимо зарегистрироваться для просмотра ссылки
Но что-то не получается.

ЧТО КОНКРЕТНО НЕ ПОЛУЧАЕТСЯ? Не ужели трудно сразу всё написать?
Stiff
Списывает товар со склада даже, если не хватает его. И не выводит сообщение о недостаче
logist
Цитата(Stiff @ 14.06.12, 11:01) необходимо зарегистрироваться для просмотра ссылки
Списывает товар со склада даже, если не хватает его

Данный пример предполагает списание товаров в любом случае, а уже затем контроль отрицательных остатков, и в случае если остатки отрицательные то происходит отмена проведения.
Поскольку товар у вас списывается, значит проблема в контроле отрицательных остатков, отладчик - точка останова в строку "Если Режим = РежимПроведенияДокумента.Оперативный Тогда" и смотрите что происходит.

p.s. ну и сам пример видоизменен у вас, может стоит использовать запись регистра из выборки первого запроса (так как это показано в примере), а не из ТЧ документа.
Stiff
Попробую по другому написать.без временных таблиц.Может есть заготовка какая-то для контроля остатков?
logist
Временные таблицы тут не причем. Не пойму в чем проблема найти косяк текущего кода, пример из книги рабочий - лично проверено. Другой заготовки нет, изобретайте.
Stiff
То что пример рабочий я сам знаю.я пробую его переделать под себя.

Взял пример, убрал то, что не нужно. Оставил только то, что связано с моей конфигурацией. Результат - списывает товары в минус, сообщение не выводит.Ну в чем причина??
Процедура ОбработкаПроведения(Отказ, Режим)
    
    Движения.ТоварыНаСкладах.Записывать = Истина;
    
    // Создать менеджер временных таблиц
    МенеджерВТ = Новый МенеджерВременныхТаблиц;
    
    Запрос = Новый Запрос;
    
    // Укажем, какой менеджер временных таблиц использует этот запрос
    Запрос.МенеджерВременныхТаблиц = МенеджерВТ;

    Запрос.Текст =
            "ВЫБРАТЬ
            |    РеализацияМатериалы.Номенклатура,
            |    РеализацияМатериалы.Номенклатура.ВидНоменклатуры КАК ВидНоменклатуры,
            |    СУММА(РеализацияМатериалы.Количество) КАК КоличествоВДокументе
            |ПОМЕСТИТЬ НоменклатураДокумента
            |ИЗ
            |    Документ.Реализация.Материалы КАК РеализацияМатериалы
            |ГДЕ
            |    РеализацияМатериалы.Ссылка = &Ссылка
            |
            |СГРУППИРОВАТЬ ПО
            |    РеализацияМатериалы.Номенклатура";

    Запрос.УстановитьПараметр("Ссылка", Ссылка);

    Результат = Запрос.Выполнить();

    Запрос2 = Новый Запрос;
    Запрос2.МенеджерВременныхТаблиц = МенеджерВТ;
    Запрос2.Текст = "ВЫБРАТЬ
                    |    НоменклатураДокумента.Номенклатура,
                    |    НоменклатураДокумента.ВидНоменклатуры,
                    |    НоменклатураДокумента.КоличествоВДокументе,
                    |    ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Количество,
                    |    ТоварыНаСкладахОстатки.Штрихкод
                    |ИЗ
                    |    НоменклатураДокумента КАК НоменклатураДокумента
                    |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
                    |                ,
                    |                Материал В
                    |                    (ВЫБРАТЬ
                    |                        НоменклатураДокумента.Номенклатура
                    |                    ИЗ
                    |                        НоменклатураДокумента)) КАК ТоварыНаСкладахОстатки
                    |        ПО НоменклатураДокумента.Номенклатура = ТоварыНаСкладахОстатки.Материал";

    
    // Запишем пустые наборы записей чтобы читать остатки без учета данных в документе
    
    Движения.ТоварыНаСкладах.Записать();

    Результат = Запрос2.Выполнить();                
    //ТЗ = Результат.Выгрузить();
    
    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        
        
        Если ВыборкаДетальныеЗаписи.ВидНоменклатуры = Перечисления.ВидНоменклатуры.Материал Тогда         // регистр ТоварыНаСкладах Расход
            // регистр ТоварыНаСкладах Расход
            
            Движения.ТоварыНаСкладах.Записывать = Истина;    
            Для Каждого ТекСтрокаМатериалы Из Материалы Цикл
            Движение = Движения.ТоварыНаСкладах.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
            Движение.Период = Дата;
            Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
            Движение.Склад = Склад;
            Движение.Штрихкод = ВыборкаДетальныеЗаписи.Штрихкод;
            Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе;
            КонецЦикла;
            
                 
            
        КонецЕсли;

            
    КонецЦикла;

    Движения.Записать();

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

КонецПроцедуры
logist
Цитата(Stiff @ 14.06.12, 12:22) необходимо зарегистрироваться для просмотра ссылки
Результат - списывает товары в минус, сообщение не выводит.Ну в чем причина??

Пользуйтесь отладчиком, гадать можно бесконечно (вдруг есть что-то вне этого кода, делающее не то что надо).

p.s. это вообще не понятно - что оно делает...
   Результат = Запрос2.Выполнить();                 
    //ТЗ = Результат.Выгрузить();
    
    ВыборкаДетальныеЗаписи = Результат.Выбрать();

    Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
        
        
        Если ВыборкаДетальныеЗаписи.ВидНоменклатуры = Перечисления.ВидНоменклатуры.Материал Тогда         // регистр ТоварыНаСкладах Расход
            // регистр ТоварыНаСкладах Расход
            
            Движения.ТоварыНаСкладах.Записывать = Истина;    
            Для Каждого ТекСтрокаМатериалы Из Материалы Цикл
            Движение = Движения.ТоварыНаСкладах.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
            Движение.Период = Дата;
            Движение.Материал = ВыборкаДетальныеЗаписи.Номенклатура;
            Движение.Склад = Склад;
            Движение.Штрихкод = ВыборкаДетальныеЗаписи.Штрихкод;
            Движение.Количество = ВыборкаДетальныеЗаписи.КоличествоВДокументе;
            КонецЦикла;
            
                
            
        КонецЕсли;

            
    КонецЦикла;

точнее не непонятно, а понятно - тупо-код какой-то, в выборке перебирать еще и материалы, и не использовать ничего из материалов...
Stiff
Сделал так. Вроде работает нормально. Может кому пригодится:
Процедура ОбработкаПроведения(Отказ, Режим)
    
Запрос = Новый Запрос;

Запрос.Текст =

"ВЫБРАТЬ
|    РеализацияМатериалы.Номенклатура,
|    СУММА(РеализацияМатериалы.Количество) КАК Количество,
|    РеализацияМатериалы.Штрихкод
|ПОМЕСТИТЬ ДокТЧ
|ИЗ
|    Документ.Реализация.Материалы КАК РеализацияМатериалы
|ГДЕ
|    РеализацияМатериалы.Ссылка = &Ссылка
|
|СГРУППИРОВАТЬ ПО
|    РеализацияМатериалы.Номенклатура,
|    РеализацияМатериалы.Штрихкод
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ
|    ДокТЧ.Номенклатура,
|    ДокТЧ.Количество,
|    ДокТЧ.Штрихкод,
|    ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
|    ДокТЧ КАК ДокТЧ
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
|                ,
|                Склад = &Склад
|                    И Материал В
|                        (ВЫБРАТЬ
|                            ДокТЧ.Номенклатура
|                        ИЗ
|                            ДокТЧ КАК ДокТЧ)) КАК ТоварыНаСкладахОстатки
|        ПО ДокТЧ.Номенклатура = ТоварыНаСкладахОстатки.Материал";

Запрос.УстановитьПараметр("Склад", Склад);

Запрос.УстановитьПараметр("Ссылка", Ссылка);

// Запишем пустые наборы записей чтобы читать остатки без учета данных в документе
    
Движения.ТоварыНаСкладах.Записать();

РезультатЗапроса = Запрос.Выполнить();

Движения.ТоварыНаСкладах.Записывать = Истина;

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

Пока Выборка.Следующий() Цикл

      Если Выборка.Количество > Выборка.Остаток Тогда

            Сообщить("Не хватает товара " + Выборка.Номенклатура + ", из необходимых " + Выборка.Количество + " в наличие имеется только " + Выборка.Остаток);

            Отказ = Истина;

      КонецЕсли;
      
      Если Не Отказ Тогда

            Движение = Движения.ТоварыНаСкладах.Добавить();
            Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
            Движение.Период = Дата;
            Движение.Материал = Выборка.Номенклатура;
            Движение.Склад = Склад;
              Движение.Штрихкод = Выборка.Штрихкод;
            Движение.Количество = Выборка.Количество;

      КонецЕсли;

КонецЦикла;

КонецПроцедуры
logist
А что тогда мешает сделать так:
"ВЫБРАТЬ
|    ДокТЧ.Номенклатура,
|    ДокТЧ.Количество,
|    ДокТЧ.Штрихкод,
|    ЕСТЬNULL(ТоварыНаСкладахОстатки.КоличествоОстаток, 0) КАК Остаток
|ИЗ
|    Документ.Реализация.Материалы КАК ДокТЧ
|        ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки(
|                ,
|                Склад = &Склад) КАК ТоварыНаСкладахОстатки
|        ПО ДокТЧ.Номенклатура = ТоварыНаСкладахОстатки.Материал
|ГДЕ
|    ДокТЧ.Ссылка = &Ссылка";
sava1
Цитата(logist @ 14.06.12, 15:20) необходимо зарегистрироваться для просмотра ссылки
А что тогда мешает сделать так:

А теперь представьте - в ТЧ 2 товара, а в остатках 200 000 - отбор только при соединении - грузим сервер
MATEVI
А так ради интереса если к запросу logist-а

|                Склад = &Склад  и Номенклатура В &МасНоменклатура) КАК ТоварыНаСкладахОстатки

//...........
Запрос.УстановитьПараметр("МасНоменклатура",Ссылка.Товары.ВыгрузитьКолонку("Номенклатура"));

Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.