Анкета / Форма документа / Модуль формы

файл
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2024, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	ЭтоСеансОбычногоПользователя = Не Пользователи.ЭтоСеансВнешнегоПользователя();
	Если Не ЭтоСеансОбычногоПользователя И Не Объект.Ссылка.Пустая() 
		И Объект.Респондент <> ВнешниеПользователи.ПолучитьОбъектАвторизацииВнешнегоПользователя() Тогда
		Отказ = Истина;
		Возврат;
	КонецЕсли;

	ОбновлениеИнформационнойБазы.ПроверитьОбъектОбработан(Объект, ЭтотОбъект);

	Если Объект.РежимАнкетирования = Перечисления.РежимыАнкетирования.Интервью Тогда

		Если Не Объект.ШаблонАнкеты.Пустая() Тогда
			РеквизитыОпрос = ЗначенияРеквизитовШаблонаАнкеты(Объект.ШаблонАнкеты);
			УстановитьЗначенияРеквизитовСогласноОпросу(РеквизитыОпрос);
		КонецЕсли;

		ВозможностьПредварительногоСохранения = Параметры.ВозможностьПредварительногоСохранения;

	КонецЕсли;

	Если Не Объект.Опрос.Пустая() Тогда
		РеквизитыОпрос = ЗначенияРеквизитовНазначенияОпроса(Объект.Опрос);
		УстановитьЗначенияРеквизитовСогласноОпросу(РеквизитыОпрос);
		Объект.ШаблонАнкеты = ШаблонАнкеты;
	КонецЕсли;

	Если ШаблонАнкеты.Пустая() Тогда
		Отказ = Истина;
		Возврат;
	КонецЕсли;

	Если Параметры.ТолькоФормаЗаполнения Тогда
		АвтоЗаголовок = Ложь;
		УстановитьЗаголовкиНадписей(РеквизитыОпрос);
	КонецЕсли;

	Анкетирование.УстановитьЭлементДереваРазделовАнкетыВступлениеЗаключение(ДеревоРазделов, 
		НСтр("ru = 'Вступление'"), "Вступление");
	Анкетирование.ЗаполнитьДеревоРазделов(ЭтотОбъект, ДеревоРазделов);
	Анкетирование.УстановитьЭлементДереваРазделовАнкетыВступлениеЗаключение(ДеревоРазделов, 
		НСтр("ru = 'Заключение'"), "Заключение");
	АнкетированиеКлиентСервер.СформироватьНумерациюДерева(ДеревоРазделов, Истина);

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

	Элементы.ПредыдущийРазделПодвал.Видимость = Ложь;
	Элементы.СледующийРазделПодвал.Видимость  = Ложь;

	УстановитьВидимостьДоступностьЭлементовФормы();

	Элементы.ГруппаДеревоРазделов.Видимость = Ложь;
	ЗаголовокКомандаРазделы = НСтр("ru = 'Показать разделы'");
	Элементы.СкрытьПоказатьДеревоРазделов.Заголовок = ЗаголовокКомандаРазделы;

	ИзменитьВидимостьЭлементовФормы(ЭтотОбъект);
		
	// СтандартныеПодсистемы.ПодключаемыеКоманды
	ПодключаемыеКоманды.ПриСозданииНаСервере(ЭтотОбъект);
	// Конец СтандартныеПодсистемы.ПодключаемыеКоманды

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

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

&НаКлиенте
Процедура ПриОткрытии(Отказ)

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

	Если (Не ТолькоПросмотр) Тогда
		УправлениеДоступностьюПодчиненныеВопросы(Ложь);
	КонецЕсли;
	
	// СтандартныеПодсистемы.ПодключаемыеКоманды
	ПодключаемыеКомандыКлиент.НачатьОбновлениеКоманд(ЭтотОбъект);
	// Конец СтандартныеПодсистемы.ПодключаемыеКоманды

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

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)

	Если Элементы.ГруппаТелоАнкеты.ТолькоПросмотр Тогда
		Модифицированность = Ложь;
	КонецЕсли;

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

&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)

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

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

&НаКлиенте
Процедура ПослеЗаписи(ПараметрыЗаписи)

	ПоказатьОповещениеПользователя(НСтр("ru = 'Изменение'"),, Строка(Объект.Ссылка), БиблиотекаКартинок.ДиалогИнформация);

	Оповестить("Запись_Анкета", Новый Структура, Объект.Ссылка);

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

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

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура РеспондентНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

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

	ОткрытьФорму(ИмяМетаданныхРеспондент + ".ФормаВыбора", Новый Структура("МассивОтбора", МассивОтбора), Элемент);

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

&НаКлиенте
Процедура Подключаемый_ПриИзмененииВопросовСУсловием(Элемент)

	УправлениеДоступностьюПодчиненныеВопросы();

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

&НаКлиенте
Процедура Подключаемый_ПриИзмененииВопроса(Элемент)

	Модифицированность = Истина;
	АнкетированиеКлиент.ПриИзмененииВопроса(ЭтотОбъект, Элемент);

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

&НаКлиенте
Процедура Подключаемый_ПриИзмененииПолосыРегулирования(Элемент)

	Модифицированность = Истина;
	АнкетированиеКлиент.ПриИзмененииПолосыРегулирования(ЭтотОбъект, Элемент);

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

&НаКлиенте
Процедура Подключаемый_ПриИзмененииПоляЧисло(Элемент)

	Модифицированность = Истина;
	АнкетированиеКлиент.ПриИзмененииПоляЧисло(ЭтотОбъект, Элемент);

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

&НаКлиенте
Процедура Подключаемый_РегулированиеПоляЧисло(Элемент, Направление, СтандартнаяОбработка)

	Модифицированность = Истина;
	АнкетированиеКлиент.РегулированиеПоляЧисло(ЭтотОбъект, Элемент, Направление, СтандартнаяОбработка);

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

&НаКлиенте
Процедура Подключаемый_НачалоВыбораТекстовыхЯчеекТабличныхВопросов(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	СтандартнаяОбработка = Ложь;

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

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

&НаКлиенте
Процедура Подключаемый_НачалоВыбораКомментарий(Элемент, ДанныеВыбора, СтандартнаяОбработка)

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

	ОбщегоНазначенияКлиент.ПоказатьФормуРедактированияКомментария(
		Элемент.ТекстРедактирования, ЭтотОбъект, Элемент.Имя, Элемент.ПодсказкаВвода);

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

&НаКлиенте
Процедура Подключаемый_ПриИзмененииФлагаНеОтвечатьНаВопрос(Элемент)

	Модифицированность = Истина;
	АнкетированиеКлиент.ПриИзмененииФлагаНеОтвечатьНаВопрос(ЭтотОбъект, Элемент);

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

&НаКлиенте
Процедура ДеревоРазделовВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)

	ТекущиеДанные = Элементы.ДеревоРазделов.ТекущиеДанные;
	Если ТекущиеДанные = Неопределено Тогда
		Возврат;
	КонецЕсли;

	ВыполнитьПостроениеФормыЗаполнения();
	УстановитьДоступностьНавигацииРазделов();

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

