Имя: Пароль:
1C
1C 7.7
v7: БУ 4.5 Запрос из отчета "Кассовая книга"
0 YurAnt
 
08.08.14
12:24
Доброго времени суток, господа форумчане. Судя по всему пятница и высокие температуры не способствуют концентрации и логическому мышлению...
Снова столкнулся в кои-то веки с семеркой.
Проблема в следующем, есть модифицированный запрос (от стандартного отличается вставками "Если"), данные вставки осуществляют проверку на соответствие записей выборки - 2м реквизитам формы.

//******************************************************************
Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(КассоваяКнига)
    |Период с НачЗапроса по КонДата;
    |ОбрабатыватьДокументы Все;
    |Обрабатывать НеПомеченныеНаУдаление;
    |ПриходДок = Документ.ПриходныйОрдер.Сумма,Документ.ПриходныйОрдерТорг.Сумма;
    |РасходДок = Документ.РасходныйОрдер.Сумма,Документ.РасходныйОрдерТорг.Сумма;  
    |";
    Если ПустоеЗначение(ОтборПоМестуХранения) = 0 Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |РасхДТСубк2 = Документ.РасходныйОрдер.Субконто2;
        |ПрКТСубк2 = Документ.ПриходныйОрдер.Субконто2;";
    КонецЕсли;
    
    Если ПустоеЗначение(ОтборПоДвижДС) = 0 Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |РасхКТСубк1 = Документ.РасходныйОрдер.Субконто1;";
    КонецЕсли;
    
    ТекстЗапроса = ТекстЗапроса + "
    |Валюта = Документ.ПриходныйОрдер.Валюта, Документ.РасходныйОрдер.Валюта;
    |Функция Приход = Сумма(ПриходДок);
    |Функция Расход = Сумма(РасходДок);
    |Группировка День;
    |Группировка Документ;";
    
    Если (ПустоеЗначение(ОтборПоМестуХранения) = 0) И (ПустоеЗначение(ОтборПоДвижДС) = 1) Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |Условие ((РасхДТСубк2 = ОтборПоМестуХранения) ИЛИ (ПрКТСубк2 = ОтборПоМестуХранения));";
    ИначеЕсли (ПустоеЗначение(ОтборПоМестуХранения) = 1) И (ПустоеЗначение(ОтборПоДвижДС) = 0) Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |Условие (РасхКТСубк1 = ОтборПоДвижДС);";
    ИначеЕсли (ПустоеЗначение(ОтборПоМестуХранения) = 0) И (ПустоеЗначение(ОтборПоДвижДС) = 0) Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |Условие ((РасхДТСубк2 = ОтборПоМестуХранения) ИЛИ (ПрКТСубк2 = ОтборПоМестуХранения) ИЛИ (РасхКТСубк1 = ОтборПоДвижДС));";
    КонецЕсли;
    
    ТекстЗапроса = ТекстЗапроса + "
    |"//}}ЗАПРОС
    ;
    Запрос.Выполнить(ТекстЗапроса);
//******************************************************************

например на форме юзер выбрал ОтборПоМестуХранения = Склад№1;
ОтборПоДвижДС = "Выплата в кассу";

соотв-но должны отбираются только записи о документах, в которых значения соответствующих субконто совпадают с реквизитом формы.

Чувствую что, что-то не так с условиями запроса, поскольку когда выбираю например отбор по движ-ю денеж средств "ОтборПоДвижДС" (а такое субконто есть только у Расходных Ордеров) - отбираются ВСЕ записи расходных ордеров вне зависимости от значения субконто...


т.е. когда заполнен ОтборПоДвижДС и не заполнен 2й отбор, в начале запроса в выборку попадает субконто1, и в условии в конце происходит по нему отбор
на первый взгляд вроде логика не нарушена (см. ниже)

ИначеЕсли (ПустоеЗначение(ОтборПоМестуХранения) = 1) И (ПустоеЗначение(ОтборПоДвижДС) = 0) Тогда
        ТекстЗапроса = ТекстЗапроса + "
        |Условие (РасхКТСубк1 = ОтборПоДвижДС);";

