Довольно часто при разработке пользовательских интерфейсов возникает задача: предоставить пользователю возможность быстро скопировать данные из внешней таблицы Excel и через буфер обмена перенести их на форму в 1С. Казалось бы, привычная комбинация клавиш Ctrl+C и Ctrl+V должна без проблем разнести данные по строкам и столбцам. Однако на практике разработчики сталкиваются с тем, что весь блок скопированных данных либо вставляется в виде сплошного текста в одну-единственную ячейку, либо вставка вовсе не срабатывает. Разберем по шагам, почему так происходит и как добиться корректного поведения табличного документа.
Проанализируем механику работы буфера обмена операционной системы и элементов управления 1С. Когда пользователь копирует диапазон ячеек из Excel, данные помещаются в буфер в виде текста, где столбцы разделены символами табуляции, а строки — знаками перевода строки. Поведение табличного документа 1С при нажатии Ctrl+V напрямую зависит от текущего состояния ячейки и настроек элемента формы:
Защита = Истина, либо ячейка имеет флаг ТолькоПросмотр = Истина, платформа не позволит вставить блок данных по ячейкам.Для того чтобы штатный механизм копирования и вставки заработал «из коробки», необходимо корректно выставить свойства элемента формы и самого табличного документа. Выполним следующие настройки:
ТабличныйДокумент или элемента управления на форме.Ложь), а флаг Редактирование — установлен (значение Истина).Посмотрим на пример установки необходимых свойств в коде формы:
&НаСервере
Процедура ИнициализироватьТабличныйДокумент()
// Отключаем защиту и просмотр, разрешаем редактирование сетки
Элементы.ПолеТабличногоДокумента.ТолькоПросмотр = Ложь;
ТабличныйДокумент.ТолькоПросмотр = Ложь;
ТабличныйДокумент.Защита = Ложь;
// Включаем вывод сетки для удобства позиционирования
ТабличныйДокумент.ОтображатьСетку = Истина;
ТабличныйДокумент.ОтображатьЗаголовки = Истина;
КонецПроцедуры
После применения этих свойств меняется и порядок действий пользователя:
В ряде сценариев требуется переносить скопированные данные не просто в свободные ячейки макета, а в строгую структуру данных — например, с валидацией типов, проверкой заполнения или вставкой в стандартную таблицу формы. Поскольку платформа 1С не поддерживает напрямую вставку внешней сетки данных в объект ТаблицаФормы через буфер, рассмотрим способ программного перехвата текста из буфера обмена операционной системы Windows с последующим разбором.
Разберем по шагам, как получить текст буфера и разложить его по ячейкам табличного документа:
&НаКлиенте
Процедура ВставитьИзБуфераОбмена()
// Получаем доступ к буферу обмена через COM-объект браузера
Попытка
ОбъектБуфера = Новый COMОбъект("htmlfile");
ТекстБуфера = ОбъектБуфера.ParentWindow.ClipboardData.GetData("Text");
Исключение
Сообщить("Не удалось прочитать буфер обмена: " + ОписаниеОшибки());
Возврат;
КонецПопытки;
Если ПустаяСтрока(ТекстБуфера) Тогда
Возврат;
КонецЕсли;
// Определяем начальную позицию вставки
ТекущаяОбласть = Элементы.ПолеТабличногоДокумента.ТекущаяОбласть;
Если ТекущаяОбласть = Неопределено Тогда
НачальнаяСтрока = 1;
НачальнаяКолонка = 1;
Иначе
НачальнаяСтрока = ТекущаяОбласть.Верх;
НачальнаяКолонка = ТекущаяОбласть.Лево;
КонецЕсли;
// Разбиваем полученный текст на массив строк
МассивСтрок = СтрРазделить(ТекстБуфера, Символы.ПС, Ложь);
Для ИндексСтроки = 0 По МассивСтрок.Количество() - 1 Цикл
СтрокаТекста = МассивСтрок[ИндексСтроки];
// Убираем возможный символ возврата каретки
СтрокаТекста = СтрЗаменить(СтрокаТекста, Символы.ВК, "");
Если ПустаяСтрока(СтрокаТекста) И ИндексСтроки = (МассивСтрок.Количество() - 1) Тогда
// Пропускаем последнюю пустую строку, часто возникающую при копировании
Продолжить;
КонецЕсли;
// Разбиваем строку на колонки по символу табуляции
МассивКолонок = СтрРазделить(СтрокаТекста, Символы.Таб, Истина);
Для ИндексКолонки = 0 По МассивКолонок.Количество() - 1 Цикл
ЗначениеЯчейки = МассивКолонок[ИндексКолонки];
НомерСтроки = НачальнаяСтрока + ИндексСтроки;
НомерКолонки = НачальнаяКолонка + ИндексКолонки;
ОбластьЯчейки = ТабличныйДокумент.Область(НомерСтроки, НомерКолонки);
ОбластьЯчейки.Текст = СокрЛП(ЗначениеЯчейки);
КонецЦикла;
КонецЦикла;
КонецПроцедуры
Рассмотрим важные нюансы, с которыми можно столкнуться при использовании как стандартного, так и программного метода переноса:
COMОбъект("htmlfile") доступно только на платформе Windows в толстом или тонком клиенте. Для веб-клиента и операционных систем на базе Linux данный вариант не подходит из-за архитектурных ограничений безопасности браузера. В веб-клиенте рекомендуется полагаться на штатную вставку через одиночный клик или использовать диалог загрузки файла.