Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Запрос по остаткам (число прочтений - 3868 )
U_zer
Экс-Участник


Запрос по остаткам
25. Сентября 2009 :: 07:27
Печать  
Всем привет!
В документе в шапке и в ТЧ есть реквизит - склад,
у рекв. Склад есть реквизит - группа.

Нужно как-то построить параметризированный запрос по  остаткам,
если выбран склад в ТЧ, то считаем по нему, если нет- то по складу шапки, а если выставлена галочка по группе, то считать плюс ко всему  - по группе складов.

Код
Выбрать все
ТЗ = "
	|declare @Тов char(9)
	|set @Тов = ?
	|select
	|sum(БигСел.КолОст) [Ост $Число],
	|sum(БигСел.КолРез) [Резв $Число]
	|from
	|(select
	|ОстТ.ресКоличествоОстаток КолОст,
	|0 КолРез
	|from $РегистрОстатки.Товары(,,измТовар = @Тов and измСклад in (select val from #TempSkl), измТовар, ресКоличество) ОстТ
	|union
	|select
	|0,
	|РезТ.ресКоличествоОстаток
	|from $РегистрОстатки.РезервыТоваров(,,измТовар = @Тов and измСклад in (select val from #TempSkl), измТовар, ресКоличество) РезТ
	|) БигСел";
 



Этот запрос работает если при его подготовке сразу сделать
УложитьСписокОбъектов()
А вот если получать склады построчно - получается фигня.
Можно ли как-то придумать, чтобы не отказываться от параметр. запроса, а то очень сильно тормозит?

Для каждой сторки выполняется следующее ...
Код
Выбрать все
	СписСкл.УдалитьВсе();
	Если табСклад.Выбран() = 1 Тогда
		_Скл = табСклад
	Иначе
		_Скл = загСклад
	КонецЕсли;
	Если ОстГрупп = 1 Тогда
		ЗапросСкл = СоздатьОбъект("OdbcRecordSet");
		ТзСкл = "
		|select
		|Скл.id [Склад $Справочник.Склады]
		|from $Справочник.Склады Скл (nolock)
		|where $Скл.спрСкладВладелец = :СклВлад";
		ЗапросСкл.УстановитьТекстовыйПараметр("СклВлад", _Скл);
		ЗапросСкл.ВыполнитьИнструкцию(ТзСкл,СписСкл);
	КонецЕсли;
	СписСкл.ДобавитьЗначение(_Скл);
	ЗапросОстПоСтр.УложитьСписокОбъектов(СписСкл, "#TempSkl");

 

  
Наверх
 
IP записан
 
Anatol
Senior Member
****
Отсутствует


тыц, пыц, тыц!!!

Сообщений: 412
Зарегистрирован: 24. Апреля 2009
Re: Запрос по остаткам
Ответ #1 - 25. Сентября 2009 :: 09:11
Печать  
а ЗначениеВСтрокуБД() тебе не подойдет?
  
Наверх
wwwICQ  
IP записан
 
vandalsvq
1c++ power user
Отсутствует


Я всего лишь als-особиратель
;-)

Сообщений: 2487
Местоположение: Уфа
Зарегистрирован: 18. Июля 2007
Пол: Мужской
Re: Запрос по остаткам
Ответ #2 - 25. Сентября 2009 :: 10:13
Печать  
Я так понимаю что тебе это надо чтобы в справочнике отображать остатки?
  

Отхожу от дел. Долго и мучительно.
Наверх
IP записан
 
U_zer
Экс-Участник


Re: Запрос по остаткам
Ответ #3 - 25. Сентября 2009 :: 13:25
Печать  
vandalsvq писал(а) 25. Сентября 2009 :: 10:13:
Я так понимаю что тебе это надо чтобы в справочнике отображать остатки?


Не в справочнике, а в документе, но я выкрутился через
create Table ....
Оказывается, параметр. запрос работает с темповой таблицей, созданной вручную.
Почему-то УложитьСписокОбъектов срабатывает только если его сделать непосредственно перед Запрос.Подготовить(). Баг это или фича - незнаю, но неприятно.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #4 - 25. Сентября 2009 :: 16:18
Печать  
Цитата:
Не в справочнике, а в документе, но я выкрутился через
create Table ....
Оказывается, параметр. запрос работает с темповой таблицей, созданной вручную.
Почему-то УложитьСписокОбъектов срабатывает только если его сделать непосредственно перед Запрос.Подготовить(). Баг это или фича - незнаю, но неприятно.

ЛУчше приведи пример полностью а то полностью представить
картину практически невозможно.
  
Наверх
 
IP записан
 
U_zer
Экс-Участник


Re: Запрос по остаткам
Ответ #5 - 28. Сентября 2009 :: 05:46
Печать  
Вот такой запрос работать не хочет:
Код
Выбрать все
Процедура ПриОткрытии()
	СписСкл = СоздатьОбъект("СписокЗначений");
	ТЗ = "
	|declare @Тов char(9)
	|set @Тов = ?
	|select
	|sum(БигСел.КолОст) [Ост $Число],
	|sum(БигСел.КолРез) [Резв $Число]
	|from
	|(select
	|ОстТ.ресКоличествоОстаток КолОст,
	|0 КолРез
	|from $РегистрОстатки.Товары(,,измТовар = @Тов and измСклад in (select val from #TempSklSC), измТовар, ресКоличество) ОстТ
	|union
	|select
	|0,
	|РезТ.ресКоличествоОстаток
	|from $РегистрОстатки.РезервыТоваров(,,измТовар = @Тов and измСклад in (select val from #TempSklSC), измТовар, ресКоличество) РезТ
	|) БигСел";

	Если ЗапросОстПоСтр.Подготовить(ТЗ) = 1 Тогда
		ЗапросОстПоСтр.ДобПараметр(1, 14, 9,0)
	Иначе
		Сообщить(ЗапросОстПоСтр.ПолучитьОписаниеОшибки());
	КонецЕсли;
КонецПроцедуры

Функция ПолучитьОстаток()
	Если табСклад.Выбран() = 1 Тогда
		_Скл = табСклад
	Иначе
		_Скл = загСклад
	КонецЕсли;
	Если ОстГрупп = 1 Тогда
		ЗапросСкл = СоздатьОбъект("OdbcRecordSet");
		ТзСкл = "
		|select
		|Скл.id [Склад $Справочник.Склады]
		|from $Справочник.Склады Скл (nolock)
		|where $Скл.спрСкладВладелец = :СклВлад";
		ЗапросСкл.УстановитьТекстовыйПараметр("СклВлад", _Скл);
		ЗапросСкл.ВыполнитьИнструкцию(ТзСкл, СписСкл);
	КонецЕсли;
	ЗапросОстПоСтр.УстПараметр(1, табТовар);
	ЗапросОстПоСтр.УложитьСписокОбъектов(СписСкл, "#TempSklSC")
 	Рез = ЗапросОстПоСтр.ВыполнитьСкалярный();
 	РезРез = Рез.Резв;
 	глОст = Рез.Ост;
 	возврат Рез.Ост
КонецФункции
 



А вот такой срабатывает на раз:
Код
Выбрать все
Процедура ПриОткрытии()
	Запрос = СоздатьОбъект("OdbcRecordSet");
	ЗапросОстПоСтр = СоздатьОбъект("OdbcRecordSet");
	Если Запрос.Выполнить("if Exists (select * from tempdb..sysobjects where id = object_id('tempdb..#TempSklSC') and sysstat & 0xf = 3 )
						  |drop table #TempSklSC") =0 Тогда
		Сообщить(Запрос.ПолучитьОписаниеОшибки());
	КонецЕсли;
	Запрос.Выполнить("Create Table #TempSklSC (sklad char(9) PRIMARY KEY CLUSTERED (sklad))");
	СписСкл = СоздатьОбъект("СписокЗначений");
	ТЗ = "
	|declare @Тов char(9)
	|set @Тов = ?
	|select
	|sum(БигСел.КолОст) [Ост $Число],
	|sum(БигСел.КолРез) [Резв $Число]
	|from
	|(select
	|ОстТ.ресКоличествоОстаток КолОст,
	|0 КолРез
	|from $РегистрОстатки.Товары(,,измТовар = @Тов and измСклад in (select sklad from #TempSklSC), измТовар, ресКоличество) ОстТ
	|union
	|select
	|0,
	|РезТ.ресКоличествоОстаток
	|from $РегистрОстатки.РезервыТоваров(,,измТовар = @Тов and измСклад in (select sklad from #TempSklSC), измТовар, ресКоличество) РезТ
	|) БигСел";

	Если ЗапросОстПоСтр.Подготовить(ТЗ) = 1 Тогда
		ЗапросОстПоСтр.ДобПараметр(1, 14, 9,0)
	Иначе
		Сообщить(ЗапросОстПоСтр.ПолучитьОписаниеОшибки());
	КонецЕсли;
КонецПроцедуры

Функция ПолучитьОстатокРезервПоСтроке()
	Если табСклад.Выбран() = 1 Тогда
		_Скл = табСклад
	Иначе
		_Скл = загСклад
	КонецЕсли;
	Запрос.Выполнить("delete from #TempSklSC");
	Тз = "insert into #TempSklSC Values(:Скл)";
	Запрос.УстановитьТекстовыйПараметр("Скл", _Скл);
	Запрос.Выполнить(Тз);
	Если ОстГрупп = 1 Тогда
		ЗапросСкл = СоздатьОбъект("OdbcRecordSet");
		ТзСкл = "
		|insert into #TempSklSC (sklad)
		|select
		|Скл.id [Склад $Справочник.Склады]
		|from $Справочник.Склады Скл (nolock)
		|where $Скл.спрСкладВладелец = :СклВлад";
		ЗапросСкл.УстановитьТекстовыйПараметр("СклВлад", _Скл);
		ЗапросСкл.Выполнить(ТзСкл);
	КонецЕсли;
	ЗапросОстПоСтр.УстПараметр(1, табТовар);
 	Рез = ЗапросОстПоСтр.ВыполнитьСкалярный();
 	РезРез = Рез.Резв;
 	глОст = Рез.Ост;
 	возврат Рез.Ост
КонецФункции	// гл
 

  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #6 - 28. Сентября 2009 :: 06:06
Печать  
По моему когда работает то папка склад входит в доп таблицу

а когда не работает то папка склад не входит в доп таблицу.
попробуй добавить папка склад в #TempSklSC.
  
Наверх
 
IP записан
 
U_zer
Экс-Участник


Re: Запрос по остаткам
Ответ #7 - 28. Сентября 2009 :: 06:26
Печать  
Z1 писал(а) 28. Сентября 2009 :: 06:06:
По моему когда работает то папка склад входит в доп таблицу

а когда не работает то папка склад не входит в доп таблицу.
попробуй добавить папка склад в #TempSklSC.


Нет. Ты не понял, когда не работает - При ВыполнитьСкалярный() -
выдает ошибку "Неверный индекс параметра".
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #8 - 28. Сентября 2009 :: 06:47
Печать  
попробуй для начала ##TempSklSC может разная видимость временной таблицы для параметр. запроса.
не знаю также будет ли в этом случае отрабатывать Отладка(1)

PS Замени вызовы Выполнить на ВыполнитьСкалярный
Выполнить устарел и оставлен только для совместимости.
  
Наверх
 
IP записан
 
U_zer
Экс-Участник


Re: Запрос по остаткам
Ответ #9 - 28. Сентября 2009 :: 07:03
Печать  
Z1 писал(а) 28. Сентября 2009 :: 06:47:
попробуй для начала ##TempSklSC может разная видимость временной таблицы для параметр. запроса.
не знаю также будет ли в этом случае отрабатывать Отладка(1)

PS Замени вызовы Выполнить на ВыполнитьСкалярный
Выполнить устарел и оставлен только для совместимости.


Там где выполнить() - это правмльно. Там помещение во врем. таблицу. Проблема в том, что если УложитьСписокОбъектов() перенести в ПриОткрытии() до Подготовить(), то все работает нормально, но тогда нет возможности вызывать УложитьСписокОбъектов() динамически - для каждой строки.
  
Наверх
 
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #10 - 28. Сентября 2009 :: 07:08
Печать  
Цитата:
Z1 писал(а) 28. Сентября 2009 :: 06:47:
попробуй для начала ##TempSklSC может разная видимость временной таблицы для параметр. запроса.
не знаю также будет ли в этом случае отрабатывать Отладка(1)

PS Замени вызовы Выполнить на ВыполнитьСкалярный
Выполнить устарел и оставлен только для совместимости.


Там где выполнить() - это правмльно. Там помещение во врем. таблицу. Проблема в том, что если УложитьСписокОбъектов() перенести в ПриОткрытии() до Подготовить(), то все работает нормально, но тогда нет возможности вызывать УложитьСписокОбъектов() динамически - для каждой строки.

Так я же и говорю попробуй использовать глобальнуюВременнуюТаблицу ##ИмяТаблицы

  
Наверх
 
IP записан
 
Salimbek
God Member
*****
Отсутствует



Сообщений: 862
Зарегистрирован: 06. Июня 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #11 - 28. Сентября 2009 :: 10:51
Печать  
Зачем надо заниматься уложением списка объектов? Что мешает написать вместо:
Цитата:
(select val from #TempSklSC)

сразу так:
Цитата:
"
           |(select
           |Скл.id
           |from $Справочник.Склады Скл (nolock)
           |where $Скл.спрСкладВладелец = :СклВлад)";

  
Наверх
ICQ  
IP записан
 
Z1
God Member
*****
Отсутствует


I Love YaBB 2!

Сообщений: 2906
Местоположение: Москва
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Запрос по остаткам
Ответ #12 - 28. Сентября 2009 :: 12:20
Печать  
Salimbek писал(а) 28. Сентября 2009 :: 10:51:
Зачем надо заниматься уложением списка объектов? Что мешает написать вместо:
Цитата:
(select val from #TempSklSC)

сразу так:
Цитата:
"
           |(select
           |Скл.id
           |from $Справочник.Склады Скл (nolock)
           |where $Скл.спрСкладВладелец = :СклВлад)";


Может быть формирует остатки не по всем складам папки а только по некоторым.
  
Наверх
 
IP записан
 
U_zer
Экс-Участник


Re: Запрос по остаткам
Ответ #13 - 28. Сентября 2009 :: 12:32
Печать  
Z1 писал(а) 28. Сентября 2009 :: 12:20:
Salimbek писал(а) 28. Сентября 2009 :: 10:51:
Зачем надо заниматься уложением списка объектов? Что мешает написать вместо:
Цитата:
(select val from #TempSklSC)

сразу так:
Цитата:
"
           |(select
           |Скл.id
           |from $Справочник.Склады Скл (nolock)
           |where $Скл.спрСкладВладелец = :СклВлад)";


Может быть формирует остатки не по всем складам папки а только по некоторым.


Я бы написал. Мне нужно считать остатки и по текущему складу, и по складам у которых  $Скл.спрСкладВладелец = :СклВлад.
Как мне написать это все в одном запросе?
  
Наверх
 
IP записан
 
alexdd
Senior Member
****
Отсутствует


I Love YaBB 2!

Сообщений: 347
Зарегистрирован: 25. Июня 2007
Re: Запрос по остаткам
Ответ #14 - 28. Сентября 2009 :: 14:17
Печать  
Цитата:
Вот такой запрос работать не хочет..

ну дык потому что, вот это
Код
Выбрать все
ЗапросОстПоСтр.УложитьСписокОбъектов(..) 


х#рит(простите мой французский) подготовленный запрос. Отсюда и сообщение про неверный индекс параметра.
Нужно создать другой объект ODBCRecordset для того же соединения и для него выполнять УложитьСписокОбъектов. Вроде должно работать Улыбка
зы: можно и одним запросом: сначала сделать тоже, что делает УложитьСписокОбъектов(можно в табличную переменную, например), потом выполнить запрос к регистру
  
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать