Получить курс валюты на дату документа в запросе 1С

ВЫБРАТЬ
	ВложенныйЗапрос.Ссылка КАК Ссылка,
	ВложенныйЗапрос.Валюта КАК Валюта,
	ВложенныйЗапрос.ДатаКурса КАК ДатаКурса,
	КурсыВалют.Курс КАК Курс,
	КурсыВалют.Кратность КАК Кратность
ИЗ
	(ВЫБРАТЬ
		ПриобретениеТоваровУслуг.Ссылка КАК Ссылка,
		ПриобретениеТоваровУслуг.Валюта КАК Валюта,
		МАКСИМУМ(КурсыВалют.Период) КАК ДатаКурса
	ИЗ
		Документ.ПриобретениеТоваровУслуг КАК ПриобретениеТоваровУслуг
			ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
			ПО ПриобретениеТоваровУслуг.Валюта = КурсыВалют.Валюта
				И ПриобретениеТоваровУслуг.Дата >= КурсыВалют.Период
	
	СГРУППИРОВАТЬ ПО
		ПриобретениеТоваровУслуг.Ссылка,
		ПриобретениеТоваровУслуг.Валюта) КАК ВложенныйЗапрос
		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.КурсыВалют КАК КурсыВалют
		ПО ВложенныйЗапрос.Валюта = КурсыВалют.Валюта
			И ВложенныйЗапрос.ДатаКурса = КурсыВалют.Период

Версионирование объектов

В модуле формы, в процедуре «ПриСозданииНаСервере», добавить:
ВерсионированиеОбъектов.ПриСозданииНаСервере(ЭтаФорма);
ВерсионированиеОбъектов.ВключитьВерсионированиеОбъекта("Документ|Справочник.Имя", Перечисления.ВариантыВерсионированияОбъектов.ВерсионироватьПриЗаписи);
В модуле формы, в процедуре «ПриЗаписиНаСервере», добавить:
ВерсионированиеОбъектовСобытия.ЗаписатьВерсиюДокумента(ТекущийОбъект, Отказ, РежимЗаписиДокумента, РежимПроведенияДокумента)
Добавить команду в ПанельНавигации.См также
	Если ПараметрКоманды = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(ПараметрКоманды) = Тип("Массив") Тогда
		Если ПараметрКоманды.Количество() = 0 Тогда
			Возврат;
		КонецЕсли;
		СсылкаНаОбъект = ПараметрКоманды[0];
	Иначе
		СсылкаНаОбъект = ПараметрКоманды;
	КонецЕсли;
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Ссылка", СсылкаНаОбъект);
	ПараметрыФормы.Вставить("ТолькоПросмотр", ПараметрыВыполненияКоманды.Источник.ТолькоПросмотр);
	
	ОткрытьФорму("РегистрСведений.ВерсииОбъектов.Форма.ВыборХранимыхВерсий",
								ПараметрыФормы,
								ПараметрыВыполненияКоманды.Источник,
							ПараметрыВыполненияКоманды.Уникальность,
							ПараметрыВыполненияКоманды.Окно);
	

Результат работы СКД в запросе

В модуле объекта Внешний отчет
 
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	
	КомпоновщикМакета 		= Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновкиДанных 	= КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, Настройки);
	
	Если МакетКомпоновкиДанных.НаборыДанных.Количество() > 0 Тогда
		Сообщить(МакетКомпоновкиДанных.НаборыДанных[0].Запрос);      // Итиоговый текст запроса
	КонецЕсли;
	
КонецПроцедуры // ПриКомпоновкеРезультата()

Блокировка повторного запуска процессов в 1С: Документооборот

Все что нужно, добавить подписку на событие ПередЗаписью для БизнесПроцессСсылка.

Процедура РУ_ПередЗаписьюБизнесПроцессаПередЗаписью(Источник, Отказ) Экспорт
	Если НЕ ЗначениеЗаполнено(Источник.Ссылка) И ЗначениеЗаполнено(Источник.Шаблон) И Источник.Предметы.Количество() > 0 Тогда 
		//Выполняем проверку только для процессов запущенных по шаблону и с указанным предметом
		
		Предмет = Источник.Предметы[0].Предмет;
		ВидПроцесса = Источник.Метаданные().Имя;
		
		Запрос = Новый Запрос;
		Запрос.Текст =  СтрЗаменить(
			"ВЫБРАТЬ
			|	БизнесПроцессыПоШаблону.Ссылка КАК СсылкаСсылка
			|ИЗ
			|	КритерийОтбора.БизнесПроцессыПоШаблону(&Шаблон) КАК БизнесПроцессыПоШаблону
			|		ЛЕВОЕ СОЕДИНЕНИЕ БизнесПроцесс.%ВИДПРОЦЕССА%.Предметы КАК КомплексныйПроцессПредметы
			|		ПО БизнесПроцессыПоШаблону.Ссылка = КомплексныйПроцессПредметы.Ссылка
			|		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ПроцессыДляЗапуска КАК ПроцессыДляЗапуска
			|		ПО БизнесПроцессыПоШаблону.Ссылка = ПроцессыДляЗапуска.БизнесПроцесс
			|ГДЕ
			|	НЕ БизнесПроцессыПоШаблону.Ссылка.Завершен
			|	И БизнесПроцессыПоШаблону.Ссылка.Состояние = ЗНАЧЕНИЕ(Перечисление.СостоянияБизнесПроцессов.Активен)
			|	И БизнесПроцессыПоШаблону.Ссылка <> &Ссылка
			|	И КомплексныйПроцессПредметы.Предмет = &Предмет
			|	И (ПроцессыДляЗапуска.Состояние ЕСТЬ NULL ИЛИ ПроцессыДляЗапуска.Состояние <> ЗНАЧЕНИЕ(Перечисление.СостоянияПроцессовДляЗапуска.СтартОтменен))", "%ВИДПРОЦЕССА%", ВидПроцесса);
		
		Запрос.УстановитьПараметр("Ссылка", Источник.Ссылка);
		Запрос.УстановитьПараметр("Предмет", Предмет);
		Запрос.УстановитьПараметр("Шаблон", Источник.Шаблон);
		
		РезультатЗапроса = Запрос.Выполнить();
		
		ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
		
		Если ВыборкаДетальныеЗаписи.Следующий() Тогда
			Сообщить("Процесс уже запущен");
			Отказ = Истина;
		КонецЕсли;
	
	КонецЕсли;	
КонецПроцедуры

APDEX: Замеры производительности

Встала задача замерить производительность открытия документов, отчетов и пр.

Стандартный ADPEX вполне походил для задачи, однако, серверный вариант замера производительности не удобен для управляемых форм. Пришлось немного допилить его.

Добавляем в серверный модуль

#Область ОценкаПроизводительности
Функция ОП_СодержитСвойство(Переменная, ИмяСвойства)
	// Инициализируем структуру для теста с ключом (значение переменной "ИмяСвойства") и значением NULL
	СтруктураПроверка = Новый Структура;
	СтруктураПроверка.Вставить(ИмяСвойства, NULL);
	// Заполняем созданную структуру из переданного значения переменной
	ЗаполнитьЗначенияСвойств(СтруктураПроверка, Переменная);
	// Если значение для свойства структуры осталось NULL, то искомое свойство не найдено, и наоборот.
	Если СтруктураПроверка[ИмяСвойства] = NULL Тогда
		Возврат Ложь;
	Иначе
		Возврат Истина;
	КонецЕсли;
КонецФункции
 
Процедура ОП_НачатьЗамерФорма(Форма) Экспорт
	Если НЕ ОП_СодержитСвойство(Форма, "ИМС_ЗамерПроизводительности") Тогда
		ОписаниеТипа = Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(14, 0, ДопустимыйЗнак.Неотрицательный));
		Реквизиты = Новый Массив;
		Реквизиты.Добавить(Новый РеквизитФормы("ИМС_ЗамерПроизводительности", ОписаниеТипа));
		Форма.ИзменитьРеквизиты(Реквизиты);
	КонецЕсли;
 
	Форма.ИМС_ЗамерПроизводительности = ОценкаПроизводительности.НачатьЗамерВремени();
КонецПроцедуры
 
Процедура ОП_ЗавершитьЗамерФорма(Форма, Операция = ".Открытие") Экспорт
	Объект = Форма.РеквизитФормыВЗначение("Объект");
 
	ИмяОбъекта = Объект.Метаданные().Имя;
	ОценкаПроизводительности.ЗакончитьЗамерВремени("Имс:"+ИмяОбъекта+Операция,Форма.ИМС_ЗамерПроизводительности);
КонецПроцедуры
 
#КонецОбласти

Дальше, добавляем новое расширение конфигурации. В расширение добавляем требуемые формы документов и на форме:

 
&НаСервере
Процедура ОП_ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	РУ.ОП_НачатьЗамерФорма(ЭтаФорма);
КонецПроцедуры
 
 
&НаКлиенте
Процедура ОП_ПриОткрытии(Отказ)
	ОП_ПриОткрытииНаСервере();
КонецПроцедуры
 
 
&НаСервере
Процедура ОП_ПриОткрытииНаСервере()
	РУ.ОП_ЗавершитьЗамерФорма(ЭтаФорма);
КонецПроцедуры
 
 
&НаСервере
Процедура ОП_ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
	Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
		РУ.ОП_НачатьЗамерФорма(ЭтаФорма);
	КонецЕсли;
КонецПроцедуры
 
 
&НаСервере
Процедура ОП_ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)
	Если ПараметрыЗаписи.РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
		РУ.ОП_ЗавершитьЗамерФорма(ЭтаФорма,".Проведение");
	КонецЕсли;
КонецПроцедуры

Главное, не забыть снять флаг «Безопасный режим» с расширения. Замеры производительности в безопасном режиме не работают.

Получить целые числа языком запросов 1С

Интересная задачка с собеседования — получить средствами языка запросов числа от -500 до 500. Само решение тривиально, но для него нужно получить перечень чисел от 0 до… ну хотя бы до 500. А это уже интереснее. Одно из возможных решений приведено ниже. Продолжая подставляя степени двойки можно получить очень длинную последовательность целых чисел.

ВЫБРАТЬ
0 КАК Числа
ПОМЕСТИТЬ Шаг0
 
ОБЪЕДИНИТЬ ВСЕ
 
ВЫБРАТЬ
1
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Лево.Числа * 2 + Право.Числа КАК Числа
ПОМЕСТИТЬ Шаг2
ИЗ
Шаг0 КАК Лево,
Шаг0 КАК Право
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Лево.Числа * 4 + Право.Числа КАК Числа
ПОМЕСТИТЬ Шаг4
ИЗ
Шаг2 КАК Лево,
Шаг2 КАК Право
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Лево.Числа * 8 + Право.Числа КАК Числа
ПОМЕСТИТЬ Шаг8
ИЗ
Шаг4 КАК Лево,
Шаг4 КАК Право
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Лево.Числа * 16 + Право.Числа КАК Числа
ПОМЕСТИТЬ Шаг16
ИЗ
Шаг8 КАК Лево,
Шаг8 КАК Право
;
 
////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
Лево.Числа * 32 + Право.Числа КАК Числа
ИЗ
Шаг16 КАК Лево,
Шаг16 КАК Право