Имя: Пароль:
1C
1C 7.7
v7: Запрос Остатков за минусом резервов
0 Double_Medved
 
21.01.14
11:54
Помогите плиз, что-то туплю, что-то явно проще делается. Мне нужно сделать запрос свободных остатков выбранной номенклатуры на всех складах. То есть из ОстатковТМЦ отнять РезервыТМЦ. Чую что этот запрос выглядит проще чем у меня

    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(Сформировать)
    |Период с ВыбНачПериода по ВыбКонПериода;
    |НоменклатураОстатки = Регистр.ОстаткиТМЦ.Номенклатура;
    |СкладОстатки = Регистр.ОстаткиТМЦ.Склад;
    |КоличествоОстатки = Регистр.ОстаткиТМЦ.Количество;
    |НоменклатураРезерв = Регистр.РезервыТМЦ.Номенклатура;
    |СкладРезерв = Регистр.РезервыТМЦ.Склад;
    |КоличествоРезерв = Регистр.РезервыТМЦ.Количество;
    |Функция КоличествоРезервНачОст = НачОст(КоличествоРезерв);
    |Функция КоличествоОстаткиНачОст = НачОст(КоличествоОстатки);
    |Группировка СкладОстатки;
    |Условие(НоменклатураОстатки = ВыбраннаяНоменклатура);
    |Условие(НоменклатураРезерв = ВыбраннаяНоменклатура);
    |"//}}ЗАПРОС
    ;
    // Если ошибка в запросе, то выход из процедуры
    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
        Возврат;
    КонецЕсли;
    
    Пока Запрос.Группировка(1) = 1 Цикл
        // Заполнение полей СкладОстатки
        КоличествоЗаМинусомРезерва = Запрос.КоличествоОстаткиНачОст - Запрос.КоличествоРезервНачОст;
    КонецЦикла;
1 povar
 
21.01.14
12:07
смотри отчет Остатки ТМЦ в типовой ТиС
2 Double_Medved
 
