Открыть excel на клиенте

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

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

Первым делом создаём форму справочника, если её ещё нет, и размещаем на форме команду «Загрузить из Эксель».

В модуле формы клиентская процедура:

&НаКлиенте
Процедура ЗагрузитьИзExcel(Команда)
	
	НомерПервойСтроки = 1;
	НомерПервойКолонки = 1;
	КоличествоСтрокВЭксель = 0;
	КоличествоКолонокВЭксель = 0;
	
	ДиалогВыбора = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	ДиалогВыбора.Заголовок = "Выберите файл";
	
	Если ДиалогВыбора.Выбрать() Тогда
		
		ИмяФайлаЭксель = ДиалогВыбора.ПолноеИмяФайла;
		
		//Подключаемся к Эксель
		Попытка
			Эксель = Новый COMОбъект("Excel.Application");
			Эксель.WorkBooks.Open(ИмяФайлаЭксель);
			Состояние("Обработка файла Microsoft Excel...");
		Исключение
			Сообщить("Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!");
			Сообщить(ОписаниеОшибки());
			Возврат;
		КонецПопытки;
		
		Попытка 
			//Открываем необходимый лист
			Эксель.Sheets(1).Select();  // лист 1, по умолчанию  
		Исключение
			//Закрываем Excel
			Эксель.ActiveWorkbook.Close();  
			Эксель = 0;
			Сообщить("Файл "+Строка(Объект.ИмяФайла)+" не соответствует необходимому формату! Первый лист не найден!");
			Возврат;
		КонецПопытки;
		
		//Получим количество строк и колонок.		
		КоличествоСтрокВЭксель = Эксель.Cells.SpecialCells(11).Row;
		КоличествоКолонокВЭксель = Эксель.Cells.SpecialCells(11).Column;
		
		// Выделяем область на листе Эксель.
		Область = Эксель.Range(Эксель.Cells(НомерПервойСтроки,НомерПервойКолонки), Эксель.Cells(КоличествоСтрокВЭксель,КоличествоКолонокВЭксель));
		
		// Выгружаем область Эксель в двумерный массив.
		Данные = Область.Value.Выгрузить();		
		
		//Отключаемся от Excel 
		Попытка
			Эксель.DisplayAlerts = 0;
			Эксель.ActiveWorkbook.Close();
			Эксель.DisplayAlerts = 1;
			Эксель.Quit(); 
			Эксель = Неопределено;        
		Исключение
			Сообщить("Не удалось отключиться от Excel - " + ОписаниеОшибки());
			Возврат;
		КонецПопытки;
		
		//Далее обрабатываем на сервере полученные из Эксель данные.
		ОбработатьДанныеИзЭксельНаСервере(Данные)
		
	КонецЕсли;
	
КонецПроцедуры

После того как мы на клиенте считали данные из файла Эксель и поместили эти данные в двумерный массив, передаём эти данные на сервер для дальнейшей обработки и заполнения табличной части.

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

В результате имеем табличную часть справочника, заполненную из файла Эксель.

Информация о материале
Категория: Программирование 1С

Опубликовано: 15 апреля 2017

Весьма частая задача, с которой сталкивается 1С разработчик – это чтение файлов Excel и загрузка их в 1С. Есть как минимум два способа прочитать файл Excel – средствами платформы 1С, или используя COM-объект приложения MS Excel. В статье рассматривается чтение файлов xls, xlsx при помощи табличного документа.

Содержание

Общая информация

В платформе 1С 8 существует объект ТабличныйДокумент, который позволяет формировать и выводить на экран печатные формы в табличном виде. Но у табличного документа есть еще одно применение – чтение данных из табличных файлов. Поддерживаются форматы xls, xlsx и ods. Т.е. можно загружать табличные файлы, созданные в пакете MS Office или OpenOffice Calc.

Значения типа Число или Дата, содержащиеся в ячейках исходного табличного файла, можно считать двумя способами – как значение, либо как текст. Рассмотрим пример: пусть в ячейке содержится число 123,456, и установлен формат с округлением до целого числа; в этом случае отображаться будет текст “123”, а значение будет храниться 123,456

  1. Если прочитать с указанием способа чтения как “Значение”, в табличный документ 1С будет прочитано исходное значение 123,456
  2. Если прочитать с указанием способа чтения как “Текст”, значение будет потеряно, и в табличный документ прочитается текст “123”

Использование объекта ВременноеХранилище

Вспомогательные процедуры — диалог выбора файла

Следующий код не является обязательным для решения задачи – путь к исходному файлу можно указать в коде, ввести вручную, скопировать из адресной строки ОС или прочитать из БД – вариантов очень много. Мы же рассмотрим пример, когда пользователь сам указывает файл на клиентском компьютере, и путь к этому файлу помещается в реквизит. В примере будем использовать реквизит формы ПутьКФайлу

