Как добавить очень большое количество сотрудников в базу 1С?

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

Когда мы только начинаем изучать систему 1С:Предприятие, мы часто сталкиваемся с базовыми понятиями, такими как "Массивы" и методы их заполнения. Например, чтобы добавить несколько элементов в массив, мы используем метод Добавить() для каждого элемента:


Сотрудники = Новый Массив;
Сотрудники.Добавить("Иванов");
Сотрудники.Добавить("Петров");
Сотрудники.Добавить("Сидоров");

Такой подход хорошо работает для небольшого количества элементов. Но что делать, если нам нужно добавить 10 000 сотрудников, особенно если мы заполняем базу данных "с нуля" или переносим данные из других систем? Очевидно, что добавление каждого элемента по одному вручную или даже программно, но последовательно вызывая метод Добавить(), становится крайне неэффективным и трудоемким.

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

Понимание задачи: Массив или база данных?

Прежде всего, давайте разберем ключевой момент: мы хотим добавить данные в массив в памяти или создать новые элементы в справочнике базы данных? Изначальный вопрос касался массива, но потребность в 10 000 сотрудниках часто подразумевает именно создание элементов справочника. Мы рассмотрим оба аспекта, так как чтение данных из внешних источников часто является первым шагом к их последующей загрузке в базу.

1. Чтение данных из внешнего файла в массив 1С

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

  1. Чтение из текстового файла

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

    
    ИмяФайла = "C:\ПутьКФайлу\Сотрудники.txt";
    МассивСотрудников = Новый Массив;
    
    Попытка
        // Указываем кодировку файла, например, UTF8. Важно, чтобы кодировка файла совпадала.
        Чтение = Новый ЧтениеТекста(ИмяФайла, КодировкаТекста.UTF8); 
        СтрокаФайла = Чтение.ПрочитатьСтроку();
        Пока СтрокаФайла <> Неопределено Цикл
            Если Не ПустаяСтрока(СтрокаФайла) Тогда
                МассивСотрудников.Добавить(СтрокаФайла);
            КонецЕсли;
            СтрокаФайла = Чтение.ПрочитатьСтроку();
        КонецЦикла;
        Чтение.Закрыть();
        Сообщить("Успешно прочитано " + МассивСотрудников.Количество() + " строк из файла.");
    Исключение
        Сообщить("Ошибка при чтении файла " + ИмяФайла + ": " + ОписаниеОшибки());
    КонецПопытки;
    
    

    Таким образом, мы построчно читаем файл и добавляем каждую строку в наш массив. Если данные в файле более структурированы (например, содержат ФИО, должность, отдел через разделитель, такой как запятая или точка с запятой), вам потребуется дополнительная обработка каждой строки для извлечения нужных полей и, возможно, создания для каждого сотрудника не просто строки, а структуры или соответствия, которые уже будут добавлены в массив.

  2. Чтение из Excel-файла

    Для чтения данных из Excel-файла мы можем использовать COM-объект Excel.Application. Этот подход позволяет получить доступ к данным ячеек и листов Excel. Он требует установленного на компьютере клиента Microsoft Excel.

    
    ИмяФайлаExcel = "C:\ПутьКФайлу\Сотрудники.xlsx";
    МассивСотрудников = Новый Массив;
    Excel = Неопределено; // Объявляем переменную заранее
    
    Попытка
        Excel = Новый COMОбъект("Excel.Application");
        Excel.Visible = Ложь; // Не показывать Excel на экране
        Книга = Excel.Workbooks.Open(ИмяФайлаExcel);
        Лист = Книга.Sheets(1); // Обращаемся к первому листу
    
        // Определяем количество строк с данными. 
        // UsedRange возвращает диапазон используемых ячеек.
        ПоследняяСтрока = Лист.UsedRange.Rows.Count; 
    
        // Начинаем со 2-й строки, если 1-я строка содержит заголовки
        Для ИндексСтроки = 2 По ПоследняяСтрока Цикл 
            ФИО = Лист.Cells(ИндексСтроки, 1).Value; // Колонка 1 для ФИО
            Если Не ПустаяСтрока(ФИО) Тогда
                МассивСотрудников.Добавить(ФИО);
            КонецЕсли;
        КонецЦикла;
    
        Книга.Close(0); // Закрываем книгу без сохранения
        Excel.Quit(); // Закрываем приложение Excel
        Сообщить("Успешно прочитано " + МассивСотрудников.Количество() + " сотрудников из Excel.");
    Исключение
        Сообщить("Ошибка при чтении Excel-файла " + ИмяФайлаExcel + ": " + ОписаниеОшибки());
        Если Excel <> Неопределено Тогда
            Excel.Quit(); // Убеждаемся, что приложение Excel закрыто при ошибке
        КонецЕсли;
    КонецПопытки;
    

    Этот пример считывает только ФИО из первой колонки. При более сложной структуре данных в Excel, мы будем считывать значения из нескольких колонок (например, Лист.Cells(ИндексСтроки, 2).Value для должности) и формировать из них, например, структуру или соответствие для каждого сотрудника, а затем добавлять эти структуры в массив.

  3. Использование ТаблицыЗначений для формирования массива

    В системе 1С часто используется объект ТаблицаЗначений для временного хранения и обработки данных. Если у вас уже есть данные в ТаблицеЗначений (например, после выполнения запроса к базе данных или после загрузки из файла через другие механизмы), вы можете легко выгрузить одну из ее колонок в массив.

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

    Метод ВыгрузитьКолонку() объекта ТаблицаЗначений является очень удобным способом быстро получить массив из значений определенной колонки. Если нам нужен массив не просто ФИО, а более сложных объектов (например, структур), нам потребуется в цикле перебрать строки таблицы значений и вручную добавлять структуры в новый массив.

