Как сохранить и просмотреть результаты тестирования сотрудников в 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке подсистем проверки знаний и тестирования часто возникает задача: пользователь прошел тест, система сформировала итоговый табличный документ с правильными и ошибочными ответами, однако куратору или преподавателю требуется открыть этот результат позже. Разберем, как правильно организовать хранение таких данных, какие типичные ошибки возникают при работе с объектом ХранилищеЗначения на управляемых формах и какие архитектурные решения лучше выбрать.

Вариант 1. Сохранение сформированного табличного документа в ХранилищеЗначения

Рассмотрим самый быстрый путь, к которому часто прибегают разработчики: сохранение готового макета или объекта ТабличныйДокумент в ресурсе регистра сведений с типом ХранилищеЗначения.

Для реализации этого подхода в конфигурации создадим периодический регистр сведений (например, Результат):

  1. Измерения: Пользователь (тип СправочникСсылка.Пользователи).
  2. Ресурсы: ХранениеОтветов (тип ХранилищеЗначения).

Проанализируем процедуру сохранения. Чтобы не перезаписать данные других пользователей и не очистить весь регистр ошибочным набором записей, воспользуемся объектом СоздатьМенеджерЗаписи на стороне сервера:


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

Теперь разберем распространенные ошибки при попытке извлечь и отобразить сохраненный документ.

Выясним причину частой ошибки новичков: метод Получить() объекта ХранилищеЗначения недоступен на клиенте в тонком клиенте и веб-клиенте. Кроме того, у элементов управляемой формы вида Поле табличного документа отсутствует метод Вывести(). Отображение выполняется через связывание с реквизитом формы.

Посмотрим на пример правильного извлечения и вывода документа на управляемой форме:


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

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

Минусы хранения готового табличного документа

Хотя вариант с сохранением ТабличныйДокумент кажется простым, проанализируем его скрытые ограничения:

  1. Раздувание базы данных: табличный документ сохраняет в бинарном виде параметры форматирования, шрифты, стили ячеек и картинки. При регулярном тестировании сотен сотрудников таблица LOB-данных в СУБД быстро растет.
  2. Невозможность аналитики: по содержимому ХранилищеЗначения невозможно построить отчеты с помощью запросов или СКД. Куратор не сможет увидеть сводную статистику по самым сложным вопросам или проблемным темам.

Вариант 2. Хранение детальных ответов в регистре сведений

Рассмотрим более грамотный архитектурный подход: сохранять в базе не графический отчет, а конкретные ответы пользователя. Это позволит в любой момент как собрать отчет заново, так и построить аналитику.

Создадим непериодический регистр сведений ОтветыПользователей со следующей структурой:

  1. Измерения: Пользователь, Тест, ДатаТестирования, Вопрос.
  2. Ресурсы: ВыбранныйОтвет, ПравильныйОтвет, ОтветВерный (тип Булево).

Разберем по шагам запись набора ответов после завершения тестирования:


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

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

Вариант 3. Использование документа для фиксации результатов

В типовых конфигурациях 1С для подобных задач применяется стандартный документ (например, ТестированиеСотрудника). Проанализируем его устройство:

  1. В реквизитах шапки фиксируются сотрудник, дата, пройденный тест, общее количество баллов и итоговый статус («Сдан» или «Не сдан»).
  2. В табличной части сохраняются строки: вопрос, выбранный вариант, признак верности ответа.

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

← На главную