Чтение файла Excel. Диалог выбора файла

Создадим обработчик события НачалоВыбора:

&НаКлиенте
Процедура ПутьКФайлуНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	ВыбратьФайлНаКлиенте();
	
КонецПроцедуры

Для того чтобы код был универсальным, и работал в случае отказа от модальных синхронных методов, нам понадобится создать асинхронную процедуру ВыбратьФайлНаКлиенте(). В ней мы создаем диалог выбора для открытия файла, указываем фильтр с нужными форматами – xls и xlsx, а также отключаем множественный выбор файлов. Перед методом ВыбратьАсинх добавляем ключевое слово Ждать, с тем чтобы дальнейший код дождался возвращаемого значения.

&НаКлиенте
Асинх Процедура ВыбратьФайлНаКлиенте()
	
	Перем Диалог;
	
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.Фильтр = "Excel файлы(*.xls;*.xlsx)|*.xls;*.xlsx";
	Диалог.ИндексФильтра = 0;
	Диалог.ПредварительныйПросмотр = Ложь;
	Диалог.МножественныйВыбор = Ложь; 
	РезультатВыбора = Ждать Диалог.ВыбратьАсинх();
	Если РезультатВыбора <> Неопределено Тогда
		ПутьКФайлу = РезультатВыбора[0];
	КонецЕсли;
	
КонецПроцедуры

Двоичные данные во временное хранилище

Логика кода будет следующая. Нам понадобятся двепроцедуры – клиентский обработчик команды, и серверный метод который и будет непосредственно считывать переданный файл.

Клиентский код:

  1. проверяем, указан ли путь к файлу. Если не указан – прекращаем выполнение
  2. Получаем двоичные данные из файла по указанному пути
  3. Помещаем эти двоичные данные во временное хранилище
  4. Далее передаем на сервер адрес этого временного хранилища
&НаКлиенте
Процедура ДвоичныеДанныеВоВременноеХранилище(Команда)

	Если Не ЗначениеЗаполнено(ПутьКФайлу) Тогда
		Возврат;
	КонецЕсли;
	
	ДД = Новый ДвоичныеДанные(ПутьКФайлу);
	АдресВХ = ПоместитьВоВременноеХранилище(ДД);
	ПрочитатьИзВХНаСервере(АдресВХ);
	
КонецПроцедуры

Серверный код:

  1. Создаем временный файл с нужным расширением (в примере – xlsx)
  2. Получаем двоичные данные из временного хранилища
  3. Записываем во временный файл
  4. Определяем вариант чтения файла – читать значения табличного документа как текст, или как значения
  5. Далее используем метод Прочитать, и считываем из временного файла данные в табличный документ

Метод Прочитать лучше делать в попытке, и отдельно продумать и написать код обработки исключения. для упрощения примера мы это исключение никак не обрабатываем. В случае, если передан поврежденный файл, или его невозможно прочитать по какой-то другой причине, он просто не считается в табличный документ.

&НаСервере
Процедура ПрочитатьИзВХНаСервере(АдресВХ, Режим = "Значение")
	
	ИмяВременногоФайла = ПолучитьИмяВременногоФайла("xlsx");
	
	ДД = ПолучитьИзВременногоХранилища(АдресВХ);
	ДД.Записать(ИмяВременногоФайла);

	Если Режим = "Текст" Тогда
		СпособЧтения = СпособЧтенияЗначенийТабличногоДокумента.Текст;
	Иначе
		СпособЧтения = СпособЧтенияЗначенийТабличногоДокумента.Значение;
	КонецЕсли;

	Попытка
		ТабДок.Прочитать(ИмяВременногоФайла, СпособЧтения);
	Исключение
	КонецПопытки;	
	
КонецПроцедуры

Рассмотренный пример является достаточно универсальным – процедуру ПрочитатьИзВХНаСервере() можно использовать с любыми двоичными данными, помещенными во временное хранилище. Это могут быть двоичные данные, полученные с веб-сервиса, считанные из базы данных, полученные из макета, созданного в конфигураторе – код от этого не изменится.

Помещение файла на сервер в 1С

Более простой, но менее универсальный способ, предназначенный исключительно для передачи файла с клиента на сервер – это использование метода НачатьПомещениеФайлаНаСервер. В платформе предусмотрено несколько методов для помещения файлов – как одиночных, так и нескольких одновременно. Эти методы делятся на синхронные и асинхронные. Начиная с версии 8.3.18 появились методы, использующие ключевые слова Асинх и Ждать. Аналогичный метод мы рассмотрели при работе с диалогом. Далее разберем “классический” вариант с обработкой оповещения. 

Логика кода следующая:

  1. Создаем описание оповещения и указываем в нем процедуру, которая будет вызвана после окончания помещения файла на сервер
  2. Указываем параметры диалога выбора файла и добавляем фильтр
  3. Вызываем помещение файла на сервер
  4. После того как файл помещен во временное хранилище, используем ту же процедуру, которую мы реализовали в первом примере – ПрочитатьИзВХНаСервере. В этом примере мы для разнообразия используем способ чтения значений как “Текст”.
&НаКлиенте
Процедура ПередачаФайла(Команда)
	
ОбработкаОкончанияПомещения = Новый ОписаниеОповещения("ОбработчикОкончанияПомещения", ЭтотОбъект);
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Фильтр = "Excel файлы(*.xls;*.xlsx)|*.xls;*.xlsx";
НачатьПомещениеФайлаНаСервер(ОбработкаОкончанияПомещения, , , АдресВХ, ПараметрыДиалога, ЭтотОбъект.УникальныйИдентификатор);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработчикОкончанияПомещения(ОписаниеПомещенногоФайла, ДополнительныеПараметры) Экспорт
	
АдресФайла = ОписаниеПомещенногоФайла.Адрес;
ПрочитатьИзВХНаСервере(АдресФайла, "Текст");
	
КонецПроцедуры

Использование потока для чтения файла

В случае, если нам нужно просто передать файл с клиента на сервер для сохранения в базу данных, либо мы хотим прочитать файл в формате ods(Open Documents Spreadsheet) или mxl(встроенный формат табличных документов 1С), мы можем воспользоваться еще одним способом – с использованием потоков данных.

В этом случае нам не понадобится создавать временный файл и следить за его корректным удалением. Код будет очень похож на прерыдущий пример. Мы также выбираем файл с использованием метода НачатьПомещениеФайлаНаСервер, но указываем другой фильтр. А в обработчике оповещения вызываем серверную процедуру ПрочитатьВПоток. В методе Прочитать() нам нужно явным образом указать тип файла табличного документа, который мы считываем.

&НаКлиенте
Процедура ПрочитатьЧерезПоток(Команда)

ОбработкаОкончанияПомещения = Новый ОписаниеОповещения("ОбработчикОкончанияПомещенияПоток", ЭтотОбъект);
ПараметрыДиалога = Новый ПараметрыДиалогаПомещенияФайлов;
ПараметрыДиалога.Фильтр = "файлы ODS или MXL|*.ods;*.mxl";

НачатьПомещениеФайлаНаСервер(ОбработкаОкончанияПомещения, , , АдресВХ, ПараметрыДиалога, ЭтотОбъект.УникальныйИдентификатор);

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

&НаКлиенте
Процедура ОбработчикОкончанияПомещенияПоток(ОписаниеПомещенногоФайла, ДополнительныеПараметры) Экспорт

АдресФайла = ОписаниеПомещенногоФайла.Адрес;
ПрочитатьВПоток(АдресФайла);

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

&НаСервере
Процедура ПрочитатьВПоток(АдресФайла)

ДД = ПолучитьИзВременногоХранилища(АдресФайла);
Поток = ДД.ОткрытьПотокДляЧтения();
ТабДок.Прочитать(Поток,,ТипФайлаТабличногоДокумента.ODS);
Поток.Закрыть();

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

Надеюсь, рассмотренные примеры помогут вам справиться с задачей передать файл с клиента на сервере и прочитать файл Excel в 1С.

Excel 1С

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

&НаКлиенте
Процедура ОткрытьФайл(Команда)

    ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);

    ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
    ДиалогВыбораФайла.Фильтр = "Лист Excel 2007+ (*.xlsx)|*.xlsx| Лист Excel 2003 (*.xls)|*.xls|";

    Если ДиалогВыбораФайла.Выбрать() Тогда
        Адрес = ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ДиалогВыбораФайла.ПолноеИмяФайла));
        ЗагрузитьТабличныйДокументИзФайла(Адрес, ДиалогВыбораФайла.ПолноеИмяФайла);
    КонецЕсли;

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

&НаСервере
Процедура ЗагрузитьТабличныйДокументИзФайла(Адрес, ИмяФайла)

    //Необходимо чтение файлов XLS или XLSX
    Расширение = Прав(ИмяФайла, 4);
    Расширение = СтрЗаменить(Расширение, ".", "");

    ФайлПриемник = ПолучитьИмяВременногоФайла(Расширение);
    ДанныеХранилища = ПолучитьИзВременногоХранилища(Адрес);
    ДанныеХранилища.Записать(ФайлПриемник);

    ТабличныйДокумент.Очистить();
    ТабличныйДокумент.Прочитать(ФайлПриемник);

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

Все статьи

  • 1С Hard Skills

  • 1.09.2019

Эту и другие технические статьи написали наши программисты 1С и получили за них премии. Если вы тоже работаете с 1С и любите делиться опытом, приходите разработчиком в Neti

Рассмотрим пример обработки COM-объекта на Клиенте на примере загрузки из файла xls.

В случаях, когда на сервере не установлен Excel или когда сервер 1С:Предприятие 64-х битный, а объем загружаемых данных небольшой, данные файла xls можно обработать на Клиенте и передать для дальнейшей обработки на Сервер. Рассмотрим на примере.

Внешняя обработка с табличной частью ТабЧасть, СотрудникСтр — строка для заполнения из xls файла на Клиенте, Сотрудник — СправочникСсылка.СотрудникиОрганизаций для заполнения из значения СотрудникСтр на Сервере. В файле xls в колонке 1 — наименования сотрудников, в колонке 2 — суммы, данные по сотрудникам начинаются с 7-й строки файла.

Обработка COM-объекта на клиенте: Загрузка из Excel в 1С

Форма обработки

Процедуры модуля формы обработки:

&НаКлиенте
Процедура ОткрытьФайл(Команда)
                ДиалогВыбораФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);        
                ДиалогВыбораФайла.Заголовок = "Прочитать табличный документ из файла";
                ДиалогВыбораФайла.Фильтр    = "Лист Excel (*.xlsx)|*.xlsx|Лист Excel (*.xls)|*.xls";
                Если ДиалогВыбораФайла.Выбрать() Тогда                   
                               ИмяФайла = ДиалогВыбораФайла.ПолноеИмяФайла;                            
                КонецЕсли;       
КонецПроцедуры
&НаКлиенте
Процедура ПрочитатьФайл(Команда)
                ПрочитатьДокумент(ИмяФайла);
                Обработать();
КонецПроцедуры
&НаКлиенте
Процедура ПрочитатьДокумент(ИмяФайла)
                Попытка
                               Excel = ПолучитьCOMОбъект(ИмяФайла);
                               ExcelЛист = Excel.Sheets(1);
                Исключение
                               Сообщить(ОписаниеОшибки());                           
                               Возврат;                            
                КонецПопытки;
               
                Объект.ТабЧасть.Очистить(); 
                сч = 7;
                Пока НЕ ПустаяСтрока(ExcelЛист.Cells(сч, 1).Value) Цикл                        
                               //Заполнение табличной части обработки
                               НоваяСтр = Объект.ТабЧасть.Добавить();
                               НоваяСтр.СотрудникСтр = СокрЛП(ExcelЛист.Cells(сч, 1).Value);
                               НоваяСтр.Сумма = ExcelЛист.Cells(сч, 2).Value;                            
                               сч = сч + 1;
                КонецЦикла;   
                Excel.Application.Quit();             
КонецПроцедуры        

&НаСервере
Процедура Обработать()
                //заполнение значений как элементов справочников
                //получение значения Сотрудник из СотрудникСтр
КонецПроцедуры

Эту статью хорошо дополняют

&НаКлиенте
Процедура ФайлНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка) //необходимо в событии «НачалоВыбора» поля ввода вызвать ДиалогВыбораФайлаДиалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
   
Диалог.Заголовок = «Выберите файл Excel»;
   
Диалог.ПредварительныйПросмотр = Ложь;
   
Диалог.Фильтр = «(*.xls,*.xlsx)|*.xls;*.xlsx;|Microsoft Excel 97/2000/XP/2003 (*.xls)|*.xls|Microsoft Excel 2007/2010 (*.xlsx)|*.xlsx»;

    Если

ЗначениеЗаполнено(Объект.Файл) Тогда
       
Диалог.ПолноеИмяФайла= Объект.Файл;
    КонецЕсли;

    Если

Диалог.Выбрать() Тогда
       
ВыбранныйФайл = Диалог.ПолноеИмяФайла;
       
Объект.Файл = ВыбранныйФайл;
       
ЧтениеExcel_через_ТД(ВыбранныйФайл);
    КонецЕсли;

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

&НаСервере
Процедура ЧтениеExcel_через_ТД(ВыбранныйФайл)//1) Выводим Excel в табличн.документ
   
ТаблДок = Новый ТабличныйДокумент;
   
ТаблДок.Прочитать(ВыбранныйФайл, СпособЧтенияЗначенийТабличногоДокумента.Значение);//2) Выгружаем в таблицу значений
   
ПЗ = Новый ПостроительЗапроса;
   
ПЗ.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТаблДок.Область());
   
ПЗ.ДобавлениеПредставлений = ТипДобавленияПредставлений.НеДобавлять;
   
ПЗ.ЗаполнитьНастройки();
   
ПЗ.Выполнить();ТаблицаЗначений = ПЗ.Результат.Выгрузить();

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

Понравилась статья? Поделить с друзьями:
  • Открыть excel в формате word
  • Открыты урок по word
  • Открытое занятие таблицы в word
  • Открытое занятие в текстовом редакторе word
  • Открыто диалоговое окно как его закрыть word