2. Программное создание элементов справочника в базе данных: как добавить 10 000 сотрудников

Теперь перейдем к главной задаче: как эффективно создать 10 000 новых элементов справочника "Сотрудники" (или любого другого справочника) в самой базе 1С. Простое последовательное создание и запись каждого элемента с помощью СоздатьЭлемент() и Записать() будет чрезвычайно медленным из-за множества обращений к базе данных. Здесь нам на помощь приходят транзакции и другие методы оптимизации.

Транзакции для массовой записи

Транзакция – это группа последовательных операций (например, записи, изменения, удаления), которая выполняется как единая логическая единица работы. Либо все операции внутри транзакции успешно завершаются (транзакция фиксируется), либо, если происходит ошибка, все изменения, сделанные внутри транзакции, откатываются к состоянию до начала транзакции. Это гарантирует целостность данных и значительно повышает производительность при массовых операциях.

В 1С мы используем следующие методы для работы с транзакциями:

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

Разберем процесс по шагам:

  1. Подготовка данных: Сначала нам нужно получить данные о 10 000 сотрудниках из нашего внешнего источника (например, текстового файла или Excel) и подготовить их в удобном для обработки формате, например, в массиве структур или ТаблицеЗначений.
  2. Цикл создания элементов с транзакциями: Мы будем перебирать наши данные о сотрудниках, создавать для каждого элемент справочника и записывать его. Каждые N записей мы будем фиксировать транзакцию и начинать новую.

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


// Предположим, у нас есть МассивСотрудников, полученный из внешнего файла,
// где каждый элемент массива - это Структура с данными сотрудника (ФИО, Должность и т.д.)
// Пример заполнения массива для демонстрации:
МассивСотрудников = Новый Массив;
Для И = 1 По 10000 Цикл
    МассивСотрудников.Добавить(Новый Структура("ФИО, Должность", "Сотрудник " + И, "Должность " + (И % 10 + 1)));
КонецЦикла;

РазмерПакетаТранзакции = 1000; // Оптимальное количество элементов в одной транзакции
СчетчикЗаписейВТранзакции = 0;
ВсегоСоздано = 0;