&НаКлиенте
Процедура КомментарийНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	ОбщегоНазначенияКлиент.ПоказатьФормуРедактированияКомментария(Элемент.ТекстРедактирования, ЭтотОбъект);

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

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура ФормаЗаполненияЗаписать(Команда)

	Отказ = ОкончаниеРедактированиеФормыЗаполнения(РежимЗаписиДокумента.Запись);
	Если Не Отказ Тогда

		ПоказатьОповещениеПользователя(НСтр("ru = 'Изменение'"),, Строка(Объект.Ссылка),
			БиблиотекаКартинок.ДиалогИнформация);

		Оповестить("Запись_Анкета", Новый Структура, Объект.Ссылка);

	КонецЕсли;

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

&НаКлиенте
Процедура ФормаЗаполненияЗавершитьИЗакрыть(Команда)

	ОбработчикОповещенияОЗакрытии = Новый ОписаниеОповещения("ВопросОПринятииАнкетыПослеЗавершения", ЭтотОбъект);
	ПоказатьВопрос(ОбработчикОповещенияОЗакрытии, 
		НСтр("ru = 'Ваша анкета будет принята. 
			|Дальнейшее заполнение анкеты будет невозможно.
			|Продолжить?'"), РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте
Процедура ПоказатьРазделы(Команда)

	ИзменитьВидимостьДеревоРазделов();

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

&НаКлиенте
Процедура СледующийРаздел(Команда)

	ИзменитьРаздел("Вперед");

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

&НаКлиенте
Процедура ПредыдущийРаздел(Команда)

	ИзменитьРаздел("Назад");

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

&НаКлиенте
Процедура ВыборРаздела(Команда)

	ВыполнитьПостроениеФормыЗаполнения();
	УстановитьДоступностьНавигацииРазделов();

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

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

#Область УстановкаЗначенийРеквизитовФормы

&НаСервере
Процедура УстановитьЗначенияРеквизитовФормыЗаполненияРаздела()

	ТаблицаВопросовРаздела.Выгрузить().ВыгрузитьКолонку("ВопросШаблона");

	Запрос = Новый Запрос;
	Запрос.Текст = 
		"ВЫБРАТЬ
		|	ВнешнийИсточник.Вопрос КАК Вопрос,
		|	ВЫРАЗИТЬ(ВнешнийИсточник.ЭлементарныйВопрос КАК ПланВидовХарактеристик.ВопросыДляАнкетирования) КАК ЭлементарныйВопрос,
		|	ВнешнийИсточник.НомерЯчейки КАК НомерЯчейки,
		|	ВнешнийИсточник.Ответ КАК Ответ,
		|	ВнешнийИсточник.ОткрытыйОтвет КАК ОткрытыйОтвет,
		|	ВнешнийИсточник.БезОтвета КАК БезОтвета
		|ПОМЕСТИТЬ ТаблицаОтветов
		|ИЗ
		|	&ВнешнийИсточник КАК ВнешнийИсточник
		|ГДЕ
		|	ВнешнийИсточник.Вопрос В(&ВопросыРаздела)
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ТаблицаОтветов.Вопрос КАК Вопрос,
		|	ТаблицаОтветов.ЭлементарныйВопрос КАК ЭлементарныйВопрос,
		|	ТаблицаОтветов.НомерЯчейки КАК НомерЯчейки,
		|	ТаблицаОтветов.Ответ КАК Ответ,
		|	ТаблицаОтветов.ОткрытыйОтвет КАК ОткрытыйОтвет,
		|	ТаблицаОтветов.ЭлементарныйВопрос.ТребуетсяКомментарий КАК ТребуетОткрытогоОтвета,
		|	ТаблицаОтветов.БезОтвета КАК БезОтвета
		|ИЗ
		|	ТаблицаОтветов КАК ТаблицаОтветов
		|ИТОГИ ПО
		|	Вопрос";

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

	Результат = Запрос.Выполнить();
	Если Не Результат.Пустой() Тогда

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

			ВыборкаВопрос = Выборка.Выбрать();
			УстановитьЗначениеРеквизита(Выборка.Вопрос, ВыборкаВопрос);

		КонецЦикла;

	КонецЕсли;

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

// Параметры:
//  ВопросШаблона  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  ДеревоАнкетыСервер  - ДеревоЗначений - дерево значений, содержащее шаблон анкеты.
//
&НаСервере
Процедура УстановитьЗначениеРеквизита(ВопросШаблона, ВыборкаВопрос)

	НайденныеСтроки = ТаблицаВопросовРаздела.НайтиСтроки(Новый Структура("ВопросШаблона", ВопросШаблона));

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

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначениеРеквизитаПростойВопрос(Вопрос, ВыборкаВопрос, СтрокаДерева)

	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);

	Если СтрокаДерева.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.НесколькоВариантовИз Тогда

		ВариантыОтветовНаВопрос = Анкетирование.ВариантыОтветовНаВопрос(СтрокаДерева.ЭлементарныйВопрос, ЭтотОбъект);

		Пока ВыборкаВопрос.Следующий() Цикл

			ПараметрыОтвета = НайтиОтветВМассиве(ВыборкаВопрос.Ответ, ВариантыОтветовНаВопрос);

			Если ПараметрыОтвета <> Неопределено Тогда
				ЭтотОбъект[ИмяВопроса + "_Реквизит_" + ПараметрыОтвета.ПорядковыйНомерРеквизита] = Истина;
				Если ПараметрыОтвета.ТребуетОткрытогоОтвета Тогда

					ЭтотОбъект[ИмяВопроса + "_Комментарий_" + ПараметрыОтвета.ПорядковыйНомерРеквизита] = 
						ВыборкаВопрос.ОткрытыйОтвет;

				КонецЕсли;
			КонецЕсли;

		КонецЦикла;

	Иначе

		Если ВыборкаВопрос.Следующий() Тогда

			Если СтрокаДерева.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.Текст Тогда

				ЭтотОбъект[ИмяВопроса] = ВыборкаВопрос.ОткрытыйОтвет;

			Иначе

				ЭтотОбъект[ИмяВопроса] = ВыборкаВопрос.Ответ;

				Если СтрокаДерева.ПоказыватьПолосуРегулирования Тогда
					ЭтотОбъект[ИмяВопроса + "_ПолосаРегулированияРеквизит"] = (ЭтотОбъект[ИмяВопроса]
						- СтрокаДерева.МинимальноеЗначение) / СтрокаДерева.ШагПолосыРегулирования;
				КонецЕсли;

				Если (СтрокаДерева.ТребуетсяКомментарий) Тогда
					ЭтотОбъект[ИмяВопроса + "_Комментарий"] = ВыборкаВопрос.ОткрытыйОтвет;
				КонецЕсли;

			КонецЕсли;

			Если СтрокаДерева.ИспользоватьОтказОтОтвета Тогда
				ЭтотОбъект[ИмяВопроса + "_ИспользоватьОтказОтОтвета"] = ВыборкаВопрос.БезОтвета;
			КонецЕсли;

		КонецЕсли;

	КонецЕсли;

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначениеРеквизитаТабличныйВопрос(Вопрос, ВыборкаВопрос, СтрокаДерева)

	Если СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.Составной Тогда

		УстановитьЗначенияРеквизитаТабличныйВопросСоставной(Вопрос, ВыборкаВопрос, СтрокаДерева);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтроках Тогда

		УстановитьЗначенияРеквизитаТабличныйВопросОтветыВСтроках(Вопрос, ВыборкаВопрос, СтрокаДерева);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВКолонках Тогда

		УстановитьЗначенияРеквизитаТабличныйВопросОтветыВКолонках(Вопрос, ВыборкаВопрос, СтрокаДерева);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтрокахИКолонках Тогда

		УстановитьЗначенияРеквизитаТабличныйВопросОтветыВСтрокахКолонках(Вопрос, ВыборкаВопрос, СтрокаДерева);

	КонецЕсли;

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначенияРеквизитаТабличныйВопросСоставной(Вопрос, ВыборкаВопрос, СтрокаДерева)

	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ИмяТаблицы = ИмяВопроса + "_Таблица";
	Таблица    = РеквизитФормыВЗначение(ИмяТаблицы);

	ВопросыАнкеты = СтрокаДерева.СоставТабличногоВопроса.Выгрузить().ВыгрузитьКолонку("ЭлементарныйВопрос");

	Пока ВыборкаВопрос.Следующий() Цикл

		Если ВопросыАнкеты.Найти(ВыборкаВопрос.ЭлементарныйВопрос) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

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

		НомерВопросаВМассиве = ВопросыАнкеты.Найти(ВыборкаВопрос.ЭлементарныйВопрос);
		Если НомерВопросаВМассиве <> Неопределено Тогда
			Таблица[ВыборкаВопрос.НомерЯчейки - 1][НомерВопросаВМассиве] = ВыборкаВопрос.Ответ;
		КонецЕсли;

	КонецЦикла;

	ЗначениеВРеквизитФормы(Таблица, ИмяТаблицы);

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначенияРеквизитаТабличныйВопросОтветыВСтроках(Вопрос, ВыборкаВопрос, СтрокаДерева)
	
	ИмяВопроса          = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ИмяТаблицы          = ИмяВопроса + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";
	Таблица             = РеквизитФормыВЗначение(ИмяТаблицы);

	ВопросыАнкеты = СтрокаДерева.СоставТабличногоВопроса.Выгрузить().ВыгрузитьКолонку("ЭлементарныйВопрос");
	Пока ВыборкаВопрос.Следующий() Цикл

		НомерВопроса = ВопросыАнкеты.Найти(ВыборкаВопрос.ЭлементарныйВопрос);
		Если (НомерВопроса <> Неопределено) И (ВыборкаВопрос.НомерЯчейки <= Таблица.Количество()) Тогда
			Таблица[ВыборкаВопрос.НомерЯчейки - 1][ИмяКолонкиБезНомера + XMLСтрока(НомерВопроса + 1)] = ВыборкаВопрос.Ответ;
		КонецЕсли;

	КонецЦикла;

	ЗначениеВРеквизитФормы(Таблица, ИмяТаблицы);

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначенияРеквизитаТабличныйВопросОтветыВКолонках(Вопрос, ВыборкаВопрос, СтрокаДерева)
	
	ИмяВопроса          = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ИмяТаблицы          = ИмяВопроса + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";
	Таблица             = РеквизитФормыВЗначение(ИмяТаблицы);

	ВопросыАнкеты = СтрокаДерева.СоставТабличногоВопроса.Выгрузить().ВыгрузитьКолонку("ЭлементарныйВопрос");
	ВопросыАнкеты.Удалить(0);

	Пока ВыборкаВопрос.Следующий() Цикл

		НомерВопроса = ВопросыАнкеты.Найти(ВыборкаВопрос.ЭлементарныйВопрос);
		Если (НомерВопроса <> Неопределено) Тогда
			Если (НомерВопроса <= Таблица.Количество()) И (ВыборкаВопрос.НомерЯчейки <= Таблица.Колонки.Количество()) Тогда
				Таблица[НомерВопроса][ИмяКолонкиБезНомера + XMLСтрока(ВыборкаВопрос.НомерЯчейки + 1)] = ВыборкаВопрос.Ответ;
			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

	ЗначениеВРеквизитФормы(Таблица, ИмяТаблицы);

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//            для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                  на вопрос шаблона анкеты.
//  СтрокаДерева - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначенияРеквизитаТабличныйВопросОтветыВСтрокахКолонках(Вопрос, ВыборкаВопрос, СтрокаДерева)

	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ИмяТаблицы = ИмяВопроса + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";
	Таблица = РеквизитФормыВЗначение(ИмяТаблицы);
	КоличествоКолонок = Таблица.Колонки.Количество();

	ВопросЯчейка = СтрокаДерева.СоставТабличногоВопроса[2].ЭлементарныйВопрос;

	Пока ВыборкаВопрос.Следующий() Цикл
		Если ВыборкаВопрос.ЭлементарныйВопрос = ВопросЯчейка Тогда
			НомерКолонки = ?(ВыборкаВопрос.НомерЯчейки % (КоличествоКолонок - 1) = 0, КоличествоКолонок - 1,
				ВыборкаВопрос.НомерЯчейки % (КоличествоКолонок - 1));
			НомерСтроки  = ЦЕЛ((ВыборкаВопрос.НомерЯчейки + ЦЕЛ(ВыборкаВопрос.НомерЯчейки / КоличествоКолонок)) / КоличествоКолонок);
			Таблица[НомерСтроки][ИмяКолонкиБезНомера + XMLСтрока(НомерКолонки + 1)] = ВыборкаВопрос.Ответ;
		КонецЕсли;
	КонецЦикла;

	ЗначениеВРеквизитФормы(Таблица, ИмяТаблицы);

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

// Параметры:
//  Вопрос  - СправочникСсылка.ВопросыШаблонаАнкеты - вопрос шаблона анкеты, 
//                 для которого устанавливаются значения реквизитов.
//  ВыборкаВопрос  - ВыборкаИзРезультатаЗапроса - выборка, содержащая значения ответов 
//                 на вопрос шаблона анкеты.
//  СтрокаДерева  - СтрокаДереваЗначений - строка дерева значений, содержащая данные вопроса шаблона анкеты.
//
&НаСервере
Процедура УстановитьЗначенияРеквизитаКомплексныйВопрос(Вопрос, ВыборкаВопрос, СтрокаДерева)
	
	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ВопросыАнкеты = СтрокаДерева.СоставКомплексногоВопроса.Выгрузить().ВыгрузитьКолонку("ЭлементарныйВопрос");

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

		Если ВопросыАнкеты.Найти(ВыборкаВопрос.ЭлементарныйВопрос) = Неопределено Тогда
			Продолжить;
		КонецЕсли;

		СтрокиВопроса = СтрокаДерева.СоставКомплексногоВопроса.НайтиСтроки(Новый Структура("ЭлементарныйВопрос",
			ВыборкаВопрос.ЭлементарныйВопрос));
		НомерСтроки = СтрокиВопроса[0].НомерСтроки;
		ИмяРеквизита =  ИмяВопроса + "_Ответ_" + Формат(НомерСтроки, "ЧГ=");

		Если ВыборкаВопрос.ЭлементарныйВопрос.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.НесколькоВариантовИз Тогда

			ВариантыОтветовНаВопрос = Анкетирование.ВариантыОтветовНаВопрос(ВыборкаВопрос.ЭлементарныйВопрос,
				ЭтотОбъект);

			ПараметрыОтвета = НайтиОтветВМассиве(ВыборкаВопрос.Ответ, ВариантыОтветовНаВопрос);
			Если ПараметрыОтвета <> Неопределено Тогда
				ЭтотОбъект[ИмяРеквизита + "_Реквизит_" + ПараметрыОтвета.ПорядковыйНомерРеквизита] = Истина;
				Если ПараметрыОтвета.ТребуетОткрытогоОтвета Тогда
					ЭтотОбъект[ИмяРеквизита + "_Комментарий_" + ПараметрыОтвета.ПорядковыйНомерРеквизита] = ВыборкаВопрос.ОткрытыйОтвет;
				КонецЕсли;
			КонецЕсли;

		ИначеЕсли ВыборкаВопрос.ЭлементарныйВопрос.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.Текст Тогда
			ЭтотОбъект[ИмяРеквизита] = ВыборкаВопрос.ОткрытыйОтвет;
		Иначе
			ЭтотОбъект[ИмяРеквизита] = ВыборкаВопрос.Ответ;

			Если (ВыборкаВопрос.ТребуетОткрытогоОтвета) Тогда
				ЭтотОбъект[ИмяВопроса + "_Комментарий_" + Формат(НомерСтроки, "ЧГ=")] = ВыборкаВопрос.ОткрытыйОтвет;
			КонецЕсли;
		КонецЕсли;

	КонецЦикла;

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

#КонецОбласти

#Область ПреобразованиеРезультатовЗаполненияАнкетыВТабличнуюЧастьДокумента

&НаСервере
Функция ОкончаниеРедактированиеФормыЗаполнения(РежимЗаписи)

	ПреобразоватьРезультатыЗаполненияРазделаВТабличнуюЧасть();
	Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
		Если ПроверитьЗаполнениеАнкеты() Тогда
			Возврат Истина;
		КонецЕсли;
	КонецЕсли;

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

	Если РежимЗаписи = РежимЗаписиДокумента.Запись Тогда
		ЗначениеВРеквизитФормы(ДокументОбъект, "Объект");
		Модифицированность = Ложь;
	КонецЕсли;

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

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

&НаСервере
Процедура ПреобразоватьРезультатыЗаполненияРазделаВТабличнуюЧасть()

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

	ПредыдущийРазделБезВопросов = (ТаблицаВопросовРаздела.Количество() = 0);

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

		Если ЗначениеЗаполнено(СтрокаТаблицы.РодительВопрос) Тогда
			НайденныеСтроки = ТаблицаВопросовРаздела.НайтиСтроки(Новый Структура("ВопросШаблона",
				СтрокаТаблицы.РодительВопрос));
			Если НайденныеСтроки.Количество() > 0 Тогда
				СтрокаРодитель = НайденныеСтроки[0];
				Если (Не ЭтотОбъект[АнкетированиеКлиентСервер.ИмяВопроса(СтрокаРодитель.КлючСтроки)] = Истина) Тогда
					Продолжить;
				КонецЕсли;
			КонецЕсли;
		КонецЕсли;

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

	КонецЦикла;

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

// Параметры:
//   СтрокаДерева - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//
&НаСервере
Процедура ЗаполнитьТаблицуОтветовТабличныйВопрос(СтрокаДерева)

	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);
	ИмяТаблицы = ИмяВопроса + "_Таблица";
	Таблица = РеквизитФормыВЗначение(ИмяТаблицы);

	Если Таблица.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;

	Если СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.Составной Тогда

		ЗаполнитьОтветыТабличныйВопросСоставной(СтрокаДерева, Таблица);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтроках Тогда

		ЗаполнитьОтветыТабличныйВопросОтветыВСтроках(СтрокаДерева, Таблица);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВКолонках Тогда

		ЗаполнитьОтветыТабличныйВопросОтветыВКолонках(СтрокаДерева, Таблица);

	ИначеЕсли СтрокаДерева.ТипТабличногоВопроса = Перечисления.ТипыТабличныхВопросов.ПредопределенныеОтветыВСтрокахИКолонках Тогда

		ЗаполнитьОтветыТабличныйВопросОтветыВСтрокахИКолонках(СтрокаДерева, Таблица);

	КонецЕсли;

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

