Имя: Пароль:
1C
1С v8
МоментВремени в запросе
,
0 1С_Дурик
 
12.01.12
13:43
Добрый день. При использовании МоментВремени, запрос выполняется очень . В чем может быть проблема.Спасибо

МоментДокумента = Новый МоментВремени(Ссылка.Дата,Ссылка);

   Запрос = Новый Запрос;
   
   Запрос.УстановитьПараметр("Счет",Счет);
   Запрос.УстановитьПараметр("Склад",Склад);
   Запрос.УстановитьПараметр("Номенклатура",Номенклатура);
   Запрос.УстановитьПараметр("Дата",МоментДокумента);
               
   Если дата = Неопределено Тогда
       Запрос.Текст = "ВЫБРАТЬ
       |    Остатки.КоличествоОстатокДт КАК Остаток
       |ИЗ
       |    РегистрБухгалтерии.Хозрасчетный.Остатки(
       |            ,
       |            Счет = &Счет,
       |            ,
       |            Субконто1 = &Номенклатура
       |                И Субконто2 = &Склад) КАК Остатки";
       
   Иначе
       
       
       
       Запрос.Текст = "ВЫБРАТЬ
       |    Остатки.КоличествоОстатокДт КАК Остаток
       |ИЗ
       |    РегистрБухгалтерии.Хозрасчетный.Остатки(
       |            &Дата,
       |            Счет = &Счет,
       |            ,
       |            Субконто1 = &Номенклатура
       |                И Субконто2 = &Склад) КАК Остатки";
   КонецЕсли;
   
   РезультатЗапроса = Запрос.Выполнить().Выгрузить();
1 vicof
 
12.01.12
13:44
очень быстро?
2 Cube
 
12.01.12
13:44
(0) Ну дык, без использования МоментВремени, запрос будет выполняться не очень...
3 1С_Дурик
 
12.01.12
13:45
*очень долго
4 1С_Дурик
 
12.01.12
13:46
без использования остатки не правильные
5 DrShad
 
12.01.12
13:46
Остатки без даты берет текущие, а с датой рассчитывает
6 Cube
 
12.01.12
13:47
Если дата = Неопределено Тогда

Что за переменная "Дата" и где она присваивается?
7 1С_Дурик
 
12.01.12
13:47
реквизит документа
8 Cube
 
12.01.12
13:48
(7) Как реквизит документа типа "Дата" может быть равен Неопределено? У тебя это условие всегда возвращает ЛОЖЬ...
9 1С_Дурик
 
12.01.12
13:49
А если использовать Ссылка.МоментВремени() на сколько будут точные остатки?
10 Cube
 
12.01.12
13:49
(9) Да хоть что используй, у тебя в любом случае выполняется первый запрос, втрой никогда не выполняется.
11 Cube
 
12.01.12
13:50
(10) То есть, выполняется только второй
12 Cube
 
12.01.12
13:50
запрос...
13 Cube
 
12.01.12
13:51
(0) Ты это при проведении документа, поди, делаешь, да?)
14 1С_Дурик
 
12.01.12
13:51
извиняюсь, не реквизит документа, я передаю
15 1С_Дурик
 
12.01.12
13:52
(13) ага
16 Cube
 
12.01.12
13:52
(14) Что передаешь? Эстафету? Кому?)) Выражайся конретнее.
17 1С_Дурик
 
12.01.12
13:53
(16)
ПроверитьОстаток(Ссылка,Строчка.Счет,Ссылка.Склад,Строчка.Номенклатура,Ссылка.Дата);
ПроверитьОстаток(Ссылка,Счет,Склад,Номенклатура,Дата=Неопределено)
18 Cube
 
12.01.12
13:53
(15) Ага... А документу разрешено оперативное проведение и проводишь ты его текущей датой, угадал?
19 Rovan
 
гуру
12.01.12
13:53
(0) а по какой день у тебя в регистре итоги рассчитаны ?
20 Cube
 
12.01.12
13:54
(17) Вместо "дата = Неопределено" используй "ЗначениеЗаполнено(Дата)"...
21 hhhh
 
12.01.12
13:54
(15) по-любому текущий остаток быстрее, хоть ты дерись. Потому что он уже есть, а если на дату, то 1С его рассчитывает из 2-х таблиц.
22 Cube
 
