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