// Получает ответы, данные респондентом на составной табличный вопрос и аккумулирует их в общей
// таблице ответов.
//
// Параметры:
//  СтрокаДерева - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//  Таблица      - ТаблицаЗначений - таблица табличного вопроса.
//
&НаСервере
Процедура ЗаполнитьОтветыТабличныйВопросСоставной(СтрокаДерева, Таблица)

	Для ИндексКолонки = 0 По СтрокаДерева.СоставТабличногоВопроса.Количество() - 1 Цикл

		Для ИндексСтроки = 0 По Таблица.Количество() - 1 Цикл

			Ответ = Таблица[ИндексСтроки][ИндексКолонки];
			Если ЗначениеЗаполнено(Ответ) Тогда

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = СтрокаДерева.СоставТабличногоВопроса[ИндексКолонки].ЭлементарныйВопрос;
				НоваяСтрока.Ответ              = Ответ;
				НоваяСтрока.НомерЯчейки        = ИндексСтроки + 1;

			КонецЕсли;
		КонецЦикла;
	КонецЦикла;

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

// Получает ответы, данные респондентом на табличный вопрос с предопределенными ответами в строках и 
// аккумулирует их в общей таблице ответов.
//
// Параметры:
//  СтрокаДерева - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//  Таблица      - ТаблицаЗначений - таблица табличного вопроса.
//
&НаСервере
Процедура ЗаполнитьОтветыТабличныйВопросОтветыВСтроках(СтрокаДерева, Таблица)

	ВопросПерваяКолонка = СтрокаДерева.СоставТабличногоВопроса[0].ЭлементарныйВопрос;
	ИмяТаблицы          = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки) + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";

	Для ИндексСтроки = 0 По Таблица.Количество() - 1 Цикл

		ЕстьХотяБыОдинОтветУказанныйРеспондентом = Ложь;

		Для ИндексКолонки = 1 По СтрокаДерева.СоставТабличногоВопроса.Количество() - 1 Цикл

			Ответ = Таблица[ИндексСтроки][ИмяКолонкиБезНомера + XMLСтрока(ИндексКолонки + 1)];
			Если ЗначениеЗаполнено(Ответ) Тогда

				ЕстьХотяБыОдинОтветУказанныйРеспондентом = Истина;

				НоваяСтрока                    = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = СтрокаДерева.СоставТабличногоВопроса[ИндексКолонки].ЭлементарныйВопрос;
				НоваяСтрока.Ответ              = Ответ;
				НоваяСтрока.НомерЯчейки        = ИндексСтроки + 1;

			КонецЕсли;

		КонецЦикла;

		Если ЕстьХотяБыОдинОтветУказанныйРеспондентом Тогда

			Ответ = Таблица[ИндексСтроки][ИмяКолонкиБезНомера + "1"];
			Если ЗначениеЗаполнено(Ответ) Тогда

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = ВопросПерваяКолонка;
				НоваяСтрока.Ответ              = Ответ;
				НоваяСтрока.НомерЯчейки        = ИндексСтроки + 1;

			КонецЕсли;

		КонецЕсли;

	КонецЦикла;

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