12.01.12
13:55
(20) А ещё лучше сделай так:
ПроверитьОстаток(Ссылка,Строчка.Счет,Ссылка.Склад,Строчка.Номенклатура, ?(ЗначениеЗаполнено(Ссылка.Дата, Ссылка.Дата, ТекущаяДата()));

И запрос один оставь, тот который с параметром "Дата".
23 1С_Дурик
 
12.01.12
13:56
(19) Дата документа 01.12.2011 23.59.59 итоги 31.12.2011
24 Cube
 
12.01.12
13:57
(22) О, лучше не так, а вот так:
ПроверитьОстаток(Ссылка,Строчка.Счет,Ссылка.Склад,Строчка.Номенклатура, ?(Ссылка.Пустая(), ТекущаяДата(), МоментВремени()));
Ну как-то так, направление я думаю, ты понял.
25 Cube
 
12.01.12
13:58
(23) Ответь на (18).
26 1С_Дурик
 
12.01.12
13:59
(18) неоперативно провожу
27 RomanYS
 
12.01.12
13:59
База файловая и в сети?
А вообще уходи от запроса в цикле, делай проверку одним запросом.
28 1С_Дурик
 
12.01.12
14:00
(27) SQL
29 Cube
 
12.01.12
14:03
(26) Ты не ответил на вопрос.
30 AndOne
 
12.01.12
14:04
Обращение к таблице остатков без указания вида субконто, сомнительное удовольствие.
31 RomanYS
 
12.01.12
14:07
(30) поддерживаю
+(27) один запрос на документ будет выполняться ненамного дольше чем твои запросы для каждой строки
32 Cube
 
12.01.12
14:10
(31) Один запрос будет выполняться гарантированно быстрее, чем его запросы для каждой строки. А за запросы в цикле, обычно, расстреливают без суда и следствия... :)
33 RomanYS
 
12.01.12
14:10
* чем каждый запрос для одной строки
34 RomanYS
 
12.01.12
14:10
(32) я про тоже, а (0) проверяет построчно
35 afk
 
12.01.12
14:22
(0) очень долго - это сколько в секундах?
36 1С_Дурик
 
12.01.12
14:42
(35) 5-10
37 Fragster
 
гуру
12.01.12
14:48
на какую дату итоги рассчитаны?
38 1С_Дурик
 
12.01.12
14:53
(32) помогите передалать запрос, мне не понятно как будут определять номенклатура и счет, когда я ТЗ передаю, что передавать в &Счет и &Номенклатура.

Запрос.Текст = "ВЫБРАТЬ
       |    Остатки.КоличествоОстатокДт КАК Остаток
       |ИЗ
       |    РегистрБухгалтерии.Хозрасчетный.Остатки(
       |            &Дата,
       |            Счет В (&Счет),
       |            ,
       |            Субконто1 В (&Номенклатура)
       |                И Субконто2 = &Склад) КАК Остатки";
39 1С_Дурик
 
12.01.12
14:53
(37) 31 12 2011
40 kabanoff
 
12.01.12
15:02
(0)+(17) ужас какой...

(38) Все можно сделать одним запросом. Получай ТЗ из самого документа и помещай результат во временную таблицу, затем эту таблицу соединяй с регистром остатков.
41 1С_Дурик
 
12.01.12
15:03
(40) пример можно?!
42 kabanoff
 
12.01.12
15:06
(40) ну или делай так (конкретный пример):

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

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

   Пока Выборка.Следующий() Цикл
       Если Выборка.Количество > Выборка.Остаток Тогда
           #Если Клиент Тогда
           Сообщить("Не хватает " + СокрЛП(Выборка.Количество-Выборка.Остаток) + " ед." +
                    " товара " + СокрЛП(Выборка.Номенклатура) +
                    " на складе " + СокрЛП(Склад) + "!",СтатусСообщения.Важное);
                #КонецЕсли
           Отказ = Истина;
       КонецЕсли;
   КонецЦикла;

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

Процедура ОбработкаПроведения(Отказ, Режим)
   
  ПроверкаОстатка(Отказ);

  Если Не Отказ Тогда
     ДвижениеПоРегистрам();
  КонецЕсли;

КонецПроцедуры
43 kabanoff
 
12.01.12
15:12
(42) Запрос, конечно, лучше сделать к таблице непосредственно самого документа:

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

СГРУППИРОВАТЬ ПО
   РасходнаяНакладнаяТовары.Номенклатура

ИНДЕКСИРОВАТЬ ПО
   Номенклатура
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
   Товары.Номенклатура,
   Товары.Количество,
   ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток, 0) КАК Остаток
