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