но вот в чем недочет пока не пойму, немного вот призадумался.
С пятницей всех. Благодарен за любые советы, с ув. YurAnt.
1 шаэс
 
08.08.14
14:03
странный запрос. у Вас всегда субконто1 и субконто2 - одни и те же?
2 YurAnt
 
14.08.14
08:01
В итоге с запросом разобрался, но попутно возникла проблеиа с бух-итогами на начало периода - а именно

//**********************************************************
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
//***************************************
Если ПустоеЗначение(ОтборПоМестуХранения) = 0 Тогда
    Ит.ИспользоватьСубконто(ВидыСубконто.МестаХранения, ОтборПоМестуХранения, 2, );
КонецЕсли;
Если ПустоеЗначение(ОтборПоДвижДС) = 0 Тогда
    Ит.ИспользоватьСубконто(ВидыСубконто.ДвиженияДенежныхСредств, ОтборПоДвижДС, 2, );
КонецЕсли;
//***************************************
Ит.ВыполнитьЗапрос(НачЗапроса, КонДата, "50.1,50.11",,,, "День", "СВ");
    Запрос = СоздатьОбъект("Запрос");
    ТекстЗапроса =
    "//{{ЗАПРОС(КассоваяКнига)
    |Период с НачЗапроса по КонДата;
    |ОбрабатыватьДокументы Все;
    |Обрабатывать НеПомеченныеНаУдаление;
    |ПриходДок = Документ.ПриходныйОрдер.Сумма,Документ.ПриходныйОрдерТорг.Сумма;
    |РасходДок = Документ.РасходныйОрдер.Сумма,Документ.РасходныйОрдерТорг.Сумма;  
    |Валюта = Документ.ПриходныйОрдер.Валюта, Документ.РасходныйОрдер.Валюта;
    |Функция Приход = Сумма(ПриходДок);
    |Функция Расход = Сумма(РасходДок);
    |Группировка День;
    |Группировка Документ;
    |"//}}ЗАПРОС
    ;
    Запрос.Выполнить(ТекстЗапроса);        
ТЗ = СоздатьОбъект("ТаблицаЗначений");
ТЗ.НоваяКолонка("Валюта", "Справочник.Валюты");
ТЗ.НоваяКолонка("ВалОстаток", "Число", 15, 2);
ТЗ.НоваяКолонка("Остаток", "Число", 15, 2);
ТЗ.НоваяКолонка("ВалПриход", "Число", 15, 2);
ТЗ.НоваяКолонка("Приход", "Число", 15, 2);
ТЗ.НоваяКолонка("ВалРасход", "Число", 15, 2);
ТЗ.НоваяКолонка("Расход", "Число", 15, 2);

Ит.ВыбратьВалюты();
Пока Ит.ПолучитьВалюту() = 1 Цикл
    Если Ит.Валюта.Выбран() = 1 Тогда
        ТЗ.НоваяСтрока();
        ТЗ.Валюта = Ит.Валюта;
        ТЗ.Остаток = Ит.СНД("С");
        ТЗ.ВалОстаток = Ит.СНД("В");
    КонецЕсли;
КонецЦикла;
ТЗ.НоваяСтрока();
ТЗ.Валюта = ПолучитьПустоеЗначение("Справочник.Валюты");
ТЗ.Остаток = Ит.СНД("С")-ТЗ.Итог("Остаток");
ТЗ.ВалОстаток = Ит.СНД("В")-ТЗ.Итог("ВалОстаток");
ТЗ.Сортировать("Валюта");
//*********************************************************

не считается остаток на начало дня, при добавлении условий отбора ("ОтборПоДвижДС" - когда в реквизите формы, юзер выбирает значение, срабатывает Если, добавляется отбор)

Ит.ИспользоватьСубконто(ВидыСубконто.ДвиженияДенежныхСредств, ОтборПоДвижДС, 2, );

