Переключение на Главную Страницу Страницы: [1] 2  ОтправитьПечать
Горячая тема (более 10 ответов) Получение строкового представления вида документа (число прочтений - 9307 )
baa
YaBB Newbies
*
Отсутствует


I Love YaBB 2!

Сообщений: 11
Зарегистрирован: 06. Апреля 2007
Получение строкового представления вида документа
06. Апреля 2007 :: 05:44
Печать  
Добрый день уважаемые.
Столкнулся с проблемой получения строкового представления вида документа из запроса.
Классический вариант запроса
Код
Выбрать все
ТекстЗапроса = "
|SELECT
|  Жур.IDDoc as [Док $Документ],
|  Жур.IDDocDef as Док_вид,
|  CAST(LEFT(Жур.Date_Time_IDDoc, 8) as DateTime) as ДатаДок
|FROM
|  _1SJourn Жур
|WHERE
|  Жур.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
 


возвращает всего лишь числовое соответствие вида. Строковое представление можно получить из файла DDS.
Получить строковое представление вида документа можно в цикле обработки ТЗ - результата запроса стандартным методом 1С - Вид(). При этом наблюдается значительная потеря времени, т.к. происходит лишнее обращение к базе данных, при котором получается сначала весь документ - Жур.IDDoc, а потом уже из него конкретно Вид().
Каких либо других методов получения строкового представления вида документа не нашел. Просмотрев форум, увидил, что вопрос поднимался с переодичностью в месяц Улыбка. Более-менее ясного ответа не нашел. А главное быстрого по скорости.
Предлагаю свое решение задачи с помощью хранимой функции.
Создание самой функции -
Код
Выбрать все
МДВ = СоздатьОбъект("MetaDataWork");
ТекстЗапросаSQL = "
	|create FUNCTION  sp_viewdoc(@val int) RETURNS varchar(40)
	|AS
	|begin
	|declare @v int;
	|declare @tval varchar(40);
	|set @v = @val;
	|set @tval = '';
	|set @tval =
	|CASE @v
	|";
	Для ъ=1 По Метаданные.Документ() Цикл
		Сообщить(""+МДВ.ИДДокумента(ъ) +" - "+ Метаданные.Документ(ъ).Идентификатор);
		ТекстЗапросаSQL = ТекстЗапросаSQL + "
		|	WHEN '"+МДВ.ИДДокумента(ъ)+"' THEN '"+Метаданные.Документ(ъ).Идентификатор+"'";
	КонецЦикла;
	ТекстЗапросаSQL = ТекстЗапросаSQL +"
	|	 ELSE 'Nodefine'
	|END;
	|RETURN(@tval);
	|end
	|";
	ЗапросSQL.Открыть(ТекстЗапросаSQL);
 


Выполняется один раз и создает хранимую функцию на сервере с именем sp_viewdoc.
Использование фукнции в запросе -
Код
Выбрать все
ТекстЗапроса = "
|SELECT
|  Жур.IDDoc as [Док $Документ],
|  Жур.IDDocDef as Док_вид,
|  dbo.sp_viewdoc(Жур.IDDocDef) ДокВид,
|  CAST(LEFT(Жур.Date_Time_IDDoc, 8) as DateTime) as ДатаДок
|FROM
|  _1SJourn Жур
|WHERE
|  Жур.Date_Time_IDDoc BETWEEN :НачДата AND :КонДата~
 


при этом 3-я строка вернет текстовое представление вида документа.
Можно использовать совместно с хранимой процедурой sp_tohex, описанной на форуме -
Код
Выбрать все
	ТекстЗапросаSQL = "
	|SELECT
	|	dbo.sp_tohex(Жур.IDDocDef, 4) + Жур.IDDoc [Док $Документ]
	|	, dbo.sp_viewdoc(Жур.IDDocDef) ДокВид
	|FROM
	|    _1SJourn Жур
	|WHERE
	|	Жур.date_time_iddoc between :НачДата and :КонДата~
	|	and Жур.closed & 1 = 1
	|order by
	|	Жур.date_time_iddoc
	|";
 


Подобную операцию можно так же было реализовать через временную таблицу, но при этом ее требуется создавать всякий раз перед запросом, а фукнция хранится на сервере постоянно.
Выигрышь скорости, по сравнению с использованием метода Вид()  - в несколько десятков раз.
  
Наверх
 
IP записан
 
Vaicartana
Junior Member
**
Отсутствует


I Love YaBB 2!

Сообщений: 50
Местоположение: Far, Far Away...
Зарегистрирован: 29. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #1 - 06. Апреля 2007 :: 06:08
Печать  
Таки да.
с Вид() что то не очень клеется.

