Как реализовать копирование и вставку ячеек из Excel в управляемую форму 1С?

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

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

Решение 1. Использование Поля табличного документа на форме

Наиболее простым, надежным и стандартным способом реализации подобного функционала является использование элемента формы Поле табличного документа. В отличие от обычной таблицы значений, табличный документ изначально спроектирован для работы с ячеистой структурой и отлично поддерживает стандартное сочетание клавиш Ctrl+C и Ctrl+V.

Рассмотрим подробнее процесс настройки формы для реализации этого механизма:

  1. Добавим на управляемую форму новый реквизит с типом данных ТабличныйДокумент (например, назовем его ТабДок).
  2. Перетащим этот реквизит на рабочую область формы, чтобы платформа автоматически создала элемент формы типа Поле табличного документа.
  3. Критически важный шаг: выделим созданный элемент формы в дереве элементов и в палитре свойств установим флажок Редактирование в значение Истина. Без этого свойства таблица откроется в режиме «только просмотр», и вставить в нее данные не удастся.
  4. Также убедимся, что на уровне самого объекта защита отключена. Это можно сделать программно при создании формы, прописав следующий код:

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    // Отключаем защиту табличного документа, чтобы разрешить редактирование и вставку
    ТабДок.Защита = Ложь;
КонецПроцедуры

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


&НаСервере
Процедура ПеренестиДанныеИзТабДокаВТабличнуюЧасть()
    // Получаем табличную часть нашего документа
    ТабличнаяЧасть = Объект.Товары;
    ТабличнаяЧасть.Очистить();
    
    // Определяем границы заполненной области табличного документа
    ВысотаТаблицы = ТабДок.ВысотаТаблицы;
    ШиринаТаблицы = ТабДок.ШиринаТаблицы;
    
    // Обходим строки табличного документа, начиная со второй (если первая строка - заголовок)
    Для СтрокаИндекс = 2 По ВысотаТаблицы Цикл
        // Проверяем, заполнена ли первая ячейка строки
        НоменклатураТекст = СокрЛП(ТабДок.Область(СтрокаИндекс, 1).Текст);
        Если ПустаяСтрока(НоменклатураТекст) Тогда
            Продолжить;
        КонецЕсли;
        
        // Создаем новую строку в табличной части 1С
        НоваяСтрока = ТабличнаяЧасть.Добавить();
        
        // Пытаемся найти номенклатуру по наименованию
        НайденнаяНоменклатура = Справочники.Номенклатура.НайтиПоНаименованию(НоменклатураТекст);
        Если ЗначениеЗаполнено(НайденнаяНоменклатура) Тогда
            НоваяСтрока.Номенклатура = НайденнаяНоменклатура;
        Иначе
            // Если номенклатура не найдена, можно обработать эту ситуацию (например, вывести предупреждение)
            Сообщить("Не удалось найти номенклатуру: " + НоменклатураТекст);
        КонецЕсли;
        
        // Получаем и преобразуем числовые данные
        КоличествоТекст = ТабДок.Область(СтрокаИндекс, 2).Текст;
        НоваяСтрока.Количество = Число(СтрЗаменить(КоличествоТекст, Символы.НПП, ""));
    КонецЦикла;
КонецПроцедуры

Решение 2. Прямая работа с буфером обмена в новых версиях платформы

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

Принцип работы строится на том, что при копировании ячеек из Excel в системном буфере обмена данные хранятся в виде обычного текста, где колонки разделены символом табуляции (Символы.Таб), а строки — переводом строки (Символы.ПС). Проанализируем пример кода, который считывает эти данные и программно заполняет таблицу значений на управляемой форме:


&НаКлиенте
Асинх Процедура ВставитьИзБуфераОбмена(Команда)
    Попытка
        // Получаем текстовое содержимое буфера обмена асинхронно
        ТекстБуфера = Ждать СредстваБуфераОбмена.ПолучитьДанныеАсинх(СтандартныйФорматДанныхБуфераОбмена.Текст);
        
        Если ПустаяСтрока(ТекстБуфера) Тогда
            ПоказатьПредупреждение(, "Буфер обмена пуст!");
            Возврат;
        КонецЕсли;
        
        // Парсим полученный текст и заполняем коллекцию
        ОбработатьТекстИзБуфера(ТекстБуфера);
    Исключение
        ВызватьИсключение "Не удалось получить данные из буфера обмена: " + ОписаниеОшибки();
    КонецПопытки;
КонецПроцедуры

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

Решение 3. Использование готовых механизмов БСП

Если ваша конфигурация разработана на основе Библиотеки стандартных подсистем (БСП), вам не обязательно изобретать велосипед и писать собственный парсер. В БСП присутствует великолепная стандартная подсистема «Загрузка данных из внешних файлов».

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

← На главную