Имя: Пароль:
1C
1С v8
Непонятная проблема с циклом
,
0 artmatru
 
26.10.12
16:47
Всем привет.
Есть документ, написал модуль проведения, простенький. Стал проверять. Проводяться только первые пять строк документа.Дальше не проводиться, никаких ошибок нет. Это весь код обработки проведения. В нем есть комментарии. Не понимаю куда рыть, может кто то подскажет где я напутал.



Запрос = Новый Запрос;
Запрос.Текст=
 "ВЫБРАТЬ
 | ОстаткиТоваровОстатки.Товар КАК Товар
 |ИЗ
 | РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
 |
 |УПОРЯДОЧИТЬ ПО
 | Товар" ;
 Результат = Запрос.Выполнить().Выбрать();
 
 // регистр ОстаткиТоваров Приход
Движения.ОстаткиТоваров.Записывать = Истина;
Для Каждого ТекСтрокаТовары Из Товары Цикл
 ТД = СокрЛП(ТекСтрокаТовары.Товар);//товар из документа, на 6 проходе сюда попадает как обычно значение товара
 Пока Результат.Следующий() Цикл //на 6 проходе программа заходит сюда и выходит из цикла
  ТР = СокрЛП(Результат.Товар);//товар из регистра
  Если ТД=ТР Тогда
   Колво = ТекСтрокаТовары.КоличествоФ-ТекСтрокаТовары.Количество;
   Движение = Движения.ОстаткиТоваров.Добавить();
   Движение.ВидДвижения = ВидДвиженияНакопления.Приход;
   Движение.Период = Дата;
   Движение.Товар = ТекСтрокаТовары.Товар;
   Движение.Количество = Колво;
   Прервать;
  КонецЕсли;
 КонецЦикла;
КонецЦикла;
1 GLazNik
 
26.10.12
16:49
(0) остатки значит есть только по первым пяти позициям :) а вообще код УГ
2 КуплюКровать
 
26.10.12
16:49
чудной запрос ))) Учи программирование в 1С8, левые соединения
3 Feanorko
 
26.10.12
16:49
Ап стену. С разбега :)
4 del123
 
26.10.12
16:50
значит есть строки, у которых для их ТД нед подходящего ТР ))
5 artmatru
 
26.10.12
16:50
сильно не пинайте я только начинаю)
6 Лефмихалыч
 
26.10.12
16:51
(0) а ты же ведь учишься только, да же и это все в какой-нить своей локальной учебной копии пишешь, так ведь?
7 del123
 
26.10.12
16:51
выгрузи результат запроса в ТЗ и уже ищи по таблице, а не так как ты ищешь..
8 artmatru
 
26.10.12
16:51
да
9 cawokru
 
26.10.12
16:52
10 Михаил Козлов
 
26.10.12
16:52
Цикл Пока внутри цикла ДЛЯ все время идет "вперед", а Вам, скорее всего нужно его каждый раз заново начинать.
11 cawokru
 
26.10.12
16:52
(9) в коллекцию
12 artmatru
 
26.10.12
16:52
в выборке запроса не правильно?
13 del123
 
26.10.12
16:52
и зачем вообще там запрос что то не понятно
14 Feanorko
 
26.10.12
16:53
(12) всё неправильно :)
15 artmatru
 
26.10.12
16:53
как ответить на конкретное сообщение?
16 GLazNik
 
26.10.12
16:54
(10) ксати да... надо так:

Результат.Сбросить();
Пока Результат.Следующий() Цикл

Но так лучше не делать.
17 cawokru
 
26.10.12
16:54
(номер-цифирькой)вот так (15)
18 Feanorko
 
26.10.12
16:54
(15) вот так - (15)
19 Alexander Shevchuck
 
26.10.12
16:54
Посмотри это для начала http://chistov.spb.ru/publ/free_webinar/6-1-0-17
20 artmatru
 
26.10.12
16:55
(17) проверка )
21 artmatru
 
26.10.12
16:56
о спасибо
22 cawokru
 
26.10.12
16:56
ВЫБРАТЬ
 | ОстаткиТоваровОстатки.Товар КАК Товар
 |ИЗ
 | табчастидокумента
| левое соединение с РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
по товар=товар
и понеслась...
23 cawokru
 
26.10.12
16:56
ну выборку естественно уже сам сформируешь
24 artmatru
 
26.10.12
16:57
слишком много ссобщений погодите сразу не смогу ответить, объяснить)
25 Лефмихалыч
 
26.10.12
16:57
(0)

ВЫБРАТЬ
  ВТ.Номенлатура, Сумма(ВТ.Количество)