// Получает ответы, данные респондентом на табличный вопрос с предопределенными ответами в строках и колонках и 
// аккумулирует их в общей таблице ответов.
//
// Параметры:
//  СтрокаДерева - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//  Таблица      - ТаблицаЗначений - таблица табличного вопроса.
//
&НаСервере
Процедура ЗаполнитьОтветыТабличныйВопросОтветыВСтрокахИКолонках(СтрокаДерева, Таблица)

	ВопросДляСтрок   = СтрокаДерева.СоставТабличногоВопроса[0].ЭлементарныйВопрос;
	ВопросДляКолонок = СтрокаДерева.СоставТабличногоВопроса[1].ЭлементарныйВопрос;
	ВопросДляЯчеек   = СтрокаДерева.СоставТабличногоВопроса[2].ЭлементарныйВопрос;

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

	ИмяТаблицы          = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки) + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";

	Для ИндексСтроки = 0 По Таблица.Количество() - 1 Цикл
		Для ИндексКолонки = 1 По Таблица.Колонки.Количество() - 1 Цикл

			Ответ = Таблица[ИндексСтроки][ИмяКолонкиБезНомера + XMLСтрока(ИндексКолонки + 1)];
			Если ЗначениеЗаполнено(Ответ) Тогда

				НомерЯчейки = ИндексКолонки + ИндексСтроки * (Таблица.Колонки.Количество() - 1);

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = ВопросДляСтрок;
				НоваяСтрока.Ответ              = ОтветыСтроки[ИндексСтроки].Ответ;
				НоваяСтрока.НомерЯчейки        = НомерЯчейки;

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = ВопросДляКолонок;
				НоваяСтрока.Ответ              = ОтветыКолонки[ИндексКолонки - 1].Ответ;
				НоваяСтрока.НомерЯчейки        = НомерЯчейки;

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = ВопросДляЯчеек;
				НоваяСтрока.Ответ              = Ответ;
				НоваяСтрока.НомерЯчейки        = НомерЯчейки;

			КонецЕсли;
		КонецЦикла;
	КонецЦикла;

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

// Получает ответы, данные респондентом на табличный вопрос с предопределенными ответами в колонках и 
// аккумулирует их в общей таблице ответов.
//
// Параметры:
//  СтрокаДерева - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//  Таблица      - ТаблицаЗначений - таблица табличного вопроса.
//
&НаСервере
Процедура ЗаполнитьОтветыТабличныйВопросОтветыВКолонках(СтрокаДерева, Таблица)

	ВопросДляКолонок = СтрокаДерева.СоставТабличногоВопроса[0].ЭлементарныйВопрос;
	ИмяТаблицы          = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки) + "_Таблица";
	ИмяКолонкиБезНомера = ИмяТаблицы + "_Колонка_";

	Для ИндексКолонки = 1 По Таблица.Колонки.Количество() - 1 Цикл

		ЕстьХотяБыОдинОтветУказанныйРеспондентом = Ложь;

		Для ИндексСтроки = 0 По Таблица.Количество() - 1 Цикл

			Ответ = Таблица[ИндексСтроки][ИмяКолонкиБезНомера + XMLСтрока(ИндексКолонки + 1)];
			Если ЗначениеЗаполнено(Ответ) Тогда

				ЕстьХотяБыОдинОтветУказанныйРеспондентом = Истина;

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = СтрокаДерева.СоставТабличногоВопроса[ИндексСтроки + 1].ЭлементарныйВопрос;
				НоваяСтрока.Ответ              = Ответ;
				НоваяСтрока.НомерЯчейки        = ИндексКолонки;

			КонецЕсли;

		КонецЦикла;

		Если ЕстьХотяБыОдинОтветУказанныйРеспондентом Тогда

			НоваяСтрока = Объект.Состав.Добавить();
			НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
			НоваяСтрока.ЭлементарныйВопрос = ВопросДляКолонок;
			НоваяСтрока.Ответ              = СтрокаДерева.ПредопределенныеОтветы[ИндексКолонки - 1].Ответ;
			НоваяСтрока.НомерЯчейки        = ИндексКолонки;

		КонецЕсли;

	КонецЦикла;

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

// Получает ответы, данные респондентом на простой вопрос и 
// аккумулирует их в общей таблице ответов.
//
// Параметры:
//  СтрокаДерева   - СтрокаДереваЗначений - строка дерева шаблона анкеты.
//
&НаСервере
Процедура ЗаполнитьОтветПростойВопрос(СтрокаДерева)

	ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаДерева.КлючСтроки);

	ОтказОтОтвета = Ложь;
	Если СтрокаДерева.ИспользоватьОтказОтОтвета Тогда
		ОтказОтОтвета = ЭтотОбъект[ИмяВопроса + "_ИспользоватьОтказОтОтвета"];
	КонецЕсли;

	Если СтрокаДерева.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.НесколькоВариантовИз Тогда

		ВариантыОтветовНаВопрос = Анкетирование.ВариантыОтветовНаВопрос(СтрокаДерева.ЭлементарныйВопрос, ЭтотОбъект);

		Счетчик = 0;
		Для Каждого ВариантОтвета Из ВариантыОтветовНаВопрос Цикл

			Счетчик = Счетчик + 1;
			ИмяРеквизита =  ИмяВопроса + "_Реквизит_" + Счетчик;

			Если ЭтотОбъект[ИмяРеквизита] Тогда

				НоваяСтрока = Объект.Состав.Добавить();
				НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
				НоваяСтрока.ЭлементарныйВопрос = СтрокаДерева.ЭлементарныйВопрос;
				НоваяСтрока.Ответ              = ВариантОтвета.Ответ;
				НоваяСтрока.НомерЯчейки        = Счетчик;
				Если ВариантОтвета.ТребуетОткрытогоОтвета Тогда
					НоваяСтрока.ОткрытыйОтвет	= ЭтотОбъект[ИмяВопроса + "_Комментарий_" + Счетчик];
				КонецЕсли;

			КонецЕсли;

		КонецЦикла;

	Иначе

		Ответ = ЭтотОбъект[ИмяВопроса];

		Если ЗначениеЗаполнено(Ответ) Или Анкетирование.РазрешенВводНулевогоЗначенияВЧисловоеПоле(СтрокаДерева)
			Или ОтказОтОтвета Тогда

			НоваяСтрока = Объект.Состав.Добавить();
			НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
			НоваяСтрока.ЭлементарныйВопрос = СтрокаДерева.ЭлементарныйВопрос;
			Если СтрокаДерева.ТипОтвета = Перечисления.ТипыОтветовНаВопрос.Текст Тогда
				НоваяСтрока.ОткрытыйОтвет = Ответ;
			Иначе
				НоваяСтрока.Ответ = Ответ;
				Если СтрокаДерева.ТребуетсяКомментарий Тогда
					НоваяСтрока.ОткрытыйОтвет = ЭтотОбъект[ИмяВопроса + "_Комментарий"];
				КонецЕсли;
			КонецЕсли;
			НоваяСтрока.БезОтвета = ОтказОтОтвета;

		КонецЕсли;

	КонецЕсли;

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

&НаСервере
Процедура ЗаполнитьОтветыКомплексныйВопрос(СтрокаДерева)

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

	Для Каждого СтрокаКомплексногоВопроса Из СтрокаДерева.СоставКомплексногоВопроса Цикл

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

			НоваяСтрока = Объект.Состав.Добавить();
			НоваяСтрока.Вопрос = СтрокаДерева.ВопросШаблона;
			НоваяСтрока.ЭлементарныйВопрос = СтрокаКомплексногоВопроса.ЭлементарныйВопрос;
			Если ТипОтвета = Перечисления.ТипыОтветовНаВопрос.Текст Тогда
				НоваяСтрока.ОткрытыйОтвет = ЭтотОбъект[ИмяРеквизита];
			Иначе
				НоваяСтрока.Ответ = ЭтотОбъект[ИмяРеквизита];
				Если СтрокаКомплексногоВопроса.ТребуетсяКомментарий Тогда
					НоваяСтрока.ОткрытыйОтвет = ЭтотОбъект[ИмяВопроса + "_Комментарий_" + Формат(
						СтрокаКомплексногоВопроса.НомерСтроки, "ЧГ=")];
				КонецЕсли;
			КонецЕсли;

		Иначе

			ВариантыОтветовНаВопрос = Анкетирование.ВариантыОтветовНаВопрос(
				СтрокаКомплексногоВопроса.ЭлементарныйВопрос, ЭтотОбъект);

			Счетчик = 0;
			Для Каждого ВариантОтвета Из ВариантыОтветовНаВопрос Цикл

				Счетчик = Счетчик + 1;
				ИмяТекРеквизита =  ИмяРеквизита + "_Реквизит_" + Счетчик;

				Если ЭтотОбъект[ИмяТекРеквизита] Тогда

					НоваяСтрока = Объект.Состав.Добавить();
					НоваяСтрока.Вопрос             = СтрокаДерева.ВопросШаблона;
					НоваяСтрока.ЭлементарныйВопрос = СтрокаКомплексногоВопроса.ЭлементарныйВопрос;
					НоваяСтрока.Ответ              = ВариантОтвета.Ответ;
					НоваяСтрока.НомерЯчейки        = Счетчик;
					Если ВариантОтвета.ТребуетОткрытогоОтвета Тогда
						НоваяСтрока.ОткрытыйОтвет	= ЭтотОбъект[ИмяРеквизита + "_Комментарий_" + Счетчик];
					КонецЕсли;

				КонецЕсли;

			КонецЦикла;

		КонецЕсли;

	КонецЦикла;

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

#КонецОбласти

#Область Прочее

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

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

	Элементы.ПредыдущийРазделПодвал.Видимость = (ТаблицаВопросовРаздела.Количество() > 0);
	Элементы.СледующийРазделПодвал.Видимость  = (ТаблицаВопросовРаздела.Количество() > 0);

	АнкетированиеКлиентСервер.ПереключитьВидимостьГруппТелаАнкеты(ЭтотОбъект, Истина);

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

// Возвращаемое значение:
//   Булево
//
&НаСервере
Функция ПроверитьЗаполнениеАнкеты()

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

	Запрос.УстановитьПараметр("ВнешнийИсточник", Объект.Состав.Выгрузить());
	Запрос.УстановитьПараметр("ШаблонАнкеты", Объект.ШаблонАнкеты);

	Результат = Запрос.Выполнить();
	Если Результат.Пустой() Тогда
		Возврат Ложь;
	КонецЕсли;

	Выборка = Результат.Выбрать();
	Пока Выборка.Следующий() Цикл
		ОбщегоНазначения.СообщитьПользователю(НСтр("ru = 'Не указан ответ на вопрос'") + "- " 
			+ СтрЗаменить(Выборка.Ссылка.ПолныйКод(), "/", ".") + " " + Выборка.Формулировка);
	КонецЦикла;

	Возврат Истина;

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

// Параметры:
//  Ответ         - Характеристика.ВопросыДляАнкетирования - ответ, который ищем.
//  МассивОтветов - Массив - массив строк таблицы значений.
//
// Возвращаемое значение:
//   Структура:
//     * ПорядковыйНомерРеквизита - Число
//     * ТребуетОткрытогоОтвета - Булево
//
&НаСервереБезКонтекста
Функция НайтиОтветВМассиве(Ответ, МассивОтветов)

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

	Для Индекс = 1 По МассивОтветов.Количество() Цикл

		Если МассивОтветов[Индекс - 1].Ответ = Ответ Тогда

			Результат.Вставить("ПорядковыйНомерРеквизита", Индекс);
			Результат.Вставить("ТребуетОткрытогоОтвета", МассивОтветов[Индекс - 1].ТребуетОткрытогоОтвета);
			Возврат Результат;
		КонецЕсли;

	КонецЦикла;

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

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

