Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Использование табличной части справочника в отчете  (Прочитано 19059 раз)
0 Пользователей и 1 Гость смотрят эту тему.
alinka1628
Интересующийся

ru
Offline Offline

« : 08-02-2012 12:05 » 

Добрый день!
Помогите пожалуйста с отчетом в 1С Бухгалтерии 8.2.
В отчете должно быть выведено Перечень номенклатуры из табличной части справочника Спецификация номенклатуры, ее количество (оттуда же) и соответствующие цены из регистрасведений.ЦеныНоменклатурыСрезПолседних (цену посчитать как среднюю за период)
Мне нужно вывести табличную часть справочника Спецификация номенклатуры. Затем обращаться программно к каждому элементу табличной части.

Код: (1C v8)
Процедура КнопкаСформироватьНажатие(Кнопка)
        // Вставить содержимое обработчика.
Запрос1 = Новый Запрос;
Запрос1.Текст =
       
        "ВЫБРАТЬ
         |      СпецификацииНоменклатуры.ИсходныеКомплектующие.(
         |              Номенклатура,
         |              Количество
         |      )
         |ИЗ
         |      Справочник.СпецификацииНоменклатуры КАК СпецификацииНоменклатуры
         |ГДЕ
         |      СпецификацииНоменклатуры.Владелец = &Владелец"
    ;
         
         Запрос1.УстановитьПараметр("Владелец",НаименованиеНоменклатуры);
         
Запрос2 = Новый Запрос;
Запрос2.Текст =
  "ВЫБРАТЬ
  |     ЦеныНоменклатурыСрезПоследних.Номенклатура,
  |     ЦеныНоменклатурыСрезПоследних.Цена,
  |     ЦеныНоменклатурыСрезПоследних.Валюта
  |ИЗ
  |     РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК ЦеныНоменклатурыСрезПоследних"
;
 
 Запрос2.УстановитьПараметр("Период", Период);
 
 //вычисление средней цены за период по комплектующим
 Результат1 = Запрос1.Выполнить().Выбрать();
 Результат2 = Запрос2.Выполнить().Выбрать();
   ДокументРезультат.Вывести(Результат1);
 Пока Результат1.Следующий() Цикл
         Кол = 0;
         Цена = 0;
         Пока Результат2.Следующий() Цикл
                 Если Результат2.Номенклатура = Результат1.ИсходныеКомплеткующие.Номенклатура Тогда
                         Цена = Цена + Результат2.Цена;
                         Кол = Кол + 1;  
                 КонецЕсли;
         КонецЦикла;
         ВПЦена = Цена/Кол;
         Стоимость = ВПЦена*Результат1.ИсходныеКомплектующие.Количество;

  КонецЦикла;
КонецПроцедуры

при выполнении запроса, выдает ошибку {Отчет.СебестоимостьПоКомплектующим.Форма.ФормаОтчета1.Форма(38)}: Поле объекта не обнаружено (ИсходныеКомплеткующие)
       Если Результат2.Номенклатура = Результат1.ИсходныеКомплеткующие.Номенклатура Тогда


« Последнее редактирование: 08-02-2012 18:49 от Kivals » Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 08-02-2012 19:01 » 

1. Используй [code=e1cv8][/code] для кода - будет читабельней
2. В таком виде, как построен Запрос1, нужна еще одна выборка, поэтому я бы переделал текст запрос по-другому:
Код: (1C v8)
Запрос1.Текст =
       
        "ВЫБРАТЬ
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура,
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Количество
         |ИЗ
         |      Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецификацииНоменклатурыИсходныеКомплектующие
         |ГДЕ
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.Владелец = &Владелец"
;
Ну и после этого обращался бы напрямую к полям:
Код: (1C v8)
Если Результат2.Номенклатура = Результат1.Номенклатура Тогда ...

3. Поле Валюта никак не использовано - спишем это на упрощение задачи для форума

4. А вообще эти запросы правильно объединить в один с использованием ЛЕВОЕ СОЕДИНЕНИЕ и все вычисления провести в самом запросе. В простейшем случае (если в регистре ЦеныНоменклатуры только одно измерение - Номенклатура, и ресурс Цена) это выглядело бы так:
Код: (1C v8)
Запрос.Текст =
       
        "ВЫБРАТЬ
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура,
         |      ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Цена,
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Количество,
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Количество * ЕСТЬNULL(ЦеныНоменклатурыСрезПоследних.Цена, 0) КАК Стоимость
         |ИЗ
         |      Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецификацииНоменклатурыИсходныеКомплектующие
         |      ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ) КАК ЦеныНоменклатурыСрезПоследних
         |      ПО ЦеныНоменклатурыСрезПоследних.Номенклатура = СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура
         |ГДЕ
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка.Владелец = &Владелец"
;

