8.х Присвоение строкам таб.части, выборки из запроса

Тема в разделе "Конфигурирование на платформе "1С:Предприятие 8"", создана пользователем Pavel2009, 24 май 2011.

  1. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Добрый день, коллеги! Подскажите, я уже не сображу, как Выборку из запроса((Выборка.ПоследняЦенаРасходной), каждое выбранное значение, присвоить строкам Цена (Строка.Цена) табличной части дока (РеализацияТоваров), у меня присваивает, последнее значение из выборки, всем строкам!
    :angry:

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

    DmitryS Опытный в 1С

    Регистрация:
    20 июл 2007
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Вы в цикле Выборки каждый раз обходите табличную часть.

    Я бы добавил в запрос "НомерСтроки" таб. части.
    И при обходе выборки получал бы нужную строку по Номеру

    Пока Выборка.Следующий() Цикл
    Цена=Выборка.Поле1;
    РеализацияТоваров[Выборка.НомерСтроки-1].Цена=(Выборка.ПоследняЦенаРасходной+(Выборка.ПоследняЦенаРасходной*Выборка.Поле1));

    КонецЦикла;
  3. 1cUserAndrew
    Online

    1cUserAndrew Профессионал в 1С Команда форума

    Регистрация:
    27 май 2010
    Сообщения:
    4.948
    Симпатии:
    149
    Баллы:
    104
    Потому что у Вас цикл перебора таб части (и соответственно присвоение цены каждой строке) находится внутри цикла обхода выборки. Т.е. на самом деле присваивается не только последнее значение из выборки, а по очереди ВСЕ значения из выборки. И последнее естественно сохраняется.

    Думаю, у Вас слегка мудреный способ присвоения цены....
    Может, надо в цикле обхода таб части делать запрос к регистрам цен (это можно вынести в отдельную функцию) и заносить ее в нужную ячейку.
    Конкретно не скажу, но что-то типа такого:

    Код:
    Процедура Моя()
    Для каждого Строка из РеализацияТоваров Цикл
    Строка.Цена = ПолучитьЦену(Строка.Номенклатура);
    КонецЦикла;
    КонецПроцедуры
    
    Функция ПолучитьЦену(Номенклатура)
    Запрос = Новый Запрос;
    //Тут делаем запрос к регистрам, получая цену для наменклатуры
    Возврат Цена;
    КонецФункции
    
    
    Это один из вариантов. Может, есть лучше...
  4. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26

    Немного переделал, но все равно все строки колонки, заполняются последним значением

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

    Dmitriy_76 Опытный в 1С Команда форума

    Регистрация:
    26 мар 2011
    Сообщения:
    2.174
    Симпатии:
    13
    Баллы:
    29
    а не проше результат запроса просто выгрузить в табличную часть ?


    Сп :

    Табличная часть (Tabular section)
    Загрузить (Load)
    Синтаксис:

    Загрузить(<Таблица>)
    Параметры:

    <Таблица> (обязательный)

    Тип: ТаблицаЗначений. Таблица значений, откуда загружается табличная часть. Колонки таблиц совмещаются по именам.
    Описание:

    Загружает табличную часть из таблицы значений. При этом все прежние строки табличной части удаляются. При загрузке значения в колонках табличной части заполняются значениями из колонок таблицы значений с совпадающими именами.

    Доступность:

    Сервер, толстый клиент, внешнее соединение.
    Примечание:

    Использование метода допустимо только в том случае, если табличная часть получена из свойства объекта. Если табличная часть получена из свойства ссылки (или выборки), то использование этого метода будет вызывать ошибку выполнения.




    РеализацияТоваров.Загрузить(Запрос.Выполнить().Выгрузить())

    вроде так
  6. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26

    Вы в цикле Выборки каждый раз обходите табличную часть.

    Я бы добавил в запрос "НомерСтроки" таб. части.
    И при обходе выборки получал бы нужную строку по Номеру

    Пока Выборка.Следующий() Цикл
    Цена=Выборка.Поле1;
    РеализацияТоваров[Выборка.НомерСтроки-1].Цена=(Выборка.ПоследняЦенаРасходной+(Выборка.ПоследняЦенаРасходной*Выборка.Поле1));

    КонецЦикла;

    Пробовал как вы написали, пишет индекс выходит за приделы массива
  7. yzek
    Offline

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    Если НомерСтроки вы получаете в запросе, тогда не надо Выборка.НомерСтроки-1, надо Выборка.НомерСтроки.
    Вы и так его получили.

    А вот если бы вы применяли подобную конструцию
    Код:
    Счетчик = 1;
    Пока Выборка.Следующий() Цикл 
    Цена=Выборка.Поле1; 
    РеализацияТоваров[Счетчик -1].Цена=(Выборка.ПоследняЦенаРасходной+
    (Выборка.ПоследняЦенаРасходной*Выборка.Поле1));
    Счетчик = Счетчик + 1;
    КонецЦикла;
    
    Тогда надо. Потому что индексы строк начинаются с 0.
  8. yzek
    Offline

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    И еще мне кажется неплохо было бы в запросе
    Код:
      |УПОРЯДОЧИТЬ ПО
    |	НомерСтроки
    
  9. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Отлично! Спасибо! Все работает! :angry:
  10. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Но есть минус, верхняя и нижняя строки, колонки цена, меняются местами.

    Код:
    Счетчик = 1;
    Пока Выборка.Следующий() Цикл 
    РеализацияТоваров[Счетчик -1].Цена=(Выборка.Цена+(Выборка.Цена*Выборка.Наценка));
    Счетчик = Счетчик + 1;
    КонецЦикла;
    
  11. yzek
    Offline

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    Я потому и сказал, что нужно упорядочить "НомерСтроки".
    Тогда строки должны идти по порядку.
    1с упорядочивает как ей удобно.
  12. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Спасибо еще раз, как то у меня тяжело идет!

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

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    Ну для начала если вы всеже используете счетчик, то Счетчик=1 вынесите за цикл, а то смысл счетчика теряется, так как каждый раз в цикле вы присваиваете ему 1.
  14. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
    Только если сидите на платформе 8.2 - обновите релиз как минимум до 8.2.13.218.
  15. yzek
    Offline

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    Поясните пожалуйста.
  16. shurikvz
    Offline

    shurikvz Модераторы Команда форума Модератор

    Регистрация:
    1 окт 2009
    Сообщения:
    8.409
    Симпатии:
    316
    Баллы:
    104
  17. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Код:
    Процедура ВалютаПриИзменении(Элемент)
    ТекущаяСтрока=ЭлементыФормы.РеализацияТоваров.ТекущиеДанные;
    
    
    
    ВалютаИЗ=1;
    ВалютаВ=1;
    Запрос=Новый Запрос;
    Запрос.Текст= "ВЫБРАТЬ
    |    МАКСИМУМ(ВЫБОР
    |            КОГДА ВалютыСрезПоследних.Валюта = &ВалютаВ
    |                ТОГДА ВалютыСрезПоследних.Курс
    |            ИНАЧЕ 0
    |        КОНЕЦ) КАК КурсВ,
    |    МАКСИМУМ(ВЫБОР
    |            КОГДА ВалютыСрезПоследних.Валюта = &ВалютаИЗ
    |                ТОГДА ВалютыСрезПоследних.Курс
    |            ИНАЧЕ 0
    |        КОНЕЦ) КАК КурсИЗ,
    |    РеализацияРеализацияТоваров.Цена КАК Цена1,
    |    РеализацияРеализацияТоваров.НомерСтроки
    |ИЗ
    |    РегистрСведений.Валюты.СрезПоследних(
    |            &Дата,
    |            Валюта = &ВалютаВ
    |                ИЛИ Валюта = &ВалютаИЗ) КАК ВалютыСрезПоследних,
    |    Документ.Реализация.РеализацияТоваров КАК РеализацияРеализацияТоваров
    |ГДЕ
    |    РеализацияРеализацияТоваров.Ссылка = &Ссылка
    |
    |СГРУППИРОВАТЬ ПО
    |   [color=#FF6666] РеализацияРеализацияТоваров.Цена,
    |    РеализацияРеализацияТоваров.НомерСтроки";[/color]
    Запрос.УстановитьПараметр("Дата", Дата);
    Запрос.УстановитьПараметр("Ссылка",Ссылка);
    Запрос.УстановитьПараметр("ВалютаИЗ",ТекущаяСтрока.ВалютаДляПересчета);
    Запрос.УстановитьПараметр("ВалютаВ",Валюта);
    Выборка = Запрос.Выполнить();
    Данные=Выборка.Выбрать();
    Пока Данные.Следующий() Цикл
    
    Если ВалютаИз=Неопределено Тогда
    КурсИз=1;
    Иначе 
    КурсИЗ=Данные.КурсИз;
    КонецЕсли;
    
    Если ВалютаВ=Неопределено Тогда
    КурсВ=1;
    Иначе
    КурсВ=Данные.КурсВ;
    КонецЕсли;
    
    Для каждого СтрокиТабЧасти из РеализацияТоваров Цикл
    
    Если Не ЗначениеЗаполнено(ТекущаяСтрока.ВалютаДляПересчета.Наименование) Тогда
    Сообщить("Заполните колонку, валюта для пересчета");
    Продолжить
    КонецЕсли;
    
    КонецЦикла;
    КонецЦикла;
    
    
    Счетчик = 1;
    РеализацияТоваров[Счетчик -1].Цена=(Данные.Цена1*Данные.КурсИз/Данные.КурсВ);
    Счетчик = Счетчик + 1;
    СтрокиТабЧасти.Сумма=СтрокиТабЧасти.Цена*СтрокиТабЧасти.Количество;
    Курс2 =Данные.КурсВ;
    
    
    Вынес за Цикл, однако изменяется только первая колонка, может дело в группировке строк?!


    Код:
    РеализацияТоваров[Данные.НомерСтроки].Цена=(Данные.Цена1*Данные.КурсИз/Данные.КурсВ);
    СтрокиТабЧасти.Сумма=СтрокиТабЧасти.Цена*СтрокиТабЧасти.Количество;
    Курс2 =Данные.КурсВ;
    
    
    
    Если брать номер строки, то изменяются все колонки кроме первой после сообщения о выходе массива за границы!
  18. DmitryS
    Offline

    DmitryS Опытный в 1С

    Регистрация:
    20 июл 2007
    Сообщения:
    119
    Симпатии:
    0
    Баллы:
    26
    Вообщето нужно было вынести за цикл только строку:

    Счетчик = 1;
  19. TopicStarter Overlay
    Pavel2009
    Offline

    Pavel2009 Опытный в 1С

    Регистрация:
    11 окт 2010
    Сообщения:
    183
    Симпатии:
    0
    Баллы:
    26
    Не могли бы, вы привести верный код?
  20. yzek
    Offline

    yzek Опытный в 1С

    Регистрация:
    13 окт 2010
    Сообщения:
    713
    Симпатии:
    0
    Баллы:
    26
    Pavel2009,
    я имел ввиду то, что перед циклом нужно определить переменную
    то есть
    сначала
    Код:
    Счетчик=1;
    
    А затем уже ваш цикл
    Код:
    Для .... Цикл
    ...
    Счетчик = Счетчик + 1;
    КонецЦикла;
    
    Чтобы прибавлять к переменной Счетчик единицу.
    А у вас получается, что
    Код:
    Для .... Цикл
    Счетчик=1;
    ...
    Счетчик = Счетчик + 1;
    КонецЦикла;
    
    Пи каждом проходе в цикле вы присваиваете переменной Счетчик единицу и сколько бы раз в цикл вы не входили Счетчик = 1 будет всегда.

Поделиться этой страницей