&НаСервере
Процедура УстановитьЗначенияРеквизитовСогласноОпросу(РеквизитыОпрос)

	ВозможностьПредварительногоСохранения = РеквизитыОпрос.ВозможностьПредварительногоСохранения;
	ШаблонАнкеты = РеквизитыОпрос.ШаблонАнкеты;
	Вступление = ?(ПустаяСтрока(РеквизитыОпрос.Вступление), 
		НСтр("ru = 'Нажмите далее для заполнения анкеты.'"), 
		РеквизитыОпрос.Вступление);
	Заключение = ?(ПустаяСтрока(РеквизитыОпрос.Заключение), 
		НСтр("ru = 'Спасибо за то, что заполнили анкету.'"), 
		РеквизитыОпрос.Заключение);

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

&НаСервере
Функция ЗначенияРеквизитовНазначенияОпроса(Опрос)

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	НазначениеОпросов.ШаблонАнкеты,
	|	НазначениеОпросов.ТипРеспондентов,
	|	НазначениеОпросов.ВозможностьПредварительногоСохранения,
	|	НазначениеОпросов.Респонденты.(
	|		Ссылка,
	|		НомерСтроки,
	|		Респондент
	|	),
	|	ШаблоныАнкет.Заголовок,
	|	ШаблоныАнкет.Вступление,
	|	ШаблоныАнкет.Заключение
	|ИЗ
	|	Документ.НазначениеОпросов КАК НазначениеОпросов
	|		ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ШаблоныАнкет КАК ШаблоныАнкет
	|		ПО НазначениеОпросов.ШаблонАнкеты = ШаблоныАнкет.Ссылка
	|ГДЕ
	|	НазначениеОпросов.Ссылка = &Опрос";

	Запрос.УстановитьПараметр("Опрос", Опрос);

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

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

&НаСервереБезКонтекста
Функция ЗначенияРеквизитовШаблонаАнкеты(ШаблонАнкеты)

	Запрос = Новый Запрос;
	Запрос.Текст =
	"ВЫБРАТЬ
	|	ШаблоныАнкет.Ссылка КАК ШаблонАнкеты,
	|	ЛОЖЬ КАК ВозможностьПредварительногоСохранения,
	|	ШаблоныАнкет.Заголовок,
	|	ШаблоныАнкет.Вступление,
	|	ШаблоныАнкет.Заключение
	|ИЗ
	|	Справочник.ШаблоныАнкет КАК ШаблоныАнкет
	|ГДЕ
	|	ШаблоныАнкет.Ссылка = &ШаблонАнкеты";

	Запрос.УстановитьПараметр("ШаблонАнкеты", ШаблонАнкеты);

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

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

&НаСервере
Процедура УстановитьЗаголовкиНадписей(РеквизитыОпрос)

	Заголовок = ?(Не ПустаяСтрока(Параметры.Заголовок), Параметры.Заголовок, РеквизитыОпрос.Заголовок);
	Элементы.НадписьВступление.Заголовок = РеквизитыОпрос.Вступление;
	Вступление = РеквизитыОпрос.Вступление;

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

&НаКлиенте
Процедура УправлениеДоступностьюПодчиненныеВопросы(УстанавливатьМодифицированность = Истина)

	Для Каждого ЭлементКоллекции Из ПодчиненныеВопросы Цикл

		ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(ЭлементКоллекции.Вопрос);
		Для Каждого ПодчиненныйВопрос Из ЭлементКоллекции.Подчиненные Цикл

			ЭлементПодчиненногоВопроса = Элементы[ПодчиненныйВопрос.ИмяЭлементаПодчиненногоВопроса];
			ЭлементПодчиненногоВопроса.ТолькоПросмотр = Не ЭтотОбъект[ИмяВопроса];
			Если СтрЧислоВхождений(ПодчиненныйВопрос.ИмяЭлементаПодчиненногоВопроса, "Реквизит") = 0 Тогда
				ЗначениеАвтоОтметкаНезаполненного = ЭтотОбъект[ИмяВопроса] И ПодчиненныйВопрос.Обязательный;
				Попытка
					ЭлементПодчиненногоВопроса.АвтоОтметкаНезаполненного = ЗначениеАвтоОтметкаНезаполненного;
				Исключение
					// АПК:280 У флажка и переключателя нет свойства АвтоОтметкаНезаполненного.
				КонецПопытки;
			КонецЕсли;
		КонецЦикла;
	КонецЦикла;

	Если ВозможностьПредварительногоСохранения И УстанавливатьМодифицированность Тогда
		Модифицированность = Истина;
	КонецЕсли;

	ОтключитьОтметкуНезаполненного();

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

&НаСервере
Процедура УстановитьВидимостьДоступностьЭлементовФормы()

	Если Параметры.ТолькоФормаЗаполнения Тогда

		ЭтоИнтервью = Объект.РежимАнкетирования = ПредопределенноеЗначение("Перечисление.РежимыАнкетирования.Интервью");

		Элементы.ГруппаОсновныеРеквизиты.Видимость              = ЭтоИнтервью;
		Элементы.Дата.Доступность                               = Ложь;
		Элементы.ФормаКоманднаяПанельПровестиИЗакрыть.Видимость = Ложь;
		Элементы.ФормаКоманднаяПанельЗаписать.Видимость         = Ложь;
		Элементы.Провести.Видимость                             = Ложь;
		Элементы.ФормаОтменаПроведения.Видимость                = Ложь;
		Элементы.ФормаПеречитать.Видимость                      = Ложь;
		Элементы.ПоказатьВСпискеАнкета.Видимость                = Ложь;
		Элементы.ФормаУстановитьПометкуУдаления.Видимость       = Ложь;
		Элементы.Комментарий.Видимость                          = Ложь;

		Элементы.РежимАнкетирования.ТолькоПросмотр = ЭтоИнтервью;
		Элементы.Опрос.ТолькоПросмотр              = ЭтоИнтервью;
		Элементы.ШаблонАнкеты.ТолькоПросмотр       = ЭтоИнтервью;

		Если Объект.Ссылка.Пустая() Тогда
			Объект.Дата = ТекущаяДатаСеанса();
		КонецЕсли;

		Если Параметры.ТолькоПросмотр = Истина Тогда

			Элементы.ГруппаТелоАнкеты.ТолькоПросмотр          = Истина;
			Элементы.ФормаЗаполненияЗавершитьИЗакрыть.Видимость = Ложь;
			Элементы.ФормаЗаполненияЗаписать.Видимость        = Ложь;

		Иначе

			Элементы.ФормаЗаполненияЗаписать.Видимость = ВозможностьПредварительногоСохранения;
			Элементы.ФормаЗаполненияЗавершитьИЗакрыть.КнопкаПоУмолчанию = Истина;

		КонецЕсли;

		Модифицированность = Ложь;

	Иначе

		Элементы.ФормаЗаполненияЗавершитьИЗакрыть.Видимость = Ложь;
		Элементы.ФормаЗаполненияЗаписать.Видимость        = Ложь;
		Элементы.ГруппаТелоАнкеты.ТолькоПросмотр          = Истина;
		Элементы.ГруппаОсновныеРеквизиты.ТолькоПросмотр   = Истина;

	КонецЕсли;

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