ПОМЕСТИТЬ Товары
ИЗ Документ.ТвойДокумент.Товары
ГДЕ Ссылка = &СсылкаНаТвойДокумент
СГРУППИРОВАТЬ ПО ВТ.Номенлатура;
ВЫБРАТЬ
ТОвары.Номенлатура, Товары.Количество, ЕСТЬNULL(Остатки.Количество,0) КАК КоличествоОстаток
ИЗ Товары
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(&МоментВремени, Номенклатура в (ВЫБРАТЬ Товары.Номенклатура)) КАК Остатки
ПО Остатки.Номенклатура = Товары.Номенклатура
26 cawokru
 
26.10.12
17:00
(25) надо оставлять всегда пространство для самостоятельного творчества, а Вы прям все и сразу...
27 artmatru
 
26.10.12
17:00
короче, выяснил с помощью отладчика, что после пятой строки переменная ТД получает значение товара без проблем, далее вложенный цикл должен найти этот товар у себя в выборке запроса, НО он не заходит дальше и переменная ТР не принимает новых значений. Поправьте если что не так
28 temsa
 
26.10.12
17:02
(0)  Пусть будет код по твоему (понимаю учишься). На зачем делаешь запрос и потом проверяешь только то что в запросе присутствует номенклатура из строк документа. Может быть все-таки хотела проверить что-то количестваенное?
29 Лефмихалыч
 
26.10.12
17:02
(27) все не так. Я уже поправил в (25)
30 cawokru
 
26.10.12
17:02
а попробуй поменять циклы местами)))
31 cawokru
 
26.10.12
17:02
и будет чудо чудесное нерациональнейшее
32 Alexander Shevchuck
 
26.10.12
17:03
Вот тебе методика контроля отрицательных остатков от Павла Чистова, попробуй ее:

Имеем конфигурацию с одним регистром накопления «ОстаткиТоваров», регистр имеет 2 измерения: «Номенклатура» и «Склад» и один ресурс «Количество». По регистру движения формируют 2 документа: «Приходная» и «Расходная». Справочники, реквизиты документов и типы данных надеюсь очевидны.

Про «Приходную» писать нечего, там просто формируются в «плюс» остатки. Про «Расходную поговорим подробнее. Для начала вспомним, как формировалась процедура проведения в 8.1.

Для начала мы получали запросом данные табличной части документа, группировали ее, чтобы исключить дубли строк, и соединяли с таблицей остатков регистра:

Запрос = Новый Запрос;

Запрос.Текст = "ВЫБРАТЬ

|     РасходнаяТовары.Номенклатура,

|     СУММА(РасходнаяТовары.Количество) КАК Количество

|ПОМЕСТИТЬ ДокТЧ

|ИЗ

|     Документ.Расходная.Товары КАК РасходнаяТовары

|ГДЕ

|     РасходнаяТовары.Ссылка = &Ссылка

|

|СГРУППИРОВАТЬ ПО

|     РасходнаяТовары.Номенклатура

|;

|

|////////////////////////////////////////////////////////////////////////////////

|ВЫБРАТЬ

|     ДокТЧ.Номенклатура,

|     ДокТЧ.Количество,

|     ЕСТЬNULL(ОстаткиТоваровОстатки.КоличествоОстаток,0) КАК Остаток

|ИЗ

|     ДокТЧ КАК ДокТЧ

|           ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.ОстаткиТоваров.Остатки(

|                       ,

|                       Склад = &Склад

|                            И Номенклатура В

|                                  (ВЫБРАТЬ

|                                        ДокТЧ.Номенклатура

|                                  ИЗ

|                                        ДокТЧ КАК ДокТЧ)) КАК ОстаткиТоваровОстатки

|           ПО ДокТЧ.Номенклатура = ОстаткиТоваровОстатки.Номенклатура";

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

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

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

Кроме этого данные табличной части документа мы использовали для дополнительного отбора при расчете виртуальной таблицы.

Обратите также внимание на функцию ЕСТЬNULL которую мы использовали для гарантии избавления от типа значения NULL в результате запроса. Остатки, которых на складе нет, не присоединятся в таблице документа, и мы поля с остатком заполним значением 0 (ноль).

После того как данные запросом были получены нам оставалось проверить остатки и сформировать движения по регистру. Причем в нашем случае никто не мешает сделать это за один проход.

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

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

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

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

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

     КонецЕсли;

   

     Если Не Отказ Тогда

           Движение = Движения.ОстаткиТоваров.Добавить();

           Движение.ВидДвижения = ВидДвиженияНакопления.Расход;

           Движение.Период = Дата;

           Движение.Номенклатура = Выборка.Номенклатура;

           Движение.Склад = Склад;

           Движение.Количество = Выборка.Количество;

КонецЕсли;

КонецЦикла;
33 temsa
 
26.10.12
17:04
И еще, а зечем при приходвании товара еще лезть в в регистрыостатков? Понимаю при расходе (списывании) есть смысл проверить если нужное количесвто или там узнать себестоимсоть списания...
34 cawokru
 
