Задачи на расчет графиков и распределение числовых данных по периодам являются базовыми для освоения алгоритмического мышления в 1С. В данной статье мы разберем классическую учебную задачу: расчет необходимого количества протеина на заданный период с учетом частоты приема и разницы в дозировке между буднями и выходными. Мы научимся работать с массивами, циклами и оператором остатка от деления.
Прежде чем приступать к написанию кода, проанализируем условия задачи. Нам необходимо:
ЧастотаПриема, ПротеинВБудни, ПротеинВВыходные и КоличествоДнейПриема.Массив.Рассмотрим подробнее ключевой инструмент — Массив. В 1С массив является универсальной коллекцией, где данные хранятся под индексами. Важно помнить, что индексация в 1С начинается с 0, поэтому первый день приема будет иметь индекс 0, а последний — КоличествоДней - 1.
Для начала инициализируем массив и подготовим переменные для хранения итогов. Разберем этот этап на примере кода:
// Предположим, переменные ЧастотаПриема, ПротеинВБудни, ПротеинВВыходные, ВсегоДней уже получены от пользователя
ГрафикПриема = Новый Массив;
ОбщийВес = 0;
ТекущийДеньНедели = 1; // Начинаем с понедельника
Проанализируем ситуацию: нам нужно пройти циклом по всем дням от 1 до ВсегоДней. На каждой итерации мы должны решить две задачи: принимается ли протеин сегодня и какая дозировка актуальна (будняя или выходного дня).
Для определения дня недели используем простую логику: если мы начинаем с 1 (понедельник), то каждый 6-й и 7-й день будут субботой и воскресеньем. Выясним причину использования оператора % (остаток от деления): он позволяет «зациклить» последовательность чисел.
Для Счетчик = 1 По ВсегоДней Цикл
// Определяем день недели (от 1 до 7)
// Так как начинаем с понедельника, используем формулу:
ДеньНедели = (Счетчик - 1) % 7 + 1;
КоличествоСегодня = 0;
// Проверяем частоту приема (например, каждый 2-й день)
Если (Счетчик - 1) % ЧастотаПриема = 0 Тогда
// Определяем тип дня (будни или выходные)
Если ДеньНедели <= 5 Тогда
КоличествоСегодня = ПротеинВБудни;
Иначе
КоличествоСегодня = ПротеинВВыходные;
КонецЕсли;
КонецЕсли;
// Добавляем данные в массив и суммируем общий итог
ГрафикПриема.Добавить(КоличествоСегодня);
ОбщийВес = ОбщийВес + КоличествоСегодня;
КонецЦикла;
Теперь, когда массив ГрафикПриема заполнен, нам нужно вывести информацию понедельно. Рассмотрим, как это сделать максимально эффективно. Мы будем перебирать массив и накапливать сумму во временную переменную, обнуляя её в конце каждой недели.
НомерНедели = 1;
СуммаЗаНеделю = 0;
Для Индекс = 0 По ГрафикПриема.Количество() - 1 Цикл
СуммаЗаНеделю = СуммаЗаНеделю + ГрафикПриема[Индекс];
// Если это 7-й день недели или последний день всего периода
Если (Индекс + 1) % 7 = 0 Или (Индекс + 1) = ГрафикПриема.Количество() Тогда
Сообщить("Неделя " + НомерНедели + " – " + СуммаЗаНеделю + "гр");
СуммаЗаНеделю = 0;
НомерНедели = НомерНедели + 1;
КонецЕсли;
КонецЦикла;
Сообщить("Всего – " + ОбщийВес + "гр");
Посмотрим на пример работы оператора %. Если Счетчик = 8 (второй понедельник), то (8-1) % 7 + 1 даст нам 7 % 7 + 1 = 0 + 1 = 1. Это надежный способ вычислять позицию внутри повторяющегося цикла.
Важные моменты:
Добавить() для динамического расширения массива. Это избавляет от необходимости заранее знать точный размер, хотя в нашей задаче он известен (ВсегоДней).Число() для преобразования, иначе математические операции вызовут ошибку.Массив в памяти 1С достаточно компактны.Хотя условие задачи требует использования массива, в реальной практике 1С-разработчики часто используют ТаблицаЗначений. Это позволяет хранить данные более структурно, например, в колонках "НомерДня", "ДеньНедели", "Вес". Однако для учебных целей работа с простым массивом лучше развивает понимание работы с индексами.
Мы проанализировали ситуацию, создали алгоритм распределения дозировок и реализовали отчетность. Подобный подход можно использовать не только для расчета протеина, но и для любых графиков: от графиков дежурств сотрудников до планов производства в сложных ERP-системах.