gifts2017

Запрос к таблице значений

Опубликовал Антон Юхлин (antonrost) в раздел Программирование - Практика программирования

Данная разработка дает возможность обращаться к таблице значений при помощи обычного запроса.
В функцию передается таблица значений, список колонок для свертки и суммирования, а также строка с доп. условиями в формате языка запросов 1С.
Функция возвращает объект типа "Запрос".
Позволяет легко группировать ТЗ по любым полям, а также делать выборку из ТЗ по любым условиям.
Синтаксис:

ТЗ_в_Запрос(ИсхТЗ, Изм, Рес, Условие="").

ИсхТЗ - Обязательный параметр. Таблица значений, к которой выполняется запрос;
Изм - Обязательный параметр. Список колонок для группировок через запятую;
Рес - Список колонок для суммирования;
Условие - произвольный текст в формате языка запросов 1С.

Функция возвращает объект типа "Запрос".

Скачать файлы

Наименование Файл Версия Размер
- 451
.zip 5,53Kb
25.09.09
451
.zip 5,53Kb Бесплатно

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Доржи Цыденов (harleq) 08.06.06 09:29
Такой метод получения данных, с помощью служебного документа, я увидел первый раз в ИТРП. Очевидный минус такого метода, блокировка транзакции при формировании отчета, но если в базе немного людей, то можно использовать.
2. Алексей Лапицкий (Lapitskiy) 14.06.06 05:03
Думаю, что через справочник будет намного быстрее
3. AntonRost (antonrost) 14.06.06 08:01
4. Сhe Burashka (CheBurator) 11.12.06 13:39
5. ROM (ROM_1C) 07.06.13 11:38
Думаю, что очень мне поможет. Спасибо!
6. ROM (ROM_1C) 07.06.13 13:37
7. Алекс Маслюков (Alex_1066) 06.06.14 16:51
Интересное решение.. Спасибо.
8. script Мальчинко (script) 12.06.14 15:49
9. script Мальчинко (script) 02.11.14 22:22
Возникла проблема. Не выводит итоги по группам справочников. В исходном запросе используется метод "Группировка Товар". Соответственно в отчет выводятся итоги по группам. После передачи ТЗ в Функция ТЗ_в_Запрос(), возвращаемый запрос не содержит итогов по группам справочника. Как быть?
10. script Мальчинко (script) 02.11.14 22:45
Решение найдено:
1. итоги по иерархии не выводятся из-за того что документ "Запрос" имеет реквизиты табл. части "Измерение1", "Измерение2", "ИзмерениеN" с неопределеным типом значения.
2. Что бы получить нужный результат прийдется изменить документ "Запрос", а именно добавить в него реквизит с определным типом значений (например: реквизит "Товар": ТипЗнч - Спр.Номенклатура). Т.е. в запросе зделать, я бы назвал, предопределенные группировки, т.е. такие для которых точно определен тип значения.
3. Прийдется переделать модуль генерации запроса.
Можно было делать и универсально, но мне и так сойдет.