Добавлено через 1 минуту и 59 секунд:
P.S. Запрос в п.4 не оптимизирован по скорости, но уж точно не будет медленней, чем алгоритм исходной задачи. Для оптимизации по скорости необходимо использовать временные таблицы (ПОМЕСТИТЬ) и срез цен делать с учетом только выбранной номенклатуры

Добавлено через 3 минуты и 19 секунд:
P.P.S. "цену посчитать как среднюю за период" - недостаточно условий. Прочитай какое бывает Среднее значение
« Последнее редактирование: 08-02-2012 19:06 от Kivals » Записан
alinka1628
Интересующийся

ru
Offline Offline

« Ответ #2 : 09-02-2012 04:29 » 

Спасибо за ответ! Попробую сделать так. А по поводу средней, в данном отчете пока достаточно так.

Добавлено через 3 часа, 18 минут и 34 секунды:
Если делать через один запрос, выводится последняя цена занесенная в регистр. А мне нужно среднюю. Можно этот расчет сделать используя один запрос?
Как и порекомендовали использую временную таблицу
« Последнее редактирование: 09-02-2012 07:48 от alinka1628 » Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 09-02-2012 11:48 » 

Можно. Тебе нужно просто РегистрСведений.ЦеныНоменклатуры (без СрезПоследних) с ограничением по (Период МЕЖДУ &ДатаНачала И &ДатаОкончания) - так выберет все изменения цен за период. Возможно еще нужен будет СредПослених на &ДатаНачала - это если нужно учесть "входящую" (на начало периода) цену
Записан
alinka1628
Интересующийся

ru
Offline Offline

« Ответ #4 : 14-02-2012 06:42 » 

Комплектующие выбранной номенклатуры с ценами вывела, пока оставила регистр сведений Цены номенклатуры. У каждой номенклатуры из справочника Спецификации номенклатуры могут быть свои спецификации с ценами (т.е. свои комплектующие). Нужно выполнять имеющийся запрос для каждой встречающейся номенклатуры. Вот что я написала, но пока не идет. Подскажите, пожалуйста как лучше сделать.
Код: (1C v8)
Функция СформироватьТекстЗапроса()
         Текст =
         "ВЫБРАТЬ
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Номенклатура,
         |      СпецификацииНоменклатурыИсходныеКомплектующие.Количество
         |ПОМЕСТИТЬ Комплектующие
         |ИЗ
         |      Справочник.СпецификацииНоменклатуры КАК СпецификацииНоменклатуры
         |              ЛЕВОЕ СОЕДИНЕНИЕ Справочник.СпецификацииНоменклатуры.ИсходныеКомплектующие КАК СпецификацииНоменклатурыИсходныеКомплектующие
         |              ПО СпецификацииНоменклатуры.ИсходныеКомплектующие.Ссылка = СпецификацииНоменклатурыИсходныеКомплектующие.Ссылка
         |ГДЕ
         |      СпецификацииНоменклатуры.Владелец = &Владелец
         |;
         |
         |////////////////////////////////////////////////////////////////////////////////
         |ВЫБРАТЬ
         |      ЦеныНоменклатуры.Номенклатура,
         |      ЦеныНоменклатуры.Валюта,
         |      ЦеныНоменклатуры.Цена
         |ПОМЕСТИТЬ РегистрЦен
         |ИЗ
         |      РегистрСведений.ЦеныНоменклатуры КАК ЦеныНоменклатуры
         |ГДЕ
         |      ЦеныНоменклатуры.Период МЕЖДУ &ДатаНачала И &ДатаОкончания
         |;
         |
         |////////////////////////////////////////////////////////////////////////////////
         |ВЫБРАТЬ
         |      Комплектующие.Номенклатура КАК Номенклатура,
         |      Комплектующие.Количество,
         |      РегистрЦен.Валюта,
         |      РегистрЦен.Цена
         |{ВЫБРАТЬ
         |      Номенклатура.*,
         |      Количество,
         |      Цена,
         |      (Комплектующие.Количество * РегистрЦен.Цена) КАК Стоимость}
         |ИЗ
         |      Комплектующие КАК Комплектующие
         |              ЛЕВОЕ СОЕДИНЕНИЕ РегистрЦен КАК РегистрЦен
         |              ПО Комплектующие.Номенклатура = РегистрЦен.Номенклатура"
;
  Возврат Текст;
         
КонецФункции


Процедура ДействияФормыСебестоимостьПоКомплектующимСформировать(Кнопка)
        //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА(СебестоимостьПоКомплектующим)
        // Данный фрагмент построен конструктором.
        // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

        СебестоимостьПоКомплектующимВывести();

        //}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПРОЦЕДУРА_ВЫЗОВА
КонецПроцедуры

