|
|
|
Как правильно выйти из цикла? | ☑ | ||
|---|---|---|---|---|
|
0
dReamzzz
13.03.08
✎
16:47
|
Условный пример:
Процедура Сформировать() Запрос=СоздатьОбъект("Запрос"); ТекстЗапроса=" |Период С НачДата По КонДата; |ОбрабатыватьДокументы Проведенные; |ВыбФирма=Документ.РасходнаяНакладная.Фирма; |Условие (ВыбФирма = Фирма); |Док=Документ.РасходнаяНакладная.ТекущийДокумент; |Контрагент=Документ.РасходнаяНакладная.Контрагент; |Товар=Документ.РасходнаяНакладная.Товар; |Группировка ВыбФирма; |Группировка Контрагент без Групп; |Группировка Док; |Группировка Товар без Групп; |"; Запрос.Выполнить(ТекстЗапроса); Пока Запрос.Группировка(1)=1 Цикл Сообщить(Запрос.ВыбФирма); Пока Запрос.Группировка(2)=1 Цикл Сообщить(Запрос.Контрагент); Пока Запрос.Группировка(3,-1)=1 Цикл Сообщить(Запрос.Док); Если Запрос.Док.КоличествоСтрок()=1 Тогда Прервать; КонецЕсли; Пока Запрос.Группировка(4)=1 Цикл КонецЦикла; КонецЦикла; КонецЦикла; КонецЦикла; КонецПроцедуры В базе за заданный период есть только два документа «Расходная накладная»: 1) Расходная накладная 1, Контрагент 1, Фирма Какая-то, количество строк 1. 2) Расходная накладная 2, Контрагент 2, Фирма Какая-то, количество строк 1. Результатом выполнения есть следующие сообщения в строке состояния: Фирма Какая-то Контрагент1 Расходная накладная 1 Контрагент 2 По моим соображениям, программа должна прекратить перебор документов по Контрагенту 1, и перейти к перебору документов по Контрагенту 2, и как только наткнется на документ, в табличной части которого одна строка – выйти из цикла. Судя по результатам, программа и не начинает перебирать документы по Контрагенту 2. Почему? Если в Группировке(3) задать направление по возрастанию, то получается правильно. Но мне важно, что бы документы выбирались, начиная с последнего. |
|||
|
1
Vlad55
13.03.08
✎
16:55
|
Прервать,Перейти?
|
|||
|
2
dReamzzz
13.03.08
✎
16:58
|
Почему Прервать не катит?
|
|||
|
3
ZOMI
13.03.08
✎
17:01
|
В чем цель ?
Соображения ,,, Как дешевый бухгалтер задачу формулируешь |
|||
|
4
vip67
13.03.08
✎
17:05
|
так, беглым глазом - что-то тут с запросом нет то...
|
|||
|
5
dReamzzz
13.03.08
✎
17:06
|
Что не то?
|
|||
|
6
dReamzzz
13.03.08
✎
17:06
|
(3) формулирую, как умеею...
|
|||
|
7
dReamzzz
13.03.08
✎
17:11
|
(3) Цель: понять, почему в данном запросе программа не перебирает документы по Контрагенту 2.
|
|||
|
8
vip67
13.03.08
✎
17:20
|
ТекстЗапроса="
|Период С НачДата По КонДата; |ОбрабатыватьДокументы Проведенные; |ВыбФирма=Документ.РасходнаяНакладная.Фирма; |Условие (ВыбФирма = Фирма); |Док=Документ.РасходнаяНакладная.ТекущийДокумент; |Контрагент=Документ.РасходнаяНакладная.Контрагент; |Товар=Документ.РасходнаяНакладная.Товар; |Группировка ВыбФирма; |Группировка Контрагент без Групп; |Группировка Док; |Группировка Товар без Групп; |"; может я и не спец в запросах,но только что почитав про них, у тебя идет присвоение переменных,потом условие,потом опять переменные. Это нормально? второй момент, группировка есть а упорядочивание (сортировать не нужно?) вот он где-то либо циклит, либо просто не доходит до нужного места. Разбей запрос на простые и проанализируй работу. |
|||
|
9
dReamzzz
13.03.08
✎
17:25
|
Всегда так писала, было нормально…
|
|||
|
10
dReamzzz
13.03.08
✎
17:27
|
…а переменная Фирма несет в себе название фирмы.
|
|||
|
11
vip67
13.03.08
✎
17:27
|
(1) сегодня читал здесь статью о том, как корректно писать код Как раз "прервать" и "перейти" считаются крайне нежелательными операторами, это так - к слову. ничего личного...
|
|||
|
12
vip67
13.03.08
✎
17:29
|
еще раз говорю - разбей запрос на простые, отбери сначала одни документы, потом другие, узнай, они у тебя вообще отбираются или нет, срабатывает ли условие, а потом уже делай запрос сложнее и приведи его в божеский вид. Может где-то какая-то переменная не выбирается - и все - хана запросу. у самого такое было.
|
|||
|
13
vip67
13.03.08
✎
17:34
|
и зачем док=...текущий документ(). Убери все и начни с простого - найдешь проблему.
кидаю теорию: Двойная группировка Этот запрос совершает очень полезную работу: он группирует всех сотрудников по должностям. Заметьте, что сначала идет группировка по должности, а затем по сотруднику, это очень важно. Обратите внимание на переменную запроса Сотр. Она ссылается на строку справочника Сотрудники. Чтобы вывести ФИО сотрудника используется обращение к атрибуту объекта: Сотр.Наименование. Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = " |Сотр = Справочник.Сотрудники.ТекущийЭлемент; |Долж = Справочник.Сотрудники.Должность; |Группировка Долж упорядочить по Долж.Наименование; |Группировка Сотр упорядочить по Сотр.Наименование; |"; Запрос.Выполнить(ТекстЗапроса); Пока Запрос.Группировка("Долж")=1 Цикл ............Сообщить(Запрос.Долж); ............Пока Запрос.Группировка("Сотр")=1 Цикл ................Сообщить("......" + Запрос.Сотр.Наименование); ............КонецЦикла; КонецЦикла; а тут и группы и без групп... Не, я в 1с то-же недавно но в програмировании - дай боже. На личном примере знаю, не так сделаешь запрос - и ничего не получишь. |
|||
|
14
dReamzzz
13.03.08
✎
17:37
|
Куда уже проще? Отладчиком проверяла – не отбирает документы по второму контрагенту! Замаялась уже сама выяснять причину, вот и прошу помочь мне!
Без оператора Прервать все работает, а с ним…- не совсем так, как я предполагала. |
|||
|
15
smaharbA
13.03.08
✎
17:38
|
Запрос.Выгрузить(ТЗ)
|
|||
|
16
Ns33
13.03.08
✎
17:45
|
Попробуй использовать Перейти (на метку за 3-й группировкой).
|
|||
|
17
vip67
13.03.08
✎
17:52
|
+(15) и посмотреть что получится, какие доки... хотя я бы убрал все лишнее и поставил услови только по контрагенту2, чтобы знать - будет ли он отбираться... Крепись - и все пройдет!!!
|
|||
|
18
Ns33
13.03.08
✎
18:01
|
Провел подобный эксперимент, реально глюк. У меня как только ставлю -1 после "прервать" сваливается в бесконечный цикл. "Перейти" не помогло.
|
|||
|
19
Ns33
13.03.08
✎
18:03
|
Остаётся старый дубовый способ, см. (15).
|
|||
|
20
Ns33
13.03.08
✎
18:08
|
Еще вариант (работает):
Пропускаем=0; Пока Запрос.Группировка(3,-1) = 1 Цикл Если Пропускаем=1 Тогда продолжить; КонецЕсли; Если Запрос.Док.КоличествоСтрок()=1 Тогда Пропускаем=1; КонецЕсли; КонецЦикла; |
|||
|
21
Ns33
13.03.08
✎
18:10
|
Дополнение к (20) после Пропускаем=1; добавить Продолжить;
|
|||
|
22
dReamzzz
13.03.08
✎
18:23
|
(21) Да, это работает! Хорошо, если у меня два документа, а если перебирать документы за год! Лучше прервать выполнение цикла, чем продолжать их перебирать!
|
|||
|
23
Дядя Васька
13.03.08
✎
22:11
|
(22) В ТЗ выгрузи и с ней изгаляйся. После Прервать не срабатывает Запрос.Группировка(3,-1), чего непонятно-то. Это одноразовая функция, работает либо до конца выборки, либо до Прервать.
Для начала сделай так, чтобы увидеть что получается, ну а дальше думаю разберешься, что с той ТЗ делать:
|
|||
|
24
Дядя Васька
13.03.08
✎
22:13
|
|Группировка Товар без Групп;
имхо, лишнее... |
|||
|
25
Дядя Васька
13.03.08
✎
22:15
|
+(23) Хотя... Если вложенная, должна и после Прервать работать, эт поэкспериментировать надо. Ну да с ТЗ полюбэ сработает, и всегда посмотреть можно что ты там выбираешь...
|
|||
|
26
dReamzzz
13.03.08
✎
22:50
|
Немного перефразирую:
Процедура Сформировать() Запрос=СоздатьОбъект("Запрос"); ТекстЗапроса=" |Период С НачДата По КонДата; |ОбрабатыватьДокументы Проведенные; |ВыбФирма=Документ.РасходнаяНакладная.Фирма; |Док=Документ.РасходнаяНакладная.ТекущийДокумент; |ДатаДок=Документ.РасходнаяНакладная.ДатаДок; |Контрагент=Документ.РасходнаяНакладная.Контрагент; |Группировка ВыбФирма; |Группировка Контрагент без Групп; |Группировка Док; |"; Запрос.Выполнить(ТекстЗапроса); Пока Запрос.Группировка(1)=1 Цикл Сообщить(Запрос.ВыбФирма); Пока Запрос.Группировка(2)=1 Цикл Сообщить(Запрос.Контрагент); Пока Запрос.Группировка(3,-1)=1 Цикл Сообщить(Запрос.Док); Если Запрос.Док.КоличествоСтрок()=1 Тогда Прервать; КонецЕсли; КонецЦикла; КонецЦикла; КонецЦикла; КонецПроцедуры Почему данный код приводит к зацикливанию? |
|||
|
27
AlexWolf
13.03.08
✎
22:58
|
мож канеш я "не умею его готовить", но всегда када пытался пользовать обратный порядок обхода запроса, отказывался от этой идеи из-за каких-нить косяков именно при обходе...
|
|||
|
28
miki
13.03.08
✎
22:59
|
(26)тебе же уже не раз написали, вот цитатко:
>>не следует прерывать последовательность просмотра временного набора данных (например, оператором Прервать;), если вы собираетесь использовать временный набор дальше или еще раз, т. к. в таком случае теряется точка позиционирования во временном наборе и продолжать просмотр невозможно; (с) ЖКК |
|||
|
29
Конь в пальто
13.03.08
✎
22:59
|
у тебя ток из вложенного цикла выходит
|
|||
|
30
dReamzzz
13.03.08
✎
23:00
|
Если убираю -1, то не зацикливает, но при этом не входит второй раз в группировку(3)!
|
|||
|
31
dReamzzz
13.03.08
✎
23:07
|
(28)Я читаю следующее:
Прервать Прерывает выполнение цикла. Синтаксис: Прервать Описание: Прерывает выполнение цикла. Оператор Прервать приводит к немедленному прекращению выполнения цикла и передает управление первому оператору, следующему за конструкцией оператора Пока или Для. Оператор Прервать может использоваться только внутри конструкций операторов цикла Пока и Для. То есть его нельзя использовать во вложенном цикле? |
|||
|
32
dReamzzz
13.03.08
✎
23:07
|
(29) а мне и нужно, чтобы выходило только из одного.
|
|||
|
33
miki
13.03.08
✎
23:19
|
(31)Порой фразы, вырванные из контекста, меняют смысл сказанного до неузнаваемости...
Дилетант (ламер) отличается от профи в том числе и тем, что понадергав из целого куски мнит себя гуру. Да, раз потратив время на решение узкой конкретной задачи. пробехав бегло соответствующий раздел мануала, можно разлулить траблу... Но это не значит, что однажды найденное удачное решение будет рулить всегда. Вещи _похожие_, зачастую, являются _разными_. Цикл циклу рознь. Те же грабли с выборкой из справочника с переназначением кода или сменой родителя... А часто люди не жалелеют время и описывают ограничения на использование функционала... Вот и твой случай прописан черным по белому в документации. Надо только прочитать и осознать... А недоступное для понимания (есть там и такое) принять как объективную реальность... Или написАть свою нетленку. Флаги с барабанами. Их есть... |
|||
|
34
dReamzzz
13.03.08
✎
23:27
|
(33) в (31)я взяла из книги "Описание встроенного языка". А в какой вы книге прочитали, то, что указали в (28)?
|
|||
|
35
АЛьФ
13.03.08
✎
23:30
|
2(34) Это из той же книги, но из раздела про запросы.
|
|||
|
36
КонецЦикла
13.03.08
✎
23:47
|
Боян, прервать при обходе группировок неготично
|
|||
|
37
dReamzzz
13.03.08
✎
23:52
|
(36) Спасибо! Мне уже (33) "толково" объяснил.
|
|||
|
38
АЛьФ
14.03.08
✎
00:07
|
2(37) ИМХО тебе надо курить в сторону метода Получить объекта Запрос.
|
|||
|
39
АЛьФ
14.03.08
✎
00:10
|
+(38) Вспомнилась давняя фича. У тебя в (26) полный код? Там нет случаем еще цикла по строкам документа?
|
|||
|
40
dReamzzz
14.03.08
✎
00:11
|
(39) Полный код
|
|||
|
41
dReamzzz
14.03.08
✎
00:14
|
Спасибо всем еще раз. Я уже прочитала в Разделе про запросы то, что было написано в (28), поняла свою ошибку.
|
| Форум | Правила | Описание | Объявления | Секции | Поиск | Книга знаний | Вики-миста |