Как скопировать данные из одного файла Excel в существующий лист другого файла в 1С без создания листа TDSheet?

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

При автоматизации обмена данными с файлами Microsoft Excel через COM-объект программисты 1С часто сталкиваются с ситуацией: при попытке скопировать данные из временной книги в определенный лист основной книги создается новый лист с именем TDSheet, а существующий лист остается без изменений.

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

Выясним причину проблемы

Проблема кроется в двух особенностях работы с Excel и платформой 1С:

  1. Происхождение имени TDSheet: Название TDSheet (сокращение от Table Document Sheet) автоматически присваивается листу платформой 1С при сохранении или экспорте объекта ТабличныйДокумент в форматы Excel (.xls или .xlsx).
  2. Поведение метода Worksheet.Copy(): В объектной модели Microsoft Excel COM/VBA метод Worksheet.Copy() предназначен исключительно для создания нового листа. Параметр, передаваемый в этот метод (например, ЛистПриемник), указан как позиция вставки. Excel воспринимает его лишь как ориентир, перед которым или после которого нужно вставить вновь созданную копию листа.

Таким образом, команда ЛистТемп.Copy(ЛистПриемник) не переносит данные внутрь листа ЛистПриемник, а создает новый лист (со стандартным именем TDSheet) рядом с ним.

Способ 1. Копирование заполненного диапазона ячеек (UsedRange)

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

Рассмотрим по шагам, как правильно реализовать этот процесс с сохранением форматирования и формул:


// Подключаемся к COM-объекту Excel
Ексель = Новый COMОбъект("Excel.Application");
Ексель.Visible = Ложь;
Ексель.DisplayAlerts = Ложь;

// Открываем целевую книгу и выбираем нужный лист
Книга = Ексель.Workbooks.Open(ИмяФайлаПриемника);
ЛистПриемник = Книга.WorkSheets("МойЛист");

// Открываем временный файл
КнигаТемп = Ексель.WorkBooks.Open(ИмяФайлаИсточник);
ЛистТемп = КнигаТемп.WorkSheets(1);

// Очищаем старое содержимое листа-приемника
ЛистПриемник.UsedRange.Clear();

// Копируем заполненный диапазон из источника в ячейку A1 приемника
ЛистТемп.UsedRange.Copy(ЛистПриемник.Range("A1"));

// Закрываем временную книгу
КнигаТемп.Close(Ложь);

// Сохраняем и закрываем основную книгу
Книга.Save();
Книга.Close();
Ексель.Quit();

Способ 2. Прямой перенос значений через массив (без применения буфера обмена)

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

Проанализируем пример кода:


КнигаТемп = Ексель.WorkBooks.Open(ИмяФайлаИсточник);
ЛистТемп = КнигаТемп.WorkSheets(1);

ЛистПриемник = Книга.WorkSheets("МойЛист");

// Очищаем данные на листе-приемнике
ЛистПриемник.UsedRange.Clear();

// Получаем размеры исходного диапазона
КоличествоСтрок = ЛистТемп.UsedRange.Rows.Count;
КоличествоКолонок = ЛистТемп.UsedRange.Columns.Count;

// Изменяем размер целевого диапазона и присваиваем значения напрямую
ЛистПриемник.Range("A1").Resize(КоличествоСтрок, КоличествоКолонок).Value = ЛистТемп.UsedRange.Value;

КнигаТемп.Close(Ложь);
Книга.Save();

Способ 3. Альтернатива без использования COM-соединения

Работа с COM-объектом Excel.Application требует наличия установленного пакета MS Office на компьютере и не подходит для выполнения на сервере под управлением ОС Linux или в фоновых заданиях. Если структура файла простая, вы можете прочитать файл средствами встроенного объекта ТабличныйДокумент:


ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ИмяФайлаИсточник, СпособЧтенияЗначенийТабличногоДокумента.Значения);

// Далее данные из ТабличногоДокумента можно обходить и обрабатывать средствами 1С
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;

Рекомендации по безопасности и производительности

  1. Очистка буфера: Если вы используете методы Copy() и Paste() через COM, очищайте режим копирования с помощью Ексель.CutCopyMode = Ложь, чтобы избегать блокировки буфера обмена.
  2. Освобождение ресурсов: Всегда закрывайте книги методом Close() и завершайте процесс Excel вызовом Quit(), иначе в диспетчере задач будут зависать фоновые процессы EXCEL.EXE.
  3. Обработка ошибок: Оборачивайте работу с COM-объектами в конструкцию Попытка ... Исключение, чтобы гарантированно закрывать открытые файлы при возникновении сбоев.
← На главную