26.10.12
17:06
(33) он просто вид движения попутал
35 Alexander Shevchuck
 
26.10.12
17:07
(33) Согласен, а я даже не обратил внимания, что вид движения приход...
36 cawokru
 
26.10.12
17:07
твой вопрос = а зачем он приходует ТекСтрокаТовары.КоличествоФ-ТекСтрокаТовары.Количество
37 cawokru
 
26.10.12
17:08
который как математика твердит всегда будет = 0
38 cawokru
 
26.10.12
17:08
букавку "ф" пропустил - виноват...
39 palpetrovich
 
26.10.12
17:09
про демо-версию уже было? :)
40 cawokru
 
26.10.12
17:09
в общем читаю и путаюсь, простите, пятница...
41 artmatru
 
26.10.12
17:09
давайте отвлечемся от частностей. сразу скажу в регистре 9 записей в доке тоже, остатки есть, почему не идет дальше 6 проходов?
42 artmatru
 
26.10.12
17:11
я еще дома перечитаю и проверю все ваши сообщения, сейчас не смогу сходу да и бежать надо а то закроют на работе)
43 Alexander Shevchuck
 
26.10.12
17:11
потому, что не выполняеться условие Если ТД=ТР Тогда
44 artmatru
 
26.10.12
17:12
(43) туда не попадает выполнение после 5 строки
45 artmatru
 
26.10.12
17:13
как будто выборка очищается
46 artmatru
 
26.10.12
17:14
ладно всем спасибо за помощь, зайду позже вечером из дома
47 temsa
 
26.10.12
17:16
(44) Если уж писать по твоему то так.

Запрос = Новый Запрос;
Запрос.Текст=
 "ВЫБРАТЬ
 | ОстаткиТоваровОстатки.Товар КАК Товар
 | ОстаткиТоваровОстатки.Количество КАК КолВоОст
 |ИЗ
 | РегистрНакопления.ОстаткиТоваров.Остатки КАК ОстаткиТоваровОстатки
 |
 |УПОРЯДОЧИТЬ ПО
 | Товар" ;
 Результат = Запрос.Выполнить();

 
 // регистр ОстаткиТоваров Приход

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

  ТР = Результат.Товар;//товар из регистра

  Если ТД=ТР Тогда
Если Результат.КолВоОст >=ТекСтрокаТовары.Количество Тогда
   Колво = ТекСтрокаТовары.КоличествоФ-ТекСтрокаТовары.Количество;
   Движение = Движения.ОстаткиТоваров.Добавить();
   Движение.ВидДвижения = ВидДвиженияНакопления.Расход;
   Движение.Период = Дата;
   Движение.Товар = ТекСтрокаТовары.Товар;
   Движение.Количество = Колво;
   Прервать;
КонецЕсли;
  КонецЕсли;
 КонецЦикла;
КонецЦикла;
48 del123
 
26.10.12
17:18
зачем плодить гоунокод, лучше сразу объяснить как надо..
49 temsa
 
26.10.12
17:18
И СокрЛП туту не нужен. Это для строк используется а товар это не строка а ссылка.
50 temsa
 
26.10.12
17:18
(48) Он упорно не хочет слышать нас.
51 cawokru
 
26.10.12
17:21
либо (10), либо (47), либо(30), но лучше все в стиле "все в запросе"
52 Alexander Shevchuck
 
26.10.12
17:21
(47) По его делать не нужно, он для каждой строки документа, выбирает по новой выборку по регистру остатков, представь, что в базе 100000 наименований номенклатуры, а сам документ на 200 строк, это какие ж тормоза будут при проведении
53 ptiz
 
26.10.12
17:22
О боже! Какой код!
54 artmatru
 
26.10.12
22:09
(10) Михаил, Вы правы, выборка проходила всего один раз
(16) помогло, но почему так нельзя делать?
55 ssh2006
 
26.10.12
23:01
56 Steel_Wheel
 
26.10.12
23:32
(3) плюсую яростно и бешенно
57 temsa
 
27.10.12
13:33
(52) О точно я даже не стал об этом думать..
58 Torquader
 
27.10.12
19:07
А почему бы в запросе не отобрать данные только по тем товарам, которые есть в документе ?
59 artmatru
 
27.10.12
21:54
(58)Это мне нужно просто для обучения. И я не понимаю как можно отобрать из данные из документа, если он еще не записан?
60 hhhh
 
27.10.12
22:48
(59) когда проводится документ, он уже записан.
61 artmatru
 
28.10.12
01:12
(60) то есть док вначале записывается, а потом отрабатывает процедура проведения, так ?
Компьютеры — это как велосипед. Только для нашего сознания. Стив Джобс