Каталог решений - Управляемые формы: чтение макетов с объединенными ячейками (в частности, и из экселей)

Управляемые формы: чтение макетов с объединенными ячейками (в частности, и из экселей)

Управляемые формы: чтение макетов с объединенными ячейками (в частности, и из экселей)

В наличии

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

Категория:

Описание

Всем добрый период времени!

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

ЧТЕНИЕ ТАБЛИЧНОГО ДОКУМЕНТА

Для чтения табличного документа в 1С можно использовать как ни странно объект "ТабличныйДокумент". С версии 8.3.7 (если не изменяет память) данный объект способен читать не только MXL-файлы, но и XLS/XLSX/ODT и какие-то еще варианты таблиц (а также, кстати, и писать).

Но как всегда есть одна малюсенькая проблемка — объект создается только на сервере. Но 1С попыталась решить данную проблему создав потоки в памяти и предоставив программисту возможность использовать их вместо пути к файлу в конструкторе объекта, но при этом необходимо указать тип читаемого файла. Правда у меня на платформе Windows 7 pro x64 c 1C 8.3.10.2466 эксель таким образом прочитать не получилось, а вот MXL читает замечательно, поэтому для екселевский файлов все-равно придется создать временный файл.

Итак, код чтения файлов:

&НаСервере
Процедура ЗагрузитьФайлНаСервере(ДД, Расширение)

	Если Расширение = "xml" Тогда 
		ЧД = Новый ЧтениеДанных(ДД);
		Таб.Прочитать(ЧД, СпособЧтенияЗначенийТабличногоДокумента.Значение, ТипФайлаТабличногоДокумента.MXL);
	Иначе
		ИмяФайла = ПолучитьИмяВременногоФайла(Расширение);
		ДД.Записать(ИмяФайла);
		Таб.Прочитать(ИмяФайла);
		УдалитьФайлы(ИмяФайла);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьФайл(Команда)
	
	Длг = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Длг.Фильтр = "MXL-files (*.mxl)|*.mxl|XLS-files (*.xls)|*.xls|XLSX-files (*.xlsx)|*.xlsx|ODS-files (*.ods)|*.ods";
	Длг.Показать(Новый ОписаниеОповещения("ПриВыбореФайла", ЭтаФорма));
	
КонецПроцедуры

&НаКлиенте
Процедура ПриВыбореФайла(Рез, Доп) Экспорт 
	
	Если Рез = Неопределено Тогда 
		Возврат
	КонецЕсли;
	
	фл = Новый Файл(Рез[0]);

	ЗагрузитьФайлНаСервере(
			Новый ДвоичныеДанные(Рез[0]),
			НРег(фл.Расширение)
		);

КонецПроцедуры

Создадим форму с табличным документом и кнопкой "Загрузить файл" и получим фот такую формочку, которая сможет прочитать MXL, XLS, XLSX и ODS файлы в табличный документ.

ВЫДЕЛЕННЫЕ ЯЧЕЙКИ

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

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

Если мы выделим теперь первую строку без объединенных ячеек, то получим следующий результат:

Т.е. тут у нас напечаталось А, Б и В. Если же мы выберем вторую строку, то получим иную картину:

Как видите, наличие объединения никоим образом не мешает нам получить данные из строки [2;2], которая у нас объединена со строкой [2;1], При том в обоих этих строках будет находиться значение "А". Если мы выделим третью строку, то получим вывод "А А А" (ну вы уже поняли, почему, да?)

ОБЪЕДИНЕННЫЕ ЯЧЕЙКИ

Для того, чтобы исправить проблему с объединенными ячейками, нужно просто узнать одну подробность: каждая ячейка имеет реквизиты "Лево", "Право", "Верх" и "Низ". И для объединенных ячеек они не будут равны. Для простого объединения по оси Х произвести чтение с учетом объединения будет достаточно просто:

	Для Каждого Область ИЗ Элементы.Таб.ПолучитьВыделенныеОбласти() Цикл 
		Для Х = Область.Лево ПО Область.Право Цикл 
			Для У = Область.Верх ПО Область.Низ Цикл 
				Сообщить(Таб.Область(У,Х).Текст);
				Х = Х + Таб.Область(У,Х).Право - Таб.Область(У,Х).Лево;
			КонецЦикла;
		КонецЦикла;
	КонецЦикла;

Мы просто добавляем к "Х" "право" и вычитаем "лево".

А для оси "У" предлагаю разобраться самостоятельно (в качестве домашнего задания).

Всех благ!

has been added to your cart:
Оформление заказа