&НаСервере
Процедура УстановитьОбработчикСобытияПриИзмененииДляВопросов()

	Если Не ВозможностьПредварительногоСохранения Тогда
		Возврат;
	КонецЕсли;

	Для Каждого СтрокаТаблицы Из ТаблицаВопросовРаздела Цикл

		Если СтрокаТаблицы.ТипВопроса = Перечисления.ТипыВопросовШаблонаАнкеты.ВопросСУсловием Тогда
			Продолжить;
		КонецЕсли;

		ИмяВопроса = АнкетированиеКлиентСервер.ИмяВопроса(СтрокаТаблицы.КлючСтроки);

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

	КонецЦикла;

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

&НаСервере
Процедура УстановитьОбработчикСобытияПриИзмененииДляКомплексныхВопросов(СтрокаТаблицы, ИмяВопроса)

	Для Каждого СтрокаКомплексногоВопроса Из СтрокаТаблицы.СоставКомплексногоВопроса Цикл

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

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

	КонецЦикла;

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

&НаКлиенте
Процедура ВыполнитьПостроениеФормыЗаполнения()

	АнкетированиеКлиентСервер.ПереключитьВидимостьГруппТелаАнкеты(ЭтотОбъект, Ложь);
	ПодключитьОбработчикОжидания("ОкончаниеПостроенияФормыЗаполнения", 0.1, Истина);

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

&НаКлиенте
Процедура ОкончаниеПостроенияФормыЗаполнения()

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

	ЭлементДляПозиционирования = Элементы.Найти(ИмяЭлементаДляПозиционирования);
	Если ЭлементДляПозиционирования <> Неопределено Тогда
		ТекущийЭлемент = ЭлементДляПозиционирования;
	КонецЕсли;

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

&НаКлиенте
Процедура ИзменитьВидимостьДеревоРазделов()

	Элементы.ГруппаДеревоРазделов.Видимость = Не Элементы.ГруппаДеревоРазделов.Видимость;
	ЗаголовокКомандаРазделы = ?(Элементы.ГруппаДеревоРазделов.Видимость, НСтр("ru = 'Скрыть разделы'"), 
		НСтр("ru = 'Показать разделы'"));
	Элементы.СкрытьПоказатьДеревоРазделов.Заголовок = ЗаголовокКомандаРазделы;

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

&НаКлиенте
Процедура УстановитьДоступностьНавигацииРазделов()

	ДоступностьПредыдущийРаздел = (Элементы.ДеревоРазделов.ТекущаяСтрока > 0);
	ДоступностьСледующийРаздел  = (ДеревоРазделов.НайтиПоИдентификатору(Элементы.ДеревоРазделов.ТекущаяСтрока + 1)
		<> Неопределено);

	Элементы.ПредыдущийРазделПодвал.Доступность = ДоступностьПредыдущийРаздел;
	Элементы.ПредыдущийРаздел.Доступность = ДоступностьПредыдущийРаздел;
	Элементы.СледующийРазделПодвал.Доступность = ДоступностьСледующийРаздел;
	Элементы.СледующийРаздел.Доступность = ДоступностьСледующийРаздел;

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

&НаКлиенте
Процедура ИзменитьРаздел(Направление)

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

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

&НаКлиенте
Процедура ВопросОПринятииАнкетыПослеЗавершения(РезультатВопроса, ДополнительныеПараметры) Экспорт

	Если РезультатВопроса = КодВозвратаДиалога.Нет Тогда
		Возврат;
	КонецЕсли;

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

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

// Параметры:
//   ИзмененныйТекст         - Строка
//   ДополнительныеПараметры - Структура
//
&НаКлиенте
Процедура РедактированиеМногострочногоТекстаПриОкончании(ИзмененныйТекст, ДополнительныеПараметры) Экспорт

	Элемент = ДополнительныеПараметры.Элемент;

	Если ТипЗнч(Элемент.Родитель) = Тип("ГруппаФормы") Тогда
		Если ЭтотОбъект[Элемент.Имя] <> ИзмененныйТекст Тогда
			ЭтотОбъект[Элемент.Имя] = ИзмененныйТекст;
			Модифицированность = Истина;
		КонецЕсли;
	Иначе

		НайденнаяСтрока = ЭтотОбъект[Элемент.Родитель.Имя].НайтиПоИдентификатору(Элемент.Родитель.ТекущаяСтрока);
		ИндексСтроки    = ЭтотОбъект[Элемент.Родитель.Имя].Индекс(НайденнаяСтрока);

		Если ЭтотОбъект[Элемент.Родитель.Имя][ИндексСтроки][Элемент.Имя] <> ИзмененныйТекст Тогда
			ЭтотОбъект[Элемент.Родитель.Имя][ИндексСтроки][Элемент.Имя] = ИзмененныйТекст;
			Модифицированность = Истина;
		КонецЕсли;

	КонецЕсли;

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

&НаКлиенте
Процедура ВыделитьВопросыНаКоторыеДаныОтветы()

	АнкетированиеКлиент.ВыделитьВопросыНаКоторыеДаныОтветы(ЭтотОбъект);

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

&НаКлиентеНаСервереБезКонтекста
Процедура ИзменитьВидимостьЭлементовФормы(Форма)

	ЭтоИнтервью = Форма.Объект.РежимАнкетирования = ПредопределенноеЗначение("Перечисление.РежимыАнкетирования.Интервью");
	Форма.Элементы.Опрос.Видимость = Не ЭтоИнтервью;
	Форма.Элементы.ШаблонАнкеты.Видимость = ЭтоИнтервью;
	Форма.Элементы.Интервьюер.Видимость = ЭтоИнтервью;

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

// СтандартныеПодсистемы.ПодключаемыеКоманды
&НаКлиенте
Процедура Подключаемый_ВыполнитьКоманду(Команда)
	ПодключаемыеКомандыКлиент.НачатьВыполнениеКоманды(ЭтотОбъект, Команда, Объект);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ПродолжитьВыполнениеКомандыНаСервере(ПараметрыВыполнения, ДополнительныеПараметры) Экспорт
	ВыполнитьКомандуНаСервере(ПараметрыВыполнения);
КонецПроцедуры

&НаСервере
Процедура ВыполнитьКомандуНаСервере(ПараметрыВыполнения)
	ПодключаемыеКоманды.ВыполнитьКоманду(ЭтотОбъект, ПараметрыВыполнения, Объект);
КонецПроцедуры

&НаКлиенте
Процедура Подключаемый_ОбновитьКоманды()
	ПодключаемыеКомандыКлиентСервер.ОбновитьКоманды(ЭтотОбъект, Объект);
КонецПроцедуры

&НаСервере
Процедура ПослеЗаписиНаСервере(ТекущийОбъект, ПараметрыЗаписи)

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

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

// Конец СтандартныеПодсистемы.ПодключаемыеКоманды

#КонецОбласти

#КонецОбласти

Связанные материалы