Процедура СебестоимостьПоКомплектующимВывести()
        //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ(СебестоимостьПоКомплектующим)
        // Данный фрагмент построен конструктором.
        // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

        ЭлементыФормы.ПолеТабличногоДокумента.Очистить();

        ПостроительОтчетаСебестоимостьПоКомплектующим.Параметры.Вставить("Владелец", Владелец);
        ПостроительОтчетаСебестоимостьПоКомплектующим.Параметры.Вставить("ДатаНачала", ДатаНачала);
        ПостроительОтчетаСебестоимостьПоКомплектующим.Параметры.Вставить("ДатаОкончания", ДатаОкончания);

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

        //выборка комплектующих номенклатуры справочника Спецификация номенклатуры

        ПостроительОтчетаСебестоимостьПоКомплектующим.РазмещениеИзмеренийВСтроках = ТипРазмещенияИзмерений.Вместе;
        ПостроительОтчетаСебестоимостьПоКомплектующим.РазмещениеРеквизитовИзмеренийВСтроках = ТипРазмещенияРеквизитовИзмерений.Отдельно;
        ПостроительОтчетаСебестоимостьПоКомплектующим.РазмещениеРеквизитовИзмеренийВКолонках = ТипРазмещенияРеквизитовИзмерений.Отдельно;
        ПостроительОтчетаСебестоимостьПоКомплектующим.РазмещениеИтоговВСтроках = ТипРазмещенияИтогов.Подвал;
        ПостроительОтчетаСебестоимостьПоКомплектующим.РазмещениеИтоговВКолонках = ТипРазмещенияИтогов.Подвал;
        ПостроительОтчетаСебестоимостьПоКомплектующим.МакетОформления = ПолучитьМакетОформления(СтандартноеОформление.Интерфейс);
        ПостроительОтчетаСебестоимостьПоКомплектующим.Вывести(ЭлементыФормы.ПолеТабличногоДокумента);

        //}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ВЫПОЛНИТЬ
КонецПроцедуры

Процедура СебестоимостьПоКомплектующимИнициализация()
        //{{КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ(СебестоимостьПоКомплектующим)
        // Данный фрагмент построен конструктором.
        // При повторном использовании конструктора, внесенные вручную изменения будут утеряны!!!

        ПостроительОтчетаСебестоимостьПоКомплектующим.Текст = СформироватьТекстЗапроса();
        ПостроительОтчетаСебестоимостьПоКомплектующим.ЗаполнитьНастройки();
        ПостроительОтчетаСебестоимостьПоКомплектующим.ЗаполнениеРасшифровки = ВидЗаполненияРасшифровкиПостроителяОтчета.ЗначенияГруппировок;
        ПостроительОтчетаСебестоимостьПоКомплектующим.ТекстЗаголовка = "Себестоимость по комплектующим";
        Настройка = ВосстановитьЗначение("НастройкаОтчетыСебестоимостьПоКомплектующимСебестоимостьПоКомплектующим_d56f9684-b254-40c9-9e79-5d95f6a0bc7b");
        Если Настройка <> Неопределено Тогда
                ПостроительОтчетаСебестоимостьПоКомплектующим.УстановитьНастройки(Настройка);
        КонецЕсли;

        //}}КОНСТРУКТОР_ВЫХОДНЫХ_ФОРМ_ПОСТРОИТЕЛЬОТЧЕТА_ИНИЦИАЛИЗАЦИЯ
КонецПроцедуры
 

Делаю через построитель отчетов, может нужно как-то по-другому?
Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 14-02-2012 07:00 » 

Непонятно что "не идет". Давай конкретней опиши ошибку...
Записан
alinka1628
Интересующийся

ru
Offline Offline

« Ответ #6 : 14-02-2012 07:22 » 

У меня по сути должен выводится многоуровневый список. Ошибку выдает:{Отчет.СебестоимостьПоКомплектующим.Форма.СебестоимостьПоКомплектующим.Форма(54)}: Ошибка при вызове метода контекста (Вывести)
        ЭлементыФормы.ПолеТабличногоДокумента.Вывести(Результат2);
по причине:
Несоответствие типов (параметр номер '1')


Добавлено через 3 минуты и 14 секунд:
Я пробую делать, в выложенном коде ошибка такая, в общем-то разницы никакой
{Отчет.СебестоимостьПоКомплектующим.Форма.СебестоимостьПоКомплектующим.Форма(54)}: Ошибка при вызове метода контекста (Вывести)
        ПостроительОтчетаСебестоимостьПоКомплектующим.Вывести(Результат2);
по причине:
Несоответствие типов (параметр номер '1')
« Последнее редактирование: 14-02-2012 07:25 от alinka1628 » Записан
Kivals
Модератор

ca
Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 26-04-2012 07:21 » 

ИМХО все прозрачно:
Смотри какой тип параметра требует ПостроительОтчета.Вывести() и какой возвращает Запрос.Выполнить() - они разные!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines