[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ДоступРазрешен`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ДоступРазрешен(ОписаниеДанных, ПравоИзменение, ВызыватьИсключение = Ложь,
			ПроверитьТолькоСтаруюВерсию = Ложь, Знач Пользователь = Неопределено)
Экспорт

	УчитыватьПривилегированныйРежим = Истина;
	ПользовательИБ = Неопределено;

	Если Пользователь <> Неопределено
	   И Пользователь = Пользователи.АвторизованныйПользователь() Тогда

		Пользователь = Неопределено;
		УчитыватьПривилегированныйРежим = Ложь;
		ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
	КонецЕсли;

	Если Пользователь = Неопределено
	   И Пользователи.ЭтоПолноправныйПользователь(,, УчитыватьПривилегированныйРежим) Тогда
		Возврат Истина;
	КонецЕсли;

	ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(ОписаниеДанных));
	Если ОбъектМетаданных = Неопределено Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Недопустимое значение параметра %1 в %2.
			           |Ожидалась ссылка, объект, ключ записи или набор записей.
			           |Передано значение: %3 (тип %4).'"),
			"ОписаниеДанных",
			?(ВызыватьИсключение,
				?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
					"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
				?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
					"УправлениеДоступом.ЧтениеРазрешено")),
			Строка(ОписаниеДанных),
			Строка(ТипЗнч(ОписаниеДанных)));
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	ПроизводительныйВариант = УправлениеДоступом.ПроизводительныйВариант();

	Если Пользователь <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
			?(ВызыватьИсключение,
				?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
					"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
				?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
					"УправлениеДоступом.ЧтениеРазрешено")),
				"Пользователь",
				Пользователь,
				Новый ОписаниеТипов("СправочникСсылка.Пользователи, СправочникСсылка.ВнешниеПользователи"));

		Если Не ПроизводительныйВариант Тогда
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Недопустимое значение параметра %1 в %2.
				           |В стандартном варианте ограничения доступа поддерживается только %3.
				           |Передано значение: %4 (тип %5).'"),
				"Пользователь",
				?(ВызыватьИсключение,
					?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
						"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
					?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
						"УправлениеДоступом.ЧтениеРазрешено")),
				"Неопределено",
				Строка(Пользователь),
				Строка(ТипЗнч(Пользователь)));
			ВызватьИсключение ТекстОшибки;
		КонецЕсли;

		Если ВызыватьИсключение Тогда
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Вызов исключения поддерживается только для текущего пользователя.
				           |В %1
				           |- либо недопустимое значение параметра %2
				           |передано значение: %3 (тип %4),
				           |- либо недопустимое значение параметра %5
				           |передано значение: %6 (тип %7).'"),
				"УправлениеДоступом.ДоступРазрешен",
				"ВызыватьИсключение",
				Строка(ВызыватьИсключение),
				Строка(ТипЗнч(ВызыватьИсключение)),
				"Пользователь",
				Строка(Пользователь),
				Строка(ТипЗнч(Пользователь)));
			ВызватьИсключение ТекстОшибки;
		КонецЕсли;

		Если Пользователи.ЭтоПолноправныйПользователь(Пользователь,, УчитыватьПривилегированныйРежим) Тогда
			Возврат Истина;
		КонецЕсли;

		ИдентификаторПользователяИБ = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Пользователь,
			"ИдентификаторПользователяИБ");

		Если ТипЗнч(ИдентификаторПользователяИБ) <> Тип("УникальныйИдентификатор") Тогда
			Возврат Ложь;
		КонецЕсли;

		ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
			ИдентификаторПользователяИБ);

		Если ПользовательИБ = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;

	ЛюбойОбъект = ОписаниеДанных; // СправочникОбъект

	Если Не ПравоИзменение Тогда
		ИмяПраваДоступа = "Чтение";

	ИначеЕсли ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(ОбъектМетаданных)
	        И Не ОбщегоНазначения.ЭтоСсылка(ТипЗнч(ЛюбойОбъект))
	        И ЛюбойОбъект.ЭтоНовый() Тогда

		ИмяПраваДоступа = "Добавление";
	Иначе
		ИмяПраваДоступа = "Изменение";
	КонецЕсли;

	ЕстьПраво = Истина;
	Если ВызыватьИсключение Тогда
		ВыполнитьПроверкуПравДоступа(ИмяПраваДоступа, ОбъектМетаданных);

	ИначеЕсли ПользовательИБ = Неопределено Тогда
		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных);

	ИначеЕсли Пользователь = Неопределено Тогда
		УстановитьОтключениеБезопасногоРежима(Истина);
		УстановитьПривилегированныйРежим(Истина);

		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных, ПользовательИБ);

		УстановитьПривилегированныйРежим(Ложь);
		УстановитьОтключениеБезопасногоРежима(Ложь);
	Иначе
		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных, ПользовательИБ);
	КонецЕсли;
	Если Не ЕстьПраво Тогда
		Возврат Ложь;
	КонецЕсли;

	Если УправлениеДоступомСлужебныйПовтИсп.ЭтоПользовательБезОграниченияДоступа(Пользователь) Тогда
		Возврат Истина;
	КонецЕсли;

	ПолноеИмя = ОбъектМетаданных.ПолноеИмя();

	Если Не ПроизводительныйВариант Тогда
		Возврат ЧтениеДоступно(ПолноеИмя, ОбъектМетаданных, ОписаниеДанных, ВызыватьИсключение);
	КонецЕсли;

	Если ЗначениеЗаполнено(Пользователь) Тогда
		ДляВнешнихПользователей = ТипЗнч(Пользователь) = Тип("СправочникСсылка.ВнешниеПользователи");
	Иначе
		ДляВнешнихПользователей = Неопределено;
	КонецЕсли;
	ИдентификаторТранзакции = Новый УникальныйИдентификатор;
	ПараметрыОграничения = ПараметрыОграничения(ПолноеИмя, ИдентификаторТранзакции, ДляВнешнихПользователей);

	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);

	ОбновитьРазрешенныеНаборыВПараметрахСеанса();

	Если ПараметрыОграничения.ОграничениеОтключено
	 Или Не ПравоИзменение
	   И ПараметрыОграничения.ОграничениеЧтенияОтключено Тогда

		Возврат Истина;
	КонецЕсли;

	СтараяВерсия = Истина;
	ПравоИзменения = Ложь;
	ЭтоНовый = Ложь;

	Если ПараметрыОграничения.ДоступЗапрещен Тогда
		ДоступРазрешен = Ложь;
	Иначе
		Запрос = Новый Запрос;
		УстановитьРазрешенныеНаборыВПараметрыЗапроса(Запрос, Пользователь);

		Запрос.Текст = ?(ПравоИзменение, ПараметрыОграничения.ТекстЗапросаПроверкиПравЧтениеИзменение,
			ПараметрыОграничения.ТекстЗапросаПроверкиПраваЧтение);

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

[Assistant]
Функция ДоступРазрешен(ОписаниеДанных, ПравоИзменение, ВызыватьИсключение = Ложь,
			ПроверитьТолькоСтаруюВерсию = Ложь, Знач Пользователь = Неопределено) Экспорт

	УчитыватьПривилегированныйРежим = Истина;
	ПользовательИБ = Неопределено;

	Если Пользователь <> Неопределено
	   И Пользователь = Пользователи.АвторизованныйПользователь() Тогда

		Пользователь = Неопределено;
		УчитыватьПривилегированныйРежим = Ложь;
		ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();
	КонецЕсли;

	Если Пользователь = Неопределено
	   И Пользователи.ЭтоПолноправныйПользователь(,, УчитыватьПривилегированныйРежим) Тогда
		Возврат Истина;
	КонецЕсли;

	ОбъектМетаданных = Метаданные.НайтиПоТипу(ТипЗнч(ОписаниеДанных));
	Если ОбъектМетаданных = Неопределено Тогда
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Недопустимое значение параметра %1 в %2.
			           |Ожидалась ссылка, объект, ключ записи или набор записей.
			           |Передано значение: %3 (тип %4).'"),
			"ОписаниеДанных",
			?(ВызыватьИсключение,
				?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
					"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
				?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
					"УправлениеДоступом.ЧтениеРазрешено")),
			Строка(ОписаниеДанных),
			Строка(ТипЗнч(ОписаниеДанных)));
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

	ПроизводительныйВариант = УправлениеДоступом.ПроизводительныйВариант();

	Если Пользователь <> Неопределено Тогда
		ОбщегоНазначенияКлиентСервер.ПроверитьПараметр(
			?(ВызыватьИсключение,
				?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
					"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
				?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
					"УправлениеДоступом.ЧтениеРазрешено")),
				"Пользователь",
				Пользователь,
				Новый ОписаниеТипов("СправочникСсылка.Пользователи, СправочникСсылка.ВнешниеПользователи"));

		Если Не ПроизводительныйВариант Тогда
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Недопустимое значение параметра %1 в %2.
				           |В стандартном варианте ограничения доступа поддерживается только %3.
				           |Передано значение: %4 (тип %5).'"),
				"Пользователь",
				?(ВызыватьИсключение,
					?(ПравоИзменение, "УправлениеДоступом.ПроверитьИзменениеРазрешено",
						"УправлениеДоступом.ПроверитьЧтениеРазрешено"),
					?(ПравоИзменение, "УправлениеДоступом.ИзменениеРазрешено",
						"УправлениеДоступом.ЧтениеРазрешено")),
				"Неопределено",
				Строка(Пользователь),
				Строка(ТипЗнч(Пользователь)));
			ВызватьИсключение ТекстОшибки;
		КонецЕсли;

		Если ВызыватьИсключение Тогда
			ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Вызов исключения поддерживается только для текущего пользователя.
				           |В %1
				           |- либо недопустимое значение параметра %2
				           |передано значение: %3 (тип %4),
				           |- либо недопустимое значение параметра %5
				           |передано значение: %6 (тип %7).'"),
				"УправлениеДоступом.ДоступРазрешен",
				"ВызыватьИсключение",
				Строка(ВызыватьИсключение),
				Строка(ТипЗнч(ВызыватьИсключение)),
				"Пользователь",
				Строка(Пользователь),
				Строка(ТипЗнч(Пользователь)));
			ВызватьИсключение ТекстОшибки;
		КонецЕсли;

		Если Пользователи.ЭтоПолноправныйПользователь(Пользователь,, УчитыватьПривилегированныйРежим) Тогда
			Возврат Истина;
		КонецЕсли;

		ИдентификаторПользователяИБ = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Пользователь,
			"ИдентификаторПользователяИБ");

		Если ТипЗнч(ИдентификаторПользователяИБ) <> Тип("УникальныйИдентификатор") Тогда
			Возврат Ложь;
		КонецЕсли;

		ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
			ИдентификаторПользователяИБ);

		Если ПользовательИБ = Неопределено Тогда
			Возврат Ложь;
		КонецЕсли;
	КонецЕсли;

	ЛюбойОбъект = ОписаниеДанных; // СправочникОбъект

	Если Не ПравоИзменение Тогда
		ИмяПраваДоступа = "Чтение";

	ИначеЕсли ОбщегоНазначения.ЭтоОбъектСсылочногоТипа(ОбъектМетаданных)
	        И Не ОбщегоНазначения.ЭтоСсылка(ТипЗнч(ЛюбойОбъект))
	        И ЛюбойОбъект.ЭтоНовый() Тогда

		ИмяПраваДоступа = "Добавление";
	Иначе
		ИмяПраваДоступа = "Изменение";
	КонецЕсли;

	ЕстьПраво = Истина;
	Если ВызыватьИсключение Тогда
		ВыполнитьПроверкуПравДоступа(ИмяПраваДоступа, ОбъектМетаданных);

	ИначеЕсли ПользовательИБ = Неопределено Тогда
		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных);

	ИначеЕсли Пользователь = Неопределено Тогда
		УстановитьОтключениеБезопасногоРежима(Истина);
		УстановитьПривилегированныйРежим(Истина);

		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных, ПользовательИБ);

		УстановитьПривилегированныйРежим(Ложь);
		УстановитьОтключениеБезопасногоРежима(Ложь);
	Иначе
		ЕстьПраво = ПравоДоступа(ИмяПраваДоступа, ОбъектМетаданных, ПользовательИБ);
	КонецЕсли;
	Если Не ЕстьПраво Тогда
		Возврат Ложь;
	КонецЕсли;

	Если УправлениеДоступомСлужебныйПовтИсп.ЭтоПользовательБезОграниченияДоступа(Пользователь) Тогда
		Возврат Истина;
	КонецЕсли;

	ПолноеИмя = ОбъектМетаданных.ПолноеИмя();

	Если Не ПроизводительныйВариант Тогда
		Возврат ЧтениеДоступно(ПолноеИмя, ОбъектМетаданных, ОписаниеДанных, ВызыватьИсключение);
	КонецЕсли;

	Если ЗначениеЗаполнено(Пользователь) Тогда
		ДляВнешнихПользователей = ТипЗнч(Пользователь) = Тип("СправочникСсылка.ВнешниеПользователи");
	Иначе
		ДляВнешнихПользователей = Неопределено;
	КонецЕсли;
	ИдентификаторТранзакции = Новый УникальныйИдентификатор;
	ПараметрыОграничения = ПараметрыОграничения(ПолноеИмя, ИдентификаторТранзакции, ДляВнешнихПользователей);

	УстановитьОтключениеБезопасногоРежима(Истина);
	УстановитьПривилегированныйРежим(Истина);

	ОбновитьРазрешенныеНаборыВПараметрахСеанса();

	Если ПараметрыОграничения.ОграничениеОтключено
	 Или Не ПравоИзменение
	   И ПараметрыОграничения.ОграничениеЧтенияОтключено Тогда

		Возврат Истина;
	КонецЕсли;

	СтараяВерсия = Истина;
	ПравоИзменения = Ложь;
	ЭтоНовый = Ложь;

	Если ПараметрыОграничения.ДоступЗапрещен Тогда
		ДоступРазрешен = Ложь;
	Иначе
		Запрос = Новый Запрос;
		УстановитьРазрешенныеНаборыВПараметрыЗапроса(Запрос, Пользователь);

		Запрос.Текст = ?(ПравоИзменение, ПараметрыОграничения.ТекстЗапросаПроверкиПравЧтениеИзменение,
			ПараметрыОграничения.ТекстЗапросаПроверкиПраваЧтение);

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

			Если Не ДоступРазрешен Тогда
				ДанныеДляПредставления = СсылкаНаОбъект;

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

			Если ТипЗнч(ОписаниеДанных) = ТипЗнч(НаборЗаписей) Тогда
				НаборЗаписей = ОписаниеДанных;
			Иначе // КлючЗаписи.
				Для Каждого ЭлементОтбора Из НаборЗаписей.Отбор Цикл
					ЭлементОтбора.Значение = ОписаниеДанных[ЭлементОтбора.Имя];
					ЭлементОтбора.Использование = Истина;
				КонецЦикла;
			КонецЕсли;

			ОтборПоИзмерениям = ОтборПоИзмерениямНабораЗаписей(НаборЗаписей, Запрос);
			ТекстЗапроса = Запрос.Текст;
			Запрос.Текст = СтрЗаменить(Запрос.Текст, "&ОтборПоИзмерениям", ОтборПоИзмерениям);
			ДоступРазрешен = Запрос.Выполнить().Пустой();

			Если ДоступРазрешен
			   И ТипЗнч(ОписаниеДанных) = ТипЗнч(НаборЗаписей)
			   И Не ПроверитьТолькоСтаруюВерсию Тогда

				СтараяВерсия = Ложь;
				Если ПараметрыОграничения.ИспользуетсяОграничениеПоВладельцу Тогда
					ПолеВладельца = ПараметрыОграничения.ПолеВладельца.Имя;
					Комбинации = ОписаниеДанных.Выгрузить(, ПолеВладельца); // ТаблицаЗначений
					Комбинации.Свернуть(ПолеВладельца);
					Запрос.УстановитьПараметр("КомбинацииЗначенийОпорныхПолей", Комбинации);
					ТекстЗапросаПодготовкиКомбинаций = // @query-part-1
					"ВЫБРАТЬ ТекущаяТаблица." + ПолеВладельца + "
					|ПОМЕСТИТЬ КомбинацииЗначенийОпорныхПолей
					|ИЗ &КомбинацииЗначенийОпорныхПолей КАК ТекущаяТаблица"; // @query-part-1
				Иначе
					ТекстЗапросаПодготовкиКомбинаций = // @query-part-1
					"ВЫБРАТЬ ТекущаяТаблица." + СтрСоединить(ПараметрыОграничения.ОпорныеПоля.Используемые, ",
					|	ТекущаяТаблица.") + "
					|ПОМЕСТИТЬ КомбинацииЗначенийОпорныхПолей
					|ИЗ &КомбинацииЗначенийОпорныхПолей КАК ТекущаяТаблица"; // @query-part-1
					ОписаниеДанных.ДополнительныеСвойства.Вставить("УправлениеДоступомИдентификаторТранзакции",
						ИдентификаторТранзакции);
					ОбновитьКлючиДоступаКНаборуЗаписей(ОписаниеДанных, Ложь, Ложь,
						ИдентификаторТранзакции, ПараметрыОграничения, "", Запрос);
					ОписаниеДанных.ДополнительныеСвойства.Удалить("УправлениеДоступомИдентификаторТранзакции");
				КонецЕсли;
				Запрос.Текст = СтрЗаменить(ТекстЗапроса, "&ОтборПоИзмерениям", "ИСТИНА");
				ПолноеИмяРегистра = Метаданные.НайтиПоТипу(ТипЗнч(ОписаниеДанных)).ПолноеИмя();
				Запрос.Текст = ТекстЗапросаПодготовкиКомбинаций + ОбщегоНазначения.РазделительПакетаЗапросов()
					+ СтрЗаменить(Запрос.Текст, ПолноеИмяРегистра + " КАК ТекущаяТаблица", // @query-part-1 @query-part-2
						"КомбинацииЗначенийОпорныхПолей КАК ТекущаяТаблица");

				ДоступРазрешен = Запрос.Выполнить().Пустой();
			КонецЕсли;
			ДанныеДляПредставления = НаборЗаписей;
		КонецЕсли;
	КонецЕсли;

	УстановитьПривилегированныйРежим(Ложь);
	УстановитьОтключениеБезопасногоРежима(Ложь);

	Если ДоступРазрешен Или Не ВызыватьИсключение Тогда
		Возврат ДоступРазрешен;
	КонецЕсли;

	Если ПравоИзменение Тогда
		ПравоЧтения = ДоступРазрешен(ОписаниеДанных, Ложь);
	Иначе
		ПравоЧтения = Ложь;
	КонецЕсли;

	СообщитьОбОшибкеДоступа(ДанныеДляПредставления, СтараяВерсия, ПравоЧтения, ПравоИзменения, ЭтоНовый);

	Возврат Ложь;

КонецФункции

// Для функции ДоступРазрешен.


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ЗаполнитьОбщиеПараметрыОбновления`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ЗаполнитьОбщиеПараметрыОбновления(Контекст)
Задания = Контекст.Задания;
	Задания.Сортировать(
		"ЕстьТочечноеЗадание Убыв,
		|ЕстьНачальноеОбновлениеТочечногоЗадания Убыв,
		|ДатаПоследнегоЗапускаТочечногоЗадания Возр,
		|ДатаДобавленияТочечногоЗадания Убыв,
		|ЕстьНачальноеОбновление Убыв,
		|ДатаПоследнегоЗапускаОбщегоЗадания Возр,
		|ЕстьДатаПоследнегоОбновленногоЭлемента Возр,
		|ДатаПоследнегоОбновленногоЭлемента Убыв,
		|ДатаДобавленияОбщегоЗадания Убыв");

	ЗаданияДляУдаления = Задания.НайтиСтроки(Новый Структура("Удалить", Истина));
	Для Каждого Задание Из ЗаданияДляУдаления Цикл
		Если Не Задание.Удалить Или Задание.ЗанятыеПотоки.Количество() > 0 Тогда
			Продолжить;
		КонецЕсли;
		СвойстваЗадания = Новый Структура("ИдентификаторСписка,
		|ДляВнешнихПользователей, ЭтоОбновлениеПрав, ЗависимыеСписки");
		ЗаполнитьЗначенияСвойств(СвойстваЗадания, Задание);
		Задания.Удалить(Задание);
		ОбновитьУровеньЗависимости(СвойстваЗадания, Задания, Контекст.ВедущиеСпискиПоЗависимым);
	КонецЦикла;
	ЗаданияДляОбновленияУровня = Задания.НайтиСтроки(Новый Структура("ОбновитьУровеньЗависимости", Истина));
	Для Каждого Задание Из ЗаданияДляОбновленияУровня Цикл
		УстановитьУровеньЗависимостиПоВедущим(Задание, Задания, Контекст.ВедущиеСпискиПоЗависимым);
		ОбновитьУровеньЗависимости(Задание, Задания, Контекст.ВедущиеСпискиПоЗависимым);
		Задание.ОбновитьУровеньЗависимости = Ложь;
	КонецЦикла;

	ОтборУровней = Новый Структура("Удалить, ЭтоОбработкаУстаревшихЭлементов", Ложь, Ложь);
	Уровни = Задания.Скопировать(ОтборУровней, "УровеньЗависимости");
	Уровни.Свернуть("УровеньЗависимости");
	Уровни.Сортировать("УровеньЗависимости");
	НаименьшийУровеньЗависимости = ?(Уровни.Количество() > 0, Уровни[0].УровеньЗависимости, 0);
	ЭтоОбработкаУстаревшихЭлементов = Уровни.Количество() = 0;
	ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания = '00010101';
	Если Уровни.Количество() > 1 Или Не ЭтоОбработкаУстаревшихЭлементов Тогда
		Для Каждого Задание Из Задания Цикл
			Если Задание.Удалить
			 Или Задание.ЕстьТочечноеЗадание Тогда
				Продолжить;
			КонецЕсли;
			Если Задание.УровеньЗависимости > НаименьшийУровеньЗависимости
			   И ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания < Задание.ДатаПоследнегоЗапускаОбщегоЗадания Тогда
				ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания = Задание.ДатаПоследнегоЗапускаОбщегоЗадания;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	ЗапускаемоеЗависимоеОбщееЗадание =
		?(ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания > ТекущаяДатаСеанса() - 10, Null, Неопределено);

	ОбщиеПараметрыОбновления = Контекст.ОбщиеПараметрыОбновления;
	ОбщиеПараметрыОбновления.ЭтоОбработкаУстаревшихЭлементов = ЭтоОбработкаУстаревшихЭлементов;
	ОбщиеПараметрыОбновления.НачальноеОбновление = Ложь;
	ПоследняяДата = '00010101';
	ЗаданиеСправочникаНаборыГруппДоступа = Неопределено;
	ГраницаОжиданияДляЗависимыхЗаданий = ТекущаяДатаСеанса() - 3;

	Для Каждого Задание Из Задания Цикл
		Если Задание.Удалить Тогда
			Продолжить;
		КонецЕсли;
		Если ЭтоОбновлениеСоставаНаборовГруппДоступа(Задание, Контекст) Тогда
			ЗаданиеСправочникаНаборыГруппДоступа = Задание;
		КонецЕсли;
		Задание.Пропустить = Ложь;
		Если Задание.ЕстьНачальноеОбновление Тогда
			ОбщиеПараметрыОбновления.НачальноеОбновление = Истина;
		Иначе
			Если Задание.УровеньЗависимости > НаименьшийУровеньЗависимости Тогда
				Если Задание.ЕстьТочечноеЗадание Тогда
					Если Задание.ДатаПоследнегоЗапускаТочечногоЗадания > ГраницаОжиданияДляЗависимыхЗаданий Тогда
						Задание.Пропустить = Истина;
						Продолжить;
					КонецЕсли;
				ИначеЕсли ЗапускаемоеЗависимоеОбщееЗадание <> Неопределено Тогда
					Задание.Пропустить = Истина;
					Продолжить;
				Иначе
					ЗапускаемоеЗависимоеОбщееЗадание = Задание;
				КонецЕсли;
			КонецЕсли;
			Если Не ЭтоОбработкаУстаревшихЭлементов И Задание.ЭтоОбработкаУстаревшихЭлементов Тогда
				Задание.Пропустить = Истина;
				Продолжить;
			КонецЕсли;
		КонецЕсли;
		Если Задание.ЕстьПерезапуск Тогда
			ОбщиеПараметрыОбновления.НачальноеОбновление = Истина;
		КонецЕсли;
		Если Задание.ДатаПоследнегоОбновленногоЭлемента > ПоследняяДата Тогда
			ПоследняяДата = Задание.ДатаПоследнегоОбновленногоЭлемента;
		КонецЕсли;
	КонецЦикла;

	Если ОбщиеПараметрыОбновления.НачальноеОбновление Тогда
		// Начало обновления.
		ОбщиеПараметрыОбновления.ДатаНачала = НачалоДня(ТекущаяДатаСеанса()) - 7 * (60 * 60 * 24); // 7 Дней.
	Иначе
		// Продолжение обновления.
		МаксимальныйПериод = МаксимальныйПериодПолученияПорцийЗапросом();

		Если МаксимальныйПериод = "Неделя" Тогда
			ДатаНачала = НачалоНедели(ПоследняяДата);

		ИначеЕсли МаксимальныйПериод = "Месяц" Тогда
			ДатаНачала = НачалоМесяца(ПоследняяДата);
		Иначе
			ЭтотГод = Год(ТекущаяДатаСеанса()) - Год(ПоследняяДата) = 0;
			СмещениеМесяца = Месяц(ТекущаяДатаСеанса()) - Месяц(ПоследняяДата);

			Если ЭтотГод И СмещениеМесяца = 0 Тогда
				ДатаНачала = НачалоМесяца(ПоследняяДата);

			ИначеЕсли ЭтотГод И СмещениеМесяца < 3 Или МаксимальныйПериод = "Квартал" Тогда
				ДатаНачала = НачалоКвартала(ПоследняяДата);
			Иначе
				ДатаНачала = НачалоГода(ПоследняяДата);
			КонецЕсли;
		КонецЕсли;

		ОбщиеПараметрыОбновления.ДатаНачала = ДатаНачала;
	КонецЕсли;
	ОбщиеПараметрыОбновления.ДатаОкончания = ПоследняяДата;

	ЗаданияДляЗапуска = Новый Массив;
	Контекст.ЗаданияДляЗапуска = ЗаданияДляЗапуска;
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ЗаполнитьОбщиеПараметрыОбновления(Контекст)

	Задания = Контекст.Задания;
	Задания.Сортировать(
		"ЕстьТочечноеЗадание Убыв,
		|ЕстьНачальноеОбновлениеТочечногоЗадания Убыв,
		|ДатаПоследнегоЗапускаТочечногоЗадания Возр,
		|ДатаДобавленияТочечногоЗадания Убыв,
		|ЕстьНачальноеОбновление Убыв,
		|ДатаПоследнегоЗапускаОбщегоЗадания Возр,
		|ЕстьДатаПоследнегоОбновленногоЭлемента Возр,
		|ДатаПоследнегоОбновленногоЭлемента Убыв,
		|ДатаДобавленияОбщегоЗадания Убыв");

	ЗаданияДляУдаления = Задания.НайтиСтроки(Новый Структура("Удалить", Истина));
	Для Каждого Задание Из ЗаданияДляУдаления Цикл
		Если Не Задание.Удалить Или Задание.ЗанятыеПотоки.Количество() > 0 Тогда
			Продолжить;
		КонецЕсли;
		СвойстваЗадания = Новый Структура("ИдентификаторСписка,
		|ДляВнешнихПользователей, ЭтоОбновлениеПрав, ЗависимыеСписки");
		ЗаполнитьЗначенияСвойств(СвойстваЗадания, Задание);
		Задания.Удалить(Задание);
		ОбновитьУровеньЗависимости(СвойстваЗадания, Задания, Контекст.ВедущиеСпискиПоЗависимым);
	КонецЦикла;
	ЗаданияДляОбновленияУровня = Задания.НайтиСтроки(Новый Структура("ОбновитьУровеньЗависимости", Истина));
	Для Каждого Задание Из ЗаданияДляОбновленияУровня Цикл
		УстановитьУровеньЗависимостиПоВедущим(Задание, Задания, Контекст.ВедущиеСпискиПоЗависимым);
		ОбновитьУровеньЗависимости(Задание, Задания, Контекст.ВедущиеСпискиПоЗависимым);
		Задание.ОбновитьУровеньЗависимости = Ложь;
	КонецЦикла;

	ОтборУровней = Новый Структура("Удалить, ЭтоОбработкаУстаревшихЭлементов", Ложь, Ложь);
	Уровни = Задания.Скопировать(ОтборУровней, "УровеньЗависимости");
	Уровни.Свернуть("УровеньЗависимости");
	Уровни.Сортировать("УровеньЗависимости");
	НаименьшийУровеньЗависимости = ?(Уровни.Количество() > 0, Уровни[0].УровеньЗависимости, 0);
	ЭтоОбработкаУстаревшихЭлементов = Уровни.Количество() = 0;
	ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания = '00010101';
	Если Уровни.Количество() > 1 Или Не ЭтоОбработкаУстаревшихЭлементов Тогда
		Для Каждого Задание Из Задания Цикл
			Если Задание.Удалить
			 Или Задание.ЕстьТочечноеЗадание Тогда
				Продолжить;
			КонецЕсли;
			Если Задание.УровеньЗависимости > НаименьшийУровеньЗависимости
			   И ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания < Задание.ДатаПоследнегоЗапускаОбщегоЗадания Тогда
				ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания = Задание.ДатаПоследнегоЗапускаОбщегоЗадания;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	ЗапускаемоеЗависимоеОбщееЗадание =
		?(ДатаПоследнегоЗапускаЗависимогоОбщегоЗадания > ТекущаяДатаСеанса() - 10, Null, Неопределено);

	ОбщиеПараметрыОбновления = Контекст.ОбщиеПараметрыОбновления;
	ОбщиеПараметрыОбновления.ЭтоОбработкаУстаревшихЭлементов = ЭтоОбработкаУстаревшихЭлементов;
	ОбщиеПараметрыОбновления.НачальноеОбновление = Ложь;
	ПоследняяДата = '00010101';
	ЗаданиеСправочникаНаборыГруппДоступа = Неопределено;
	ГраницаОжиданияДляЗависимыхЗаданий = ТекущаяДатаСеанса() - 3;

	Для Каждого Задание Из Задания Цикл
		Если Задание.Удалить Тогда
			Продолжить;
		КонецЕсли;
		Если ЭтоОбновлениеСоставаНаборовГруппДоступа(Задание, Контекст) Тогда
			ЗаданиеСправочникаНаборыГруппДоступа = Задание;
		КонецЕсли;
		Задание.Пропустить = Ложь;
		Если Задание.ЕстьНачальноеОбновление Тогда
			ОбщиеПараметрыОбновления.НачальноеОбновление = Истина;
		Иначе
			Если Задание.УровеньЗависимости > НаименьшийУровеньЗависимости Тогда
				Если Задание.ЕстьТочечноеЗадание Тогда
					Если Задание.ДатаПоследнегоЗапускаТочечногоЗадания > ГраницаОжиданияДляЗависимыхЗаданий Тогда
						Задание.Пропустить = Истина;
						Продолжить;
					КонецЕсли;
				ИначеЕсли ЗапускаемоеЗависимоеОбщееЗадание <> Неопределено Тогда
					Задание.Пропустить = Истина;
					Продолжить;
				Иначе
					ЗапускаемоеЗависимоеОбщееЗадание = Задание;
				КонецЕсли;
			КонецЕсли;
			Если Не ЭтоОбработкаУстаревшихЭлементов И Задание.ЭтоОбработкаУстаревшихЭлементов Тогда
				Задание.Пропустить = Истина;
				Продолжить;
			КонецЕсли;
		КонецЕсли;
		Если Задание.ЕстьПерезапуск Тогда
			ОбщиеПараметрыОбновления.НачальноеОбновление = Истина;
		КонецЕсли;
		Если Задание.ДатаПоследнегоОбновленногоЭлемента > ПоследняяДата Тогда
			ПоследняяДата = Задание.ДатаПоследнегоОбновленногоЭлемента;
		КонецЕсли;
	КонецЦикла;

	Если ОбщиеПараметрыОбновления.НачальноеОбновление Тогда
		// Начало обновления.
		ОбщиеПараметрыОбновления.ДатаНачала = НачалоДня(ТекущаяДатаСеанса()) - 7 * (60 * 60 * 24); // 7 Дней.
	Иначе
		// Продолжение обновления.
		МаксимальныйПериод = МаксимальныйПериодПолученияПорцийЗапросом();

		Если МаксимальныйПериод = "Неделя" Тогда
			ДатаНачала = НачалоНедели(ПоследняяДата);

		ИначеЕсли МаксимальныйПериод = "Месяц" Тогда
			ДатаНачала = НачалоМесяца(ПоследняяДата);
		Иначе
			ЭтотГод = Год(ТекущаяДатаСеанса()) - Год(ПоследняяДата) = 0;
			СмещениеМесяца = Месяц(ТекущаяДатаСеанса()) - Месяц(ПоследняяДата);

			Если ЭтотГод И СмещениеМесяца = 0 Тогда
				ДатаНачала = НачалоМесяца(ПоследняяДата);

			ИначеЕсли ЭтотГод И СмещениеМесяца < 3 Или МаксимальныйПериод = "Квартал" Тогда
				ДатаНачала = НачалоКвартала(ПоследняяДата);
			Иначе
				ДатаНачала = НачалоГода(ПоследняяДата);
			КонецЕсли;
		КонецЕсли;

		ОбщиеПараметрыОбновления.ДатаНачала = ДатаНачала;
	КонецЕсли;
	ОбщиеПараметрыОбновления.ДатаОкончания = ПоследняяДата;

	ЗаданияДляЗапуска = Новый Массив;
	Контекст.ЗаданияДляЗапуска = ЗаданияДляЗапуска;
	Контекст.ЕстьОтложенныеЗадания = Ложь;

	Для Каждого Задание Из Задания Цикл
		Если Задание.Удалить Или Задание.Пропустить Тогда
			Задание.Запускать = Ложь;
			Если Задание.Пропустить Тогда
				Контекст.ЕстьОтложенныеЗадания = Истина;
			КонецЕсли;
			Продолжить;
		КонецЕсли;

		Если ЗаданиеСправочникаНаборыГруппДоступа <> Неопределено Тогда
			Если Задание.ЕстьТочечноеЗадание Или Задание = ЗаданиеСправочникаНаборыГруппДоступа Тогда
				Задание.Запускать = Истина;
			ИначеЕсли ОбщиеПараметрыОбновления.НачальноеОбновление Тогда
				Задание.Запускать = Задание.ЕстьНачальноеОбновление Или Задание.ЕстьПерезапуск;
			КонецЕсли;

		ИначеЕсли Задание.ЕстьТочечноеЗадание Или Задание.ЭтоОбновлениеПрав Тогда
			Задание.Запускать = Истина;

		ИначеЕсли ОбщиеПараметрыОбновления.НачальноеОбновление Тогда
			Задание.Запускать = Задание.ЕстьНачальноеОбновление Или Задание.ЕстьПерезапуск;
		Иначе
			Задание.Запускать = Не ПериодОбновленияДоПериодаДанных(ОбщиеПараметрыОбновления.ДатаНачала,
				Задание.ДатаПоследнегоОбновленногоЭлемента);
		КонецЕсли;

		Если Задание.Запускать Тогда
			ЗаданияДляЗапуска.Добавить(Задание);
		Иначе
			Контекст.ЕстьОтложенныеЗадания = Истина;
		КонецЕсли;
	КонецЦикла;

	Если Не ЗагружатьСвободныеПотокиСледующимиЗаданиямиПриДлительныхЗапросах() Тогда
		Контекст.ЕстьОтложенныеЗадания = Ложь;
	КонецЕсли;

	Если Не Контекст.ЕстьЗапущенноеЗадание
	   И Контекст.ЕстьОтложенныеЗадания
	   И Контекст.ЗанятыеПотоки.Количество() < Контекст.КоличествоПотоков Тогда

		Контекст.ЕстьОтложенныеЗадания = Ложь;
		КоличествоСвободныхПотоков = Контекст.КоличествоПотоков - Контекст.ЗанятыеПотоки.Количество();
		КоличествоДополнительныхЗаданий = 0;

		Для Каждого Задание Из Задания Цикл
			Если Задание.Удалить
			 Или Задание.Запускать
			 Или Не ЭтоОбработкаУстаревшихЭлементов
			   И Задание.ЭтоОбработкаУстаревшихЭлементов Тогда
				Продолжить;
			КонецЕсли;
			Если КоличествоДополнительныхЗаданий >= КоличествоСвободныхПотоков Тогда
				Контекст.ЕстьОтложенныеЗадания = Истина;
				Прервать;
			КонецЕсли;
			Задание.Запускать = Истина;
			ЗаданияДляЗапуска.Добавить(Задание);
			КоличествоДополнительныхЗаданий = КоличествоДополнительныхЗаданий + 1;
		КонецЦикла;
	КонецЕсли;

	КоличествоОсновныхЗаданий = ЗаданияДляЗапуска.Количество();
	Если КоличествоОсновныхЗаданий > 0 Тогда
		Контекст.КоличествоДополнительныхПорций = Цел(Контекст.КоличествоПотоков / КоличествоОсновныхЗаданий);
	Иначе
		Контекст.КоличествоДополнительныхПорций = 0;
	КонецЕсли;

	КоличествоЗаданий = Задания.Количество();
	Если КоличествоЗаданий = 0 Тогда
		ДостаточностьПотоков = 0;
	ИначеЕсли Контекст.КоличествоПотоков > КоличествоЗаданий Тогда
		ДостаточностьПотоков = 1;
	Иначе
		ДостаточностьПотоков = Контекст.КоличествоПотоков / КоличествоЗаданий;
	КонецЕсли;
	НагруженностьОтПотоков = Контекст.КоличествоПотоков * 0.025;
	Если НагруженностьОтПотоков > 1 Тогда
		НагруженностьОтПотоков = 1;
	КонецЕсли;
	ОбщиеПараметрыОбновления.МаксимумМиллисекундОбработки =
		Цел(МинимальноеКоличествоСекундОбработкиПорцииВОтдельномПотоке() * 1000
		* (1 + НагруженностьОтПотоков) * (1 + ДостаточностьПотоков));

КонецПроцедуры

// Для процедур ДобавитьЗаданияОбновленияДоступа, ЗапуститьОбновлениеДоступаСписка,
// ВыполнитьОбновлениеДоступаСписка.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ПроверитьОграничениеДляВидаПользователей`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ПроверитьОграничениеДляВидаПользователей(Контекст, Результат, ДляВнешнихПользователей, ДополнительныйКонтекст)
ТекстОграничения = ?(ДляВнешнихПользователей, Контекст.ОбщийРезультат.ДляВнешнихПользователей,
		Контекст.ОбщийРезультат.ДляПользователей).ПроверяемоеОграничение;

	СтруктураОграничения = РассчитаннаяСтруктураОграничения(Контекст.ПолноеИмя,
		ТекстОграничения, Контекст.ОбщийРезультат.ТекстВМодулеМенеджера, ДляВнешнихПользователей, Истина);

	Если СтруктураОграничения <> Неопределено
	   И СтруктураОграничения.ОписаниеОшибок.ЕстьОшибки Тогда

		Результат.ОписаниеОшибок = СтруктураОграничения.ОписаниеОшибок;
		Контекст.УчетЗависимостейДоступен = Ложь;
		Возврат;
	КонецЕсли;

	ДополнительныйКонтекст = НовыйДополнительныйКонтекст();
	ДобавитьДополнительныйКонтекст(Контекст.ПолноеИмя,
		ДополнительныйКонтекст, Контекст.ОписаниеОграничения, ДляВнешнихПользователей);

	ОшибкаПриВызовеИсключения = Новый Структура("Текст", Неопределено);
	ДополнительныйКонтекст.Вставить("ОшибкаПриВызовеИсключения", ОшибкаПриВызовеИсключения);

	Попытка
		ПараметрыОграничения = ПараметрыОграниченияПоСтруктуреОграничения(Контекст.ПолноеИмя,
			СтруктураОграничения, ДляВнешнихПользователей, Контекст.ОбщийКонтекст, ДополнительныйКонтекст);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ПараметрыОграничения = Неопределено;
		Если ЗначениеЗаполнено(ОшибкаПриВызовеИсключения.Текст) Тогда
			Результат.ОшибкаФормированияПараметровОграничения = ОшибкаПриВызовеИсключения.Текст;
		Иначе
			Результат.ОшибкаФормированияПараметровОграничения =
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Не удалось сформировать параметры ограничения доступа по причине:
					           |%1'"), ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
		КонецЕсли;
		Контекст.УчетЗависимостейДоступен = Ложь;
	КонецПопытки;

	Если ПараметрыОграничения <> Неопределено Тогда
		Результат.ОграничениеПоВладельцуВозможно = ПараметрыОграничения.ПолеВладельца <> Неопределено;
		ПараметрыОграничения.Контекст.СпискиСЗаписьюКлючейДляЗависимыхСписковБезКлючей = Новый Соответствие;
		УстановитьСвойстваЗаписиКлючейДоступа(ПараметрыОграничения);
		ПараметрыОграничения.Вставить("БезЗаписиКлючейДоступаДляПользователейИВнешнихПользователей", Ложь);
		Для Каждого КлючИЗначение Из ПараметрыОграничения.ВедущиеСписки.ПоЗначениямПолей Цикл
			Контекст.ВедущиеСписки.Вставить(КлючИЗначение.Ключ, Неопределено);
		КонецЦикла;
		Для Каждого КлючИЗначение Из ПараметрыОграничения.ВедущиеСписки.ПоКлючамДоступа Цикл
			Контекст.ВерсииОграниченийСписков.Вставить(КлючИЗначение.Ключ, Неопределено);
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ПроверитьОграничениеДляВидаПользователей(Контекст, Результат, ДляВнешнихПользователей, ДополнительныйКонтекст)

	ТекстОграничения = ?(ДляВнешнихПользователей, Контекст.ОбщийРезультат.ДляВнешнихПользователей,
		Контекст.ОбщийРезультат.ДляПользователей).ПроверяемоеОграничение;

	СтруктураОграничения = РассчитаннаяСтруктураОграничения(Контекст.ПолноеИмя,
		ТекстОграничения, Контекст.ОбщийРезультат.ТекстВМодулеМенеджера, ДляВнешнихПользователей, Истина);

	Если СтруктураОграничения <> Неопределено
	   И СтруктураОграничения.ОписаниеОшибок.ЕстьОшибки Тогда

		Результат.ОписаниеОшибок = СтруктураОграничения.ОписаниеОшибок;
		Контекст.УчетЗависимостейДоступен = Ложь;
		Возврат;
	КонецЕсли;

	ДополнительныйКонтекст = НовыйДополнительныйКонтекст();
	ДобавитьДополнительныйКонтекст(Контекст.ПолноеИмя,
		ДополнительныйКонтекст, Контекст.ОписаниеОграничения, ДляВнешнихПользователей);

	ОшибкаПриВызовеИсключения = Новый Структура("Текст", Неопределено);
	ДополнительныйКонтекст.Вставить("ОшибкаПриВызовеИсключения", ОшибкаПриВызовеИсключения);

	Попытка
		ПараметрыОграничения = ПараметрыОграниченияПоСтруктуреОграничения(Контекст.ПолноеИмя,
			СтруктураОграничения, ДляВнешнихПользователей, Контекст.ОбщийКонтекст, ДополнительныйКонтекст);
	Исключение
		ИнформацияОбОшибке = ИнформацияОбОшибке();
		ПараметрыОграничения = Неопределено;
		Если ЗначениеЗаполнено(ОшибкаПриВызовеИсключения.Текст) Тогда
			Результат.ОшибкаФормированияПараметровОграничения = ОшибкаПриВызовеИсключения.Текст;
		Иначе
			Результат.ОшибкаФормированияПараметровОграничения =
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Не удалось сформировать параметры ограничения доступа по причине:
					           |%1'"), ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
		КонецЕсли;
		Контекст.УчетЗависимостейДоступен = Ложь;
	КонецПопытки;

	Если ПараметрыОграничения <> Неопределено Тогда
		Результат.ОграничениеПоВладельцуВозможно = ПараметрыОграничения.ПолеВладельца <> Неопределено;
		ПараметрыОграничения.Контекст.СпискиСЗаписьюКлючейДляЗависимыхСписковБезКлючей = Новый Соответствие;
		УстановитьСвойстваЗаписиКлючейДоступа(ПараметрыОграничения);
		ПараметрыОграничения.Вставить("БезЗаписиКлючейДоступаДляПользователейИВнешнихПользователей", Ложь);
		Для Каждого КлючИЗначение Из ПараметрыОграничения.ВедущиеСписки.ПоЗначениямПолей Цикл
			Контекст.ВедущиеСписки.Вставить(КлючИЗначение.Ключ, Неопределено);
		КонецЦикла;
		Для Каждого КлючИЗначение Из ПараметрыОграничения.ВедущиеСписки.ПоКлючамДоступа Цикл
			Контекст.ВерсииОграниченийСписков.Вставить(КлючИЗначение.Ключ, Неопределено);
		КонецЦикла;
		Попытка
			ДобавитьТекстыЗапросовВПараметрыОграничения(ПараметрыОграничения);
		Исключение
			ИнформацияОбОшибке = ИнформацияОбОшибке();
			Если ЗначениеЗаполнено(ОшибкаПриВызовеИсключения.Текст) Тогда
				Результат.ОшибкаФормированияТекстовЗапросов = ОшибкаПриВызовеИсключения.Текст;
			Иначе
				Результат.ОшибкаФормированияТекстовЗапросов =
					СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Не удалось сформировать тексты запросов на основе параметров ограничения доступа по причине:
						           |%1'"), ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке));
			КонецЕсли;
			Контекст.УчетЗависимостейДоступен = Ложь;
		КонецПопытки;
	КонецЕсли;

	Если Контекст.УчитыватьЗависимости Тогда
		Возврат;
	КонецЕсли;

	СокращенныеСвойства = Новый Структура;
	СокращенныеСвойства.Вставить("ДоступЗапрещен", Ложь);
	СокращенныеСвойства.Вставить("ПолеВладельца", Неопределено);
	СокращенныеСвойства.Вставить("ОпорныеПоля", Неопределено);
	СокращенныеСвойства.Вставить("ИмяОтдельногоРегистраКлючей", Неопределено);
	ДополнительныйКонтекст.СвойстваОграниченияСписков.Вставить(Контекст.ПолноеИмя, СокращенныеСвойства);

	Если Не Контекст.УчетЗависимостейДоступен Тогда
		Возврат;
	КонецЕсли;

	ЗаполнитьЗначенияСвойств(СокращенныеСвойства, ПараметрыОграничения);

КонецПроцедуры

// Для функций ХранимыеПараметрыОграниченияДоступа, РассчитанныеПараметрыОграничения.

Функция ОбщаяВерсия(ОбщийКонтекст, ПолноеИмя, ВерсияДляПользователей, ВерсияДляВнешнихПользователей)

	Если ОбщийКонтекст.СпискиСОграничением.Получить(ПолноеИмя) = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;

	Возврат Строка(ВерсияДляПользователей) + Символы.ПС + Строка(ВерсияДляВнешнихПользователей);

КонецФункции

// Для функции РассчитанныеПараметрыОграничения.

Процедура УстановитьСвойстваЗаписиКлючейДоступа(Результат)

	БезЗаписиКлючей = Ложь;
	СЗаписьюКлючаДляЗависимыхСписковБезКлючей = Ложь;

	Если Результат.ОграничениеОтключено
	 Или Результат.ДоступЗапрещен
	 Или Результат.ИспользуетсяОграничениеПоВладельцу Тогда

		Если Результат.ИспользуетсяОграничениеПоВладельцу
		 Или Результат.Контекст.БезОбъектаМетаданных
		 Или Результат.Контекст.СпискиСЗаписьюКлючейДляЗависимыхСписковБезКлючей.Получить(
		 		Результат.Список) = Неопределено Тогда

			БезЗаписиКлючей = Истина;
		Иначе
			СЗаписьюКлючаДляЗависимыхСписковБезКлючей = Истина;
		КонецЕсли;
	КонецЕсли;

	Результат.Вставить("БезЗаписиКлючейДоступа", БезЗаписиКлючей);
	Результат.Вставить("СЗаписьюКлючаДоступаДляЗависимыхСписковБезКлючей",
		СЗаписьюКлючаДляЗависимыхСписковБезКлючей);

КонецПроцедуры

// Для функций РассчитанныеПараметрыОграничения, ХранимыеПараметрыОграниченияДоступа.
//
// Возвращаемое значение:
//   Структура:
//     * Текст - Строка
//     * ТекстДляВнешнихПользователей - Строка
//     * ПоВладельцуБезЗаписиКлючейДоступа - Булево
//                                         - Неопределено
//     * ПоВладельцуБезЗаписиКлючейДоступаДляВнешнихПользователей - Булево
//                                                                - Неопределено
//     * ТекстВМодулеМенеджера - Булево
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `РазобратьВыбор`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура РазобратьВыбор(Контекст)
Строка = Контекст.Строка;

	СвойстваУзла = "Источник, Узел, Выбор, Когда, Иначе";
	НовоеОписание = Новый Структура(СвойстваУзла, Строка, "Выбор");
	НовоеОписание.Когда = Новый Массив;

	ПропуститьАнализКогда = Ложь;

	Выбор = СтрокаТаблицы(Строка.Строки[0], Контекст);
	Если Выбор.Строки.Количество() > 0 Тогда
		ПерваяСтрокаВыбора = СтрокаТаблицы(Выбор.Строки[0], Контекст);
		Если ПерваяСтрокаВыбора.Вид = "Имя" Тогда
			НовоеОписание.Выбор = ОписаниеУзлаПолеИлиУзлаКонстанта(ПерваяСтрокаВыбора);
		Иначе
			ПропуститьАнализКогда = Истина;
			УстановитьОшибкуВСтроке(ПерваяСтрокаВыбора, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Когда аргумент ключевого слова ""%1"" указан, то это может быть только имя поля'"),
				Строка.Символы));
		КонецЕсли;
	КонецЕсли;

	Индекс = 1;
	Пока Истина Цикл
		СледующаяСтрока = СтрокаТаблицы(Строка.Строки[Индекс], Контекст);
		Если СледующаяСтрока.Уточнение <> "Когда" Тогда
			Прервать;
		КонецЕсли;
		ОписаниеКогдаТогда = Новый Структура("Условие, Значение");
		НовоеОписаниеКогда = НовоеОписание.Когда; // Массив
		НовоеОписаниеКогда.Добавить(ОписаниеКогдаТогда);

		Когда = СледующаяСтрока;

		Если Не ПропуститьАнализКогда Тогда
			ПерваяПодстрокаКогда = ?(Когда.Строки.Количество() = 0, Неопределено,
				СтрокаТаблицы(Когда.Строки[0], Контекст));

			Если НовоеОписание.Выбор = Неопределено Тогда
				РазобратьВыражение(Когда.Строки, ОписаниеКогдаТогда.Условие, Контекст);

			ИначеЕсли Когда.Строки.Количество() = 0 Тогда
				Если ЗначениеЗаполнено(Когда.Символы) Тогда
					УстановитьОшибкуВСтроке(Когда, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Так как после ключевого слова ""%1"" указано поле, то после ключевого слова ""%2""
						           |должно быть указано, либо предопределенное значение, либо константа'"),
						Строка.Символы,
						Когда.Символы));
				КонецЕсли;

			ИначеЕсли ПерваяПодстрокаКогда.Вид = "Число"
			      Или ПерваяПодстрокаКогда.Вид = "ПроизвольнаяСтрока"
			      Или ПерваяПодстрокаКогда.Вид = "КлючевоеСлово"
			        И (    ПерваяПодстрокаКогда.Уточнение = "Истина"
			           Или ПерваяПодстрокаКогда.Уточнение = "Ложь"
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура РазобратьВыбор(Контекст)

	Строка = Контекст.Строка;

	СвойстваУзла = "Источник, Узел, Выбор, Когда, Иначе";
	НовоеОписание = Новый Структура(СвойстваУзла, Строка, "Выбор");
	НовоеОписание.Когда = Новый Массив;

	ПропуститьАнализКогда = Ложь;

	Выбор = СтрокаТаблицы(Строка.Строки[0], Контекст);
	Если Выбор.Строки.Количество() > 0 Тогда
		ПерваяСтрокаВыбора = СтрокаТаблицы(Выбор.Строки[0], Контекст);
		Если ПерваяСтрокаВыбора.Вид = "Имя" Тогда
			НовоеОписание.Выбор = ОписаниеУзлаПолеИлиУзлаКонстанта(ПерваяСтрокаВыбора);
		Иначе
			ПропуститьАнализКогда = Истина;
			УстановитьОшибкуВСтроке(ПерваяСтрокаВыбора, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Когда аргумент ключевого слова ""%1"" указан, то это может быть только имя поля'"),
				Строка.Символы));
		КонецЕсли;
	КонецЕсли;

	Индекс = 1;
	Пока Истина Цикл
		СледующаяСтрока = СтрокаТаблицы(Строка.Строки[Индекс], Контекст);
		Если СледующаяСтрока.Уточнение <> "Когда" Тогда
			Прервать;
		КонецЕсли;
		ОписаниеКогдаТогда = Новый Структура("Условие, Значение");
		НовоеОписаниеКогда = НовоеОписание.Когда; // Массив
		НовоеОписаниеКогда.Добавить(ОписаниеКогдаТогда);

		Когда = СледующаяСтрока;

		Если Не ПропуститьАнализКогда Тогда
			ПерваяПодстрокаКогда = ?(Когда.Строки.Количество() = 0, Неопределено,
				СтрокаТаблицы(Когда.Строки[0], Контекст));

			Если НовоеОписание.Выбор = Неопределено Тогда
				РазобратьВыражение(Когда.Строки, ОписаниеКогдаТогда.Условие, Контекст);

			ИначеЕсли Когда.Строки.Количество() = 0 Тогда
				Если ЗначениеЗаполнено(Когда.Символы) Тогда
					УстановитьОшибкуВСтроке(Когда, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
						НСтр("ru = 'Так как после ключевого слова ""%1"" указано поле, то после ключевого слова ""%2""
						           |должно быть указано, либо предопределенное значение, либо константа'"),
						Строка.Символы,
						Когда.Символы));
				КонецЕсли;

			ИначеЕсли ПерваяПодстрокаКогда.Вид = "Число"
			      Или ПерваяПодстрокаКогда.Вид = "ПроизвольнаяСтрока"
			      Или ПерваяПодстрокаКогда.Вид = "КлючевоеСлово"
			        И (    ПерваяПодстрокаКогда.Уточнение = "Истина"
			           Или ПерваяПодстрокаКогда.Уточнение = "Ложь"
			           Или ПерваяПодстрокаКогда.Уточнение = "Неопределено"
			           Или ПерваяПодстрокаКогда.Уточнение = "Значение" ) Тогда

				Если ПерваяПодстрокаКогда.Уточнение = "Значение" Тогда
					ОписаниеКогдаТогда.Условие = Новый Структура("Источник, Узел",
						ПерваяПодстрокаКогда, ПерваяПодстрокаКогда.Уточнение);

					РазобратьПараметрыФункцииЗначениеИлиФункцииТип(ПерваяПодстрокаКогда,
						ОписаниеКогдаТогда.Условие, Истина, Контекст);
				Иначе
					ОписаниеКогдаТогда.Условие = ОписаниеУзлаПолеИлиУзлаКонстанта(ПерваяПодстрокаКогда);
				КонецЕсли;
			ИначеЕсли ЗначениеЗаполнено(Когда.Символы) Тогда
				УстановитьОшибкуВСтроке(ПерваяПодстрокаКогда, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
					НСтр("ru = 'Так как после ключевого слова ""%1"" указано поле, то после ключевого слова ""%2""
					           |должно быть указано, либо предопределенное значение, либо константа'"),
					Строка.Символы,
					Когда.Символы));
			КонецЕсли;
		КонецЕсли;

		СоставТогда = СтрокаТаблицы(Строка.Строки[Индекс + 1], Контекст);
		Если СоставТогда.Строки.Количество() > 0 Тогда
			РазобратьВыражение(СоставТогда.Строки, ОписаниеКогдаТогда.Значение, Контекст);

		ИначеЕсли ЗначениеЗаполнено(СоставТогда.Символы) Тогда
			УстановитьОшибкуВСтроке(ПерваяПодстрокаКогда, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'После ключевого слова ""%1"" должно быть указано логическое выражение'"), СоставТогда.Символы));
		КонецЕсли;

		Индекс = Индекс + 2;
	КонецЦикла;

	РазобратьВыражение(СледующаяСтрока.Строки, НовоеОписание.Иначе, Контекст);

	ДобавитьАргументФункциюВыборОператор(Контекст, НовоеОписание);

КонецПроцедуры

// Для процедуры РазобратьВыражение.

Процедура РазобратьОшибочноеКлючевоеСлово(Контекст)

	Строка = Контекст.Строка;
	Контекст.Описание = Неопределено;

	Если Строка.Тип = "Неопределен" Тогда
		// Для зарезервированных слов ошибка уже установлена.
		Возврат;
	КонецЕсли;

	Если Строка.Тип = "ЗначениеСравнения" Тогда
		Если Строка.Уточнение = "Отключено" Тогда
			// "Отключено".
			УстановитьОшибкуВСтроке(Строка, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Значение ""%1"" может использоваться только как уточняемое значение
				           |в параметрах функции ""%2""'"),
				Строка.Символы,
				КлючевоеСловоСУчетомЯзыка("ЗначениеРазрешено", Контекст)));
		Иначе
			// "ПустаяСсылка" или "Null".
			УстановитьОшибкуВСтроке(Строка, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'Значение ""%1"" может использоваться только как уточняемое значение
				           |в параметрах функций проверки разрешений'"),
				Строка.Символы));
		КонецЕсли;

	ИначеЕсли Строка.Тип = "ИмяТипа" Тогда
		// "Число", "Строка", "Дата", "Булево".
		УстановитьОшибкуВСтроке(Строка, ПодставитьКлючевыеСловаВСтроку(Контекст,
			НСтр("ru = 'Имя типа ""%1"" может использоваться только, как параметр функции ""%2"" или
			           |как уточняемое значение в параметрах функций проверки разрешений'"),
			Строка.Символы,
			"Тип"));
	Иначе
		УстановитьОшибкуВСтроке(Строка, СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Обработка ключевого слова ""%1"" не определена'"), Строка.Символы));
	КонецЕсли;

КонецПроцедуры

// Для процедур РазобратьВыражение, РазобратьОператор, РазобратьФункцию, РазобратьВыбор.

Процедура ДобавитьАргументФункциюВыборОператор(Контекст, ДобавляемоеОписание)

	// Текущий узел: Любой.
	// Добавляемое описание: Поле, Значение, Константа, Не, Выбор, любая функция.

	Описание = Контекст.Описание; // См. ОписаниеУзла

	Если Описание = Неопределено Тогда
		Контекст.Описание = ДобавляемоеОписание;

	ИначеЕсли Описание.Узел = "И"
	      Или Описание.Узел = "Или" Тогда

		Если Описание.Аргументы.Количество() = 1 Тогда
			Описание.Аргументы.Добавить(ДобавляемоеОписание);
		Иначе
			ОбработатьПропущеннуюЛогическуюОперацию(Контекст, Описание.Аргументы[1], ДобавляемоеОписание);
		КонецЕсли;

	ИначеЕсли Описание.Узел = "Не" Тогда

		Если Не ЗначениеЗаполнено(Описание.Аргумент) Тогда
			Описание.Аргумент = ДобавляемоеОписание;
		Иначе
			ОбработатьПропущеннуюЛогическуюОперацию(Контекст, Описание.Аргумент, ДобавляемоеОписание);
		КонецЕсли;

	ИначеЕсли Описание.Источник.Вид = "Операция" Тогда

		Если Не ЗначениеЗаполнено(Описание.ВторойАргумент) Тогда
			Описание.ВторойАргумент = ДобавляемоеОписание;
			// Проверка корректности аргументов выполняется
			// в процедуре ОтметитьНекорректныеАргументыИЗапрещенныеУзлы.
		Иначе
			ОбработатьПропущеннуюЛогическуюОперацию(Контекст, Описание.ВторойАргумент, ДобавляемоеОписание);
		КонецЕсли;

	ИначеЕсли СтрНайти(",Поле,Значение,Константа,В,ЕстьNull,Выбор,", "," + Описание.Узел + ",") > 0
	      Или Описание.Источник.Тип = "Функция" Тогда
		// Второй аргумент операции В уже разобран в процедуре РазобратьОперациюВ.
		// Второй аргумент Null операции Есть уже разобран в функции ФункцииСВыражениямиВСкобках.
		// Остальные узлы не имеют второго аргумента.
		ОбработатьПропущеннуюЛогическуюОперацию(Контекст, Неопределено, ДобавляемоеОписание);
	Иначе
		ТекстОшибки = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Не определена обработка узла ""%1""'"), Описание.Узел);
		ВызватьИсключение ТекстОшибки;
	КонецЕсли;

КонецПроцедуры

// Для процедуры ДобавитьАргументФункциюВыборОператор


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ОбработкаПроверкиЗаполненияНаСервере`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ОбработкаПроверкиЗаполненияНаСервере(Форма, Объект, Отказ)
Экспорт

	ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияКонтактнойИнформации = Истина;

	ИмяОбъекта = Объект.Ссылка.Метаданные().Имя;
	УровеньОшибок = 0;
	ПредыдущийВид = Неопределено;

	ИменаТабличныхЧастейПоВидамКИ = Неопределено;

	Для Каждого СтрокаТаблицы Из УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеКонтактнойИнформацииНаФорме(Форма) Цикл

		ВидИнформации = СтрокаТаблицы.Вид;
		ТипИнформации = СтрокаТаблицы.Тип;
		Комментарий   = СтрокаТаблицы.Комментарий;
		ИмяРеквизита  = СтрокаТаблицы.ИмяРеквизита;
		СвойствоВидаИнформации = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ВидИнформации, "ОбязательноеЗаполнение, ВидРедактирования");
		ОбязательноеЗаполнение = СвойствоВидаИнформации.ОбязательноеЗаполнение;

		Если СтрокаТаблицы.ЭтоРеквизитТабличнойЧасти Тогда

			Если ИменаТабличныхЧастейПоВидамКИ = Неопределено Тогда
				Отбор = Новый Структура("ЭтоРеквизитТабличнойЧасти", Истина);
				ВидыКИТабличнойЧасти = УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеКонтактнойИнформацииНаФорме(Форма).Выгрузить(Отбор , "Вид");
				// @skip-check query-in-loop - Выполняется только в одной итерации, при первом появлении реквизита табличной части
				ИменаТабличныхЧастейПоВидамКИ = ИменаТабличныхЧастейПоВидамКИ(ВидыКИТабличнойЧасти, ИмяОбъекта);
			КонецЕсли;

			ИмяТабличнойЧасти = ИменаТабличныхЧастейПоВидамКИ[ВидИнформации];
			ТабличнаяЧастьФормы = Форма.Объект[ИмяТабличнойЧасти];

			Для Каждого СтрокаТабличнойЧастиФормы Из ТабличнаяЧастьФормы Цикл

				Представление = СтрокаТабличнойЧастиФормы[ИмяРеквизита];
				Поле = "Объект." + ИмяТабличнойЧасти + "[" + XMLСтрока((СтрокаТабличнойЧастиФормы.НомерСтроки - 1)) + "]." + ИмяРеквизита;

				Если ОбязательноеЗаполнение И ПустаяСтрока(Представление) И Не ВидИнформации.ПометкаУдаления Тогда

					ОбщегоНазначения.СообщитьПользователю(
					СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Поле ""%1"" не заполнено.'"), ВидИнформации.Наименование),,Поле);
					ТекущийУровеньОшибок = 2;

				Иначе

					Значение = СтрокаТабличнойЧастиФормы[ИмяРеквизита + "Значение"];

					ТекущийУровеньОшибок = ПроверитьЗаполнениеКонтактнойИнформации(Представление, Значение, ВидИнформации,
						ТипИнформации, ИмяРеквизита, , Поле);

					СтрокаТабличнойЧастиФормы[ИмяРеквизита] = Представление;
					СтрокаТабличнойЧастиФормы[ИмяРеквизита + "Значение"] = Значение;

				КонецЕсли;

				УровеньОшибок = ?(ТекущийУровеньОшибок > УровеньОшибок, ТекущийУровеньОшибок, УровеньОшибок);

			КонецЦикла;

		Иначе
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ОбработкаПроверкиЗаполненияНаСервере(Форма, Объект, Отказ) Экспорт

	ПараметрыСеанса.ИнтерактивнаяПроверкаЗаполненияКонтактнойИнформации = Истина;

	ИмяОбъекта = Объект.Ссылка.Метаданные().Имя;
	УровеньОшибок = 0;
	ПредыдущийВид = Неопределено;

	ИменаТабличныхЧастейПоВидамКИ = Неопределено;

	Для Каждого СтрокаТаблицы Из УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеКонтактнойИнформацииНаФорме(Форма) Цикл

		ВидИнформации = СтрокаТаблицы.Вид;
		ТипИнформации = СтрокаТаблицы.Тип;
		Комментарий   = СтрокаТаблицы.Комментарий;
		ИмяРеквизита  = СтрокаТаблицы.ИмяРеквизита;
		СвойствоВидаИнформации = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(ВидИнформации, "ОбязательноеЗаполнение, ВидРедактирования");
		ОбязательноеЗаполнение = СвойствоВидаИнформации.ОбязательноеЗаполнение;

		Если СтрокаТаблицы.ЭтоРеквизитТабличнойЧасти Тогда

			Если ИменаТабличныхЧастейПоВидамКИ = Неопределено Тогда
				Отбор = Новый Структура("ЭтоРеквизитТабличнойЧасти", Истина);
				ВидыКИТабличнойЧасти = УправлениеКонтактнойИнформациейКлиентСервер.ОписаниеКонтактнойИнформацииНаФорме(Форма).Выгрузить(Отбор , "Вид");
				// @skip-check query-in-loop - Выполняется только в одной итерации, при первом появлении реквизита табличной части
				ИменаТабличныхЧастейПоВидамКИ = ИменаТабличныхЧастейПоВидамКИ(ВидыКИТабличнойЧасти, ИмяОбъекта);
			КонецЕсли;

			ИмяТабличнойЧасти = ИменаТабличныхЧастейПоВидамКИ[ВидИнформации];
			ТабличнаяЧастьФормы = Форма.Объект[ИмяТабличнойЧасти];

			Для Каждого СтрокаТабличнойЧастиФормы Из ТабличнаяЧастьФормы Цикл

				Представление = СтрокаТабличнойЧастиФормы[ИмяРеквизита];
				Поле = "Объект." + ИмяТабличнойЧасти + "[" + XMLСтрока((СтрокаТабличнойЧастиФормы.НомерСтроки - 1)) + "]." + ИмяРеквизита;

				Если ОбязательноеЗаполнение И ПустаяСтрока(Представление) И Не ВидИнформации.ПометкаУдаления Тогда

					ОбщегоНазначения.СообщитьПользователю(
					СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Поле ""%1"" не заполнено.'"), ВидИнформации.Наименование),,Поле);
					ТекущийУровеньОшибок = 2;

				Иначе

					Значение = СтрокаТабличнойЧастиФормы[ИмяРеквизита + "Значение"];

					ТекущийУровеньОшибок = ПроверитьЗаполнениеКонтактнойИнформации(Представление, Значение, ВидИнформации,
						ТипИнформации, ИмяРеквизита, , Поле);

					СтрокаТабличнойЧастиФормы[ИмяРеквизита] = Представление;
					СтрокаТабличнойЧастиФормы[ИмяРеквизита + "Значение"] = Значение;

				КонецЕсли;

				УровеньОшибок = ?(ТекущийУровеньОшибок > УровеньОшибок, ТекущийУровеньОшибок, УровеньОшибок);

			КонецЦикла;

		Иначе

			ЭлементФормы = Форма.Элементы.Найти(ИмяРеквизита);
			Если ЭлементФормы = Неопределено Или ВидИнформации.ПометкаУдаления Тогда
				Продолжить; // Элемент не был создан. Не была вызвана отложенная инициализация.
			КонецЕсли;

			Если (СвойствоВидаИнформации.ВидРедактирования = "Диалог"
				Или ТипИнформации = Перечисления.ТипыКонтактнойИнформации.ВебСтраница)
				И Не УправлениеКонтактнойИнформациейКлиентСервер.КонтактнаяИнформацияЗаполнена(Строка(Форма[ИмяРеквизита])) Тогда
				Представление = "";
			Иначе
				Представление = Форма[ИмяРеквизита];
			КонецЕсли;

			Если ВидИнформации <> ПредыдущийВид И ОбязательноеЗаполнение И ПустаяСтрока(Представление)
				И Не ЕстьДругиеЗаполненныеСтрокКИДанногоВида(Форма, СтрокаТаблицы, ВидИнформации) Тогда
				// И нет других строк с данными для видов КИ с множественными значениями.

				ОбщегоНазначения.СообщитьПользователю(
				СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Поле ""%1"" не заполнено.'"), ВидИнформации.Наименование),,, ИмяРеквизита);
				ТекущийУровеньОшибок = 2;

			Иначе

				ТекущийУровеньОшибок = ПроверитьЗаполнениеКонтактнойИнформации(Представление, СтрокаТаблицы.Значение,
					ВидИнформации, ТипИнформации, ИмяРеквизита, Комментарий);

			КонецЕсли;

			УровеньОшибок = ?(ТекущийУровеньОшибок > УровеньОшибок, ТекущийУровеньОшибок, УровеньОшибок);

		КонецЕсли;

		ПредыдущийВид = ВидИнформации;

	КонецЦикла;

	Если УровеньОшибок <> 0 Тогда
		Отказ = Истина;
	КонецЕсли;

КонецПроцедуры

// Обработчик для события формы ПередЗаписьюНаСервере.
// Вызывается из модуля формы объекта-владельца КИ при внедрении подсистемы.
//
// Параметры:
//    Форма  - ФормаКлиентскогоПриложения - форма объекта-владельца, предназначенная для вывода контактной информации.
//    Объект - СправочникОбъект
//           - ДокументСсылка - объект-владелец контактной информации.
//             ДанныеФормыСтруктура - Объект, содержащий табличную часть с контактной информацией. Поддерживает работу
//                              со скрываемыми видами контактной информации только для уже существующих объектов,
//                              из-за невозможности установить ссылку для нового объекта.
//    Отказ  - Булево - если Истина, то объект не был записан, т.к. во время записи возникли ошибки.
//

Процедура ПередЗаписьюНаСервере(Форма, Объект, Отказ = Ложь) Экспорт

	КонтактнаяИнформация = КонтактнаяИнформацияИзРеквизитовФормы(Форма, Объект);

	ЭтоПараметрыОсновногоОбъекта  = Истина;
	ПараметрыКонтактнойИнформации = Неопределено;
	СкрываемыеВиды                = Новый Массив;

	ОпределитьПараметрыКонтактнойИнформацииПоВладельцу(Форма, Объект, ПараметрыКонтактнойИнформации, ЭтоПараметрыОсновногоОбъекта, СкрываемыеВиды);

	Если Объект.Ссылка.Пустая() И ТипЗнч(Объект) <> Тип("ДанныеФормыСтруктура") Тогда

		Если ЭтоПараметрыОсновногоОбъекта Тогда

			НоваяСсылка = Объект.ПолучитьСсылкуНового();
			МенеджерОбъекта = ОбщегоНазначения.МенеджерОбъектаПоСсылке(Объект.Ссылка);
			Если НоваяСсылка = МенеджерОбъекта.ПустаяСсылка() Тогда
				Объект.УстановитьСсылкуНового(МенеджерОбъекта.ПолучитьСсылку());
			КонецЕсли;
			ПараметрыКонтактнойИнформации.Владелец = Объект.ПолучитьСсылкуНового();

		Иначе
			Возврат;
		КонецЕсли;

	КонецЕсли;

	Если СкрываемыеВиды.Количество() = 0 Тогда
		Объект.КонтактнаяИнформация.Очистить();
	Иначе

		Индекс = Объект.КонтактнаяИнформация.Количество() -1;
		Пока Индекс >= 0 Цикл
			СтрокаТаблицы = Объект.КонтактнаяИнформация.Получить(Индекс);
			Если СкрываемыеВиды.Найти(СтрокаТаблицы.Вид) = Неопределено Тогда
				Объект.КонтактнаяИнформация.Удалить(СтрокаТаблицы);
			КонецЕсли;
			Индекс = Индекс - 1;
		КонецЦикла;

	КонецЕсли;

	УстановитьКонтактнуюИнформациюОбъекта(Объект, КонтактнаяИнформация);

КонецПроцедуры

// Добавляет (удаляет) поле ввода или комментарий на форму, обновляя данные.
// Вызывается из модуля формы объекта-владельца контактной информации.
//
// Параметры:
//    Форма     - ФормаКлиентскогоПриложения - форма объекта-владельца, предназначенная для вывода контактной информации.
//    Объект    - ДанныеФормыСтруктура - объект-владелец контактной информации.
//    Результат - Неопределено - служебный реквизит, полученный из предыдущего обработчика события.
//              - Структура: - набор свойств динамический:
//      * ПоменятьМестамиЭлементы - Булево - если значения элементов меняются местами.
//      * ПервыйЭлемент - Строка - если значения элементов меняются местами.
//      * ВторойЭлемент - Строка - если значения элементов меняются местами.
//      * ОбновитьКонтекстноеМеню - Булево -  если выполняется обновление меню
//      * ИмяРеквизита - Строка - если выполняется обновление меню
//      * ДобавляемыйВид - Булево - при добавлении нового элемента
//      * ЭтоДобавлениеКомментария - Булево - при добавлении комментария
//      * ОбновитьКонтекстноеМеню - Булево - при обновлении контекстного меню
//      * ИмяЭлементаДляРазмещения - Строка -  если добавляет новый элемент, комментарий или обновляется контекстное меню
//      * Комментарий - Строка - при обновлении контекстного меню
//       * Перечитать  - Булево - если нужно полностью обновить контактную информацию в рамках элемента для размещения.
//
// Возвращаемое значение:
//    Неопределено - значение не используется, обратная совместимость.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ФорматированиеРезультатовАвтоподбора`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ФорматированиеРезультатовАвтоподбора(ДанныеВыбора, Знач Текст, ВыделятьУстаревшиеАдреса = Истина)
Экспорт

	Если Не УправлениеКонтактнойИнформациейСлужебныйПовтИсп.ДоступныМодулиРаботаСАдресами() Тогда
		Возврат;
	КонецЕсли;

	МодульРаботаСАдресамиКлиентСервер = ОбщегоНазначения.ОбщийМодуль("РаботаСАдресамиКлиентСервер");

	// Оформление списка поиска
	ФрагментыТекстаПоиска = СтрРазделить(Текст, " ");
	Для каждого СтрокаДанных Из ДанныеВыбора Цикл

		Если ТипЗнч(СтрокаДанных.Значение) = Тип("Структура")
			И СтрокаДанных.Значение.Свойство("Адрес") Тогда

			Если ЗначениеЗаполнено(СтрокаДанных.Значение.Адрес) И ТипЗнч(СтрокаДанных.Значение.Адрес) = Тип("Строка") Тогда
				Адрес = JSONВКонтактнуюИнформациюПоПолям(СтрокаДанных.Значение.Адрес, Перечисления.ТипыКонтактнойИнформации.Адрес);
				СтрокаДанных.Значение.Представление = МодульРаботаСАдресамиКлиентСервер.ПредставлениеАдреса(Адрес, Ложь);
			КонецЕсли;
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ФорматированиеРезультатовАвтоподбора(ДанныеВыбора, Знач Текст, ВыделятьУстаревшиеАдреса = Истина) Экспорт

	Если Не УправлениеКонтактнойИнформациейСлужебныйПовтИсп.ДоступныМодулиРаботаСАдресами() Тогда
		Возврат;
	КонецЕсли;

	МодульРаботаСАдресамиКлиентСервер = ОбщегоНазначения.ОбщийМодуль("РаботаСАдресамиКлиентСервер");

	// Оформление списка поиска
	ФрагментыТекстаПоиска = СтрРазделить(Текст, " ");
	Для каждого СтрокаДанных Из ДанныеВыбора Цикл

		Если ТипЗнч(СтрокаДанных.Значение) = Тип("Структура")
			И СтрокаДанных.Значение.Свойство("Адрес") Тогда

			Если ЗначениеЗаполнено(СтрокаДанных.Значение.Адрес) И ТипЗнч(СтрокаДанных.Значение.Адрес) = Тип("Строка") Тогда
				Адрес = JSONВКонтактнуюИнформациюПоПолям(СтрокаДанных.Значение.Адрес, Перечисления.ТипыКонтактнойИнформации.Адрес);
				СтрокаДанных.Значение.Представление = МодульРаботаСАдресамиКлиентСервер.ПредставлениеАдреса(Адрес, Ложь);
			КонецЕсли;

		КонецЕсли;

		Представление = СтрокаДанных.Представление;
		Для каждого ФрагментТекстаПоиска Из ФрагментыТекстаПоиска Цикл
			ПредставлениеСВыделением = СтрНайтиИВыделитьОформлением(Представление, ФрагментТекстаПоиска);
			Если ПредставлениеСВыделением <> Неопределено Тогда
				Представление = ПредставлениеСВыделением;
			КонецЕсли;
		КонецЦикла;
		СтрокаДанных.Представление = Представление;

	КонецЦикла;

КонецПроцедуры

// Функция-конструктор результата проверки.
//
// Возвращаемое значение:
//   Структура:
//   * СписокОшибок - СписокЗначений
//   * Результат - Строка
//

Функция РезультатПроверки()

	РезультатПроверки = Новый Структура;
	РезультатПроверки.Вставить("Результат", "");
	РезультатПроверки.Вставить("СписокОшибок", Новый СписокЗначений);
	Возврат РезультатПроверки

КонецФункции

Функция ЭтоТипАдрес(ЗначениеТипа)
	Возврат СтрСравнить(ЗначениеТипа, Строка(ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.Адрес"))) = 0;
КонецФункции

Функция ИсправитьПорциюВидовКонтактнойИнформации(Знач ПроблемныеОбъекты, Проверка)

	ИсправленоОбъектов = 0;

	ТекстЗапроса = "ВЫБРАТЬ
	|	ПроблемныеОбъекты.ПроблемныйОбъект КАК Ссылка
	|ПОМЕСТИТЬ ПроблемныеОбъекты
	|ИЗ
	| &ПроблемныеОбъекты КАК ПроблемныеОбъекты
	|ИНДЕКСИРОВАТЬ ПО
	| ПроблемныйОбъект
	|;
	|
	|ВЫБРАТЬ
	|	ВидыКонтактнойИнформации.Ссылка КАК Ссылка,
	|ВЫБОР
	|	КОГДА ВидыКонтактнойИнформации.ИмяПредопределенногоВида <> """"
	|	ТОГДА ВидыКонтактнойИнформации.ИмяПредопределенногоВида
	|	ИНАЧЕ ВидыКонтактнойИнформации.ИмяПредопределенныхДанных
	|КОНЕЦ КАК ИмяПредопределенногоВида
	|ИЗ
	|	Справочник.ВидыКонтактнойИнформации КАК ВидыКонтактнойИнформации
	|ГДЕ
	|	ВидыКонтактнойИнформации.ЭтоГруппа = ИСТИНА
	|;";

	ОбъектыМетаданных = ОбъектыСодержащиеКонтактнуюИнформацию();
	НаборТекстаЗапроса = Новый Массив;

	ШаблонЗапроса = "ВЫБРАТЬ
	|	МАКСИМУМ(КонтактнаяИнформация.Ссылка) КАК Ссылка,
	|	КонтактнаяИнформация.Вид КАК Вид
	|ИЗ
	|	ПроблемныеОбъекты КАК ПроблемныеОбъекты
	|		ЛЕВОЕ СОЕДИНЕНИЕ &ПолноеИмяОбъектаСКонтактнойИнформацией КАК КонтактнаяИнформация
	|		ПО (КонтактнаяИнформация.Вид = ПроблемныеОбъекты.Ссылка)
	|ГДЕ
	|	НЕ КонтактнаяИнформация.Ссылка ЕСТЬ NULL
	|
	|СГРУППИРОВАТЬ ПО
	|	КонтактнаяИнформация.Вид";

	Для каждого ОбъектМетаданных Из ОбъектыМетаданных Цикл
		НаборТекстаЗапроса.Добавить(СтрЗаменить(ШаблонЗапроса, "&ПолноеИмяОбъектаСКонтактнойИнформацией",
		ОбъектМетаданных.Метаданные().ПолноеИмя() + ".КонтактнаяИнформация"));
	КонецЦикла;

	Запрос = Новый Запрос;
	Запрос.Текст = ТекстЗапроса + СтрСоединить(НаборТекстаЗапроса, Символы.ПС + " ОБЪЕДИНИТЬ ВСЕ " + Символы.ПС);
	Запрос.Параметры.Вставить("ПроблемныеОбъекты", ПроблемныеОбъекты);

	РезультатыЗапроса = Запрос.ВыполнитьПакет();

	ИменаГрупп = РезультатыЗапроса.Получить(1).Выгрузить();
	ИменаГрупп.Индексы.Добавить("ИмяПредопределенногоВида");

	РезультатЗапроса = РезультатыЗапроса.Получить(2);

	Если РезультатЗапроса.Пустой() Тогда
		Возврат ИсправленоОбъектов;
	КонецЕсли;

	СтрокаЗапроса = РезультатЗапроса.Выбрать();
	Пока СтрокаЗапроса.Следующий() Цикл

		СсылкаНаЭлемент = СтрокаЗапроса.Ссылка;
		ПолноеИмя = СсылкаНаЭлемент.Метаданные().ПолноеИмя();

		СтрокаСИменемГруппы = ИменаГрупп.Найти(СтрЗаменить(ПолноеИмя, ".", ""), "ИмяПредопределенногоВида"); // СправочникСсылка.ВидыКонтактнойИнформации
		Если СтрокаСИменемГруппы <> Неопределено Тогда

			НачатьТранзакцию();

			Попытка
				Блокировка = Новый БлокировкаДанных;
				ЭлементБлокировки = Блокировка.Добавить("Справочник.ВидыКонтактнойИнформации");
				ЭлементБлокировки.УстановитьЗначение("Ссылка", СтрокаЗапроса.Вид);
				Блокировка.Заблокировать();

				Объект = СтрокаЗапроса.Вид.ПолучитьОбъект();
				Если Объект = Неопределено Тогда
					ЗафиксироватьТранзакцию();
					Продолжить;
				КонецЕсли;

				ЗаблокироватьДанныеДляРедактирования(СтрокаЗапроса.Вид);

				Объект.Родитель = СтрокаСИменемГруппы.Ссылка;
				ОбновлениеИнформационнойБазы.ЗаписатьДанные(Объект);

				ИсправленоОбъектов = ИсправленоОбъектов + 1;

				ЗафиксироватьТранзакцию();
			Исключение
				ОтменитьТранзакцию();
				ЗаписьЖурналаРегистрации(СобытиеЖурналаРегистрации(), УровеньЖурналаРегистрации.Ошибка,,, ОбработкаОшибок.ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
				Продолжить;
			КонецПопытки;

			Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.КонтрольВеденияУчета") Тогда
				МодульКонтрольВеденияУчета = ОбщегоНазначения.ОбщийМодуль("КонтрольВеденияУчета");
				МодульКонтрольВеденияУчета.ОчиститьРезультатПроверки(СтрокаЗапроса.Вид, Проверка);
			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

	Возврат ИсправленоОбъектов;

КонецФункции

Функция ОбъектыСодержащиеКонтактнуюИнформацию() Экспорт

	ОбъектыМетаданных = Новый Массив; // Массив из СправочникСсылка, ДокументСсылка
	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ВидыКонтактнойИнформации.Ссылка,
	|ВЫБОР
	|	КОГДА ВидыКонтактнойИнформации.ИмяПредопределенногоВида <> """"
	|	ТОГДА ВидыКонтактнойИнформации.ИмяПредопределенногоВида
	|	ИНАЧЕ ВидыКонтактнойИнформации.ИмяПредопределенныхДанных
	|КОНЕЦ КАК ИмяПредопределенногоВида
	|ИЗ
	|	Справочник.ВидыКонтактнойИнформации КАК ВидыКонтактнойИнформации
	|ГДЕ
	|	ВидыКонтактнойИнформации.ЭтоГруппа = ИСТИНА";

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

	Возврат ОбъектыМетаданных;

КонецФункции


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `СформироватьПечатныеФормыВФоне`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция СформироватьПечатныеФормыВФоне(ПараметрыФоновойПечати)
Экспорт

	ИменаМакетов = ПараметрыФоновойПечати.ИменаМакетов;
	ПараметрыВывода = ПараметрыФоновойПечати.ПараметрыВывода;
	ТекущийЯзык = ПараметрыФоновойПечати.ТекущийЯзык;
	ОбъектыПечати = ПараметрыФоновойПечати.ОбъектыПечати;
	ПараметрыПечати = ПараметрыФоновойПечати.ПараметрыПечати;
	СодержимоеХранилищ = ПараметрыФоновойПечати.СодержимоеХранилищ;
	УникальныйИдентификаторХранилища = ПараметрыФоновойПечати.УникальныйИдентификаторХранилища;
	ПоместитьВХранилища(ПараметрыПечати, СодержимоеХранилищ, УникальныйИдентификаторХранилища);
	ПараметрыФоновойПечати.Удалить("СодержимоеХранилищ");

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

		ДополнительныеПараметры = Неопределено;
		ПараметрыПечати.Свойство("ДополнительныеПараметры", ДополнительныеПараметры);

		ПечатныеФормы = СформироватьПечатныеФормы(ПараметрыФоновойПечати.ИмяМенеджераПечати, ИменаМакетов,
			ПараметрыФоновойПечати.ПараметрКоманды, ДополнительныеПараметры, ТипыОбъектовПечати, ТекущийЯзык);
		ОбъектыПечати = ПечатныеФормы.ОбъектыПечати;
		ПараметрыВывода = ПечатныеФормы.ПараметрыВывода;
		Результат = ПечатныеФормы.КоллекцияПечатныхФорм;
	КонецЕсли;

	// Установка признака сохранения печатной формы в файл (не открывать форму, сразу сохранять в файл).
	Если ТипЗнч(ПараметрыПечати) = Тип("Структура") И ПараметрыПечати.Свойство("ФорматСохранения")
		И ЗначениеЗаполнено(ПараметрыПечати.ФорматСохранения) Тогда
		НайденныйФормат = НастройкиФорматовСохраненияТабличногоДокумента().Найти(ТипФайлаТабличногоДокумента[ПараметрыПечати.ФорматСохранения], "ТипФайлаТабличногоДокумента");
		Если НайденныйФормат <> Неопределено Тогда
			НастройкиФорматаСохранения = Новый Структура("ТипФайлаТабличногоДокумента,Представление,Расширение,Фильтр");
			ЗаполнитьЗначенияСвойств(НастройкиФорматаСохранения, НайденныйФормат);
    // TODO: допиши оставшуюся часть

[Assistant]
Функция СформироватьПечатныеФормыВФоне(ПараметрыФоновойПечати) Экспорт

	ИменаМакетов = ПараметрыФоновойПечати.ИменаМакетов;
	ПараметрыВывода = ПараметрыФоновойПечати.ПараметрыВывода;
	ТекущийЯзык = ПараметрыФоновойПечати.ТекущийЯзык;
	ОбъектыПечати = ПараметрыФоновойПечати.ОбъектыПечати;
	ПараметрыПечати = ПараметрыФоновойПечати.ПараметрыПечати;
	СодержимоеХранилищ = ПараметрыФоновойПечати.СодержимоеХранилищ;
	УникальныйИдентификаторХранилища = ПараметрыФоновойПечати.УникальныйИдентификаторХранилища;
	ПоместитьВХранилища(ПараметрыПечати, СодержимоеХранилищ, УникальныйИдентификаторХранилища);
	ПараметрыФоновойПечати.Удалить("СодержимоеХранилищ");

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

		ДополнительныеПараметры = Неопределено;
		ПараметрыПечати.Свойство("ДополнительныеПараметры", ДополнительныеПараметры);

		ПечатныеФормы = СформироватьПечатныеФормы(ПараметрыФоновойПечати.ИмяМенеджераПечати, ИменаМакетов,
			ПараметрыФоновойПечати.ПараметрКоманды, ДополнительныеПараметры, ТипыОбъектовПечати, ТекущийЯзык);
		ОбъектыПечати = ПечатныеФормы.ОбъектыПечати;
		ПараметрыВывода = ПечатныеФормы.ПараметрыВывода;
		Результат = ПечатныеФормы.КоллекцияПечатныхФорм;
	КонецЕсли;

	// Установка признака сохранения печатной формы в файл (не открывать форму, сразу сохранять в файл).
	Если ТипЗнч(ПараметрыПечати) = Тип("Структура") И ПараметрыПечати.Свойство("ФорматСохранения")
		И ЗначениеЗаполнено(ПараметрыПечати.ФорматСохранения) Тогда
		НайденныйФормат = НастройкиФорматовСохраненияТабличногоДокумента().Найти(ТипФайлаТабличногоДокумента[ПараметрыПечати.ФорматСохранения], "ТипФайлаТабличногоДокумента");
		Если НайденныйФормат <> Неопределено Тогда
			НастройкиФорматаСохранения = Новый Структура("ТипФайлаТабличногоДокумента,Представление,Расширение,Фильтр");
			ЗаполнитьЗначенияСвойств(НастройкиФорматаСохранения, НайденныйФормат);
			НастройкиФорматаСохранения.Фильтр = НастройкиФорматаСохранения.Представление + "|*." + НастройкиФорматаСохранения.Расширение;
			НастройкиФорматаСохранения.ТипФайлаТабличногоДокумента = ПараметрыПечати.ФорматСохранения;
		КонецЕсли;
	КонецЕсли;

	РезультатФормирования = Новый Структура("КоллекцияПечатныхФорм,ПараметрыФоновогоЗадания,ОфисныеДокументы,
	|ОбъектыПечати,ПараметрыВывода,ПараметрыПечати,Сообщения");
	РезультатФормирования.ПараметрыВывода = ПараметрыВывода;
	РезультатФормирования.ПараметрыФоновогоЗадания = ПараметрыФоновойПечати;
	РезультатФормирования.ПараметрыПечати = ПараметрыПечати;
	ОфисныеДокументы = Новый Соответствие();

	Для Каждого СтрокаРезультата Из Результат Цикл
		Если ЗначениеЗаполнено(СтрокаРезультата.ОфисныеДокументы) Тогда
			СтрокаРезультата.ОфисныеДокументы.Удалить(Неопределено);
			Для Каждого ОфисныйДокумент Из СтрокаРезультата.ОфисныеДокументы Цикл
				ОфисныеДокументы.Вставить(ОфисныйДокумент.Ключ, ПолучитьИзВременногоХранилища(ОфисныйДокумент.Ключ));
			КонецЦикла;
			Если СтрокаРезультата.ОфисныеДокументы.Количество() = 0 Тогда
				СтрокаРезультата.ОфисныеДокументы = Неопределено;
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;

	РезультатФормирования.КоллекцияПечатныхФорм = ОбщегоНазначения.ТаблицаЗначенийВМассив(Результат);

	РезультатФормирования.ОфисныеДокументы = ОфисныеДокументы;
	РезультатФормирования.ОбъектыПечати = ОбъектыПечати;
	РезультатФормирования.Сообщения = ПолучитьСообщенияПользователю();

	Возврат РезультатФормирования;

КонецФункции

// Формирует печатную форму по внешнему источнику.
//
// Параметры:
//   ДополнительнаяОбработкаСсылка - СправочникСсылка.ДополнительныеОтчетыИОбработки - внешняя обработка.
//   ПараметрыИсточника            - Структура:
//       * ИдентификаторКоманды - Строка - список макетов, перечисленных через запятую.
//       * ОбъектыНазначения    - Массив
//   КоллекцияПечатныхФорм - см. описание процедуры Печать() в документации.
//   ОбъектыПечати         - СписокЗначений  - см. описание процедуры Печать() в документации.
//   ПараметрыВывода       - Структура       - см. описание процедуры Печать() в документации.
//

Процедура ПечатьПоВнешнемуИсточнику(ДополнительнаяОбработкаСсылка, ПараметрыИсточника, КоллекцияПечатныхФорм,
	ОбъектыПечати, ПараметрыВывода) Экспорт

	МодульДополнительныеОтчетыИОбработки = ОбщегоНазначения.ОбщийМодуль("ДополнительныеОтчетыИОбработки");
	ВнешняяОбработкаОбъект = МодульДополнительныеОтчетыИОбработки.ОбъектВнешнейОбработки(ДополнительнаяОбработкаСсылка);
	Если ВнешняяОбработкаОбъект = Неопределено Тогда
		ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Внешняя обработка ""%1"" (тип ""%2"") не обслуживается.'"),
			Строка(ДополнительнаяОбработкаСсылка),
			Строка(ТипЗнч(ДополнительнаяОбработкаСсылка)));
	КонецЕсли;

	КоллекцияПечатныхФорм = ПодготовитьКоллекциюПечатныхФорм(ПараметрыИсточника.ИдентификаторКоманды);
	Если Не ЗначениеЗаполнено(ПараметрыВывода) Тогда
		ПараметрыВывода = ПодготовитьСтруктуруПараметровВывода();
	КонецЕсли;
	ПараметрыВывода.Вставить("ДополнительнаяОбработкаСсылка", ДополнительнаяОбработкаСсылка);

	ВнешняяОбработкаОбъект.Печать(
		ПараметрыИсточника.ОбъектыНазначения,
		КоллекцияПечатныхФорм,
		ОбъектыПечати,
		ПараметрыВывода);

	// Проверим, все ли макеты были сформированы.
	Для Каждого ПечатнаяФорма Из КоллекцияПечатныхФорм Цикл
		Если Не ПечатнаяФорма.ОфисныеДокументы = Неопределено Тогда
			ПечатнаяФорма.ТабличныйДокумент = Новый ТабличныйДокумент;
		КонецЕсли;

		Если ПечатнаяФорма.ТабличныйДокумент = Неопределено Тогда
			ТекстСообщенияОбОшибке = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru = 'В обработчике печати не был сформирован табличный документ для: %1'"),
				ПечатнаяФорма.ИмяМакета);
			ВызватьИсключение(ТекстСообщенияОбОшибке);
		КонецЕсли;

		ПечатнаяФорма.ТабличныйДокумент.КоличествоЭкземпляров = ПечатнаяФорма.Экземпляров;

		Если Не МакетСуществует(ПечатнаяФорма.ПолныйПутьКМакету) Тогда
			ПечатнаяФорма.ПолныйПутьКМакету = "";
		КонецЕсли;

		ПечатнаяФорма.Защита = ПечатнаяФорма.ТабличныйДокумент.Защита;
	КонецЦикла;

КонецПроцедуры

// См. ПодключаемыеКомандыПереопределяемый.ПриОпределенииСоставаНастроекПодключаемыхОбъектов

Процедура ПриОпределенииСоставаНастроекПодключаемыхОбъектов(НастройкиПрограммногоИнтерфейса) Экспорт
	Настройка = НастройкиПрограммногоИнтерфейса.Добавить();
	Настройка.Ключ          = "ДобавитьКомандыПечати";
	Настройка.ОписаниеТипов = Новый ОписаниеТипов("Булево");
КонецПроцедуры

// См. ПодключаемыеКомандыПереопределяемый.ПриОпределенииВидовПодключаемыхКоманд

Процедура ПриОпределенииВидовПодключаемыхКоманд(ВидыПодключаемыхКоманд) Экспорт
	Вид = ВидыПодключаемыхКоманд.Добавить();
	Вид.Имя         = "Печать";
	Вид.ИмяПодменю  = "ПодменюПечать";
	Вид.Заголовок   = НСтр("ru = 'Печать'");
	Вид.Порядок     = 40;
	Вид.Картинка    = БиблиотекаКартинок.Печать;
	Вид.Отображение = ОтображениеКнопки.КартинкаИТекст;
КонецПроцедуры

// См. ПодключаемыеКомандыПереопределяемый.ПриОпределенииКомандПодключенныхКОбъекту


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало функция `ПодготовитьСтруктуруПараметровВывода`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Функция ПодготовитьСтруктуруПараметровВывода()
Экспорт

	ПараметрыВывода = Новый Структура;
	ПараметрыВывода.Вставить("ЗаголовокФормы", "");
	ПараметрыВывода.Вставить("ДоступнаПечатьПоКомплектно", Ложь); // не используется
	ПараметрыВывода.Вставить("КодЯзыка", ОбщегоНазначения.КодОсновногоЯзыка());
    // TODO: допиши оставшуюся часть

[Assistant]
Функция ПодготовитьСтруктуруПараметровВывода() Экспорт

	ПараметрыВывода = Новый Структура;
	ПараметрыВывода.Вставить("ЗаголовокФормы", "");
	ПараметрыВывода.Вставить("ДоступнаПечатьПоКомплектно", Ложь); // не используется
	ПараметрыВывода.Вставить("КодЯзыка", ОбщегоНазначения.КодОсновногоЯзыка());

	СтруктураПараметровПисьма = Новый Структура("Получатель,Тема,Текст", Неопределено, "", "");
	ПараметрыВывода.Вставить("ПараметрыОтправки", СтруктураПараметровПисьма);

	Возврат ПараметрыВывода;

КонецФункции

// Параметры:
//  КомандаПечати - СтрокаТаблицыЗначений из см. СоздатьКоллекциюКомандПечати
//  НастройкиСохранения - см. УправлениеПечатью.НастройкиСохранения
//  СписокОбъектов - Массив
//  Результат - ТаблицаЗначений:
//   * ИмяФайла - Строка
//   * ДвоичныеДанные - ДвоичныеДанные
//

Процедура ВыполнитьКомандуПечатиВФайл(КомандаПечати, НастройкиСохранения, СписокОбъектов, Результат)

	Если Не ЗначениеЗаполнено(НастройкиСохранения.ФорматыСохранения) Тогда
		НастройкиСохранения.ФорматыСохранения.Добавить(СтандартныеПодсистемыСервер.ТипФайлаТабличногоДокументаPDF());
	КонецЕсли;

	ДанныеПечати = Неопределено;
	Если КомандаПечати.МенеджерПечати = "СтандартныеПодсистемы.ДополнительныеОтчетыИОбработки" Тогда
		Источник = КомандаПечати.ДополнительныеПараметры.Ссылка;
		ДанныеПечати = СформироватьВнешнююПечатнуюФорму(Источник, КомандаПечати.Идентификатор, СписокОбъектов);
	Иначе
		ДанныеПечати = СформироватьПечатныеФормы(КомандаПечати.МенеджерПечати, КомандаПечати.Идентификатор,
		СписокОбъектов, КомандаПечати.ДополнительныеПараметры);
	КонецЕсли;

	КоллекцияПечатныхФорм = ДанныеПечати.КоллекцияПечатныхФорм;
	ОбъектыПечати = ДанныеПечати.ОбъектыПечати;

	ПодписиИПечатиОбластей = Неопределено;
	Если НастройкиСохранения.ПодписьИПечать Тогда
		ПодписиИПечатиОбластей = ПодписиИПечатиОбластей(ОбъектыПечати);
	КонецЕсли;

	ТаблицаФорматов = НастройкиФорматовСохраненияТабличногоДокумента();

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

		Если НастройкиСохранения.ПодписьИПечать Тогда
			ДобавитьПодписьИПечать(ПечатнаяФорма.ТабличныйДокумент, ПодписиИПечатиОбластей);
		Иначе
			УбратьПодписьИПечать(ПечатнаяФорма.ТабличныйДокумент);
		КонецЕсли;

		ПечатныеФормыПоОбъектам = ПечатныеФормыПоОбъектам(ПечатнаяФорма.ТабличныйДокумент, ОбъектыПечати);
		Для Каждого СоответствиеОбъектаПечатнойФорме Из ПечатныеФормыПоОбъектам Цикл

			ОбъектПечати = СоответствиеОбъектаПечатнойФорме.Ключ;
			ТабличныйДокумент = СоответствиеОбъектаПечатнойФорме.Значение;

			Если ТабличныйДокумент.ВысотаТаблицы = 0 Тогда
				Продолжить;
			КонецЕсли;

			Для Каждого Формат Из НастройкиСохранения.ФорматыСохранения Цикл
				ТипФайла = Формат;
				Если ТипЗнч(ТипФайла) = Тип("Строка") Тогда
					ТипФайла = ТипФайлаТабличногоДокумента[ТипФайла];
				КонецЕсли;
				ТипФайла = ИспользуемыйТипФайлаТабличногоДокумента(ТипФайла);

				НастройкиФормата = ТаблицаФорматов.НайтиСтроки(Новый Структура("ТипФайлаТабличногоДокумента", ТипФайла))[0];

				РасширениеФайла = НастройкиФормата.Расширение;
				ЗаданныеИменаПечатныхФорм = ПечатнаяФорма.ИмяФайлаПечатнойФормы;
				НазваниеПечатнойФормы = ПечатнаяФорма.СинонимМакета;

				ИмяФайла = ИмяФайлаПечатнойФормыОбъекта(ОбъектПечати, ЗаданныеИменаПечатныхФорм, НазваниеПечатнойФормы) + "." + РасширениеФайла;
				Если НастройкиСохранения.ПереводитьИменаФайловВТранслит Тогда
					ИмяФайла = СтроковыеФункции.СтрокаЛатиницей(ИмяФайла)
				КонецЕсли;
				ИмяФайла = ОбщегоНазначенияКлиентСервер.ЗаменитьНедопустимыеСимволыВИмениФайла(ИмяФайла);

				Файл = Результат.Добавить();
				Файл.ИмяФайла = ИмяФайла;
				Файл.ДвоичныеДанные = ТабличныйДокументВДвоичныеДанные(ТабличныйДокумент, ТипФайла);
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;

КонецПроцедуры

Функция ИспользуемыйТипФайлаТабличногоДокумента(ТипФайла)

	Если ТипФайла = ТипФайлаТабличногоДокумента.PDF
		Или Строка(ТипФайла) = "PDF_A_1"
		Или Строка(ТипФайла) = "PDF_A_2"
		Или Строка(ТипФайла) = "PDF_A_3" Тогда
		Возврат СтандартныеПодсистемыСервер.ТипФайлаТабличногоДокументаPDF();
	КонецЕсли;

	ЗаменяемыеТипы = Новый Соответствие;
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.HTML, ТипФайлаТабличногоДокумента.HTML5);
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.HTML3, ТипФайлаТабличногоДокумента.HTML5);
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.HTML4, ТипФайлаТабличногоДокумента.HTML5);
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.MXL7, ТипФайлаТабличногоДокумента.MXL);
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.XLS95, ТипФайлаТабличногоДокумента.XLS);
	ЗаменяемыеТипы.Вставить(ТипФайлаТабличногоДокумента.XLS97, ТипФайлаТабличногоДокумента.XLS);

	Результат = ЗаменяемыеТипы[ТипФайла];
	Если Результат = Неопределено Тогда
		Результат = ТипФайла;
	КонецЕсли;

	Возврат Результат;

КонецФункции

Функция МакетыПечатныхФорм(ТолькоОбработкиИОтчеты = Ложь) Экспорт

	Результат = Новый Соответствие;

	КоллекцииОбъектовМетаданных = Новый Массив; // Массив из КоллекцияОбъектовМетаданных -
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Обработки);
	КоллекцииОбъектовМетаданных.Добавить(Метаданные.Отчеты);
	Если Не ТолькоОбработкиИОтчеты Тогда
		КоллекцииОбъектовМетаданных.Добавить(Метаданные.Справочники);
		КоллекцииОбъектовМетаданных.Добавить(Метаданные.Документы);
		КоллекцииОбъектовМетаданных.Добавить(Метаданные.БизнесПроцессы);
		КоллекцииОбъектовМетаданных.Добавить(Метаданные.Задачи);
		КоллекцииОбъектовМетаданных.Добавить(Метаданные.ЖурналыДокументов);
	КонецЕсли;

	Для Каждого КоллекцияОбъектовМетаданных Из КоллекцииОбъектовМетаданных Цикл
		Для Каждого ОбъектМетаданныхКоллекции Из КоллекцияОбъектовМетаданных Цикл
			ОбъектМетаданных = ОбъектМетаданныхКоллекции; // ОбъектМетаданныхДокумент -
			Для Каждого Макет Из ОбъектМетаданных.Макеты Цикл
				Если СтрНайти(Макет.Имя, "ПФ_") > 0 Тогда
					Если (КоллекцияОбъектовМетаданных = Метаданные.Обработки Или КоллекцияОбъектовМетаданных = Метаданные.Отчеты)
						И Не ПравоДоступа("Просмотр", ОбъектМетаданных) Тогда
						Продолжить;
					КонецЕсли;
					Результат.Вставить(Макет, ОбъектМетаданных);
				КонецЕсли;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;

	Для Каждого Макет Из Метаданные.ОбщиеМакеты Цикл
		Если СтрНайти(Макет.Имя, "ПФ_") > 0 Тогда
			Результат.Вставить(Макет, Метаданные.ОбщиеМакеты);
		КонецЕсли;
	КонецЦикла;

	Возврат Результат;

КонецФункции

// Возвращаемое значение:
//  ТабличныйДокумент, ДвоичныеДанные - макет.
//


[System] Ты пишешь корректный код на 1С:Enterprise Script и отвечаешь только кодом, если тебя просят дописать код.

[User]
Дополни код на 1С. Ниже начало процедура `ПодготовитьФормуДляОтложеннойИнициализации`.
Сохрани стиль и синтаксис, верни только готовый код без пояснений.

Процедура ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, Индекс)
ГруппаФормы = Форма.Элементы[ИмяЭлементаДляРазмещения];
	Если ГруппаФормы.Вид <> ВидГруппыФормы.Страница Тогда
		Родитель = СтраницаРодитель(ГруппаФормы);
	Иначе
		Родитель = ГруппаФормы;
	КонецЕсли;

	Если Родитель <> Неопределено
		И Не Форма.ПараметрыСвойств.Свойство(Родитель.Имя) Тогда
		ИмяДекорации = "Свойства_ПустаяДекорация" + Индекс;
		Форма.ПараметрыСвойств.КоллекцияДекораций.Добавить(ИмяДекорации);
		Декорация = Форма.Элементы.Добавить(ИмяДекорации, Тип("ДекорацияФормы"), ГруппаФормы);

		ГруппаСтраниц = Родитель.Родитель;
		ЗаголовокСтраницы = ?(ЗначениеЗаполнено(Родитель.Заголовок), Родитель.Заголовок, Родитель.Имя);
		ЗаголовокГруппыСтраниц = ?(ЗначениеЗаполнено(ГруппаСтраниц.Заголовок), ГруппаСтраниц.Заголовок, ГруппаСтраниц.Имя);

		ПредупреждениеОРазмещении = НСтр("ru = 'Для отображения дополнительных реквизитов разместите группу ""%1"" не первым элементом (после любой другой группы) в группе ""%2"" (меню Еще - Изменить форму).'");
		ПредупреждениеОРазмещении = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПредупреждениеОРазмещении,
			ЗаголовокСтраницы, ЗаголовокГруппыСтраниц);
    // TODO: допиши оставшуюся часть

[Assistant]
Процедура ПодготовитьФормуДляОтложеннойИнициализации(Форма, ИмяЭлементаДляРазмещения, Индекс)

	ГруппаФормы = Форма.Элементы[ИмяЭлементаДляРазмещения];
	Если ГруппаФормы.Вид <> ВидГруппыФормы.Страница Тогда
		Родитель = СтраницаРодитель(ГруппаФормы);
	Иначе
		Родитель = ГруппаФормы;
	КонецЕсли;

	Если Родитель <> Неопределено
		И Не Форма.ПараметрыСвойств.Свойство(Родитель.Имя) Тогда
		ИмяДекорации = "Свойства_ПустаяДекорация" + Индекс;
		Форма.ПараметрыСвойств.КоллекцияДекораций.Добавить(ИмяДекорации);
		Декорация = Форма.Элементы.Добавить(ИмяДекорации, Тип("ДекорацияФормы"), ГруппаФормы);

		ГруппаСтраниц = Родитель.Родитель;
		ЗаголовокСтраницы = ?(ЗначениеЗаполнено(Родитель.Заголовок), Родитель.Заголовок, Родитель.Имя);
		ЗаголовокГруппыСтраниц = ?(ЗначениеЗаполнено(ГруппаСтраниц.Заголовок), ГруппаСтраниц.Заголовок, ГруппаСтраниц.Имя);

		ПредупреждениеОРазмещении = НСтр("ru = 'Для отображения дополнительных реквизитов разместите группу ""%1"" не первым элементом (после любой другой группы) в группе ""%2"" (меню Еще - Изменить форму).'");
		ПредупреждениеОРазмещении = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ПредупреждениеОРазмещении,
			ЗаголовокСтраницы, ЗаголовокГруппыСтраниц);
		ТекстПодсказки = НСтр("ru = 'Также можно установить стандартные настройки формы:
			|   • в меню Еще выбрать пункт Изменить форму...;
			|   • в открывшейся форме ""Настройка формы"" в меню Еще выбрать пункт ""Установить стандартные настройки"".'");

		Декорация.ОтображениеПодсказки = ОтображениеПодсказки.Кнопка;
		Декорация.Заголовок  = ПредупреждениеОРазмещении;
		Декорация.Подсказка  = ТекстПодсказки;
		Декорация.ЦветТекста = ЦветаСтиля.ПоясняющийОшибкуТекст;

		// Страница, на которой размещаются дополнительные реквизиты.
		Форма.ПараметрыСвойств.Вставить(Родитель.Имя);
	КонецЕсли;

	ГруппаФормы.РазрешитьИзменениеСостава = Ложь;

КонецПроцедуры

// Заполняет легенду меток в форме владельца свойств.
//
// Параметры:
//  Форма              - ФормаКлиентскогоПриложения - уже настроена в процедуре ПриСозданииНаСервере.
//
//  Объект             - Неопределено - взять объект из реквизита формы "Объект".
//                     - СправочникОбъектИмяСправочника
//                     - ДокументОбъектИмяДокумента
//                     - ПланВидовХарактеристикОбъектИмяПланаВидовХарактеристик
//                     - БизнесПроцессОбъектИмяБизнесПроцесса
//                     - ЗадачаОбъектИмяЗадачи
//                     - ПланВидовРасчетаОбъектИмяПланаВидовРасчета
//                     - ПланСчетовОбъектИмяПланаСчетов
//                     - ДанныеФормыСтруктура
//

Процедура ЗаполнитьЛегендуМеток(Форма, Объект)

	Если НЕ Форма.Свойства_ИспользоватьСвойства
	 ИЛИ НЕ Форма.Свойства_ИспользоватьДопРеквизиты Тогда
		Возврат;
	КонецЕсли;

	ИмяЭлементаДляРазмещенияЛегендыМеток = Форма.Свойства_ИмяЭлементаДляРазмещенияЛегендыМеток;
	Если Не ЗначениеЗаполнено(ИмяЭлементаДляРазмещенияЛегендыМеток) Тогда
		Возврат;
	КонецЕсли;

	Метки = УправлениеСвойствамиСлужебный.СписокСвойствДляВидаОбъектов(
		Форма.ПараметрыСвойств.ВидОбъектов, "Метки").ВыгрузитьКолонку("Свойство");
	Если Метки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	ВидимостьЛегендыМеток = ХранилищеОбщихНастроек.Загрузить("Свойства", "ВидимостьЛегендыМеток");

	Если ВидимостьЛегендыМеток = Неопределено Тогда
		ВидимостьЛегендыМеток = Ложь;
		ОбщегоНазначения.ХранилищеОбщихНастроекСохранить("Свойства", "ВидимостьЛегендыМеток", ВидимостьЛегендыМеток);
	КонецЕсли;

	НовыйЭлемент = Форма.Элементы.Добавить("ПоказатьЛегенду", Тип("ДекорацияФормы"),
		Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток]);
	НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
	НовыйЭлемент.Гиперссылка = Истина;
	НовыйЭлемент.УстановитьДействие("Нажатие", "Подключаемый_УстановитьВидимостьЛегендыМеток");
	Если ВидимостьЛегендыМеток Тогда
		НовыйЭлемент.Картинка = БиблиотекаКартинок.СтрелкаВправоЗеленая;
	Иначе
		НовыйЭлемент.Картинка = БиблиотекаКартинок.СтрелкаВнизЗеленая;
	КонецЕсли;

	ГруппаСкрываемаяЧастьЛегенды = Форма.Элементы.Добавить("ГруппаСкрываемаяЧастьЛегенды", Тип("ГруппаФормы"),
		Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток]);
	ГруппаСкрываемаяЧастьЛегенды.Вид = ВидГруппыФормы.ОбычнаяГруппа;
	ГруппаСкрываемаяЧастьЛегенды.Видимость = ВидимостьЛегендыМеток;
	ГруппаСкрываемаяЧастьЛегенды.ОтображатьЗаголовок = Ложь;
	ГруппаСкрываемаяЧастьЛегенды.Группировка = Форма.Элементы[ИмяЭлементаДляРазмещенияЛегендыМеток].Группировка;

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

	Для Каждого Метка Из Метки Цикл
		Метка = РеквизитыМеток.Получить(Метка);
		Если Метка = Неопределено Или Метка.ПометкаУдаления Тогда
			Продолжить;
		КонецЕсли;

		Группа = Форма.Элементы.Добавить("Группа" + Метка.Имя, Тип("ГруппаФормы"), ГруппаСкрываемаяЧастьЛегенды);
		Группа.Вид = ВидГруппыФормы.ОбычнаяГруппа;
		Группа.ОтображатьЗаголовок = Ложь;
		Группа.Группировка = ГруппировкаПодчиненныхЭлементовФормы.ГоризонтальнаяВсегда;

		МеткаЛегенды = Форма.Свойства_ОписаниеЛегендыМеток.Добавить();
		МеткаЛегенды.Метка = Метка.Ссылка;
		МеткаЛегенды.ИмяМетки = Метка.Имя;

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

		НовыйЭлемент = Форма.Элементы.Добавить("Легенда_" + Метка.Имя, Тип("ДекорацияФормы"), Группа);
		НовыйЭлемент.Вид = ВидДекорацииФормы.Картинка;
		НовыйЭлемент.Картинка = КартинкаМеткиПоЦвету(Метка.ЦветСвойств);
		НовыйЭлемент.Подсказка = Метка.Наименование;
		НовыйЭлемент.ОтображениеПодсказки = ОтображениеПодсказки.ОтображатьСправа;
	КонецЦикла;

КонецПроцедуры

Функция СтраницаРодитель(ГруппаФормы)

	Родитель = ГруппаФормы.Родитель;
	Если ТипЗнч(Родитель) = Тип("ГруппаФормы") Тогда
		Родитель.РазрешитьИзменениеСостава = Ложь;
		Если Родитель.Вид = ВидГруппыФормы.Страница Тогда
			Возврат Родитель;
		Иначе
			Возврат СтраницаРодитель(Родитель);
		КонецЕсли;
	КонецЕсли;

	Возврат Неопределено;

КонецФункции

Процедура ОбновитьКлючНазначенияФормы(Форма, КлючНазначения)

	Если КлючНазначения = Неопределено Тогда
		КлючНазначения = КлючНаборовСвойств(Форма.Свойства_НаборыДополнительныхРеквизитовОбъекта);
	КонецЕсли;

	Если ПустаяСтрока(КлючНазначения) Тогда
		Возврат;
	КонецЕсли;

	НачалоКлюча = "КлючНаборовСвойств";
	КлючНаборовСвойств = НачалоКлюча + Лев(КлючНазначения + "00000000000000000000000000000000", 32);

	НовыйКлюч = НовыйКлючНазначения(Форма.КлючНазначенияИспользования, НачалоКлюча, КлючНаборовСвойств);
	Если НовыйКлюч <> Неопределено Тогда
		Форма.КлючНазначенияИспользования = НовыйКлюч;
	КонецЕсли;

КонецПроцедуры

Функция РезультатВычисленияУсловия(Форма, ОписаниеОбъекта, Параметры)
	ПараметрыУсловия = Новый Структура;
	ПараметрыУсловия.Вставить("ЗначенияПараметров", Параметры.ЗначенияПараметров);
	ПараметрыУсловия.Вставить("Форма", Форма);
	ПараметрыУсловия.Вставить("ОписаниеОбъекта", ОписаниеОбъекта);

	Возврат ОбщегоНазначения.ВычислитьВБезопасномРежиме(Параметры.КодУсловия, ПараметрыУсловия);
КонецФункции