Переключение на Главную Страницу Страницы: 1 ОтправитьПечать
Обычная тема $ПоследнееЗначение в DBF (число прочтений - 5501 )
Alister
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 123
Зарегистрирован: 19. Мая 2006
$ПоследнееЗначение в DBF
28. Июня 2006 :: 18:07
Печать  
Народ ! Кто как решает вопрос с периодическими реквизитами ?
Из статьи "Эффективное использование MSSQL в 1С при помощи ВК 1С++"  : "Для получения их значений служит виртуальное значение
$ПоследнееЗначение.<ИмяСправочника >| Константа.<ИмяРеквизита |
ИмяКонстанты>(<ИдОбъекта>, <Дата>[, <Время>[, <ИДДокумента>]]), которое является коррелированным подзапросом (вложенный запрос, в котором используется значения основного)." Такое элегантное решение для SQL, а как же DBF - дискриминация по формату базы Улыбка
Из той же статьи решение через доп.запрос но это не удобно если надо получить сразу несколько периодических реквизитов.
Вопрос spock`у (как разработчику OLEDB в 1С++) нельзя ли подобный коррелированный подзапрос сделать для DBF ?
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #1 - 29. Июня 2006 :: 04:00
Печать  
А попробуй-ка написать универсальный запрос виртуальной функции, который можно встроить в любую задумку пользователя.
Вот для t-sql сделано через подзапрос в select-list'е, а для vfpoledb9 такой номер не проходит. Точнее проходит, но есть ограничение на TOP 1 в подзапросе.
Я делал так:
Код
Выбрать все
	тЗапрос = "
	|SELECT
	|	сНормы.id as [ЭлНорм $Справочник.НормыРасходов],
	|	$сНормы.ВидЭлемента as [ВидЭлемента $Перечисление.ВидыНоменклатуры],
	|	$сНормы.Элемент as [Элемент $Справочник.Номенклатура],
	|	сНорма.value as [Норма $Число],
	|	сКолВо.value as [КолПрод $Число],
	|	сСтоим.value as [Стоимость $Число]
	|
	|FROM
	|	$Справочник.НормыРасходов as сНормы
	|
	|LEFT JOIN $Справочник.Номенклатура as Ном ON (Ном.id = сНормы.parentext) AND (Ном.id = :ТекНоменк)
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Норма)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Норма
	|		) as сНорма
	|ON сНорма.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.КолПрод)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.КолПрод
	|		) as сКолВо
	|ON сКолВо.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Стоимость)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Стоимость
	|		) as сСтоим
	|ON сСтоим.objid = сНормы.id
	|
	|WHERE
	|	сНормы.PARENTEXT = :ТекНоменк
	|";
 

  
Наверх
ICQ  
IP записан
 
DrACe
1c++ donor
1c++ power user
Отсутствует


1С++ любитель

Сообщений: 447
Местоположение: г. Новосибирск
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #2 - 29. Июня 2006 :: 04:14
Печать  
а может реализовать это с помощью хранимой процедуры?
вроде слышал, что некоторые драйвера их поддерживают
  
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #3 - 29. Июня 2006 :: 05:11
Печать  
vfpoledb9 точно может использовать хранимые процедуры.
Хранимые процедуры представляют из себя текстовые файлики с расширением prg
  
Наверх
ICQ  
IP записан
 
DrACe
1c++ donor
1c++ power user
Отсутствует


1С++ любитель

Сообщений: 447
Местоположение: г. Новосибирск
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #4 - 29. Июня 2006 :: 05:56
Печать  
spock писал(а) 29. Июня 2006 :: 05:11:
vfpoledb9 точно может использовать хранимые процедуры.
Хранимые процедуры представляют из себя текстовые файлики с расширением prg


тогда может быть кто-нибудь поднапряжется и напишет универсальную процедуру, которую можно будет включить в поставку с 1С++??

кто это будет?..  Круглые глаза ... и надо ли?..
  
Наверх
 
IP записан
 
Alister
Full Member
***
Отсутствует


I Love YaBB 2!

Сообщений: 123
Зарегистрирован: 19. Мая 2006
Re: $ПоследнееЗначение в DBF
Ответ #5 - 29. Июня 2006 :: 10:49
Печать  
spock писал(а) 29. Июня 2006 :: 04:00:
А попробуй-ка написать универсальный запрос виртуальной функции, который можно встроить в любую задумку пользователя.
Вот для t-sql сделано через подзапрос в select-list'е, а для vfpoledb9 такой номер не проходит. Точнее проходит, но есть ограничение на TOP 1 в подзапросе.
Я делал так:
Код
Выбрать все
	тЗапрос = "
	|SELECT
	|	сНормы.id as [ЭлНорм $Справочник.НормыРасходов],
	|	$сНормы.ВидЭлемента as [ВидЭлемента $Перечисление.ВидыНоменклатуры],
	|	$сНормы.Элемент as [Элемент $Справочник.Номенклатура],
	|	сНорма.value as [Норма $Число],
	|	сКолВо.value as [КолПрод $Число],
	|	сСтоим.value as [Стоимость $Число]
	|
	|FROM
	|	$Справочник.НормыРасходов as сНормы
	|
	|LEFT JOIN $Справочник.Номенклатура as Ном ON (Ном.id = сНормы.parentext) AND (Ном.id = :ТекНоменк)
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Норма)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Норма
	|		) as сНорма
	|ON сНорма.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.КолПрод)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.КолПрод
	|		) as сКолВо
	|ON сКолВо.objid = сНормы.id
	|
	|LEFT JOIN (
	|		SELECT
	|			c_dt.objid as objid,
	|			c_dt.value as value
	|		FROM 1sconst as c_dt
	|		WHERE
	|			c_dt.date IN (SELECT MAX(c.date)
	|						FROM 1sconst as c
	|						WHERE
	|							(c.date <= :КонДата~~) AND
	|							(c.id = $ИсторияРеквизита.НормыРасходов.Стоимость)
	|							AND (c.objid = c_dt.objid)
	|						) AND
	|			c_dt.id = $ИсторияРеквизита.НормыРасходов.Стоимость
	|		) as сСтоим
	|ON сСтоим.objid = сНормы.id
	|
	|WHERE
	|	сНормы.PARENTEXT = :ТекНоменк
	|";
 


Написать к сожалению тяму не хватает Печаль
Использую тоже подзапрос через 1sconst , но душа просит большего вот и нудю Улыбка
  
Наверх
 
IP записан
 
Thor
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 82
Зарегистрирован: 12. Июля 2006
Re: $ПоследнееЗначение в DBF
Ответ #6 - 12. Июля 2006 :: 10:51
Печать  
Всем привет.
Вопрос: А можно ли получить последнее значение периодического реквизита с помощью прямого запроса к DBF-базе, используя Microsoft Visual Foxpro Driver? Т.е. существует ли такой запрос? К сожалению, ODBC драйвер, в отличие от vfpoledb, не поддерживает вложенные запросы при присоединении, а во всех ссылках, которые я нашел используется конструкция
Код
Выбрать все
...
LEFT JOIN (SELECT ...
 



Попробовал сам сварганить запрос:
Код
Выбрать все
	|SELECT
	|	Спр.ID as [Товар $Справочник.ТМЦ],
	|	Спр.ID as [ID],
	|	Спр.Descr as Наименование,
	|	$Спр.Автор as Автор,
	|	$Спр.ГодИздания as ГодИздания,
	|	$Спр.СтавкаНДС as [ВидНДС $Справочник.НалогиОтчисления],
	|		   сЦены.value as [Цена $Число],
	|	$Спр.ШтрихКод as ШтрихКод
	|FROM
	|	$Справочник.ТМЦ as Спр
	|LEFT JOIN 1sconst as сЦены ON Спр.id = сЦены.objid
	| WHERE
	|  (сЦены.date IN (
	|   SELECT MAX(c.date)
	|   FROM
	| 	  1sconst as c
	|   WHERE
	|    (c.date <= :ДатаЦены~~) AND (c.id = $ИсторияРеквизита.ТМЦ.Цена_Розн) AND (сЦены.objid = c.objid)
	|				  ) AND (сЦены.id = $ИсторияРеквизита.ТМЦ.Цена_Розн)
	|  )"
 



Выдает ошибку "State S1000, native 602, message [Microsoft][ODBC Visual FoxPro Driver]Operation is invalid for a Memo, General, or Picture field."

Подскажите, есть ли шансы или безнадежно?

ЗЫ. В MS Access запрос проходит на ура. Кстати, где можно тестировать запросы под DBF (аналог QA)?
  
Наверх
ICQ  
IP записан
 
Alex_Bob
Full Member
***
Отсутствует



Сообщений: 136
Местоположение: Липецк
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #7 - 26. Сентября 2006 :: 08:46
Печать  
В продолжение темы...

Цитата:
Вопрос: А можно ли получить последнее значение периодического реквизита с помощью прямого запроса к DBF-базе, используя Microsoft Visual Foxpro Driver?


Можно вообще обойтись без LEFT JOIN, используя вспомогательные таблицы

1. Сокращаем размер 1sconst для ускорения последующих запросов
Код
Выбрать все
|SELECT *
|FROM 1sconst
|WHERE (id = $ИсторияРеквизита.ТМЦ.Цена_Розн) AND
|	   (date <= :ДатаЦены~~)
|INTO TABLE myconst 



2. Оставляем составные ключи последних значений
Код
Выбрать все
|SELECT objid, MAX(date) as date0
|FROM myconst
|GROUP BY objid
|INTO TABLE _c1 



3. Находим последние значения
Код
Выбрать все
|SELECT myconst.objid as objid, myconst.value as value
|FROM myconst, _c1
|WHERE (myconst.objid=_c1.objid) AND (myconst.date=_c1.date0)
|INTO TABLE _c2 



4. Подставляем как реквизит справочника
Код
Выбрать все
|SELECT Спр.ID as [Товар $Справочник.ТМЦ],
|	Спр.ID as [ID],
|	Спр.Descr as Наименование,
|	$Спр.Автор as Автор,
|	$Спр.ГодИздания as ГодИздания,
|	$Спр.СтавкаНДС as [ВидНДС $Справочник.НалогиОтчисления],
|	   сЦены.value as [Цена $Число],
|	$Спр.ШтрихКод as ШтрихКод
|FROM
|	$Справочник.ТМЦ as Спр, _c2 as сЦены
|WHERE
|	 (Спр.ID=cЦены.objid) 


 
Такая последовательность запросов в DBF должна отработать быстрее, чем запрос с LEFT JOIN.
Только не забыть потом удалить результаты первых трех запросов. В данном случае это будут файлы MYCONST.DBF,_C1.DBF,_C2.DBF в каталоге ИБ.
  

Необходимо время, чтобы восстановить хаос. (с) Дж. Буш (младший)
Наверх
 
IP записан
 
spock
1c++ developer
1c++ moderator
Отсутствует



Сообщений: 822
Местоположение: Новосибирск
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #8 - 26. Сентября 2006 :: 09:45
Печать  
Alex_Bob писал(а) 26. Сентября 2006 :: 08:46:
Такая последовательность запросов в DBF должна отработать быстрее, чем запрос с LEFT JOIN.

Для справки: а точно быстрее? А то меня мучают мутные сомнения.
  
Наверх
ICQ  
IP записан
 
Alex_Bob
Full Member
***
Отсутствует



Сообщений: 136
Местоположение: Липецк
Зарегистрирован: 19. Мая 2006
Пол: Мужской
Re: $ПоследнееЗначение в DBF
Ответ #9 - 26. Сентября 2006 :: 10:58
Печать  
С точно таким запросом не пробовал, пробовал с Подразделением в справочнике Сотрудники (вывожу список сотрудников из другой базы в ТП), там результаты такие:
с LEFT JOIN - 25 сек
способом, описанным выше - 3 сек.
Справочник Сотрудники ~ 9000 записей
1sconst - 17Мб

Правда там у меня эта последовательность запросов объединена в хранимую процедуру
  

Необходимо время, чтобы восстановить хаос. (с) Дж. Буш (младший)
Наверх
 
IP записан
 
Переключение на Главную Страницу Страницы: 1
ОтправитьПечать