2(ArtBear и Spok) может можно в запросе добавить мета-параметр, возвращающий вид документа? Это ведь в принципе не сложно?
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #2 - 06. Апреля 2007 :: 06:40
Печать  
Ну вообще-то, вместо UDF на сервере можно было создать просто функцию в ГМ, тогда бы и запрос был проще, и результат запроса был бы компактнее (не содержал бы строковые Ид вида), и лишних вычислений на сервере бы небыло, и обращения к базе для получения строкового вида бы не потребовалось.

Имхо надо в объект MetaDataWork добавить метод:
ВидДокументаПоИД(ИдДокумента)
Возвращает: тип Строка, вид документа.
Параметры:
- ИдДокумента - Число, Строка - идентификатор вида документа, может передаваться строкой в 4 символа 36-ричного вида числа(для DBF формата ИБ).
Вот это действительно очень просто и максимально эффективно.
  
Наверх
ICQ  
IP записан
 
baa
YaBB Newbies
*
Отсутствует


I Love YaBB 2!

Сообщений: 11
Зарегистрирован: 06. Апреля 2007
Re: Получение строкового представления вида докуме
Ответ #3 - 06. Апреля 2007 :: 06:48
Печать  
2 (DmitrO)
Какую именно функцию добавить в ГМ?
Насчет >Имхо надо в объект MetaDataWork добавить метод
конечно лучше добавить, тем более, что наверное функция пользовалась бы стпросом, если о ней периодически спрашивают.
По-поводу, усложнения запроса...
Я не увидил, что он особо усложнился. Добавился всего лишь вызов функции  dbo.sp_viewdoc(Жур.IDDocDef).
Да и кто возращает результат сам SQL сервер, а он побыстрее это делает чем 1С
  
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #4 - 06. Апреля 2007 :: 06:52
Печать  
Цитата:
Какую именно функцию добавить в ГМ?

функцию с тем же функционалом что и на сервере, которая по ИД будет возвращать вид документа, но не обращаясь к базе.
  
Наверх
ICQ  
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #5 - 06. Апреля 2007 :: 07:16
Печать  
А зачем вообще нужен вид документа в результате запроса?
Вероятно для того, чтобы потом сделать что-то типа такого:
Код
Выбрать все
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку()=1 Цикл
    Если ТЗ.ВидДокумента="РасходнаяНакладная" Тогда
	  ...
    ИначеЕсли ТЗ.ВидДокумента="ПриходнаяНакладная" Тогда
	  ...
    Иначе
	  ...
    КонецЕсли;
КонецЦикла;
 



Но ведь такой код будет эффективнее, за счет того что сравниваться будут не строки, а числа:
Код
Выбрать все
ВидРасходная = Запрос.мд.ИДДокумента("РасходнаяНакладная");
ВидПриходная = Запрос.мд.ИДДокумента("ПриходнаяНакладная");
ТЗ.ВыбратьСтроки();
Пока ТЗ.ПолучитьСтроку()=1 Цикл
    Если ТЗ.Док_вид=ВидРасходная Тогда
	  ...
    ИначеЕсли ТЗ.Док_вид=ВидПриходная Тогда
	  ...
    Иначе
	  ...
    КонецЕсли;
КонецЦикла;
 


  
Наверх
ICQ  
IP записан
 
baa
YaBB Newbies
*
Отсутствует


I Love YaBB 2!

Сообщений: 11
Зарегистрирован: 06. Апреля 2007
Re: Получение строкового представления вида докуме
Ответ #6 - 06. Апреля 2007 :: 07:30
Печать  
Цитата:
функцию с тем же функционалом что и на сервере, которая по ИД будет возвращать вид документа, но не обращаясь к базе.

я сомневаюсь, что функция с тем же функционалом будет работать быстрее в 1С, чем на SQL-сервере. За что, собственно, боремся - за скорость.
Цитата:
А зачем вообще нужен вид документа в результате запроса?
Вероятно для того, чтобы потом сделать что-то типа такого:

не факт! допустим мне нужен был текстовый вид именно для отображения, а не для проверки условий, при которой, согласен, эффективнее сравнивать числовые значения, как в вашем примере.
Но ситуаций, когда может потребоватся отобразить именно вид документа - море.

Я думаю, оптимальнее всего было вставить такую функцию в MetaDataWork, как и было предложено выше.
  
Наверх
 
IP записан
 
trad
1c++ power user
1c++ donor
1c++ moderator
Отсутствует



Сообщений: 3050
Местоположение: Киров
Зарегистрирован: 23. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #7 - 06. Апреля 2007 :: 07:45
Печать  
на ряду с добавлением MetaDataWork::ВидДокументаПоИД(), я бы предложил внести специальное типизирующее имя $ВидДокумента (или $ВидДокументаСтр) для его применения в типизирующем псевдониме колонки.
пример:
select
 Жур.IDDocDef as [Вид $ВидДокумента]
...
На основании этого ODBCRecordset, при получении выборки, записывал бы в результат вместо int/char(4) - строковое представление вида
  

1&&2&&3
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #8 - 06. Апреля 2007 :: 08:25
Печать  
Цитата:
допустим мне нужен был текстовый вид именно для отображения,

Хм, если для отображения пользователю, тогда, вообще-то, отображать нужно предствление вида, а не вид.
Если для отображения себе (программисту просто взглянуть), тогда можно и сам документ смотреть, и о быстродействии можно не говорить.
  
Наверх
ICQ  
IP записан
 
baa
YaBB Newbies
*
Отсутствует


I Love YaBB 2!

Сообщений: 11
Зарегистрирован: 06. Апреля 2007
Re: Получение строкового представления вида докуме
Ответ #9 - 06. Апреля 2007 :: 08:37
Печать  
Цитата:
Хм, если для отображения пользователю, тогда, вообще-то, отображать нужно предствление вида, а не вид.
Если для отображения себе (программисту просто взглянуть), тогда можно и сам документ смотреть, и о быстродействии можно не говорить.

Не спорю, именно представление вида и нужно выводить.
У меня был частный случай, когда понадобился именно вид. Но заменить вид на представление ничего не стоит.
Отображать себе (т.е. программисту), вообще не имеет смысла, т.к. сам документ гараздо больше информации скажет, чем название вида.
  
Наверх
 
IP записан
 
kiruha
1c++ power user
Отсутствует



Сообщений: 1249
Зарегистрирован: 11. Апреля 2007
Re: Получение строкового представления вида докуме
Ответ #10 - 20. Апреля 2007 :: 11:00
Печать  
для ДБФ самым быстрым - добавление в запрос строки вида

Код
Выбрать все
|,ICASE(Жур.IDDOCDEF=$ВидДокумента.Счет, 'Счет'
|,Жур.IDDOCDEF=$ВидДокумента.КоммерческоеПредложение,'Коммерческое Пр.'
|,'  ') as ВидДокумента
 


благо не так много документов двигает нужный регистр.

(строковое представление одинакового размера - форматирование не сохранилось)
  
Наверх
 
IP записан
 
ev-kov
God Member
*****
Отсутствует



Сообщений: 694
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #11 - 20. Апреля 2007 :: 11:22
Печать  
А две типизации по IDDOC в одном запросе возможно  сделать ? IDDOC из двух разных таблиц.
  

Информация - то, что снижает неопределенность в какой-либо области и очень важно не ошибиться областью в наш информационный век!
Наверх
 
IP записан
 
DmitrO
1c++ power user
Отсутствует


ex developer

Сообщений: 579
Местоположение: г. Киров
Зарегистрирован: 22. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #12 - 20. Апреля 2007 :: 13:30
Печать  
ev-kov писал(а) 20. Апреля 2007 :: 11:22:
А две типизации по IDDOC в одном запросе возможно  сделать ? IDDOC из двух разных таблиц.

конечно:
Код
Выбрать все
select
   t1.iddoc as [ДокПоступления $Документ],
   t1.iddocdef as [ДокПоступления_вид],
   t2.iddoc as [ДокОтражения $Документ],
   t2.iddocdef as [ДокОтражения_вид],
...
 

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


Ламер - вансист

Сообщений: 262
Местоположение: Ukraine, Kyiv
Зарегистрирован: 27. Декабря 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #13 - 23. Апреля 2007 :: 08:22
Печать  
Спасибо baa, воспользовался его пользовательской функцией.

Только обозвал её как следует (sp_ вроде как для процедур применяется: stored procedure) и убрал лишнее:
Код
Выбрать все
textSQLque="create function dbo.fn_kindofdoc(@val int)
	|returns varchar(40)
	|as
	|begin
	|declare @tval varchar(40)
	|set @tval = case @val";
	for V=1 to metadata.document() do
		textSQLque=textSQLque+"
		|	when "+_rs.md.getdocID(V)+" then '"+metadata.document(V).identifier+"'";
	enddo;
	textSQLque=textSQLque+"
	|	else 'Nodefine'
	|	end
	|return (@tval)
	|end"; 

« Последняя редакция: 23. Апреля 2007 :: 12:16 - Kapet »  
Наверх
ICQ  
IP записан
 
vivm
Full Member
***
Отсутствует



Сообщений: 159
Местоположение: Новосибирск
Зарегистрирован: 26. Мая 2006
Пол: Мужской
Re: Получение строкового представления вида докуме
Ответ #14 - 23. Июня 2007 :: 09:39
Печать  
Можно через создание таблицы, только не временной, а постоянной: http://www.1cpp.ru/forum/YaBB.pl?num=1182591175/0
  
Наверх
ICQ  
IP записан
 
Переключение на Главную Страницу Страницы: [1] 2 
ОтправитьПечать