ИЗ
   Товары КАК Товары
       ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(
               &НаДату,
               Склад = &Склад
                   И Номенклатура В
                       (ВЫБРАТЬ
                           Товары.Номенклатура
                       ИЗ
                           Товары)) КАК ОстаткиТоваровОстатки
       ПО Товары.Номенклатура = ОстаткиТоваровОстатки.Номенклатура
44 Fragster
 
гуру
12.01.12
15:16
(43) зачем? лишний раз базу подергать? а если это в "передЗаписью"?
45 kabanoff
 
12.01.12
15:19
(42) Строку:
Запрос.УстановитьПараметр("НаДату", Новый Граница(Дата, ВидГраницы.Включая));
надо заменить на:
Запрос.УстановитьПараметр("НаДату", Новый Граница(ЭтотОбъект.МоментВремени(), ВидГраницы.Исключая));

иначе при перепроведении документа будут учитываться остатки с его собственными движениями.

Ну и код:
СгруппированныеТовары = Товары.Выгрузить();
   СгруппированныеТовары.Свернуть("Номенклатура", "Количество");

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

выкосить за ненадобностью.
46 Fragster
 
гуру
12.01.12
15:30
(45) а если при перепроведении сдвинули дату вперед? надо еще с таблицей регистра объединить с отбором по ссылке, дате и вывернутыми движениями.

а вообще - нужно просто после записи посмотреть "а что это мы нафигачили" и если что - откатить
47 kabanoff
 
12.01.12
15:53
(46) Ну тогда надо запрещать изменять дату проведенного документа :)
А насчет "откатить" - этот принцип используется в 8.2, там парадигма несколько другая. В 8.1 это будет не оптимально.
48 1С_Дурик
 
12.01.12
15:56
Сделал вот так запрос. Для 110 позиций выполнялся около 1 мин

ВЫБРАТЬ
                      |    Товары.Номенклатура,
                      |    Товары.Счет,
                      |    Товары.Количество
                      |ПОМЕСТИТЬ Товары
                      |ИЗ
                      |    &ТЧОстатков КАК Товары
                      |;
                      |
                      |////////////////////////////////////////////////////////////////////////////////
                      |ВЫБРАТЬ
                      |    Товары.Номенклатура,
                      |    ВложенныйЗапрос.КоличествоОстатокДт КАК Остаток,
                      |    ВложенныйЗапрос.КоличествоОстатокДт - Товары.Количество КАК КонОстаток
                      |ИЗ
                      |    Товары КАК Товары
                      |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
                      |            ХозрасчетныйОстатки.КоличествоОстатокДт КАК КоличествоОстатокДт,
                      |            ХозрасчетныйОстатки.Счет КАК Счет,
                      |            ХозрасчетныйОстатки.Субконто1 КАК Субконто1,
                      |            ХозрасчетныйОстатки.Субконто2 КАК Субконто2
                      |        ИЗ
                      |            РегистрБухгалтерии.Хозрасчетный.Остатки(&Дата, , ,Субконто2 = &Склад) КАК ХозрасчетныйОстатки) КАК ВложенныйЗапрос
                      |        ПО Товары.Номенклатура = ВложенныйЗапрос.Субконто1
                      |            И Товары.Счет = ВложенныйЗапрос.Счет";
49 kabanoff
 
12.01.12
15:56
(44) Ну контроль остатков обычно выполняется в обработке проведения.
А так согласен, нужно думать головой и решать в каждом конкретном случае.
50 kabanoff
 
