Фикс процедуры заполнения документа Формирование книги продаж для КА 1.1.81.3

20.01.17

Разработка - Запросы

Неоптимальный отбор с использованием ПостроителяЗапроса

В одном из обновлений от 1С доработан модуль заполнения документа Формирование записей книги продаж после чего время ожидания стало неприлично долгим. Замер производительности показал 1063,478002 (это 17 минут) - после оптимизации кода 66,239374 (1 минута).

Проблема в процедуре модуля документа РаспределитьОплатыПоДеревуСФ(). Тут в цикле создается таблица значений с помощью ПостроителяЗапроса - это результат отбора строк. Для оптимизации достаточно заменить несколько строк кода.

После внесения правок можно использовать типовой алгоритм заполнения  - для этого достаточно в комментарий документа написать " [ТиповойАлгоритмЗаполнения] " и сохранить его.

Платформа 1С 8.2, MSSQL.

Надеюсь эта маленькая правка кому-нибудь сэкономит время! :)

// Процедура вызывается из тела процедуры "ЗаполнитьРазделРеализация".
// В процессе работы процедуры общая сумма НДС, которая может быть признана
// в качестве вычета распределяется по конкретным событиям оплаты, для того
// чтобы сопоставить факт признания вычета по НДС и факт оплаты поставщику, связанный
// с этим признанием.
Процедура РаспределитьОплатыПоДеревуСФ(Дерево_НДСНачисленный, ТаблицаРезультатов, СписокСчетовФактур, РаспределенныеОплаты, ОтражатьВРеестре = Истина, ОтражатьВидНачисления = Ложь )
	
	НДСНалоговыйПериод = Неопределено;
	
	Построитель_РаспределенныеОплаты = Новый построительЗапроса();
	Построитель_РаспределенныеОплаты.ИсточникДанных = Новый ОписаниеИсточникаДанных(РаспределенныеОплаты);
	
	// Подготовка структуры отбора
	Отбор = Построитель_РаспределенныеОплаты.Отбор;
	Отбор.Добавить("СчетФактура");
	Отбор.СчетФактура.Использование = Истина;
	Отбор.Добавить("РаспределеннаяОплата");
	Отбор.РаспределеннаяОплата.ВидСравнения = ВидСравнения.Больше;
	Отбор.РаспределеннаяОплата.Значение = 0;
	Отбор.РаспределеннаяОплата.Использование = Истина;
	
	Построитель_РаспределенныеОплаты.Порядок.Добавить("ДатаОплаты");
	
	ТаблицаОплат = Новый ТаблицаЗначений();
	ТаблицаОплат.Колонки.Добавить("ДокументОплаты");
	ТаблицаОплат.Колонки.Добавить("ДатаОплаты",Новый ОписаниеТипов("Дата", , , Новый КвалификаторыДаты(ЧастиДаты.ДатаВремя)));
	ТаблицаОплат.Колонки.Добавить("СуммаОплаты",Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15,2)));
	
	ТаблицаИсточникаПостроителя = Построитель_РаспределенныеОплаты.ИсточникДанных.ИсточникДанных;
	МоментОпределения_ПоОтгрузке = Перечисления.МоментыОпределенияНалоговойБазыНДС.ПоОтгрузке;
	
	//[+] -> ДОБАВЛЯЕМ СВОИ ПЕРЕМЕННЫЕ
	ВремТаблицаИсточникаПостроителя = ТаблицаИсточникаПостроителя.СкопироватьКолонки();
	ИспользоватьТиповойАлгоритм     = (СтрЧислоВхождений(Ссылка.Комментарий, "[ТиповойАлгоритмЗаполнения]") > 0);
	//[+] <-
	
	Для каждого СтрокаСФ Из Дерево_НДСНачисленный.Строки Цикл
		
		ТаблицаОплат.Очистить();
		
		Если УчетНДС.ДляСчетаФактурыНеТребуетсяОплата(СтрокаСФ.СчетФактура) Тогда
			НаличиеОплатыНеТребуется = Истина;
		Иначе
			НаличиеОплатыНеТребуется = (СтрокаСФ.Строки[0].МоментОпределенияНалоговойБазыНДС = МоментОпределения_ПоОтгрузке) Или Дата >= '20080101';
			
			//[*] -> МЕНЯЕМ ТИПОВОЙ АЛГОРИТМ...
			//Отбор = Построитель_РаспределенныеОплаты.Отбор;
			//Отбор.СчетФактура.Значение = СтрокаСФ.СчетФактура;
			//Отбор.РаспределеннаяОплата.ВидСравнения = ?(СтрокаСФ.СуммаСНДС>0,ВидСравнения.Больше,ВидСравнения.Меньше);
			//
			//Построитель_РаспределенныеОплаты.Выполнить();
			//Если Построитель_РаспределенныеОплаты.Результат.Пустой() и не НаличиеОплатыНеТребуется и СтрокаСФ.СуммаСНДС	>= 0 Тогда
			//	// Оплата не обнаружена
			//	Продолжить;
			//КонецЕсли; 
			//
			//ВыборкаОплат = Построитель_РаспределенныеОплаты.Результат.Выгрузить(ОбходРезультатаЗапроса.Прямой);
			
			//...С СОХРАНЕНИЕМ ФУНКЦИОНАЛЬНОСТИ ТИПОВОГО ЗАПОЛНЕНИЯ
			//
			Если ИспользоватьТиповойАлгоритм Тогда
				Отбор = Построитель_РаспределенныеОплаты.Отбор;
				Отбор.СчетФактура.Значение = СтрокаСФ.СчетФактура;
				Отбор.РаспределеннаяОплата.ВидСравнения = ?(СтрокаСФ.СуммаСНДС>0,ВидСравнения.Больше,ВидСравнения.Меньше);
				
				Построитель_РаспределенныеОплаты.Выполнить();
				Если Построитель_РаспределенныеОплаты.Результат.Пустой() и не НаличиеОплатыНеТребуется и СтрокаСФ.СуммаСНДС	>= 0 Тогда
					// Оплата не обнаружена
					Продолжить;
				КонецЕсли; 
				
				ВыборкаОплат = Построитель_РаспределенныеОплаты.Результат.Выгрузить(ОбходРезультатаЗапроса.Прямой);
			Иначе
				ПоискОтбор   = Новый Структура();
				ПоискОтбор.Вставить("СчетФактура", СтрокаСФ.СчетФактура);
				ПоискОплат   = ТаблицаИсточникаПостроителя.НайтиСтроки(ПоискОтбор);
				ВыборкаОплат = ВремТаблицаИсточникаПостроителя.Скопировать();
				Если ПоискОплат.Количество() > 0 Тогда
					Для каждого СтрокаПоиска Из ПоискОплат Цикл
						Если СтрокаСФ.СуммаСНДС > 0 Тогда
							Если СтрокаПоиска.РаспределеннаяОплата > 0 Тогда
								СтрокаВыборки = ВыборкаОплат.Добавить();
								ЗаполнитьЗначенияСвойств(СтрокаВыборки, СтрокаПоиска);
							КонецЕсли;	
						Иначе
							Если СтрокаПоиска.РаспределеннаяОплата < 0 Тогда
								СтрокаВыборки = ВыборкаОплат.Добавить();
								ЗаполнитьЗначенияСвойств(СтрокаВыборки, СтрокаПоиска);
							КонецЕсли;	
						КонецЕсли;
					КонецЦикла;		
				КонецЕсли;
				
				Если ВыборкаОплат.Количество() = 0 Тогда
					Если (НЕ НаличиеОплатыНеТребуется И СтрокаСФ.СуммаСНДС >= 0) Тогда
						// Оплата не обнаружена
						Продолжить;
					КонецЕсли;	
				КонецЕсли;
			КонецЕсли;
			//[*] <-
				
			СуммаКПогашению = СтрокаСФ.СуммаСНДС;

			Для каждого СтрокаРаспределеннойОплаты Из ВыборкаОплат Цикл
/// ....
	
	РаспределенныеОплаты = ТаблицаИсточникаПостроителя.Скопировать();
	
КонецПроцедуры // РаспределитьОплатыПоДеревуСФ()

P.S.: ну а дальше запросы, но это уже совсем другая история...

Вступайте в нашу телеграмм-группу Инфостарт

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Инструментарий разработчика Роли и права Запросы СКД Программист Руководитель проекта 1С:Предприятие 8 Платные (руб)

Инструменты для разработчиков 1С 8.3: Infostart Toolkit. Автоматизация и ускорение разработки на управляемых формах. Легкость работы с 1С.

16500 руб.

02.09.2020    267170    1488    421    

1177

Инструментарий разработчика Запросы Программист 1С 8.3 1С:Бухгалтерия 3.0 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Структура запроса. Обработка визуально показывает, из какого количества подзапросов состоит запрос.

2 стартмани

06.07.2026    3226    42    XSlava    20    

42

Запросы Программист 1С 8.3 Россия Бесплатно (free)

Визуальный «Конструктор запроса» 1С, встроенный прямо в VS Code, — аналог конструктора из Конфигуратора и EDT, но без запуска платформы. Расширение читает конфигурацию, выгруженную в файлы, позволяет собрать запрос мышью и генерирует корректный текст на языке запросов 1С (SDBL). Открывает уже существующий текст запроса из кода для правки и — что особенно ценно — сохраняет комментарии при цикле «открыть - править - сохранить». Подходит тем, кто пишет код 1С в VS Code, держит под рукой множество проектов и не хочет ради одного запроса запускать тяжёлый Конфигуратор или EDT.

