Имя: Пароль:
1C
 
Переделать из запроса в цикле "по человечески"
0 ac13
 
27.08.18
16:46
Простой пример. Как из этого сделать нормально?

Для каждого Строка из Товары Цикл
    Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("Номенклатура", Строка.Номенклатура);
    Запрос.Текст = "ВЫБРАТЬ
    |    ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
    |ГДЕ
    |    ТоварыНаСкладахОстатки.Номенклатура = &Номенклатура";
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Строка.Количество = Выборка.Остаток;
    КонецЦикла;
КонецЦикла;
1 Джинн
 
27.08.18
16:48
Соединить регистр и ТЧ документа в запросе.
2 Timon1405
 
27.08.18
16:48
выделяешь код, ПКМ -> Рефакторинг -> Убрать запрос в цикле
3 Lexey_
 
27.08.18
16:48
(0) нормально это не только избавиться от запроса в цикле, но и использовать параметры виртуальной таблицы вместо секции ГДЕ
4 piter3
 
27.08.18
16:48
убрать к чертям где,заменить на параметры списком.Убрать цикл.
5 ac13
 
27.08.18
16:49
(1) а если у меня будет не ТЧ документа, а ТЧ обработки?
6 Lexey_
 
27.08.18
16:50
(5) то что?
7 Мистикан
 
27.08.18
16:50
(5) а разницы?
8 Пуля
 
27.08.18
16:52
Передай списком значений и замени условие ТоварыНаСкладахОстатки.Номенклатура = &Номенклатура";
9 ac13
 
27.08.18
16:53
(2) такое разве есть?
10 Tonik992
 
27.08.18
16:54
(9) это в люкс версии
11 Мистикан
 
27.08.18
16:55
Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("СписокНоменклатуры", ТЧ.Выгрузить().ВыгрузитьКолонку("Номенклатура"));
    Запрос.Текст = "ВЫБРАТЬ
    |    ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
    |ИЗ
    |    РегистрНакопления.ТоварыНаСкладах.Остатки КАК ТоварыНаСкладахОстатки
    |ГДЕ
    |    ТоварыНаСкладахОстатки.Номенклатура В &Номенклатура";
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Строка.Количество = Выборка.Остаток;
    КонецЦикла;
12 piter3
 
27.08.18
16:55
(11) где зачем?
13 Мистикан
 
27.08.18
16:55
а вообще лучше соединять с регистром, нулевые остатки будут
14 Мистикан
 
27.08.18
16:55
(12) ой да
15 Мистикан
 
27.08.18
16:56
Запрос = Новый Запрос;
    Запрос.УстановитьПараметр("СписокНоменклатуры", ТЧ.Выгрузить().ВыгрузитьКолонку("Номенклатура"));
    Запрос.Текст = "ВЫБРАТЬ
    |    ТоварыНаСкладахОстатки.КоличествоОстаток КАК Остаток
    |ИЗ
    |РегистрНакопления.ТоварыНаСкладах.Остатки(,Номенклатура В (&Номенклатура)) КАК ТоварыНаСкладахОстатки";
    Выборка = Запрос.Выполнить().Выбрать();
    Пока Выборка.Следующий() Цикл
        Строка.Количество = Выборка.Остаток;
    КонецЦикла;
16 Михаил Козлов
 
27.08.18
16:57
(11) "Строка.Количество = Выборка.Остаток;" Строка чему равна?
17 ac13
 
27.08.18
16:57
(10) что за люкс версия?
(15) спасибо за наглядный пример
18 Мистикан
 
27.08.18
16:58
(16) сам разберется ему запрос нужен =)
19 Мистикан
 
27.08.18
17:00
(17) смысл в том что ГДЕ накладывает отбор уже на выборку. Т е запрос получил всю номенклатуру, а потом фильтр. Поэтому нужно отбор делать в параметрах
20 ac13
 
27.08.18
17:03
(19) понял, спасибо
21 ac13
 
27.08.18
17:19
На этом моменте Строка.Количество откуда берется?

Пока Выборка.Следующий() Цикл
    Строка.Количество = Выборка.Остаток;
КонецЦикла;
22 Михаил Козлов
 
27.08.18
17:21
(21) Надо думать это какая-то строка ТЧ обработки с номенклатурой из выборки.
23 ac13
 
27.08.18
17:22
То есть чтобы получить эту строку мне все равно нужно делать цикл обхода строк ТЧ?
24 Михаил Козлов
 
27.08.18
17:27
1. Можно ТЧ.НайтиСтроки(...).
2. Можно поместить ТЧ во временную таблицу, соединиться с остатками, выгрузить результат запроса в ТЧ.
3. Если не нужны строки ТЧ с 0 остатками, можно выгрузить результат запроса в (15) в ТЧ обработки (только не забыть добавить поле ТоварыНаСкладахОстатки.Номенклатура КАК Номенклатура.
25 ac13
 
27.08.18
17:30
(24) спасибо, через найти сделал
26 Мистикан
 
27.08.18
17:35
Запрос.УстановитьПараметр("ТЗ",ТЧ.Выгрузить("Номенклатура"));

Запрос.Текст = "Выбрать
ТЗ.Номенклатура
ПОМЕСТИТЬ ТЗ
ИЗ
&ТЗ КАК ТЗ;
ВЫБРАТЬ
ТЗ.Номенклатура,
Остатки.КоличествоОстаток
ИЗ
ТЗ КАК ТЗ
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ТоварыНаСкладах.Остатки() КАК Остатки
ПО ТЗ.Номенклатура = Остатки.Номенклатура";
27 Мистикан
 
27.08.18
17:38
можешь передать все данные таблицы,обработать в запросе, потом обратно загрузить ее
28 dmt
 
27.08.18
17:39
или передать номер строки в запрос, потом по индексу к строке обратиться
29 ac13
 
27.08.18
17:40
(27) (28) ага, понял, спасибо за помощь
30 Мистикан
 
27.08.18
17:44
(29) но вообще таблицы значений работают крайне неэффективно, отвыкай с ними работать, на мелких базах разницы не увидишь, а вот на больших объемах данных потери производительности вообще печальны.
31 ac13
 
27.08.18
17:51
(30) с чем в данном случае работать?
32 Скиурус
 
27.08.18
17:51
(30) Особенно неэффективно они работают у тех, кто никогда не слыхал про индексирование и типизацию колонок.
33 Cthulhu
 
27.08.18
18:38
(11),(15): "Номенклатура В (&Номенклатура))" или все-таки "Номенклатура В (&СписокНоменклатуры))" ?..
34 Сияющий в темноте
 
27.08.18
20:10
И все потому,что в 1с не сделали отдельно Prepare,и отдельно Execute.
Данный пример очень хорошо показывает,что они нужны.

при выборе одной записи регистра идет поиск по индексу и ответ сразу,когда мы делаем соединение,поиск по индексу будет только в соединении,а номенклатура будет просто выбираться из таблицы(если не сделать таблицу,то будет полное сканирование)потом мы получаем результат,который хоть и индексирован(если сказать системе,что нам нужен индекс),но все равно будет поиск.
запрос в цикле,в итоге,будет медленнее только из-за накладных расходов на создание запроса и поход на сервер.
35 Михаил Козлов
 
27.08.18
20:23
(25) Лучше не Найти, а НайтиСтроки: если в ТЧ 2 (или более) строк с одной номенклатурой.
36 MSOliver
 
28.08.18
01:36
ТС - стаж на форуме семь лет! и такой вопрос...
37 SleepyHead
 
гуру
28.08.18
05:35
(36) Да ладно, вон есть люди - В/У получают и не ездят, а стаж идёт.
38 DSSS
 
28.08.18
05:39
(37) Да, есть такие. Я, например, права получил в 2003, а машину купил только в 2017.
Итого 14 лет безаварийного стажа.
39 Jonny_Khomich
 
28.08.18
05:42
не забудь про период, а то получишь ерунду
40 Мистикан
 
31.08.18
13:42
(36) человек сидел на фиксе и куролесил 7.7 =) норм чу
41 ac13
 
31.08.18
14:00
(40) то, что я зареган 7 лет, это не значит, что я 7 лет одинэсом занимался)
Проблемы невозможно решaть нa том же уровне компетентности, нa котором они возникaют. Альберт Эйнштейн