Помогите с запросом 1С Предприятие 7.7

Тема в разделе "Продукты 1C", создана пользователем Den1xxx, 16 авг 2017.

  1. Den1xxx

    Den1xxx

    Moderator
    Регистр.:
    15 янв 2014
    Сообщения:
    284
    Симпатии:
    156
    Здравствуйте.
    Чего-то торможу я с запросом, помогите кто может, буду благодарен.

    Задача:
    Выбрать из ТТН в нужном периоде документы с нужными реквизитами, выбрать нижние цены из номенклатуры, сравнить цены отгрузки и минимальные и вывести разницу, для подсчёта прибыли

    Собственно в запросе нужно выбрать реквизиты Документ.РасходнаяНакладная и Справочник.Номенклатура, по совпадению товаров.

    Запрос по выборке из ТТН я написал:
    Код:
    Период с ВыбНачПериода по ВыбКонПериода;
    ДатаДок  = Документ.РасходнаяНакладная.ДатаДок;
    НомерДок  = Документ.РасходнаяНакладная.НомерДок;
    Контрагент  = Документ.РасходнаяНакладная.Контрагент;
    ВидОтгрузки = Документ.РасходнаяНакладная.ВидОтгрузки;
    Курс  = Документ.РасходнаяНакладная.Курс;
    Товар = Документ.РасходнаяНакладная.Товар;
    Колво = Документ.РасходнаяНакладная.Количество;
    Цена = Документ.РасходнаяНакладная.Цена;
    НДС = Документ.РасходнаяНакладная.НДС;
    Всего = Документ.РасходнаяНакладная.Всего;
    Группировка Документ;
    Группировка Товар без групп;
    Условие(Товар в ВыбНоменклатура);
    Условие(ВидОтгрузки = 1);
    Он работает хорошо, результат вставляем в таблицу значений.
    Возможно ли в этом же запросе добавить выборку из Справочник.Номенклатура, из подчиненного ему справочника Цены, чтобы эта цена выводилась по отгруженному Товару?
    Товар в РасходнаяНакладная имеет тип Справочник.Номенклатура
    Мне кажется, должно быть простое решение, но как-то не доходит, как выбрать из подчиненного справочника.
    Помогите пожалуйста, мозг сломал.
     
  2. layman

    layman Создатель

    Регистр.:
    4 фев 2008
    Сообщения:
    18
    Симпатии:
    24
    До запроса
    СпрТЦ = СоздатьОбъект("Справочник.ТипыЦен");
    СпрЦен = СоздатьОбъект("Справочник.Цены");
    СпрТЦ.НайтиПоНаименованию("СвойТипЦен",0,1);
    ТипЦены = СпрТЦ.ТекущийЭлемент();
    В группировки Товар
    СпрЦен.ИспользоватьВладельца(Запрос.Товар);
    Если СпрЦен.НайтиПоРеквизиту("ТипЦен",ТипЦены,0) = 1 Тогда
    Цена = СпрЦен.Цена.Получить(Запрос.ДатаДок)
     
    Den1xxx нравится это.
  3. Den1xxx

    Den1xxx

    Moderator
    Регистр.:
    15 янв 2014
    Сообщения:
    284
    Симпатии:
    156
    Спасибо, я именно так далее и делаю.
    У меня вопрос немного в другом: возможно ли вместо создания объекта — сделать выборку при помощи указанного запроса?
    Т.е. дергать базу 1 раз, а не несколько, тем более что это «дергание» получается в цикле.
    Это у меня такая обработка написана. Из БД данные: в товаре поле минимальной цены сравнивается с ценой продажи и выводится таблица — сколько сэкономили или наоборот сработали в убыток.
    Конечная процедура работает и выглядит так:
    Процедура Сформировать()
    Если (ПустоеЗначение(КурсРубляРФ) = 1)
    ИЛИ (ПустоеЗначение(КурсДоллараСША) = 1)
    ИЛИ (ПустоеЗначение(КратностьРубляРФ) = 1)
    ИЛИ (ПустоеЗначение(КратностьДоллараСША) = 1)
    Тогда
    Предупреждение("Не заполнены все курсы валют!",5);
    Возврат;
    КонецЕсли;

    Таб = СоздатьОбъект("Таблица");
    Запрос = СоздатьОбъект("Запрос");

    Заголовок = ?(ПустоеЗначение(ЗаголовокОтчета)=1,"Отчет по ценам",ЗаголовокОтчета);
    Таб.ИсходнаяТаблица("Таблица11");

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

    // Убираем ненужных свидетелей
    Если НеКонтрагент.РазмерСписка() <> 0 Тогда
    ТекстЗапроса = ТекстЗапроса + "Условие(НЕ(Контрагент в НеКонтрагент));
    |";

    КонецЕсли;


    Если ФлТолькоСотрудники = 3 Тогда
    ТекстЗапроса = ТекстЗапроса + "Условие(ВидОтгрузки = 7);
    |";
    ИначеЕсли ФлТолькоСотрудники = 2 Тогда
    ТекстЗапроса = ТекстЗапроса + "Условие(ВидОтгрузки = 1);
    |";
    КонецЕсли;

    // Если ошибка в запросе, то выход из процедуры
    Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
    Сообщить(ТекстЗапроса);
    Возврат;
    КонецЕсли;

    ТзТТН = СоздатьОбъект("ТаблицаЗначений");
    Запрос.Выгрузить(ТзТТН, 1, 0);
    ТзТТН.НоваяКолонка("Страна", "Справочник.ОКСМ");
    ТзТТН.НоваяКолонка("МинЦена");
    ТзТТН.НоваяКолонка("МинСумма");
    ТзТТН.НоваяКолонка("Партия");
    ТзТТН.НоваяКолонка("Разница");
    ТзТТН.НоваяКолонка("СуммаВал");
    ТзТТН.НоваяКолонка("РазницаВал");
    ТзТТН.НоваяКолонка("Примечание");
    ТзТТН.ВыбратьСтроки();

    Цены = СоздатьОбъект("Справочник.Цены");
    ТипЦен = СоздатьОбъект("Справочник.ТипыЦен");

    //////////////Формируем таблицу товаров//////////////
    Пока ТзТТН.ПолучитьСтроку() = 1 Цикл
    ТзТТН.Примечание = "";
    Если ПустоеЗначение(ТзТТН.Контрагент.СтранаРегистрации) = 1 Тогда
    ТзТТН.Страна = "Белоруссия";
    Сообщить("Не указана страна по " + ТзТТН.Контрагент, "!!!");
    Иначе
    ТзТТН.Страна = ТзТТН.Контрагент.СтранаРегистрации;
    КонецЕсли;
    Если (ТзТТН.ВидОтгрузки = 7) Тогда
    ТзТТН.Контрагент = "Сотрудникам в счет з/платы";
    КонецЕсли;

    //////////////Валюта//////////
    Валюта = СокрЛП(ТзТТН.ТипЦен.Валюта.Наименование);
    Если (ПустоеЗначение(Валюта) = 1) Тогда
    Валюта = "РБ";
    Если (ТзТТН.Курс<>0) И (ТзТТН.Курс<>1) Тогда
    ТзТТН.Примечание = ТзТТН.Примечание + " Проверьте тип цен: " + " курс " + ТзТТН.Курс;
    КонецЕсли;
    КонецЕсли;

    Если (Валюта="RUB") Тогда
    Валюта = "РФ";
    КонецЕсли;

    /////////////Партия/////////////
    Если (ПустоеЗначение(ТзТТН.КолвоМО1) = 1) ИЛИ (ПустоеЗначение(ТзТТН.КолвоМО2) = 1) Тогда
    ТзТТН.Примечание = ТзТТН.Примечание + " Не заполнено количество мелкого опта!";
    Партия = "крупный опт";
    Иначе
    Если (ТзТТН.Колво <= ТзТТН.КолвоМО1) Тогда
    Партия = "мелкий опт 1";
    ИначеЕсли (ТзТТН.Колво <= ТзТТН.КолвоМО2) Тогда
    Партия = "мелкий опт 2";
    Иначе
    Партия = "крупный опт";
    КонецЕсли;
    КонецЕсли;

    ТзТТН.Партия = Валюта + " " + Партия;

    //////////////Цены/////////////////
    Цены.ИспользоватьВладельца(ТзТТН.Товар);
    Цены.ИспользоватьДату(ТзТТН.ДатаДок);
    Если ТипЦен.НайтиПоНаименованию(ТзТТН.Партия) = 1 Тогда
    Если Цены.НайтиПоРеквизиту("ТипЦен",ТипЦен.ТекущийЭлемент(),0) = 1 Тогда
    ТзТТН.МинЦена = Цены.Цена;
    Иначе
    ТзТТН.МинЦена = ТзТТН.Цена;
    ТзТТН.Примечание = ТзТТН.Примечание + " Не найдена цена '" + ТзТТН.Партия + "', установлена по ТТН!";
    КонецЕсли;
    КонецЕсли;
    ТзТТН.МинЦена = ?(ТзТТН.МинЦена=0,ТзТТН.Цена,ТзТТН.МинЦена);
    ТзТТН.Всего = ТзТТН.Колво * ТзТТН.Цена;
    ТзТТН.МинСумма = ТзТТН.Колво * ТзТТН.МинЦена;
    ТзТТН.Разница = ТзТТН.Всего - ТзТТН.МинСумма;

    Если (Валюта="РФ") Тогда
    Если (БратьКурсИзДокумента=1) Тогда
    ТзТТН.СуммаВал = ТзТТН.ВсегоСумма*ТзТТН.Курс/КратностьРубляРФ;
    ТзТТН.РазницаВал = ТзТТН.Разница*ТзТТН.Курс/КратностьРубляРФ;
    Иначе
    ТзТТН.СуммаВал = ТзТТН.ВсегоСумма*КурсРубляРФ/КратностьРубляРФ;
    ТзТТН.РазницаВал = ТзТТН.Разница*КурсРубляРФ/КратностьРубляРФ;
    КонецЕсли;
    ИначеЕсли (Валюта="USD") Тогда
    Если (БратьКурсИзДокумента=1) Тогда
    ТзТТН.СуммаВал = ТзТТН.ВсегоСумма*ТзТТН.Курс/КратностьДоллараСША;
    ТзТТН.РазницаВал = ТзТТН.Разница*ТзТТН.Курс/КратностьДоллараСША;
    Иначе
    ТзТТН.СуммаВал = ТзТТН.ВсегоСумма*КурсДоллараСША/КратностьДоллараСША;
    ТзТТН.РазницаВал = ТзТТН.Разница*КурсДоллараСША/КратностьДоллараСША;
    КонецЕсли;
    Иначе
    ТзТТН.СуммаВал = ТзТТН.ВсегоСумма;
    ТзТТН.РазницаВал = ТзТТН.Разница;
    КонецЕсли;
    КонецЦикла;

    ТзСтраны = СоздатьОбъект("ТаблицаЗначений");
    ТзТТН.Выгрузить(ТзСтраны,,, "Страна, ВсегоКолво, ВсегоСумма, СуммаВал, Разница, РазницаВал");
    ТзСтраны.Свернуть("Страна", "ВсегоКолво, ВсегоСумма, СуммаВал, Разница, РазницаВал");
    ТзСтраны.Сортировать("Страна");

    ТзКлиенты = СоздатьОбъект("ТаблицаЗначений");
    ТзТТН.Выгрузить(ТзКлиенты,,, "Страна, Контрагент, ВсегоКолво, ВсегоСумма, СуммаВал, Разница, РазницаВал");
    ТзКлиенты.Свернуть("Страна, Контрагент", "ВсегоКолво, ВсегоСумма, СуммаВал, Разница, РазницаВал");
    ТзКлиенты.Сортировать("Контрагент");

    СтрокаКурса = ?(
    БратьКурсИзДокумента=1,
    "Курсы валют взяты из документа на дату отгрузки",
    "курс рубля РФ "+СокрЛП(КурсРубляРФ)+", курс доллара США "+СокрЛП(КурсДоллараСША)
    );

    Таб.ВывестиСекцию("Шапка");

    ТзСтраны.ВыбратьСтроки();
    Пока ТзСтраны.ПолучитьСтроку() = 1 Цикл
    Таб.ВывестиСекцию("Страна");
    НомерПП = 0;
    ТзКлиенты.ВыбратьСтроки();
    Пока ТзКлиенты.ПолучитьСтроку() = 1 Цикл
    Если ТзКлиенты.Страна = ТзСтраны.Страна Тогда
    НомерПП = НомерПП + 1;
    Таб.ВывестиСекцию("Клиент");
    ТзТТН.ВыбратьСтроки();
    Пока ТзТТН.ПолучитьСтроку() = 1 Цикл
    Если (ТзТТН.Страна = ТзСтраны.Страна) И (ТзТТН.Контрагент = ТзКлиенты.Контрагент) Тогда
    Таб.ВывестиСекцию("Документ");
    КонецЕсли;
    КонецЦикла;
    КонецЕсли;
    КонецЦикла;
    КонецЦикла;


    Таб.ВывестиСекцию("Подвал");
    //Таб.Опции(,,4,, "амькдл5л55", "скк445п66");
    Таб.ТолькоПросмотр(1);
    Таб.Показать(Заголовок,"");

    КонецПроцедуры //Сформировать
    Как бы работает всё, но остался вопрос оптимизации.
     
  4. layman

    layman Создатель

    Регистр.:
    4 фев 2008
    Сообщения:
    18
    Симпатии:
    24
    Для оптимизации, перепиши на прямые запросы с использованием ВК 1sqlite. вот пример sql.ru/forum/536527/1s-kak-poluchit-periodicheskie-rekvizyty-na-datu