26.06.2026    6811    Alex_YAM    5    

33

WEB-интеграция Запросы Программист 1С 8.3 Абонемент ($m)

Post1C - это внешняя обработка, которая превращает 1С в полноценный инструмент для тестирования REST API. Всё управление сосредоточено в одном окне: настройка запроса, выполнение, просмотр ответа и генерация кода - без переключения между формами. Аналог Postman, но работающий в привычной среде 1С.

1 стартмани

02.04.2026    2925    80    priem_nv    24    

66

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:Зарплата и кадры государственного учреждения 3 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

QueryConsole1C — расширение, включающее консоль запросов с поддержкой исполняемых представлений — аналогов виртуальных таблиц, основанных на методах программного интерфейса ЗУП. Оно позволяет выполнять запросы с учётом встроенной бизнес-логики, отлаживать алгоритмы получения данных и автоматически генерировать код на встроенном языке 1С.

1 стартмани

16.05.2025    12010    153    zup_dev    32    

86

Инструментарий разработчика Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

В данной публикации рассказывается о решении, которое позволяет находить сразу все ошибки в тексте запроса за раз, а не только самую первую.

2 стартмани

05.03.2025    6833    23    XilDen    12    

29

Обновление 1С Запросы Программист 1С:Предприятие 8 1С:ERP Управление предприятием 2 Абонемент ($m)

Данный инструмент помогает анализировать доработанную конфигурацию после обновления на новый релиз и находить «битые» тексты запросов, в которых участвуют несуществующие в новом релизе метаданные.

3 стартмани

06.02.2025    6105    36    XilDen    26    

42
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Tangram 165 16.02.17 18:35 Сейчас в теме
1.1.81.2 тоже самое... большое тебе спасибо!
2. Nuuq 76 16.02.17 21:42 Сейчас в теме
(1) А "на дворе" 1.1.82.2, но в типовом релизе КА ред. 1.1 без перемен :)

Пожалуйста!
3. pentaleksei 25.07.18 09:44 Сейчас в теме
Отлично работает в УПП 1.3.107.2. Спасибо
Для отправки сообщения требуется регистрация/авторизация