тогда Ит.СНД("С")- возвращает пустое значение.
когда ИспользоватьСубконто (извиняюсь за тавтологию) не используется - выводится стандартный остаток на нач. дня по всем, без отборов по субконто соответственно.
3 YurAnt
 
14.08.14
11:28
Я определенно чего-то не понимаю...
Упростил пока что задачу, дабы понять. Создал Чистую форму, и накидал туда конструктором бух.запроса

на форме 3 реквизита ВыбНачПериода,ВыбКонПериода, и ВыбСубконто1
(Рис.1) http://savepic.su/4272601.png

последний реквизит конструктор сделал неопределенного типа (в итоге для выбора он недоступен) - поправил руками на "Справочник.ДвиженияДенежныхСредств"

В код внес условие когда он выбран и Иначе. Если он выбран - работает условие отбора... и вот как оно отбирает хоть убейте не пойму.

//***********************************************************
//{{БУХГАЛТЕРСКИЙ ЗАПРОС(Сформировать)

//Данный фрагмент построен конструктором.
//При повторном использовании конструктора, внесенные вручную изменения будут потеряны!!!

//{{ Схема номер 7


Процедура Сформировать()
Таб = СоздатьОбъект("Таблица");
Таб.ИсходнаяТаблица("Сформировать");
Ит = СоздатьОбъект("БухгалтерскиеИтоги");
Ит.Рассчитать(ВыбНачПериода,ВыбКонПериода);
Если ПустоеЗначение(ВыбСубконто1) = 0 Тогда
    ДебетСальдоНач = Ит.СНДРС(СчетПоКоду("50.1"), "С",, ВыбСубконто1, "!"); // ДебетСальдоНач
Иначе
    ДебетСальдоНач = Ит.СНДРС(СчетПоКоду("50.1"), "С",,  , "!");
КонецЕсли;
    
Таб.ВывестиСекцию("Секция");
Таб.ТолькоПросмотр(1);
Таб.Показать("Сформировать","");
КонецПроцедуры
//}}БУХГАЛТЕРСКИЙ ЗАПРОС  

Процедура ПриОткрытии()

//{{ИНИЦИАЛИЗАЦИЯ БУХГАЛТЕРСКОГО ЗАПРОСА(Сформировать)
//{{ИНИЦИАЛИЗАЦИЯ БУХГАЛТЕРСКОГО ЗАПРОСА

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

Собственно проверяю на конкретном документе.
(Рис.2) http://savepic.su/4260313.png
на пикче - видно что от 01-08-14 есть док.
то есть даже если остаток на нач дня 01-08-14 нулевой, то на 02-08-14 он должен измениться на сумму ПКО (см Рис.2)
однако он выдает всегда нулевой остаток...
не могу понимать в чем тут замес =/

С ув. YurAnt.
4 YurAnt
 
14.08.14
11:32
PS когда отбора нет - т.е. в Условие отрабатывает сегмент кода с

Иначе ДебетСальдоНач = Ит.СНДРС(СчетПоКоду("50.1"), "С",,  , "!");

он выдает корректный остаток на нач дня, но само собой по всем ДДС без отбора.
5 YurAnt
 
14.08.14
15:05
это было ооооочень странно, однако мне удалось разобраться.
убрал отбор итогов после "ДвиженияДенежныхСредств" (см. код ниже)

//**********************************************************
Если ПустоеЗначение(ОтборПоДвижДС) = 0 Тогда
    Ит.ИспользоватьСубконто(ВидыСубконто.ДвиженияДенежныхСредств, , 1, );
КонецЕсли;
//**********************************************************

При

"...
Ит.ВыбратьСубконто();
    Пока Ит.ПолучитьСубконто() = 1 Цикл
..."

значения Ит.СНД, Ит.СНДРС = 0, т.е. выбирать субконто нет смысла, поскольку непустое Ит.ПредставлениеСубконто() и ненулевое значение Ит.СНД существуют только в выборке Ит.ВыбратьПериоды();

собственно туда и копал. По получению периода повесил заполнение таблицы Остатков. Взлетело.

Так или иначе проблема решена полностью.
Программист всегда исправляет последнюю ошибку.