21.01.14
12:14
(1)А подскажи плиз как можно нормально посмотреть в отладчике текст запроса? А то он выводится в одну строку, и видимо еще где-то обрывается, не все видно, я вот поэтому и не смог передрать (
3 aka AMIGO
 
21.01.14
12:14
(0) ВыбраннаяНоменклатура - один элемент?
тогда ИМХО - гораздо проще сделать обращением к регистрам

Ост = Регистр.ОстаткиТМЦ.СводныйОстаток(,ВыбраннаяНоменклатура,,,"Количество");
Рез = Регистр.РезервыТМЦ.СводныйОстаток(,ВыбраннаяНоменклатура,,,"Количество");

КоличествоЗаМинусомРезерва = Ост - Рез;

ЗЫ. ну, проверить только запятые
4 aka AMIGO
 
21.01.14
12:15
(2) в отладчике обрывается на 255-м символе
5 Double_Medved
 
21.01.14
12:21
(3) я потому и хочу запросом, потому что запросом быстрее. У меня там в документе у любой выбранной строки показывается остаток номенклатуры, чтобы менеджеры не путались.
6 aka AMIGO
 
21.01.14
12:24
(5) ну, твоя воля.. у меня именно так считаются остатки в каждой строке документов, тормозов не замечено.
ЗЫ. если на дату дока - то временный расчет НА(ТекущийДок..
7 aka AMIGO
 
21.01.14
12:29
а почему в запросе у тебя функция "НачОст(" ? вроде-б нелогично
8 Double_Medved
 
21.01.14
12:34
(6)А можешь рассказать как там примерно дело обстоит? Просто с ТА я заманался. То есть вот например создают новый документ - он же будет после ТА,это надо брать тогда остатки на ТА? И вот если открывают старый документ? Тогда делать временный расчет на текущий документ? Я что-то путаюсь когда надо делать временный расчет, а когда не надо
9 Кукуев
 
21.01.14
12:59
Попробуй сделать вывод
Предупреждение(ТекстЗапроса);
10 aka AMIGO
 
21.01.14
13:02
(8) ты всё в принципе правильно говоришь. Временный расчет - на определенную точку временной оси, это может быть дата, или документ


""..создают новый документ - он же будет после ТА,это надо брать тогда остатки на ТА?"" - да, и временный расчет в этом случае не нужен, т.е. как в (3)

""..если открывают старый документ? Тогда делать временный расчет на текущий документ?"" - да.

ВР = создатьОбъект("Регистры");
РегОст = ВР.ОстаткиТМЦ;
РегРез = ВР.РезервыТМЦ;
ВР.ВременныйРасчет(1);
РассчитатьРегистрыНа(ТекущийДокумент());

Ост = РегОст.СводныйОстаток(...
...
11 Кукуев
 
21.01.14
13:02
(9) + После формирования текста запроса, естественно :)
12 aka AMIGO
 
21.01.14
13:03
(10) + забыл:
РегОст.      УстановитьЗначениеФильтра("Номенклатура",ТвояНоменклатура,?);
...
13 Double_Medved
 
21.01.14
13:11
(10)(12) Спасибо, я видимо сделал ошибку в том что я всегда делал ВременныйРасчет, даже в новых документах, за счет этого шло торможение. Попробую делать ВременныйРасчет только для старых документов, их все равно реже открывают.
14 Double_Medved
 
21.01.14
13:12
(11)Спасибо, попробую
15 aka AMIGO
 
21.01.14
13:31
(13) хороший пример - в модуле документа, напрмер, "ЗаявкаПокупателя", если глянуть в процедуру ПроведениеПоРегистрам()
там быстренько проверяется наличие ТМЦ на предмет записи в регистры заявок и резервов..

С проверкой ИтогиАктуальны()..

модифицируй под себя..
16 Double_Medved
 
21.01.14
13:32
Подскажите а как правильно получать ТА? ПолучитьДатуТА() Возвращает саму дату или время тоже? Например создали и провели документ сегодня в 10.00. Потом значит в 12.00 создают новый документ. Я сравниваю ДатаДок и ТА, и они выходит будут равны? Там же нет учета времени? Тогда в 12.00 в не проведенном документе он покажет остаток на 10.00, и это правильно. Потом ТА при проведении переместится в 12.00. И вот тут откроют документ  который был в 10.00. Сравним ДатаДок и ТА. Они будут равны или нет? Дата одна, время разное. Если там только дата - то даты будут равны и он посчитает на ТА, о она стоит в 12.00, и выходит что остаток будет некорректный.... Вот что меня гложет, в дате только дата или еще и время?
17 aka AMIGO
 
21.01.14
13:49
описание внутр.яз есть? посмотри ч1 стр292 ИтогиАктуальны, там рассказано много чего про это
18 Double_Medved
 
21.01.14
18:41
Терпение и трут
Вроде все работает, считает остатки до проведения документа, и даже после его проведения показывает остатки на позицию документа, до его проведения. При создании документа после ТА - смотрит остатки на конец ТА
Функция СвободныеОстатки()
    ИнфоТекст = ""; //Строка для вывода результата
    Рег = СоздатьОбъект("Регистры");
    РегРезервы = Рег.РезервыТМЦ;
    РегОстатки = Рег.ОстаткиТМЦ;
    СпособРасчета  = "По";
    Если Выбран() = 0 Тогда  
        Если ДатаДок < ПолучитьДатуТА() Тогда  //Если ДатаДок нового документа меньше Даты ТА, посчитаем на конец ДатаДок
            ГраницаРасчета = ДатаДок;
        Иначе            
            ГраницаРасчета = ПолучитьПозициюТА();//Если ДатаДок нового документа равна Дате ТА, посчитаем на конец ТА
        КонецЕсли;
    Иначе
        ПозДок = ТекущийДокумент().ПолучитьПозицию();
        Если ПозДок <= ПолучитьПозициюТА() Тогда  //Если позиция существующего документа меньше или равна ТА, посчтиаем на начало его позиции
            ГраницаРасчета = ПозДок;
            СпособРасчета  = "На";
        Иначе            
            ГраницаРасчета = ПолучитьПозициюТА(); //Если позиция существующего документа больше ТА, посчитаем на конец ТА
        КонецЕсли;
    КонецЕсли;
    РегРезервы.УстановитьЗначениеФильтра("Номенклатура",Номенклатура,1);  //Установим фильтр по номенклатуре
    РегОстатки.УстановитьЗначениеФильтра("Номенклатура",Номенклатура,1);
    РегРезервы.ВременныйРасчет(1);
    РегОстатки.ВременныйРасчет(1);
    Если СпособРасчета = "По" Тогда
        Рег.РассчитатьРегистрыПо(ГраницаРасчета);  //Рассчитаем
    Иначе
        Рег.РассчитатьРегистрыНа(ГраницаРасчета);
    КонецЕсли;
    
    Склады = СоздатьОбъект("Справочник.Склады");  //Переберем все склады и посмотрим на них остатки
    Склады.ВыбратьЭлементы();
    Пока Склады.ПолучитьЭлемент() = 1 Цикл
        РезервПоСкладу = РегРезервы.СводныйОстаток(,Номенклатура,Склады.ТекущийЭлемент(),,,"Количество");
        ОстаткиПоСкладу = РегОстатки.СводныйОстаток(,Номенклатура,Склады.ТекущийЭлемент(),,"Количество");
        КоличествоОстатковЗаМинусомРезерва = ОстаткиПоСкладу - РезервПоСкладу;    
        Если КоличествоОстатковЗаМинусомРезерва <> 0 Тогда
            ИнфоТекст = ИнфоТекст + Склады.ТекущийЭлемент()+ ": " + КоличествоОстатковЗаМинусомРезерва + " шт, ";    
        КонецЕсли;  
    КонецЦикла;  
    ДлинаИнфоТекст = СтрДлина(ИнфоТекст);  //Уберем последнюю запятую
    ИнфоТекст = Лев(ИнфоТекст,ДлинаИнфоТекст-2);
    Если ИнфоТекст = "" Тогда
        ИнфоТекст = "нет";
    КонецЕсли;
    Если (Номенклатура.ВидНоменклатуры = Перечисление.ВидыНоменклатуры.Услуга)
        или (Номенклатура.ВидНоменклатуры = Перечисление.ВидыНоменклатуры.Работа) Тогда
        ИнфоТекст = "";
    КонецЕсли;
    Возврат ИнфоТекст;    
КонецФункции
19 Double_Medved
 
21.01.14
18:42
Распознаватель понаставил много пустых строк, сории, может как-то не так копирнул
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.