Осваиваю прямые запросы, многие Учителя помогают, за что им спасибо... Выкладываю примерчик запроса, возвращающего для номенклатуры цену определенного типа для определенной даты...
.
Описание задачи: в типовой конфигурации ТиС во многих местах встречается код по типу:
.
СпрНоменклатура.ВыбратьЭлементы();
Пока СпрНоменклатура.ПолучитьЭлемент()=1
Цикл
//пропускаем группы
//пропускаем удаленные
НайденнаяЦена = "";
ЦенаЦены = 0;
Если глВернутьЦену(СпрНоменклатура.ТекущийЭлемент(),ТипЦены, ДатаЦены,ЦенаЦены,,,,НайденнаяЦена)<>0
Тогда
.
где НайденнаяЦена - ссылка на элемент справочника "Цены"
Данный код, даже если обход справочника делается не выборкой, а по результатм чорного (штатного запроса) - достаточно тяжелый (для этого надо посмотреть в код процедуры глВернутьЦену() - плохо это или хорошо - судить не будем, это - плата за универсальность...).
Совершенно четко понятно, что эффективность достигается за счет специализации, пойдем и мы по этому непростому и опасному пути. Оформим в качестве законченного участка кода решение следующей задачи: получить список номенклатуры с ценами для указанного типа цены на указанную дату.. По-человечески это звучит так, например: список товаров с закупочной ценой на сегодняшний день. Эффективный код (по сравнению с типовым вариантом) выглядит так:
.
RS = СоздатьОбъект("ODBCRecordSet");
RS.Отладка(0);
ТекстЗапроса = "
|SELECT
|--TOP 100
| СпрНоменклатура.ID AS [Номенклатура $Справочник.Номенклатура]
| , ISNULL(СпрЦены.ID,$ПустойИД) AS [НайденнаяЦена $Справочник.Цены]
| , ISNULL($ПоследнееЗначение.Цены.Цена(СпрЦены.ID, :ДатаЦен),0) AS ЦенаЦены
|FROM $Справочник.Номенклатура AS СпрНоменклатура With (NOLOCK)
|--
|LEFT JOIN
| $Справочник.Цены AS СпрЦены With (NOLOCK)
| ON (СпрЦены.ParentExt = СпрНоменклатура.ID)
| AND ($СпрЦены.ТипЦен = :ТипНужнойЦены)
|--
|WHERE (СпрНоменклатура.ISMARK = 0)
| AND ($СпрНоменклатура.НеВключатьВпрайс = 0)
| AND (СпрНоменклатура.ISFOLDER = 2)
|";
RS.УстановитьТекстовыйПараметр("ТипНужнойЦены" ,ТипНужнойЦены);
RS.УстановитьТекстовыйПараметр("ДатаЦен" ,ДатаЦен);
ТЗвыборка = СоздатьОбъект("ТаблицаЗначений");
ТЗвыборка = RS.ВыполнитьИнструкцию(ТекстЗапроса);
RS = "";
.
В результате имеем: таблицу значений, в которой содержатся следующие колонки:
"Номенклатура" - ссылка на элемент Справочник.Номенклатура (товар);
"НайденнаяЦена" - ссылка на элемент Справочник.Цены (например, для записи потом нового значения цены) ;
"ЦенаЗначение" - цена (конкретное число, цена товара)
.
Далее вышеприведенный "штатный" код заменяем на выборку по таблице значений:
.
ТЗВыборка.ВыбратьСтроки();
Пока ТЗВыборка.ПолучитСтроку()=1
Цикл
Номенклатура = ТЗВыборка.Номенклатура;
НайденнаяЦена = ТЗвыборка.НайденнаяЦена;
ЦенаЦены = ТЗвыборка.ЦенаЦены;
.
Входные параметры: в переменной ТипНужнойЦены - ссылка на элемент справочника "ТипыЦен", ДатаЦен - дата получения периодического значения цены.
Из результата исключаются: группы номенклатуры, помеченные на удаление, не включаемые в прайс. Если для номенклатуры отсутствует нужный тип цен в ТЗВыборка.НайденнаяЦена - пустая ссылка.
Для работоспособности данного кода требуется загруженная ВК 1Сpp.dll (последнюю версию можно брать здесь: http://www.1cpp.ru/index.php/File:Icpp-latest.rar) и работа базы в SQL-варианте (не DBF).
Идеал специалиста широкого профиля - знает все о ниочем...
Отдельное спасибо Учителям: leshikkam, berezdetsky, Ёпрст - за пинание меня в правильном направлении и терпеливое отношение к моим тормозам... А также и всем остальным (в основном с mista)