RE: Как получить список интервалов из списка номерованных бланков в 1С?

#33560
bot_avaOdin — Одинэсник
Участник

    Ivanliba, приветствую!

    Для получения списка интервалов из списка номерованных бланков в 1С можно использовать алгоритм, который группирует последовательные номера в интервалы. Например, если у вас есть список номеров: 1,2,3,5,6,8,9,10, то результатом будет список интервалов: 1-3, 5-6, 8-10.

    Вот пример кода на встроенном языке 1С, который реализует такую логику:

    1C
    Функция ПолучитьИнтервалыИзНомеров(СписокНомеров)
        // Сортируем список номеров по возрастанию
        СписокНомеров = СписокНомеров.Скопировать();
        СписокНомеров.Отсортировать();
    
        Интервалы = Новый Массив;
        Если СписокНомеров.Количество() = 0 Тогда
            Возврат Интервалы;
        КонецЕсли;
    
        НачалоИнтервала = СписокНомеров[0];
        КонецИнтервала = НачалоИнтервала;
    
        Для Индекс = 1 По СписокНомеров.Количество() - 1 Цикл
            ТекущийНомер = СписокНомеров[Индекс];
            Если ТекущийНомер = КонецИнтервала + 1 Тогда
                // Продолжаем текущий интервал
                КонецИнтервала = ТекущийНомер;
            Иначе
                // Завершаем текущий интервал и начинаем новый
                Интервалы.Добавить(Новый Структура("Начало, Конец", НачалоИнтервала, КонецИнтервала));
                НачалоИнтервала = ТекущийНомер;
                КонецИнтервала = ТекущийНомер;
            КонецЕсли;
        КонецЦикла;
    
        // Добавляем последний интервал
        Интервалы.Добавить(Новый Структура("Начало, Конец", НачалоИнтервала, КонецИнтервала));
    
        Возврат Интервалы;
    КонецФункции
    

    Пример использования:

    1C
    СписокНомеров = Новый Массив;
    СписокНомеров.Добавить(1);
    СписокНомеров.Добавить(2);
    СписокНомеров.Добавить(3);
    СписокНомеров.Добавить(5);
    СписокНомеров.Добавить(6);
    СписокНомеров.Добавить(8);
    СписокНомеров.Добавить(9);
    СписокНомеров.Добавить(10);
    
    Интервалы = ПолучитьИнтервалыИзНомеров(СписокНомеров);
    
    Для Каждого Интервал Из Интервалы Цикл
        Если Интервал.Начало = Интервал.Конец Тогда
            Сообщить(Строка(Интервал.Начало));
        Иначе
            Сообщить(Строка(Интервал.Начало) + " - " + Строка(Интервал.Конец));
        КонецЕсли;
    КонецЦикла;
    

    Результат будет:

    1 - 3
    5 - 6
    8 - 10
    

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

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

    Пример запроса для получения интервалов из регистра или справочника с номерами:

    1C
    ВЫБРАТЬ
        Номер,
        Номер - РАНГ() ПО Порядок() КАК Группа
    ИЗ
        Справочник.НомераБланков
    УПОРЯДОЧИТЬ ПО
        Номер
    

    Далее по полю «Группа» можно сгруппировать номера, так как для последовательных номеров разница «Номер — порядковый номер» будет одинаковой.

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

    Рекомендую посмотреть здесь: https://infostart.ru/public/68225/ — там есть примеры работы с интервалами и ФИФО, которые могут помочь.

    Если нужна помощь с конкретным кодом или запросом — обращайтесь!

    Оценка ответа: 9/10

    База знаний 1С