Почему 1С зависает при сохранении большого пакета данных в Excel и как это исправить?

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

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

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

Анализируем проблему: ограничения Excel и 1С

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

  1. Ограничения Microsoft Excel

    Ключевым фактором является сам формат Excel. Мы должны учитывать следующие жесткие ограничения:

    • Максимальное количество строк: Начиная с версии Excel 2007 (включая Office 2016, как в нашем случае), максимальное количество строк на одном листе составляет 1 048 576. Попытка записать большее количество строк в один лист Excel приведет к ошибке, как это было подтверждено в сообщении 9 ("Ошибка экспорта табличного документа: Документ Excel 2007 не может содержать более 16384 колонок и 1048576 строк").

    • Максимальное количество столбцов: На одном листе Excel может быть не более 16 384 столбцов.

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

  2. Производительность Excel при работе с большими данными

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

    • Долгое открытие и сохранение файла.

    • Замедление при прокрутке, фильтрации и сортировке данных.

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

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

  3. Нехватка системных ресурсов

    Экспорт очень большого объема данных требует значительных ресурсов как от сервера 1С, так и от клиентского компьютера (если экспорт выполняется на клиенте):

    • Оперативная память (ОЗУ): При обработке миллионов строк требуется значительный объем памяти для хранения данных в процессе формирования Excel-файла.

    • Процессор: Процесс формирования и записи файла Excel является ресурсоемким и требует вычислительной мощности.

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

    Зависания могут быть вызваны нехваткой этих ресурсов, а не только ошибками в коде 1С.

  4. Методика работы 1С с пакетами документов

    1С для сохранения в Excel использует внутренние компоненты, а не напрямую офисное приложение (сообщение 8). Метод ПакетОтображаемыхДокументов.Записать() является высокоуровневым и абстрагируется от низкоуровневой работы с Excel. Однако, даже эта компонента подчиняется ограничениям формата Excel и системным ресурсам.

    В нашем случае, попытка записать 10 000 000+ строк через ПакетОтображаемыхДокументов, даже с разбивкой на 11 листов по 1 000 000 записей на лист, все равно привела к зависанию, что указывает на общую проблему масштабируемости.

Основные подходы к решению проблемы

Теперь, когда мы понимаем причины зависаний, рассмотрим эффективные стратегии для экспорта больших объемов данных из 1С.

  1. Разбивка данных на части

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

    Разбивка на листы в одном файле

    Если заказчику критично получить данные в одном файле, мы можем разбивать их на листы. Однако помним, что оптимальное количество строк на лист может быть значительно меньше максимального лимита в 1 048 576. Мы можем начать с 100 000 строк на лист или даже с 65 536 строк (старый лимит Excel, который часто является более производительным для обработки), как предлагалось в сообщениях 2 и 7.

    Разбивка на отдельные файлы

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

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

    Пример реализации в 1С

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

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

    
    // Инициализируем переменные для отслеживания количества строк и файлов
    МаксимальноеКоличествоСтрокНаЛист = 1000000; // Пример: 1 миллион строк на лист
    МаксимальноеКоличествоЛистовВФайле = 2;   // Пример: 2 листа в одном Excel-файле
    
    // Предполагаем, что у нас есть ТаблицаЗначений, которую нужно выгрузить
    // Замените этот код на ваш способ получения данных в ТабДок
    ТабДок = Новый ТабличныйДокумент();
    // ... Код по заполнению ТабДок из ТаблицаЗначений ...
    
    ПутьКФайлу = "C:\Выгрузки\"; // Укажите желаемый путь
    ИмяФайлаБезРасширения = Формат(ТекущаяДата, "ДФ='dd.MM.yyyy'") + "_отчет_";
    
    СчетчикФайлов = 1;
    ПакетДокументов = Новый ПакетОтображаемыхДокументов();
    НомерТекущегоЛиста = 1;
    
    // Здесь имитируем добавление данных в ТабДок и его листы
    // В реальном сценарии вы будете итерировать по вашим данным
    // и добавлять их в ТабДок, а затем в ПакетОтображаемыхДокументов
    
    // Допустим, мы хотим выгрузить 10 миллионов строк
    // Для примера, создадим "много" строк в ТабДок, чтобы показать логику
    // В реальном коде у вас уже будет заполненный ТабДок или вы будете заполнять его порциями.
    // Для демонстрации представим, что ТабДок уже содержит данные для первого листа
    // ТабДок.Очистить();
    // Для Инд = 1 По МаксимальноеКоличествоСтрокНаЛист Цикл
    //     ТабДок.ВывестиСекцию("СтрокаТаблицы"); // Предполагаем наличие секции
    // КонецЦикла;
    // Это был бы первый лист.
    // Далее мы имитируем создание нескольких листов и их добавление в пакет.
    
    Для НомерЛиста = 1 По 11 Цикл // Имитируем создание 11 листов
        // Создаем новый табличный документ для каждого листа
        ТекущийЛистТабДок = Новый ТабличныйДокумент();
        // Здесь мы заполняем ТекущийЛистТабДок данными
        // Для примера, просто добавим заголовок и предположим, что
        // данные будут добавлены внутри цикла
        ТекущийЛистТабДок.Область(1,1).Текст = "Лист №" + НомерЛиста;
        // Предположим, что ТекущийЛистТабДок содержит до МаксимальноеКоличествоСтрокНаЛист строк
        // ... Код по заполнению ТекущийЛистТабДок ...
    
        // Добавляем текущий табличный документ как лист в пакет
        ПакетДокументов.Добавить(ТекущийЛистТабДок, "Лист " + НомерЛиста);
        НомерТекущегоЛиста = НомерТекущегоЛиста + 1;
    
        // Проверяем, достигли ли мы максимального количества листов для текущего файла
        Если ПакетДокументов.КоличествоЛистов() = МаксимальноеКоличествоЛистовВФайле Тогда
            // Сохраняем текущий пакет в новый файл
            ПолныйПутьКФайлу = ПутьКФайлу + ИмяФайлаБезРасширения + СчетчикФайлов + ".xlsx";
            Сообщить("Сохраняем файл: " + ПолныйПутьКФайлу);
            ПакетДокументов.Записать(ПолныйПутьКФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
                    
            // Создаем новый пакет для следующей части данных
            ПакетДокументов = Новый ПакетОтображаемыхДокументов();
            СчетчикФайлов = СчетчикФайлов + 1;
            НомерТекущегоЛиста = 1; // Сбрасываем счетчик листов для нового файла
        КонецЕсли;
    КонецЦикла;
    
    // Сохраняем оставшиеся данные, если они есть в последнем пакете
    Если ПакетДокументов.КоличествоЛистов() > 0 Тогда
        ПолныйПутьКФайлу = ПутьКФайлу + ИмяФайлаБезРасширения + СчетчикФайлов + ".xlsx";
        Сообщить("Сохраняем последний файл: " + ПолныйПутьКФайлу);
        ПакетДокументов.Записать(ПолныйПутьКФайлу, ТипФайлаПакетаОтображаемыхДокументов.XLSX);
    КонецЕсли;
    
    Сообщить("Выгрузка завершена.");
    

    Мы можем экспериментировать с оптимальным количеством строк на лист или количеством листов в файле. Начинайте с меньших значений (например, 100 000 строк на лист или 1 лист на файл), а затем постепенно увеличивайте их, чтобы найти баланс между удобством для заказчика и производительностью.

  2. Использование альтернативных форматов данных

    Если конечная цель — анализ данных, а не интерактивная работа именно в Excel с его формулами и форматированием, мы можем рассмотреть другие, более эффективные форматы для выгрузки больших объемов информации. Для быстрой передачи данных отчетов в аналитические системы можно использовать решение для обмена данными с MS Power BI и Excel.

    Эти форматы гораздо лучше подходят для машинной обработки и интеграции с другими системами.

    • CSV (Comma Separated Values): Этот формат является текстовым, "легким" и идеально подходит для экспорта больших объемов данных. CSV-файлы быстро генерируются и могут быть легко импортированы в различные системы анализа, включая сам Excel, базы данных (SQL), BI-инструменты или специализированные скрипты обработки данных. Они не имеют ограничений Excel на количество строк и значительно быстрее в создании.

    • XML / JSON: Эти форматы предназначены для обмена структурированными данными. XML более многословен, в то время как JSON обычно более компактен и быстрее обрабатывается, занимая меньше места благодаря меньшему количеству служебных тегов. Они отлично подходят для интеграции с внешними системами и веб-сервисами, где требуется передача данных со сложной структурой.

    • HTML4: В некоторых случаях выгрузка в "Документ HTML4" может быть значительно быстрее, чем в XLS. Такой файл корректно открывается в Excel, где его при необходимости можно пересохранить в нужный формат (например, XLSX), если пользователь все же хочет работать с ним в Excel. Это может быть компромиссным решением, ускоряющим этап выгрузки.

    • Прямой доступ к SQL-базе: Для опытных программистов и системных администраторов, при наличии соответствующей лицензии и глубоких знаний T-SQL, возможен прямой доступ к базе данных, на которой работает 1С (MS SQL, PostgreSQL). Этот метод обеспечивает максимальную скорость извлечения данных, так как мы работаем непосредственно с СУБД, минуя интерфейс 1С. Однако такой подход требует осторожности, понимания архитектуры базы данных 1С и может нарушать лицензионную политику.

    • Экстракторы данных / BI-системы: Существуют специализированные инструменты (например, "Экстрактор 1С"), разработанные для высокоскоростной выгрузки больших объемов данных из 1С в аналитические базы данных (например, ClickHouse, MS SQL) для дальнейшей обработки и анализа в Business Intelligence (BI) системах (например, Power BI, Tableau). Эти решения часто поддерживают многопоточность, инкрементальную загрузку данных и оптимизированы для работы с миллионами и миллиардами записей.

  3. Оптимизация программного экспорта из 1С

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

    • Минимизация обращений к COM-объектам Excel: Если мы используем прямую работу с объектами COM Excel (что в случае ПакетОтображаемыхДокументов осуществляется через внутренние компоненты 1С, но важно для общего понимания), следует минимизировать количество таких обращений. Например, лучше заполнить диапазон ячеек за одно обращение, чем каждую ячейку по отдельности.

    • Загрузка данных в массивы и обработка порциями: Вместо построчной записи данных непосредственно в файл, мы можем сначала собрать необходимые данные в массив или таблицу значений в 1С, а затем выгружать их блоками. Это уменьшает накладные расходы на каждое отдельное действие записи.

    • Фоновый режим: В 1С есть возможность запускать длительные операции, такие как экспорт данных, в фоновом режиме. Это позволяет пользователю продолжить работу в системе, не дожидаясь завершения экспорта. Механизм фоновых заданий особенно полезен для очень больших выгрузок, которые могут занимать часы.

    • Настройка размера буфера экспорта: Некоторые методы экспорта в 1С позволяют настраивать размер буфера, что может влиять на производительность при работе с большими объемами данных.

  4. Работа с требованиями заказчика

    Часто заказчики настаивают на получении "одного файла Excel" с огромным объемом данных, не осознавая технических ограничений и проблем с производительностью, как это было отмечено в сообщении 15 и 17. В таких ситуациях наша задача — не просто отказать, а объяснить ситуацию и предложить более эффективные альтернативы.

    • Демонстрация проблемы: Лучший способ убедить заказчика — это наглядно продемонстрировать проблему. Предложите ему попробовать открыть и поработать с тестовым файлом в 1 миллион строк, который, как мы видели, может сохраняться 30 минут и весить сотни мегабайт. Заказчик быстро поймет, что интерактивная работа с таким файлом будет неэффективной и неудобной.

    • Предложение компромиссов: Возможно, удастся договориться о нескольких файлах (например, по два листа на файл, как предлагал автор в сообщении 15, или по 100 000 строк в файле), которые будет проще обрабатывать. Или о переходе на другой формат с возможностью последующей обработки в специализированных инструментах.

    • Объяснение альтернативных инструментов анализа: Если речь идет об аналитике, возможно, Excel не является лучшим инструментом для миллионов записей. Мы можем предложить использовать BI-системы, базы данных или специализированные отчеты в 1С, которые могут обрабатывать большие объемы данных гораздо более эффективно и предоставлять более гибкие возможности для анализа.

    • Ссылки на регламентные выгрузки: Если у заказчика уже есть регламентные выгрузки по 900 000 строк, которые работают, это подтверждает, что объемы до 1 миллиона строк могут быть жизнеспособными, но требуют времени. Это можно использовать как отправную точку для дальнейших предложений по оптимизации.

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

← На главную