Есть справочник Вопросы содержащий реквизит ТекстВопроса (тип строка) и справочник Ответы с реквизитом правильный ответ (булево). Вместе, эти 2 справочника нужны чтобы пользователь мог составить тест тому кого собирается тестировать: вводится текст вопроса в реквизит ТекстВопроса 1 Перемешивание вопросов и ответов которые заданы к вопросу. Какую задать команду или обработчик чтобы порядок реквизитов каждый раз был бы случайным?
Пользователь при нажатии на кнопку перемешает созданный порядок вопросов и ответов к ним, причём изменяются только номер вопроса и положение реквизитов в созданном вопросе.
Возможный вариант: прикрутить ГСЧ к их именам, но я пока не знаю как именно это нужно сделать.
Второй вариант: код справочника рандомно прописывается по нажатию кнопки. И выводи вопросы отсортированные по коду. Но здесь следует учесть что код будет в пределах заданных ответов отдельно к каждому вопросу: в одном вопросе может быть разное число ответов.
2 Выбор нескольких вариантов правильных ответов проходящим тест и их засчитывание как верное, если пользователь при создании вопроса задал несколько правильных ответов. Пока что я не знаю как это реализовать, у меня получилось сделать пока что только так: 1 вопрос - 1 верный ответ.
3 Как уместить несколько вопросов с ответами на одной странице, и кнопкам: назад и вперед задать горячие клавиши на лево и право (я про кнопки в виде стрелок) ?
1. Код формы Главная: эта страница по которой пользователь после авторизации или регистрации, в случае если он гость, попадает на страницу где по нажатию кнопки Начать тест он проходит тест.
&НаКлиенте
Процедура НачатьТест(Команда)
ТестВПроцессе=Истина;
ЗапВопросыОтветы();
Если ВопросыОтветы.Количество()=0 Тогда
Предупреждение ("Тест не найден. Обратитесь к администратору");
Возврат;
КонецЕсли;
Элементы.Начало.Видимость=Ложь;
Элементы.Тест.Видимость=Истина;
НомерТекущегоВопроса=1;
ЗапОтветы();
КонецПроцедуры
&НаКлиенте
Процедура УстановитьВидимость()
Если НомерТекущегоВопроса=1 Тогда
Элементы.Назад.Видимость=Ложь;
Элементы.ЗавершитьТест.Видимость=Ложь;
ИначеЕсли ВопросыОтветы.Количество()= НомерТекущегоВопроса Тогда
Элементы.Вперед.Видимость=Ложь;
Элементы.ЗавершитьТест.Видимость=Истина;
Иначе
Элементы.Назад.Видимость=Истина;
Элементы.Вперед.Видимость=Истина;
Элементы.ЗавершитьТест.Видимость=Ложь;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура Вперед(Команда)
НомерТекущегоВопроса=НомерТекущегоВопроса+1;
ЗапОтветы();
КонецПроцедуры
&НаКлиенте
Процедура Назад(Команда)
НомерТекущегоВопроса=НомерТекущегоВопроса-1;
ЗапОтветы();
КонецПроцедуры
&НаКлиенте
Процедура ЗапОтветы()
УстановитьВидимость();
ЗапОтветыНаСервере();
КонецПроцедуры
&НаСервере
Процедура ЗапОтветыНаСервере()
ВариантОтвета.Очистить();
Стр=ВопросыОтветы.Получить(НомерТекущегоВопроса-1);
З=Новый Запрос;
З.Текст="
|ВЫБРАТЬ
| Ссылка
|ИЗ
| Справочник.Ответы
|ГДЕ Владелец=&Вопрос
|УПОРЯДОЧИТЬ ПО КОД";
З.УстановитьПараметр("Вопрос",Стр.Вопрос);
Выб=З.Выполнить().Выбрать();
Пока Выб.Следующий() Цикл
ВариантОтвета.Добавить(Выб.Ссылка,Выб.Ссылка.Наименование);
КонецЦикла;
Если НЕ Стр.Ответ.Пустая() Тогда
Зн=ВариантОтвета.НайтиПоЗначению(Стр.Ответ);
Зн.Пометка=Истина;
КонецЕсли;
Элементы.ТекстВопроса.Заголовок=Стр.Вопрос.Наименование+Символы.ПС+Стр.Вопрос.ТекстВопроса;
КонецПроцедуры
&НаСервере
Процедура ЗапВопросыОтветы()
З=Новый Запрос;
З.Текст="
|ВЫБРАТЬ
|Ссылка КАК Вопрос
|ИЗ Справочник.Вопросы
|ГДЕ НЕ ПометкаУдаления
|УПОРЯДОЧИТЬ ПО Код";
ВопросыОтветы.Загрузить(З.Выполнить().Выгрузить());
КонецПроцедуры
&НаСервере
Функция ПроверкаОтветаНаВсеВопросы(КолПО)
фл=Истина;
Для Каждого Стр Из ВопросыОтветы Цикл
Если Стр.Ответ.Пустая() Тогда
фл=Ложь;
Сообщить("Вы не ответили на "+Стр.Вопрос.Наименование);
КонецЕсли;
Если Стр.Ответ.ПравильныйОтвет Тогда КолПО=КолПО+1; КонецЕсли;
КонецЦикла;
Возврат фл;
КонецФункции
&НаКлиенте
Процедура ЗавершитьТест(Команда)
ОтветНаВопрос=Вопрос("Вы действительно хотите закончить тест?",РежимДиалогаВопрос.ДаНет);
Если ОтветНаВопрос=КодВозвратаДиалога.Нет Тогда Возврат КонецЕсли;
КолПО=0;
Если НЕ ПроверкаОтветаНаВсеВопросы(КолПО) Тогда Возврат КонецЕсли;
ТестВПроцессе=Ложь;
Элементы.Тест.Видимость=Ложь;
Элементы.РезультатТекст.Заголовок="Вы ответили правильно на "+КолПО+" вопросов из "+ВопросыОтветы.Количество();
Элементы.РезультатТекст.Видимость=Истина;
КонецПроцедуры
&НаКлиенте
Процедура ВариантОтветаПометкаПриИзменении(Элемент)
Стр=Элементы.ВариантОтвета.ТекущиеДанные;
Если Стр.Пометка Тогда
Для Каждого Зн Из ВариантОтвета Цикл
Если Стр.Значение=Зн.Значение Тогда Продолжить КонецЕсли;
Зн.Пометка=Ложь;
КонецЦикла;
Зн=ВопросыОтветы.Получить(НомерТекущегоВопроса-1);
Зн.Ответ=Стр.Значение;
Иначе
Зн=ВопросыОтветы.Получить(НомерТекущегоВопроса-1);
Зн.Ответ=NULL;
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ПриОткрытии(Отказ)
ТестВПроцессе=Ложь;
КонецПроцедуры
&НаКлиенте
Процедура ПередЗакрытием(Отказ, СтандартнаяОбработка)
Отказ=ТестВПроцессе;
КонецПроцедуры
&НаКлиенте
Процедура Войти(Команда)
ОткрытьФорму("ОбщаяФорма.Авторизация");
КонецПроцедуры
Какую задать команду или обработчик чтобы порядок реквизитов каждый раз был бы случайным?
1.1. Если алгоритм обработки результатов запроса зависит от порядка записей в запросе или если результат обработки запроса в той или иной форме представляется пользователю, то в тексте запроса следует использовать предложение УПОРЯДОЧИТЬ ПО. В отсутствие выражения УПОРЯДОЧИТЬ ПО невозможно сделать никаких предположений о том, в каком порядке будут представлены записи в результатах запроса.
&НаСервере
Процедура ЗапВопросыОтветы()
З=Новый Запрос;
З.Текст="
|ВЫБРАТЬ
|Ссылка КАК Вопрос
|ИЗ Справочник.Вопросы
|ГДЕ НЕ ПометкаУдаления
|УПОРЯДОЧИТЬ ПО Код";
ВопросыОтветы.Загрузить(З.Выполнить().Выгрузить());
КонецПроцедуры