12.01.12
16:02
(48)
1. Ты е%анулся? Получать остатки по РБ без указания счета - это глупость.
1.1. У тебя остатки номенклатуры могут на разных счетах лежать?
2. Пользуйся ограничением типов по субконто и конструкцией ВЫРАЗИТЬ().
3. Используй ограничение по номенклатуре в параметрах виртуальной таблицы Остатков РБ (как это сделано в (42).
4. В данном случае запрос к остаткам РБ можно делать без вложенного запроса.
51 1С_Дурик
 
12.01.12
16:08
(50) 1.Разве я не указал??? "И Товары.Счет = ВложенныйЗапрос.Счет"
52 hhhh
 
12.01.12
16:11
(51) вот ты указал

ИЗ
                      |            РегистрБухгалтерии.Хозрасчетный.Остатки(&Дата, , ,Субконто2


таблица остатков формируется по всему плану счетов. Там счетов 150-200.
53 1С_Дурик
 
12.01.12
16:16
не пойму как сделать, помогите пожалуйста
54 hhhh
 
12.01.12
16:54
(&Дата, , Счет В (&СписокСчетов),Субконто2
55 1С_Дурик
 
12.01.12
16:59
Так правильно будет?

РегистрБухгалтерии.Хозрасчетный.Остатки(
                  |                    &Дата,
                  |                    Счет В
                  |                        (ВЫБРАТЬ
                  |                            Товары.Счет
                  |                        ИЗ
                  |                            Товары),
                  |                    ,
                  |                    Субконто2 = &Склад) КАК ХозрасчетныйОстатки
56 1С_Дурик
 
12.01.12
19:07
подскажите альтернативу МоментВремени, при использовании, запрос выполняется 7.355 сек, при использовании Граница 0.423 сек. Итоги пересчитал, тестирование и исправление ИБ делал, ничего не помогает...
57 kabanoff
 
13.01.12
09:54
(55) Да, только добавь еще ограничение по типам субконто в параметры виртуальной таблицы:
&СписокСубконто
где СписокСубконто - список значений с элементами ПВХ "ВидыСубконтоХозрасчетные".

и вырази тип Субконто2, т.е.
ВЫРАЗИТЬ(Субконто2 КАК Справочник.Склады) = &Склад

Индексирование еще по счету во временную таблицу добавь:
ИНДЕКСИРОВАТЬ ПО Счет, Номенклатура
58 1С_Дурик
 
13.01.12
12:40
сделал вот так, ругается
Ошибка обработки представления "РегистрБухгалтерии.Хозрасчетный.Остатки:Недопустимое значение параметра виды субконто."
Запрос.УстановитьПараметр("СписокСубконто",ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные);
Запрос.Текст = "ВЫБРАТЬ
                      |    Товары.Номенклатура КАК Номенклатура,
                      |    Товары.Счет КАК Счет,
                      |    Товары.Количество
                      |ПОМЕСТИТЬ Товары
                      |ИЗ
                      |    &ТЧОстатков КАК Товары
                      |
                      |ИНДЕКСИРОВАТЬ ПО
                      |    Счет,
                      |    Номенклатура
                      |;
                      |
                      |////////////////////////////////////////////////////////////////////////////////
                      |ВЫБРАТЬ
                      |    Товары.Номенклатура,
                      |    ВложенныйЗапрос.КоличествоОстатокДт КАК Остаток,
                      |    ВложенныйЗапрос.КоличествоОстатокДт - Товары.Количество КАК КонОстаток
                      |ИЗ
                      |    Товары КАК Товары
                      |        ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБРАТЬ
                      |            ХозрасчетныйОстатки.КоличествоОстатокДт КАК КоличествоОстатокДт,
                      |            ХозрасчетныйОстатки.Счет КАК Счет,
                      |            ХозрасчетныйОстатки.Субконто1 КАК Субконто1,
                      |            ХозрасчетныйОстатки.Субконто2 КАК Субконто2
                      |        ИЗ
                      |            РегистрБухгалтерии.Хозрасчетный.Остатки(
                      |                    &Дата,
                      |                    Счет В
                      |                        (ВЫБРАТЬ
                      |                            Товары.Счет
                      |                        ИЗ
                      |                            Товары),
                      |                    &СписокСубконто,
                      |                    ВЫРАЗИТЬ(Субконто2 КАК Справочник.Склады) = &Склад) КАК ХозрасчетныйОстатки) КАК ВложенныйЗапрос
                      |        ПО Товары.Номенклатура = ВложенныйЗапрос.Субконто1
                      |            И Товары.Счет = ВложенныйЗапрос.Счет";
59 hhhh
 
13.01.12
12:51
(58) ну вот это бред ИМХО

Запрос.УстановитьПараметр("СписокСубконто",ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные);
60 kabanoff
 
13.01.12
12:55
(58) Очевидно надо сделать так:

СписокСубконто = Новый СписокЗначений;
СписокСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура); //если под субконто1 в запросе понимается номенклатура
СписокСубконто.Добавить(ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Склады); //в запросе это у тебя субконто2

Запрос.УстановитьПараметр("СписокСубконто", СписокСубконто);
61 1С_Дурик
 
13.01.12
13:46
спасибо. Запрос работает, но проблема осталась, долго выполняется. Если момент времени использую = 14,773 сек, если ссылка.дата = 4,417 сек
Компьютер — устройство, разработанное для ускорения и автоматизации человеческих ошибок.