SeAn1s
Интересующийся
Offline
|
|
« : 26-04-2010 09:23 » |
|
Написал отчет, с таким запросом: "//{{ЗАПРОС(Сформировать) |Период С НачДата По КонДата; |ОбрабатыватьДокументы Все; |Обрабатывать НеПомеченныеНаУдаление; |ДокГ = Документ.ГашениеКупона.ТекущийДокумент; |ДокН = Документ.РасходнаяРозничная.ТекущийДокумент; |ИДСделки = Документ.ГашениеКупона.Купон.ИДСделки, Документ.РасходнаяРозничная.ИД; |Сум = Документ.РасходнаяРозничная.Сумма; |Возврат = Документ.РасходнаяРозничная.ЧекНаВозврат; |Функция СуммаДок = Сумма(Сум) Когда (Возврат = 0); |Функция СуммаВозврат = Сумма(Сум) Когда (Возврат = 1); |Группировка ИДСделки Без упорядочивания Все; |Группировка ДокН Без упорядочивания Все; |";//}}ЗАПРОС Запрос = СоздатьОбъект("Запрос"); Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Возврат; КонецЕсли;
Пока Запрос.Группировка(1) = 1 Цикл Если (ПустоеЗначение(Запрос.ДокГ) = 1) Тогда Продолжить; КонецЕсли; СуммаОбщая = Запрос.СуммаДок - Запрос.СуммаВозврат; Таб.ВывестиСекцию("ИДСделки"); Пока Запрос.Группировка(2) = 1 Цикл СуммаНакладной = Запрос.СуммаДок - Запрос.СуммаВозврат; Таб.ВывестиСекцию("Накладные"); КонецЦикла; КонецЦикла;
Проблема в следующем: В таком варианте в отчет включаются непроведенные и непомеченные на удаление документы РасходнаяРозничная. Документы ГашениеКупона вообще не проводятся, поэтому если в запросе поставить "ОбрабатыватьДокументы Проведенные", то отчет станет вообще пустой. Как исключить из запроса непроведенные РасходныеРозничные? И еще мне не нравится проверка Если (ПустоеЗначение(Запрос.ДокГ) = 1) Тогда Продолжить; КонецЕсли;
при обходе результатов запроса. Можно ли заменить эту проверку чем то в тексте запроса?
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #1 : 26-04-2010 10:28 » |
|
А зачем нужно |ДокГ = Документ.ГашениеКупона.ТекущийДокумент; |ДокН = Документ.РасходнаяРозничная.ТекущийДокумент;
? Почему не так: |Док = Документ.ГашениеКупона.ТекущийДокумент, Документ.РасходнаяРозничная.ТекущийДокумент;
? В моем случае для проверки проведенности расходной вставляем следующее условие (в конец запроса): |Условие((Док.Вид()=""ГашениеКупона"") ИЛИ (Док.Проведен() = 1));
Что касается проверки в цикле - то она по идее тоже уйдет в моем варианте
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #2 : 26-04-2010 11:23 » |
|
А зачем нужно |ДокГ = Документ.ГашениеКупона.ТекущийДокумент; |ДокН = Документ.РасходнаяРозничная.ТекущийДокумент;
? Почему не так: |Док = Документ.ГашениеКупона.ТекущийДокумент, Документ.РасходнаяРозничная.ТекущийДокумент;
? Я так сначала и пытался сделать, и не понимаю почему, но так результат запроса пустой получался. И |Условие (Док.Проведен = 1); тоже пытался делать, ругается: "Значение не представляет агрегатный объект (Проведен):2".
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #3 : 26-04-2010 12:55 » |
|
Вместо добавления в текст запроса строчки |Условие (Док.Проведен() = 1); можно опять же вставить в цикл по группировке 2 такую проверку Если Запрос.ДокН.Проведен() = 0 Тогда Продолжить; КонецЕсли; , т.е. получится Пока Запрос.Группировка(2) = 1 Цикл Если Запрос.ДокН.Проведен() = 0 Тогда Продолжить; КонецЕсли; СуммаНакладной = Запрос.СуммаДок - Запрос.СуммаВозврат; Таб.ВывестиСекцию("Накладные"); КонецЦикла; но мне это не нравится, будет медленней чем в тексте запроса. Может все таки есть способ?
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #4 : 26-04-2010 17:27 » |
|
Ты разные тексты написал. Сравни: Условие (Док.Проведен() = 1); и Условие (Док.Проведен = 1);
Насчет того, что будет медленней - не уверен. Это тестировать нужно. Запросы в 7.7 вообще слабо оптимизируются, особенно если используется вызов функций
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #5 : 27-04-2010 01:01 » |
|
Ты разные тексты написал. Сравни: Условие (Док.Проведен() = 1); и Условие (Док.Проведен = 1);
Просто ошибся, когда сообщение писал, а как редактировать его не нашел. Так что конечно Док.Проведен() = 1 правильно, именно это и пытался использовать. Не получилось. А насчет медленней, я тестировал. Действительно медленней, если перебор в цикле, а не в тексте запроса. На сервере это замедление практически не чувствуется, а на удаленном компе очень даже заметно.
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #6 : 27-04-2010 08:57 » |
|
Те строки, которые я написал у меня точно работают (ну только другие виды документов брал для проверки), так что ошибку ищи в другом. Важно чтобы в одном условии присутсвовало ИЛИ, т.е. чтобы один вид документов отбирался полностью, а второй - только проведенные. Кстати: в твоем случае ошибка может быть из-за того, что у тебя две переменных документа и для каждой строки результата запроса одна из них будет незаполнена - вот тебе и выдает, что "Значение не представляет агрегатный объект (Проведен):2 [для пустой переменной]"
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #7 : 27-04-2010 13:28 » |
|
у тебя две переменных документа и для каждой строки результата запроса одна из них будет незаполнена - вот тебе и выдает, что "Значение не представляет агрегатный объект (Проведен):2 [для пустой переменной]"
Я проверял условие и для варианта, когда документ 1. То есть исключал из запроса второй документ. Результат тот же.
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #8 : 27-04-2010 19:14 » |
|
У тебя в базе есть документы РасходнаяНакладная и ПриходнаяНакладная? Вот этот запрос рабочий (обработка в атаче): Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Период с ВыбНачПериода по ВыбКонПериода; |ОбрабатыватьДокументы все; |Обрабатывать НеПомеченныеНаУдаление; |Без итогов; |Док = Документ.ПриходнаяНакладная.ТекущийДокумент, Документ.РасходнаяНакладная.ТекущийДокумент; |Группировка Док; |Условие((Док.Вид()=""РасходнаяНакладная"") ИЛИ (Док.Проведен() = 1)); |"//}}ЗАПРОС ;
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #9 : 27-04-2010 19:15 » |
|
Результат запроса: расходные попадают все, приходные - только проведенные
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #10 : 28-04-2010 02:22 » |
|
Хм. У меня твоя обработка тоже работает. Почему же не работает мой отчет? Точнее он работает, но в том варианте о котором я писал выше.
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #11 : 28-04-2010 02:29 » |
|
Вот то что имеется сейчас, работает: Процедура Сформировать() Запрос = СоздатьОбъект("Запрос"); ТекстЗапроса = "//{{ЗАПРОС(Сформировать) |Период С НачДата По КонДата; |ОбрабатыватьДокументы Все; |Обрабатывать НеПомеченныеНаУдаление; |ДокГ = Документ.ГашениеКупона.ТекущийДокумент; |ДокН = Документ.РасходнаяРозничная.ТекущийДокумент; |Автор = Документ.ГашениеКупона.Автор; |ИДСделки = Документ.ГашениеКупона.Купон.ИДСделки, Документ.РасходнаяРозничная.ИД; |Сум = Документ.РасходнаяРозничная.Сумма; |Возврат = Документ.РасходнаяРозничная.ЧекНаВозврат; |Функция СуммаДок = Сумма(Сум) Когда (Возврат = 0); |Функция СуммаВозврат = Сумма(Сум) Когда (Возврат = 1); |"; Если (СЗ.РазмерСписка() > 0) Тогда Если СЗ.НайтиЗначение("<<по всем авторам>>") = 0 Тогда ТекстЗапроса = ТекстЗапроса + "Условие (Автор в СЗ); |"; КонецЕсли; КонецЕсли; ТекстЗапроса = ТекстЗапроса + " |Группировка ИДСделки Без упорядочивания Все; |Группировка ДокН Без упорядочивания Все; |";//}}ЗАПРОС Запрос = СоздатьОбъект("Запрос"); Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда Сообщить("Запрос не выполнен!"); Возврат; КонецЕсли; // Подготовка к заполнению выходных форм данными запроса Таб = СоздатьОбъект("Таблица"); // Заполнение полей "Заголовок" Таб.ВывестиСекцию("Шапка"); Состояние("Заполнение выходной таблицы..."); Таб.Опции(0, 0, Таб.ВысотаТаблицы(), 0); Пока Запрос.Группировка(1) = 1 Цикл // Заполнение полей ГашениеКупона Если (ПустоеЗначение(Запрос.ДокГ) = 1) Тогда Продолжить; КонецЕсли; СуммаОбщая = Запрос.СуммаДок - Запрос.СуммаВозврат; Таб.ВывестиСекцию("ИДСделки"); Пока Запрос.Группировка(2) = 1 Цикл // Заполнение полей РасходнаяРозничная Накл = Запрос.ДокН; Если Накл.Проведен() = 0 Тогда Продолжить; КонецЕсли; Ном = Накл.НомерДок; Дат = Накл.ДатаДок; Коммент = Накл.Комментарий; СуммаНакладной = Запрос.СуммаДок - Запрос.СуммаВозврат; Таб.ВывестиСекцию("Накладные"); КонецЦикла; КонецЦикла; // Вывод заполненной формы Таб.ПараметрыСтраницы(1,,,20,10,10,10,,,1,1,); Таб.ТолькоПросмотр(1); Таб.Показать("Отчет о гашении купонов",""); КонецПроцедуры //Сформировать()
Другие варианты либо не работали неправильно, либо выдавали ошибки.
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #12 : 28-04-2010 02:32 » |
|
Чувствую, что проблема в первой группировке (там не по документам, а по реквизиту документов).
|
|
|
Записан
|
|
|
|
Kivals
|
|
« Ответ #13 : 28-04-2010 06:48 » |
|
Правильно чувствуешь. Вот ключевой момент у меня в запросе: "Без итогов;" Если тебе нужно с итогами (т.е. чтобы раздельно вызывать группировки) то лучше написать функцию: Функция ПроверитьДокумент(Док) Если ПустоеЗначение(Док)=1 Тогда Возврат 1; КонецЕсли; // Это для группировок, где документ не заполнен Если Док.Вид()="ГашениеКупона" Тогда Возврат 1; КонецЕсли; // Это для документов, которые должны попасть проведенные и не проведенные Возврат Док.Проведен(); // Все остальные - только проведенные КонецФункции Тогда в запросе будет: Условие(ПроверитьДокумент(Док)=1);
|
|
|
Записан
|
|
|
|
SeAn1s
Интересующийся
Offline
|
|
« Ответ #14 : 28-04-2010 07:08 » |
|
Хм. Вечером попробую. Спасибо большое!
|
|
|
Записан
|
|
|
|
|