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