Попытка
    НачатьТранзакцию(); // Начинаем первую транзакцию

    Для Каждого ДанныеСотрудника Из МассивСотрудников Цикл
        НовыйСотрудник = Справочники.Сотрудники.СоздатьЭлемент();
        НовыйСотрудник.Наименование = ДанныеСотрудника.ФИО; // Пример: ФИО в Наименование
        НовыйСотрудник.Должность = ДанныеСотрудника.Должность; // Пример: Должность
        // Заполняем другие реквизиты элемента справочника из ДанныеСотрудника, например:
        // НовыйСотрудник.ИНН = ДанныеСотрудника.ИНН; 
        // НовыйСотрудник.ДатаПриемаНаРаботу = ДанныеСотрудника.ДатаПриема;

        НовыйСотрудник.Записать(); // Записываем элемент, но изменения пока не фиксируются в базе до ЗафиксироватьТранзакцию()

        СчетчикЗаписейВТранзакции = СчетчикЗаписейВТранзакции + 1;
        ВсегоСоздано = ВсегоСоздано + 1;

        Если СчетчикЗаписейВТранзакции >= РазмерПакетаТранзакции Тогда
            ЗафиксироватьТранзакцию(); // Фиксируем изменения текущего пакета
            Сообщить("Зафиксирован пакет из " + СчетчикЗаписейВТранзакции + " сотрудников. Всего создано: " + ВсегоСоздано);
            СчетчикЗаписейВТранзакции = 0;
            НачатьТранзакцию(); // Начинаем новую транзакцию для следующего пакета
        КонецЕсли;
    КонецЦикла;

    // Фиксируем оставшиеся элементы, если они не набрали полный пакет
    Если СчетчикЗаписейВТранзакции > 0 Тогда
        ЗафиксироватьТранзакцию();
        Сообщить("Зафиксирован последний пакет из " + СчетчикЗаписейВТранзакции + " сотрудников. Всего создано: " + ВсегоСоздано);
    КонецЕсли;

Исключение
    // В случае ошибки, откатываем все изменения текущей транзакции
    ОтменитьТранзакцию();
    Сообщить("Произошла ошибка при создании сотрудников. Транзакция отменена. " + ОписаниеОшибки());
    Возврат;
КонецПопытки;

Сообщить("Процесс создания сотрудников завершен. Всего успешно создано: " + ВсегоСоздано);

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

Важно: Подбор оптимального значения РазмерПакетаТранзакции может потребовать экспериментов в вашей конкретной конфигурации и на вашем оборудовании. Начните с 500-1000 и корректируйте, наблюдая за производительностью и потреблением ресурсов.

Стандартные механизмы загрузки данных

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

Мы настоятельно рекомендуем рассмотреть использование этих стандартных механизмов, если они подходят для вашей задачи. Они часто включают в себя:

  1. Выбор справочника или документа, в который будут загружаться данные.
  2. Указание источника данных (файл Excel, CSV, текстовый файл или табличный документ 1С формата .mxl).
  3. Настройку сопоставления колонок в исходном файле с реквизитами справочника 1С.
  4. Определение правил поиска существующих элементов для обновления (например, по наименованию, коду, ИНН) или всегда создавать новые.
  5. Выполнение загрузки, часто с возможностью предварительного просмотра, протоколирования ошибок и гибкой настройкой поведения при возникновении проблем.

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

Дополнительные оптимизации при работе с большими объемами данных

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

  1. Оптимизация запросов: Если данные для создания элементов вы извлекаете из других частей базы 1С или у вас есть сложные условия выборки, убедитесь, что ваши запросы к базе данных максимально оптимизированы. Это включает уменьшение количества соединений, использование индексов, избегание операций, требующих полного сканирования больших таблиц, а также использование пакетных запросов, если это возможно.
  2. Использование клиент-серверной архитектуры: Для работы с большими базами данных и большим количеством пользователей, а также для операций, требующих значительных вычислительных ресурсов, переход на клиент-серверный вариант работы (с использованием СУБД типа MS SQL Server, PostgreSQL или IBM DB2) является практически обязательным. Сервер СУБД эффективно обрабатывает данные, что многократно повышает скорость и стабильность системы за счет более эффективного управления ресурсами и параллельной обработки.
  3. Отключение индексирования и контроля уникальности (с осторожностью): В некоторых очень специфических случаях, для экстремально быстрой загрузки, можно временно отключать некоторые индексы или контроль уникальности в справочниках на время загрузки, а затем включать их обратно и перестраивать индексы. Этот подход требует очень глубокого понимания системы и потенциальных рисков нарушения целостности данных, поэтому его следует применять крайне осторожно и только в контролируемых условиях, при этом обязательно имея свежую резервную копию базы данных.
  4. Внешние источники данных и интеграция: Для очень больших объемов данных, которые нецелесообразно хранить непосредственно в базе 1С, или для частой синхронизации с другими системами, можно использовать внешние базы данных. 1С имеет механизмы интеграции с ними, например, через веб-сервисы, HTTP-сервисы, или прямые подключения к внешним базам данных (технология ADO/OLE DB), что позволяет работать с данными без их физического перемещения в базу 1С.

Заключение

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

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

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

← На главную