Функция ТЗ_в_Запрос(ИсхТЗ, Изм, Рес="", Условие="") Экспорт
	
	СписокИзмерений = СоздатьОбъект("СписокЗначений");
	СписокРесурсов  = СоздатьОбъект("СписокЗначений");
	ДокЗапрос		= СоздатьОбъект("Документ.Запрос");
	ТЗ				= СоздатьОбъект("ТаблицаЗначений");

	//Чтобы не засорять базу, удаляем случайно оставшиеся предыдущие документы "Запрос",
	// кроме тех, которые в данный момент кем-нибудь используются.
	НачатьТранзакцию();
		ДокЗапрос.ВыбратьДокументы();
		Пока ДокЗапрос.ПолучитьДокумент() = 1 Цикл
			Попытка
				ДокЗапрос.Удалить();
			Исключение
			КонецПопытки;
		КонецЦикла;
	ЗафиксироватьТранзакцию();

	// Подготавливаем таблицу для загрузки в документ. 
	_ИсхТЗ = СоздатьОбъект("ТаблицаЗначений");
	ВремТЗ = СоздатьОбъект("ТаблицаЗначений");

	// _ИсхТЗ - из ИсхТЗ выгружаются используемые столбца в нужном порядке;
	ИсхТЗ.Выгрузить(_ИсхТЗ,,,Изм+?(ПУстоеЗначение(Рес)=1,"",",")+Рес);

	
	//Загоняем строку-перечень измерений в список
	Стр = СокрЛП(Изм);
	Поз = Найти(Изм, ",");
	Пока 0 < Поз Цикл
		СписокИзмерений.ДобавитьЗначение(СокрП(Лев(Стр, Поз-1)));
		Стр = СокрЛ(Сред(Стр, Поз+1));
		Поз = Найти(Стр, ",");
	КонецЦикла;
	СписокИзмерений.ДобавитьЗначение(СокрЛП(Стр));

	//Загоняем строку-перечень ресурсов в список
	Если ПустоеЗначение(Рес) = 0 Тогда
		Стр = СокрЛП(Рес);
		Поз = Найти(Рес, ",");
		Пока 0 < Поз Цикл
			СписокРесурсов.ДобавитьЗначение(СокрП(Лев(Стр, Поз-1)));
			Стр = СокрЛ(Сред(Стр, Поз+1));
			Поз = Найти(Стр, ",");
		КонецЦикла;
		СписокРесурсов.ДобавитьЗначение(СокрЛП(Стр));
	КонецЕсли;
	
	// ВремТЗ - Структура из документа.........,
	Для Ном = 1 По СписокИзмерений.РазмерСписка() Цикл
		ИдИзм = СписокИзмерений.ПолучитьЗначение(Ном);
		Если ИдИзм = "Товар" Тогда
			ВремТЗ.НоваяКолонка("Товар");
		Иначе	
			ВремТЗ.НоваяКолонка(Шаблон("Измерение[Ном]"));
		КонецЕсли;
	КонецЦикла;
	Для Ном = 1 По СписокРесурсов.РазмерСписка() Цикл
		ВремТЗ.НоваяКолонка(Шаблон("Ресурс[Ном]"));
	КонецЦикла;

	// ВремТЗ - .............., данные из _ИсхТЗ
	ВремТЗ.КоличествоСтрок(_ИсхТЗ.КоличествоСтрок());
	ВремТЗ.Заполнить(_ИсхТЗ);

	
	// Создаем документ, по которому будем делать запрос.
	ДокЗапрос.Новый();

	// Если есть оперативный учет, то документ обязательно должен быть до ТА
	Попытка
		ПолучитьДатуТА();
		ЕстьОперУчет = 1;
	Исключение
		ЕстьОперУчет = 0;
	КонецПопытки;

	Если ЕстьОперУчет = 1 Тогда
		ДокЗапрос.ДатаДок = ПолучитьДатуТА()-1;
	КонецЕсли;
    
	//Заполняем документ
	ДокЗапрос.ЗагрузитьТабличнуюЧасть(ВремТЗ);
	ДокЗапрос.Записать();
	
	// Что-бы никто не удалил пока выпоняется запрос.
	ДокЗапрос.Блокировка(1);
    
	// Понадобится для условия - фильтр по документу.
	ТекущДок = ДокЗапрос.ТекущийДокумент();
	
	// Создаем текст запроса.
	ТекстЗапроса="ОбрабатыватьДокументы Все;
	|ТекДок = Документ.Запрос.ТекущийДокумент;";
	Для Ном = 1 По СписокИзмерений.РазмерСписка() Цикл
		ИдИзм = СписокИзмерений.ПолучитьЗначение(Ном);
		Если ИдИзм = "Товар" Тогда
			ТекстЗапроса=ТекстЗапроса+"
			|Товар = Документ.Запрос.Товар;";
		Иначе	
			ТекстЗапроса=ТекстЗапроса+Шаблон("
			|[ИдИзм] = Документ.Запрос.Измерение[Ном];");
		КонецЕсли;
	КонецЦикла;
	Для Ном = 1 По СписокРесурсов.РазмерСписка() Цикл
		ИдРес = СписокРесурсов.ПолучитьЗначение(Ном);
		ТекстЗапроса=ТекстЗапроса+Шаблон("
		|_[ИдРес] = Документ.Запрос.Ресурс[Ном];");
	КонецЦикла;
	Для Ном = 1 По СписокРесурсов.РазмерСписка() Цикл
		ИдРес = СписокРесурсов.ПолучитьЗначение(Ном);
		ТекстЗапроса=ТекстЗапроса+Шаблон("
		|Функция [ИдРес] = Сумма(_[ИдРес]);");
	КонецЦикла;
	Для Ном = 1 По СписокИзмерений.РазмерСписка() Цикл
		ИдИзм = СписокИзмерений.ПолучитьЗначение(Ном);
		Если ИдИзм = "Товар" Тогда
			ТекстЗапроса=ТекстЗапроса+"
			|Группировка Товар;";
		Иначе	
			ТекстЗапроса=ТекстЗапроса+Шаблон("
			|Группировка [ИдИзм];");
		КонецЕсли;
	КонецЦикла;
	ТекстЗапроса=ТекстЗапроса+"
	|Условие (Запрос.ТекДок = ТекущДок);";


	// Добавляем внешнее условие (или еще что-нибудь !!!)
	// Внимание !!! Во внешнем условии перед идентификатором ресурса должен быть знак нижнего подч.:
	// Например: _Сумма, _Количество.
	
	Если ПустоеЗначение(Условие) = 0 Тогда
		ТекстЗапроса=ТекстЗапроса+"
		|"+Условие;
	КонецЕсли;
	
	//// Отладка текста запроса
	//Текст = СоздатьОбъект("Текст");
	//Текст.ДобавитьСтроку(ТекстЗапроса);
	//Текст.Показать();
	
	Запрос = СоздатьОбъект("Запрос");
	Если Запрос.Выполнить(ТекстЗапроса) = 0 Тогда
		Сообщить("Ошибка при выполнении запроса");
		Возврат 0;
	КонецЕсли;
	
	// Отработанный материал - в утиль...
	ДокЗапрос.Удалить();

	Возврат Запрос;
	
	
КонецФункции // ЗапросТЗ()
...Показать Скрыть
11. AndreyKaRu (AndreyKaRu) 29.05.15 18:30
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа