Как получить новые даты после перемещения или изменения размера элемента в 1С:Планировщике?

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

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

Получение новых дат после интерактивного редактирования

Когда пользователь взаимодействует с элементами Планировщика — перемещает их или изменяет их размеры, нам необходимо получить новые значения дат начала и окончания работ. Для этого в Планировщике предусмотрено специальное событие, которое вызывается после завершения таких операций.

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

  1. Элемент: Ссылка на сам элемент формы Планировщик.
  2. НовыйЭлемент: Булево значение. Если Истина, это означает, что был создан новый элемент Планировщика. Если Ложь, редактировался уже существующий.
  3. ОтменаРедактирования: Булево значение, указывающее, была ли операция редактирования отменена (например, с помощью клавиши Esc).

Самое главное для нас — это коллекция Элемент.ВыделенныеЭлементы. После окончания редактирования эта коллекция будет содержать те элементы, над которыми выполнялось действие. Каждый элемент в этой коллекции имеет свойства Начало и Конец, которые уже будут содержать актуальные, измененные пользователем значения. Мы можем просто пройтись по этой коллекции и извлечь обновленные даты.

Посмотрим на пример кода, демонстрирующий, как это сделать:


&НаКлиенте
Процедура ПланировщикПриОкончанииРедактирования(Элемент, НовыйЭлемент, ОтменаРедактирования)
    // Проверим, не была ли операция отменена
    Если ОтменаРедактирования Тогда
        Возврат;
    КонецЕсли;

    // Создадим массив для хранения обновленных данных
    МассивИзмененныхЭлементов = Новый Массив;

    // Переберем все элементы, над которыми выполнялось действие
    Для Каждого ТекущийЭлементПланировщика Из Элемент.ВыделенныеЭлементы Цикл
        // Каждый элемент в коллекции уже содержит актуальные даты Начало и Конец
        // Мы можем получить их напрямую
        ДатаНачала = ТекущийЭлементПланировщика.Начало;
        ДатаОкончания = ТекущийЭлементПланировщика.Конец;

        // Если элемент был создан новый, возможно, нам потребуется дополнительная логика
        Если НовыйЭлемент Тогда
            Сообщить("Создан новый элемент: Начало = " + Формат(ДатаНачала, "ДЛФ=ДВ") + ", Конец = " + Формат(ДатаОкончания, "ДЛФ=ДВ"));
            // Здесь может быть логика для инициализации нового элемента,
            // например, привязка к новому заданию
        Иначе
            Сообщить("Изменен существующий элемент: Начало = " + Формат(ДатаНачала, "ДЛФ=ДВ") + ", Конец = " + Формат(ДатаОкончания, "ДЛФ=ДВ"));
            // Здесь может быть логика для обновления существующего задания в базе данных
        КонецЕсли;

        // Добавим данные элемента в массив для дальнейшей обработки, например, для записи в базу данных
        МассивИзмененныхЭлементов.Добавить(ТекущийЭлементПланировщика.Выгрузить());
    КонецЦикла;

    // После сбора данных, мы можем вызвать серверную процедуру для их сохранения
    // СоздатьЗапись(МассивИзмененныхЭлементов, НовыйЭлемент);
КонецПроцедуры

Таким образом, Планировщик сам отслеживает изменения и предоставляет нам готовые обновленные даты через свойства Начало и Конец каждого элемента в коллекции ВыделенныеЭлементы. Нам остается только забрать эти данные и при необходимости сохранить их в нашей информационной базе, что актуально, когда ведется учет рабочего времени программиста.

Настройка отображения нерабочих часов и произвольных периодов

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

Свойство ТекущиеПериодыОтображения является коллекцией объектов ПериодОтображенияПланировщика. Каждый такой объект имеет свойства Начало и Конец, определяющие конкретный видимый интервал. Добавляя элементы в эту коллекцию, мы явно указываем, какие временные промежутки должны быть видны на шкале времени, тем самым скрывая все остальное.

Давайте рассмотрим пример, как мы можем отобразить только определенные часы в течение дня, например, с 8:00 до 18:00, или даже несколько интервалов в день, имитируя рабочие смены, как того требует учет рабочего времени:


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

    // Очищаем существующие периоды отображения, чтобы задать свои
    Реквизит1.ТекущиеПериодыОтображения.Очистить();

    // Задаем несколько интервалов отображения в течение дня
    // Например, три 2-часовых интервала, начиная с 8:00, 10:00, 12:00
    Для Инд = 0 По 2 Цикл // Для трех интервалов
        НачалоИнтервала = Реквизит1.НачалоПериодаОтображения + 8 * 3600 + Инд * 2 * 3600; // Начинаем с 8:00, каждый следующий через 2 часа
        КонецИнтервала = НачалоИнтервала + 2 * 3600; // Длительность каждого интервала 2 часа
        
        // Добавляем новый период отображения
        Реквизит1.ТекущиеПериодыОтображения.Добавить(НачалоИнтервала, КонецИнтервала);
    КонецЦикла;

    // В данном примере, чтобы имитировать сокрытие нерабочих часов в течение дня,
    // мы задаем несколько интервалов. Если же нужно просто скрыть часы вне рабочего дня,
    // например, для каждого дня недели, то можно добавить интервалы для каждого дня:
    
    // Пример для отображения только рабочих часов с 9:00 до 18:00 каждый рабочий день недели
    // (предполагаем, что Реквизит1.НачалоПериодаОтображения и КонецПериодаОтображения уже заданы на неделю)
    // Если требуется скрывать часы и в выходные, то нужно предварительно отфильтровать дни

    // ДатаДляПеребора = Реквизит1.НачалоПериодаОтображения;
    // Пока ДатаДляПеребора <= Реквизит1.КонецПериодаОтображения Цикл
    //     Если ДеньНедели(ДатаДляПеребора) <> 6 И ДеньНедели(ДатаДляПеребора) <> 7 Тогда // Проверяем, что это не суббота и не воскресенье
    //         НачалоРабочегоДня = НачалоДня(ДатаДляПеребора) + 9 * 3600; // 9:00 утра
    //         КонецРабочегоДня = НачалоДня(ДатаДляПеребора) + 18 * 3600; // 18:00 вечера
    //         Реквизит1.ТекущиеПериодыОтображения.Добавить(НачалоРабочегоДня, КонецРабочегоДня);
    //     КонецЕсли;
    //     ДатаДляПеребора = ДатаДляПеребора + 24 * 3600; // Переходим к следующему дню
    // КонецЦикла;

КонецПроцедуры

Обратите внимание, что свойства НачалоПериодаОтображения и КонецПериодаОтображения задают общие границы отображаемого диапазона. А ТекущиеПериодыОтображения позволяет уточнить и детализировать этот диапазон, исключая ненужные временные отрезки. Это дает нам полный контроль над тем, что пользователь видит на шкале времени.

Добавление элемента "Планировщик" в конфигурацию

Для тех, кто только начинает работать с Планировщиком, может быть неочевидным, как добавить его на форму. Планировщик не является отдельным объектом конфигурации, таким как документ или справочник. Это управляемый элемент формы, для модификации которого может пригодиться программная модификация форм - текучий конструктор.

Чтобы добавить Планировщик на форму, используя стандартные средства или программное изменение форм, выполните следующие шаги в конфигураторе:

  1. Откройте форму, на которую вы хотите добавить Планировщик (например, форму документа, отчета или обработки).
  2. В палитре элементов управления формы (обычно находится слева), найдите раздел "Элементы формы" или "Реквизиты формы".
  3. Создайте новый реквизит формы с типом "Планировщик". После создания реквизита, он автоматически отобразится в списке элементов формы.
  4. Перетащите этот реквизит на рабочую область формы.

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

Навигация по Планировщику с помощью кнопок "Вперед" и "Назад"

Реализация навигации по Планировщику с помощью стрелок "Вперед" и "Назад", синхронизированной с полем календаря, является распространенной задачей. Это позволяет пользователю легко переключаться между днями, неделями или другими периодами.

Для этого нам понадобится:

  1. Реквизит формы типа "Дата" с видом "Поле календаря". Он будет служить точкой отсчета для отображаемого периода Планировщика.
  2. Обработчик события ПриИзменении для этого реквизита даты, который будет обновлять Планировщик.
  3. Две кнопки (например, "СтрелкаВлево" и "СтрелкаВправо"), которые будут программно изменять значение реквизита даты, тем самым запуская обновление Планировщика.

Рассмотрим необходимые примеры кода.

Связывание Планировщика с полем календаря

Для начала, давайте свяжем Планировщик с реквизитом даты, чтобы при изменении даты в календаре Планировщик автоматически переключался на соответствующий день.


&НаКлиенте
Процедура ДатаПриИзменении(Элемент)
    // Очищаем текущие периоды отображения, чтобы задать новый
    Планировщик.ТекущиеПериодыОтображения.Очистить();
    
    // Устанавливаем начало и конец периода отображения Планировщика на выбранный день
    Планировщик.НачалоПериодаОтображения = НачалоДня(Дата);
    Планировщик.КонецПериодаОтображения = КонецДня(Дата);
    
    // Выравниваем границы элементов по шкале времени для более аккуратного отображения
    Планировщик.ВыравниватьГраницыЭлементовПоШкалеВремени = Истина;
    
    // Вызываем процедуру инициализации или обновления данных Планировщика
    // (предполагается, что эта процедура заполняет Планировщик элементами)
    // ИнициализацияПланировщика(); 
КонецПроцедуры

Реализация кнопок "Вперед" и "Назад"

Теперь создадим обработчики для кнопок, которые будут смещать дату на один день влево или вправо и вызывать обновление Планировщика.


&НаКлиенте
Процедура СтрелкаВлево(Команда)
    // Очищаем текущие периоды отображения
    Планировщик.ТекущиеПериодыОтображения.Очистить();
    
    // Смещаем конец периода отображения на предыдущий день (минус 1 секунда от начала текущего дня)
    Планировщик.КонецПериодаОтображения = НачалоДня(Дата) - 1;
    
    // Устанавливаем начало периода отображения на начало дня, к которому мы перешли
    Планировщик.НачалоПериодаОтображения = НачалоДня(Планировщик.КонецПериодаОтображения);
    
    // Обновляем реквизит "Дата" на форме, чтобы синхронизировать календарь
    Дата = Планировщик.НачалоПериодаОтображения;
    
    Планировщик.ВыравниватьГраницыЭлементовПоШкалеВремени = Истина;
    // ИнициализацияПланировщика();
КонецПроцедуры

&НаКлиенте
Процедура СтрелкаВправо(Команда)
    // Очищаем текущие периоды отображения
    Планировщик.ТекущиеПериодыОтображения.Очистить();
    
    // Смещаем начало периода отображения на следующий день (плюс 1 секунда от конца текущего дня)
    Планировщик.НачалоПериодаОтображения = КонецДня(Дата) + 1;
    
    // Устанавливаем конец периода отображения на конец дня, к которому мы перешли
    Планировщик.КонецПериодаОтображения = КонецДня(Планировщик.НачалоПериодаОтображения);
    
    // Обновляем реквизит "Дата" на форме, чтобы синхронизировать календарь
    Дата = Планировщик.НачалоПериодаОтображения;
    
    Планировщик.ВыравниватьГраницыЭлементовПоШкалеВремени = Истина;
    // ИнициализацияПланировщика();
КонецПроцедуры

Важно помнить, что после изменения свойств Планировщика, таких как НачалоПериодаОтображения и КонецПериодаОтображения, необходимо повторно заполнить его элементами, чтобы отобразить актуальные данные для нового периода. Для этого обычно используется отдельная процедура, например, ИнициализацияПланировщика(), которая вызывается после каждого изменения периода.

Выборочное отображение измерений (ресурсов)

Иногда требуется, чтобы Планировщик отображал не все доступные измерения (например, всех сотрудников), а только те, которые актуальны для текущего периода или соответствуют определенным критериям. Например, отображать только работающих сотрудников в определенный день, скрывая тех, у кого выходной.

Изначально в более ранних версиях платформы 1С считалось, что такая функциональность не поддерживается. Однако, как показывает практика, это можно реализовать путем динамического формирования списка измерений Планировщика.

Суть решения заключается в следующем:

  1. При заполнении Планировщика мы формируем коллекцию ИзмеренияПланировщика.
  2. Вместо того чтобы добавлять в эту коллекцию все доступные измерения, мы сначала выполняем запрос к данным (например, к регистру графиков работы), чтобы определить, какие измерения (например, сотрудники) активны или работают в текущий отображаемый период.
  3. Только те измерения, которые удовлетворяют нашим условиям (например, имеют рабочий день с определенным ВидИнтервала), добавляются в коллекцию ИзмеренияПланировщика.

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


// Предположим, у нас есть коллекция сотрудников, которые потенциально могут быть отображены
// И есть функция, которая проверяет, работает ли сотрудник в заданный день

Процедура ИнициализацияПланировщика(Планировщик)
    Планировщик.Измерения.Очистить(); // Очищаем существующие измерения

    ДатаНачалаПериода = Планировщик.НачалоПериодаОтображения;
    ДатаКонцаПериода = Планировщик.КонецПериодаОтображения;

    // Пример запроса к регистру сведений "ГрафикиРаботы"
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗЛИЧНЫЕ
        |    ГрафикиРаботы.Сотрудник
        |ИЗ
        |    РегистрСведений.ГрафикиРаботы КАК ГрафикиРаботы
        |ГДЕ
        |    ГрафикиРаботы.Дата >= &НачалоПериода
        |    И ГрафикиРаботы.Дата <= &КонецПериода
        |    И ГрафикиРаботы.ВидИнтервала = &ВидИнтервала"; // Например, "РабочийДень"

    Запрос.УстановитьПараметр("НачалоПериода", НачалоДня(ДатаНачалаПериода));
    Запрос.УстановитьПараметр("КонецПериода", КонецДня(ДатаКонцаПериода));
    Запрос.УстановитьПараметр("ВидИнтервала", Перечисления.ВидыИнтерваловГрафикаРаботы.РабочийДень); // Пример

    РезультатЗапроса = Запрос.Выполнить();
    Выборка = РезультатЗапроса.Выбрать();

    Пока Выборка.Следующий() Цикл
        НовоеИзмерение = Планировщик.Измерения.Добавить(Выборка.Сотрудник);
        // Можно также настроить заголовок и другие свойства измерения
        НовоеИзмерение.Заголовок = Выборка.Сотрудник.Наименование;
    КонецЦикла;

    // После добавления измерений, заполняем события для этих измерений
    // ЗаполнитьСобытияПланировщика(Планировщик);
КонецПроцедуры

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

Фиксация шкалы времени и ресурсов

Многие пользователи сталкиваются с желанием "закрепить" шкалу времени (которая обычно находится сверху) и заголовки ресурсов (слева) таким образом, чтобы при прокрутке Планировщика эти элементы оставались видимыми. Это особенно актуально для больших графиков, где прокрутка может привести к потере контекста.

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

К сожалению, на данный момент нет прямой декларативной возможности "закрепить" шкалу времени или ресурсы в Планировщике, подобно тому, как это делается с областями в табличных документах. Если такая функциональность критически важна, это может потребовать более сложной реализации, возможно, с использованием составных элементов формы или веб-компонентов, что выходит за рамки стандартного использования Планировщика.

Разработчики платформы 1С постоянно работают над улучшением функциональности, и возможно, в будущих версиях появятся новые возможности для управления видимостью и закреплением элементов Планировщика.

Сохранение повторяющихся событий с расписанием

Когда мы работаем с повторяющимися событиями в Планировщике, важно понимать разницу между основным событием и его экземплярами (замещающими элементами). Основное событие содержит информацию о дате начала, дате окончания и правилах повторения (расписании). Замещающие элементы — это визуальные представления этого расписания на шкале времени.

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

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

Посмотрим, как правильно организовать сохранение основного события. Адаптируем пример кода для сохранения:


&НаСервере
Функция СоздатьЗапись (МассивЭлементов, НовыйЭлемент)
    // Перебираем элементы, которые были отредактированы или созданы
    Для Каждого Эл из МассивЭлементов Цикл
        // Мы предполагаем, что в МассивЭлементов передаются выгруженные элементы Планировщика.
        // Каждый такой элемент может быть основным или замещающим.
        // Важно: для сохранения расписания нам нужен именно основной элемент.

        // Если это новый элемент или существующий, но с измененным расписанием,
        // мы должны сохранить или обновить его как основное событие.
        
        // Пример для регистра сведений, где хранится само событие и его расписание
        НаборЗаписей = РегистрыСведений.ГрафикиРаботы.СоздатьНаборЗаписей();
        // Предположим, что ключ записи - это ссылка на объект-владелец или UUID события
        // Если это новый элемент, мы создаем новую запись.
        // Если это существующий элемент, мы его находим и обновляем.

        // Для упрощения примера, допустим, мы всегда создаем новую запись
        // и в реальном приложении здесь будет логика поиска и обновления существующей записи
        // по уникальному идентификатору события
        
        // Для демонстрации мы предполагаем, что мы работаем с основным элементом.
        // В реальном коде необходимо различать основной элемент и его замещающие.
        // Основной элемент будет иметь заполненное свойство Эл.Расписание.

        Если НовыйЭлемент Тогда
            // Если создан новый элемент, мы добавляем новую запись
            НовЗапись = НаборЗаписей.Добавить();
            НовЗапись.Начало = Эл.Начало;
            НовЗапись.Конец = Эл.Конец;
            НовЗапись.Сотрудник = Эл.ЗначенияИзмерений.Получить("Сотрудник");
            // Если у элемента есть расписание, сохраняем его
            Если Эл.Расписание <> Неопределено Тогда
                НовЗапись.Расписание = Эл.Расписание; // Сохраняем объект Расписание
            КонецЕсли;
        Иначе
            // Если элемент редактировался, то мы должны найти соответствующую запись
            // и обновить ее. Здесь нужна логика поиска записи по идентификатору.
            // Например, Эл.ИдентификаторСобытия содержит ссылку на нашу запись в регистре.
            
            // НаборЗаписей.Отбор.ИдентификаторСобытия.Установить(Эл.ИдентификаторСобытия);
            // НаборЗаписей.Прочитать();
            // Если НаборЗаписей.Количество() > 0 Тогда
            //     ОбновляемаяЗапись = НаборЗаписей[0];
            //     ОбновляемаяЗапись.Начало = Эл.Начало;
            //     ОбновляемаяЗапись.Конец = Эл.Конец;
            //     // Если Расписание изменилось, тоже его обновляем
            //     Если Эл.Расписание <> Неопределено Тогда
            //         ОбновляемаяЗапись.Расписание = Эл.Расписание;
            //     КонецЕсли;
            // КонецЕсли;
            // Иначе... обработка ошибок или создание новой записи, если не найдено
        КонецЕсли;
        
        // Записываем набор записей (для нового элемента или обновленного)
        НаборЗаписей.Записать(); 
    КонецЦикла;
КонецФункции

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

Установка начальной длительности для нового перетаскиваемого элемента

При перетаскивании нового элемента на Планировщик извне (например, из другого списка или таблицы) он по умолчанию может отображаться с минимальной длительностью (например, 30 минут). Часто возникает необходимость, чтобы новый элемент сразу имел заданную длительность, например, 2 или 3 часа, еще до того, как пользователь отпустит кнопку мыши.

Для этого мы можем программно установить свойство Конец для нового элемента, основываясь на его Начале и желаемой длительности. Это делается в событии Планировщика, которое срабатывает при создании нового элемента, например, в ПриНачалеПеретаскивания или другом событии, где доступен только что созданный элемент.

Представим, что у нас есть событие, которое предоставляет доступ к новому создаваемому элементу. В нем мы можем установить длительность:


// Пример обработчика события, где создается новый элемент и его свойства могут быть изменены
// В реальном Планировщике это может быть часть обработчика ПриОкончанииПеретаскивания,
// где НовыйЭлемент = Истина, или специального события создания.

// Допустим, у нас есть доступ к объекту нового элемента Планировщика
Процедура УстановитьДлительностьНовогоЭлемента(НовыйЭлементПланировщика, ДлительностьВЧасах)
    // Убедимся, что Начало уже установлено (например, местом куда перетащили)
    Если НовыйЭлементПланировщика.Начало <> Неопределено Тогда
        // Устанавливаем Конец, прибавляя к Началу желаемую длительность
        НовыйЭлементПланировщика.Конец = НовыйЭлементПланировщика.Начало + ДлительностьВЧасах * 3600;
    КонецЕсли;
КонецПроцедуры

Таким образом, пользователь увидит "фантом" нового элемента уже нужной длительности, что улучшает интерактивность и предсказуемость поведения Планировщика.

Настройка периодичности отображения (неделя, месяц, день)

Для гибкого отображения временной шкалы по дням, неделям, месяцам или другим интервалам используются свойства ЕдиницаПериодическогоВарианта и КратностьПериодическогоВарианта Планировщика.

  1. ЕдиницаПериодическогоВарианта: Определяет базовую единицу шкалы времени. Возможные значения — это перечисление ТипЕдиницыШкалыВремени, которое может быть День, Неделя, Месяц, Квартал, Год, Час, Минута, Секунда.
  2. КратностьПериодическогоВарианта: Определяет количество этих базовых единиц. Например, если ЕдиницаПериодическогоВарианта = Неделя, а КратностьПериодическогоВарианта = 2, то Планировщик будет отображать двухнедельные интервалы.

Также очень важно правильно настроить НачалоПериодаОтображения и КонецПериодаОтображения, чтобы они соответствовали выбранной периодичности. Например, если мы хотим видеть текущую неделю, то НачалоПериодаОтображения должно быть НачалоНедели(ТекущаяДата()), а КонецПериодаОтображения — КонецНедели(ТекущаяДата()).

Пример настройки для отображения текущей недели:


&НаСервере
Процедура УстановитьОтображениеПоНеделям(Планировщик)
    Планировщик.ЕдиницаПериодическогоВарианта = ТипЕдиницыШкалыВремени.Неделя;
    Планировщик.КратностьПериодическогоВарианта = 1; // Одна неделя
    
    // Устанавливаем период отображения на текущую неделю
    Планировщик.НачалоПериодаОтображения = НачалоНедели(ТекущаяДата());
    Планировщик.КонецПериодаОтображения = КонецНедели(ТекущаяДата());

    // Возможно, потребуется также настроить ШкалаВремени.Положение = ПоложениеШкалыВремени.Верх;
    // для вертикальной шкалы времени, если измерения идут слева
КонецПроцедуры

&НаСервере
Процедура УстановитьОтображениеПоДнямСКратностью(Планировщик)
    Планировщик.ЕдиницаПериодическогоВарианта = ТипЕдиницыШкалыВремени.День;
    Планировщик.КратностьПериодическогоВарианта = 5; // Отображать 5 дней
    
    // Устанавливаем период отображения, например, на 5 дней вперед от текущей даты
    Планировщик.НачалоПериодаОтображения = НачалоДня(ТекущаяДата());
    Планировщик.КонецПериодаОтображения = НачалоДня(ТекущаяДата()) + 5 * 24 * 3600 - 1; // 5 дней минус 1 секунда, чтобы конец был в конце последнего дня
КонецПроцедуры

Экспериментируя с этими свойствами, мы можем добиться желаемого масштаба и детализации отображения Планировщика.

Обновление Планировщика при изменении данных в документе

Для того чтобы Планировщик всегда отображал актуальные данные, нам необходимо реализовать механизм его обновления при изменении исходных данных (например, в документе, который является источником заданий).

Наиболее эффективные подходы для этого:

  1. Обновление по событию ПриИзменении реквизитов: Если Планировщик отображает данные, зависящие от определенных полей на форме документа, можно вызывать процедуру заполнения Планировщика в обработчиках ПриИзменении для этих полей.
  2. Обновление по событию ПриЗаписи документа: После того как документ был записан, его данные изменились. В обработчике события ПриЗаписиНаСервере или ПослеЗаписиНаСервере мы можем обновить Планировщик на форме, если он открыт, или предусмотреть механизм для его обновления при следующем открытии.
  3. Обновление по событию ПриАктивизации формы: Если форма с Планировщиком может долго оставаться открытой, и данные могли измениться внешними факторами, можно обновлять Планировщик при каждой активации формы, чтобы гарантировать актуальность.

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

Оптимизация производительности при большом количестве измерений

Когда Планировщик содержит большое количество измерений (например, 260 и более), его отрисовка и взаимодействие могут стать очень медленными. Это является распространенной проблемой, и есть несколько подходов для ее решения.

  1. Порционная загрузка и отображение данных: Вместо того чтобы загружать и отрисовывать все 260 измерений и тысячи событий сразу, мы можем загружать только те, которые видны в текущем диапазоне прокрутки. Это требует реализации логики, которая отслеживает видимую область Планировщика и динамически подгружает/выгружает измерения и события.
  2. Оптимизация запросов к данным: Убедимся, что запросы, которые извлекают данные для Планировщика, максимально эффективны. Используем индексы, избегаем избыточных соединений и полей, не читаем данные, которые не будут использованы для Планировщика.
  3. Кэширование данных: Если данные изменяются редко, их можно кэшировать на сервере или клиенте. Это позволит избежать повторных обращений к базе данных при каждом обновлении или перерисовке Планировщика.
  4. Упрощение оформления элементов: Сложное оформление каждого элемента Планировщика (множество цветов, градиентов, иконок, большого объема текста) может значительно замедлять отрисовку. Попробуем максимально упростить визуальное представление.
  5. Перенос логики на клиент (при возможности): Если часть обработки данных возможно выполнить на клиенте, это может снять нагрузку с сервера.
  6. Использование альтернативных подходов (HTML + JS): В экстремальных случаях, когда встроенный Планировщик не справляется с объемами или требованиями к интерактивности, некоторые разработчики прибегают к полной переработке интерфейса с использованием веб-технологий (HTML + JavaScript). При этом сам элемент 1С:Планировщик не используется, а вместо него на форму встраивается поле HTML-документа, в котором рисуется собственный график. Это позволяет достичь очень высокой производительности и гибкости, но требует значительных усилий по разработке и поддержке. При таком подходе, данные также сначала извлекаются 1С-кодом, а затем передаются в JavaScript для отрисовки.

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

Дополнительные возможности и настройки Планировщика

Помимо рассмотренных выше вопросов, Планировщик предлагает ряд других полезных свойств и функций:

  1. ОтображатьПеренесенныеЗаголовки: Это свойство Планировщика влияет на то, как отображаются заголовки измерений и временной шкалы. Если оно установлено в Истина, заголовки измерений могут отображаться также и сверху, рядом с временной шкалой. Если мы хотим, чтобы измерения были только слева, а даты — только сверху (стандартное расположение), то это свойство должно быть установлено в Ложь.
  2. Хранение данных: Важно помнить, что Планировщик — это всего лишь "визуализатор". Он сам по себе не хранит данные. Все данные для элементов Планировщика (заданий, событий) должны храниться в нашей информационной базе — в регистрах, документах, справочниках. При открытии формы с Планировщиком мы должны программно выгружать данные из базы в Планировщик, а при их изменении — сохранять обратно.
  3. Настройка толщины рамки события: Для изменения толщины рамки отдельного элемента Планировщика используется свойство ЭлементПланировщика.Оформление.Рамка.Толщина. Мы можем установить это свойство, например, в обработчике события ПриПолученииДанных, где настраиваем оформление каждого элемента. Например, ЭлементПланировщика.Оформление.Рамка.Толщина = 2;.
  4. Выравнивание текста в элементе: Для настройки выравнивания текста внутри элемента Планировщика используется свойство ЭлементПланировщика.Оформление.ГоризонтальноеПоложениеТекста. Возможные значения включают ГоризонтальноеПоложениеТекста.Лево, ГоризонтальноеПоложениеТекста.Центр, ГоризонтальноеПоложениеТекста.Право.

Разобравшись с этими аспектами, мы сможем эффективно использовать Планировщик в наших решениях 1С:Предприятие 8.3, создавая удобные и функциональные интерфейсы для управления временными задачами и ресурсами.

← На главную