Загрузка из EXCEL в 1С на платформе 8.3.6/8.3.7/8.3.8/8.3.9/8.3.10 (с картинками)

Импорт содержимого из файлов в форматах XLS (Microsoft Excel 97), Microsoft Office OpenXML (Microsoft Excel 2007- 2010) и ODS (OpenDocument) в таблицу значений.

При написании публикации использовалась версия платформы 8.3.6.1760.
Модифицирована на версии платформы 8.3.10.2168.

Заметки из Зазеркалья: http://v8.1c.ru/o7/


Одним из полезных нововведений на платформе 8.3.6 стала возможность возможность импорта содержимого из файлов в форматах XLS (Microsoft Excel 97), Microsoft Office OpenXML (Microsoft Excel 2007- 2010) и ODS (OpenDocument) в табличный документ.
На платформе 8.3.10 появилась возможность считывания данных с отдельных листов книги EXCEL.
Данная возможность доступна как в интерактивном режиме, так и из встроенного языка.
Реализована поддержка вставки из буфера обмена областей, скопированных из Microsoft Excel и OpenOffice Calc.
Реализация импорта из EXCEL на встроенном языке стала возможна в результате нововведений в функционал объекта «ТабличныйДокумент»:
Для метода «Прочитать» объекта «ТабличныйДокумент» реализован параметр «СпособЧтенияЗначений» (Новое системное перечисление «СпособЧтенияЗначенийТабличногоДокумента»).

В данной публикации приводится пример реализации функционала импорта из файлов EXCEL (xlsx, xls, ods) в таблицу значений в режиме 1С:Предприятие на платформе 8.3.6.


Методы загрузки из внешнего источника:
— Метод «MS ADO» (Чтение файлов xls, xlsx, xlsb средствами Microsoft ADO): //infostart.ru/public/163640/
— Метод «MS EXCEL» (Чтение файлов xls, xlsx, xlsb с картинками средствами Microsoft Office): //infostart.ru/public/163641/
— Метод «LO CALC» (Чтение файлов xls, xlsx, xlsb, ods, sxc с картинками средствами LibreOffice): //infostart.ru/public/163642/
— Метод «NativeXLSX» (Чтение файлов xlsx с картинками средствами 1С. ПостроительDOM): //infostart.ru/public/300092/
— Метод «NativeXLSX». Предыдущий вариант (Чтение файлов xlsx средствами 1С. ЧтениеXML):
//infostart.ru/public/225624/
— Метод «Excel1C» (Загрузка на платформе 8.3.6 с картинками. Чтение файлов xls, xlsx, ods): //infostart.ru/public/341855/
— Список листов файла: //infostart.ru/public/163724/


Данный функционал включен в обработку:
Импорт из EXCEL и др.источников (xls,xlsx,ods,sxc,dbf,mxl,csv,sql) в 1С: //infostart.ru/public/120961/


О файле EXCEL:
В общем случае файл EXCEL содержит несколько листов с данными.
Метод табличного документа «Прочитать» читает все листы в 1 (один) табличный документ на платформах 8.3.6-8.3.9, а на платформе 8.3.10 можно считать отдельные листы файла EXCEL.
Поэтому для использования данного функционала на версиях платформы 8.3.6-8.3.9 необходимо использовать файлы EXCEL, содержащие 1 (один) лист с данными, для платформы 8.3.10, такого ограничения нет.
О листе файла EXCEL:
Содержимое на листе должно быть разнесено по соответствующим колонкам по назначению.
В качестве примера содержимого листа может служить обычный прайс.
Рекомендутся ячейки таблицы на листе файла оформлять рамкой  «Все границы».
Колонки результирующей таблицы значений формируются по количеству, определяемому свойством «ШиринаТаблицы» табличного документа.
В последствии для удобства пустые колонки удаляются из результирующей таблицы значений.
О типах значений файла EXCEL:
Числа — как «число», даты — как «дата», Стоки — как «строка», Булево — как «строка» вида «ИСТИНА» («TRUE») или «ЛОЖЬ» («FALSE»).
В результирующую таблицу значений записываются типизованные значения.
О картинках файла EXCEL:
В исходном файле EXCEL это могут быть как ссылки на файлы, разделенные между собой символом «Перевод строки» в пределах одной ячейки, так и собственно картинки.
Картинки должны находиться в пределах ячейки. В одной ячейке может быть несколько картинок.
В результирующую таблицу значений записываются ссылки на файлы картинок.
Каждая ячейка колонки может, в общем случае, содержать несколько ссылок на файлы, разделенные между собой символом «Перевод строки».

Перем ВерсияПриложенияБезНомераСборки;

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Перем СистемнаяИнформация, СписокЛистов;

СистемнаяИнформация = Новый СистемнаяИнформация;
ВерсияПриложенияБезНомераСборки = ВерсияБезНомераСборки(СистемнаяИнформация.ВерсияПриложения);

// Чтение в реквизит обработки, который может быть выведен на форму обработки.
// Объект.ТабличныйДокумент.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);

// Запись табличного документа в файл на диске.
// Для работы с табличным документом предусмотрена утилита 1С http://v8.1c.ru/metod/fileworkshop.htm
// Объект.ТабличныйДокумент.Записать("D:Товар1Лист.MXL", ТипФайлаТабличногоДокумента.MXL);

// Примеры вызова:
Если ВерсияПриложенияМеньше8310() Тогда
// Платформа 8.3.9 и более ранние (Файл EXCEL как 1 лист).
ИмяФайла = "D:1_LIST.xlsx";
ТЗ = ЗагрузитьМетодом_EXCEL1C(ИмяФайла, "");                 // Считать весь файл.
ТЗ = ЗагрузитьМетодом_EXCEL1C(ИмяФайла, "", 1, 3, 4);    // Считать с 3-ой до 4-ой строки всего файла.
Иначе
// Платформа 8.3.10 (Облать = Лист данных).
ИмяФайла = "D:N_LIST.xlsx";
СписокЛистов = ПолучитьСписокЛистов_EXCEL1C(ИмяФайла);
ТЗ = ЗагрузитьМетодом_EXCEL1C(ИмяФайла, СписокЛистов[0].Значение); // Считать 1-ый лист из списка по алфавиту.
ТЗ = ЗагрузитьМетодом_EXCEL1C(ИмяФайла, СписокЛистов[1].Значение); // Считать 2-ой лист из списка по алфавиту.
ТЗ = ЗагрузитьМетодом_EXCEL1C(ИмяФайла, СписокЛистов[1].Значение, 1, 3, 4); // Считать с 3-ой до 4-ой строки 2-го листа из списка по алфавиту.
КонецЕсли;

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

&НаСервере
Функция ПолучитьСписокЛистов_EXCEL1C(Знач ФайлEXCEL)
Перем ТабличныйДокумент, ОбластьТД;
Перем СписокЛистов;

СписокЛистов = Новый СписокЗначений;

ТабличныйДокумент = Новый ТабличныйДокумент;
Попытка
// Выполняется долго на больших файлах.
ТабличныйДокумент.Прочитать(ФайлEXCEL);
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат Новый СписокЗначений;
КонецПопытки;

Для Каждого ОбластьТД ИЗ ТабличныйДокумент.Области Цикл
СписокЛистов.Добавить(ОбластьТД.Имя);
КонецЦикла;

Возврат СписокЛистов;

КонецФункции

// Метод "EXCEL1C" для файлов EXCEL с расширениями: xlsx, xls, ods.
//
// Параметры:
//  ФайлEXCEL - Полное имя файла (путь к файлу с именем файла и расширением).
//      ИмяЛиста - Имя листа файла (платформа 8.3.10).
//  СтрокаЗаголовка (по умолчанию = 1) - Номер строки файла типа MXL, в которой расположены заголовки колонок.
//  Не используется.
//  В обработке 1-я строка анализируется для сопоставления колонок файла с реквизитами объектов 1С.
//  НачСтрока (по-умолчанию = 0) - Номер начальной строки, начиная с которой считываются данные из файла.
//  КонСтрока (по-умолчанию = 0) - Номер конечной строки, которой заканчиваются считываемые данные из файла.
//  Если НачСтрока=0 и КонСтрока=0, то считывается вся таблица, находящаяся в файле.
//  КолвоСтрокФайла - Количество строк в файле. Возвращается в вызвавшую процедуру.
//
// Возвращаемые значения:
//         ТаблицаРезультат - Результат считывания данных из файла.
//
&НаСервере
Функция ЗагрузитьМетодом_EXCEL1C(Знач ФайлEXCEL, Знач ИмяЛиста = "", Знач СтрокаЗаголовка = 1, НачСтрока = 0, КонСтрока = 0, КолвоСтрокФайла = 0)
Перем ТабличныйДокумент, ОбластьФайла, КолВоКолонокФайла, ИмяКолонки, Область, ТекущаяОбласть, нСтрока, нКолонка, НоваяСтрокаТФ, ЗначениеЯчейки;
Перем ТаблицаРезультат;

ТабличныйДокумент = Новый ТабличныйДокумент;
Попытка
// Выполняется долго на больших файлах.
ТабличныйДокумент.Прочитать(ФайлEXCEL, СпособЧтенияЗначенийТабличногоДокумента.Значение);    // СпособЧтенияЗначенийТабличногоДокумента - новый параметр платформы 8.3.6. Второе значение "Текст".
Исключение
Сообщить(ОписаниеОшибки(), СтатусСообщения.Внимание);
Возврат Новый ТаблицаЗначений;
КонецПопытки;

ОбластьФайла = ТабличныйДокумент;
Если ВерсияПриложенияМеньше8310() Тогда
// Платформа 8.3.9 и более ранние (Файл EXCEL как 1 лист).
КолвоСтрокФайла = ОбластьФайла.ВысотаТаблицы;
КолВоКолонокФайла = ОбластьФайла.ШиринаТаблицы;
Иначе
// Платформа 8.3.10 (Облать = Лист данных).
ОбластьФайла = ТабличныйДокумент.ПолучитьОбласть(ИмяЛиста);
КолВоСтрокФайла = ОбластьФайла.ПолучитьРазмерОбластиДанныхПоВертикали();
КолВоКолонокФайла = ОбластьФайла.ПолучитьРазмерОбластиДанныхПоГоризонтали();
КонецЕсли;

// Проверка заполненности листа.
Если КолвоСтрокФайла = 0 Тогда
// Завершение работы.
// Закрытие Объектов.
ТабличныйДокумент = Неопределено;
Возврат Новый ТаблицаЗначений;    // В случае ошибки возвращаем пустую таблицу значений.
КонецЕсли;

// Создание результирующей таблицы, в которую будут записываться считанные из файла данные.
ТаблицаРезультат = Новый ТаблицаЗначений;

// Формирование колонок результирующей таблицы.

// "НомерСтроки" - для наглядности и удобства.
// В зависимости от разрабатываемой обработки.
// "Сопоставлено" - может быть другим.
// Здесь же могут быть добавлены другие колонки, не формируемые из содержимого файла.
ТаблицаРезультат.Колонки.Добавить("НомерСтроки", Новый ОписаниеТипов("Число"), "№", 4);
ТаблицаРезультат.Колонки.Добавить("Сопоставлено", Новый ОписаниеТипов("Булево"), "Сопоставлено", 1);

Для ит = 1 ПО КолВоКолонокФайла Цикл
нКолонка = СтрЗаменить(ит, Символы.НПП, "");
ИмяКолонки = "N" + нКолонка;
ТаблицаРезультат.Колонки.Добавить(ИмяКолонки);
КонецЦикла;

// 1-я строка. Заголовки.
НоваяСтрокаТФ = ТаблицаРезультат.Добавить();
НоваяСтрокаТФ.НомерСтроки = 1;
Для ит=1 ПО КолВоКолонокФайла Цикл
нКолонка = СтрЗаменить(ит, Символы.НПП, "");
ИмяКолонки = "N" + нКолонка;
НоваяСтрокаТФ[ИмяКолонки] = ОбластьФайла.ПолучитьОбласть("R1" + "C"+нКолонка).ТекущаяОбласть.Текст;

// Используется при формировании таблицы на форме обработки.
ШиринаКолонки = ТаблицаРезультат.Колонки[ИмяКолонки].Ширина;
ДлинаСтроки    = СтрДлина(СокрЛП(НоваяСтрокаТФ[ИмяКолонки]));
ТаблицаРезультат.Колонки[ИмяКолонки].Ширина = ?(ШиринаКолонки < ДлинаСтроки, ДлинаСтроки, ШиринаКолонки);
КонецЦикла;

НачСтрока = ?(НачСтрока = 0, 2, НачСтрока);
КонСтрока = ?(КонСтрока = 0, КолвоСтрокФайла, КонСтрока);

Для нСтрокаТФ = НачСтрока ПО КонСтрока Цикл
НоваяСтрокаТФ = ТаблицаРезультат.Добавить();
НоваяСтрокаТФ[0] = нСтрокаТФ;
нСтрока = СтрЗаменить(нСтрокаТФ, Символы.НПП, "");
Для нКолонкаТФ = 1 ПО КолВоКолонокФайла Цикл
нКолонка = СтрЗаменить(нКолонкаТФ, Символы.НПП, "");
Область = ОбластьФайла.ПолучитьОбласть("R"+нСтрока+"C"+нКолонка);
ТекущаяОбласть = Область.ТекущаяОбласть;
Попытка
ЗначениеЯчейки = ТекущаяОбласть.Значение;        // Число, Дата.
Исключение
ЗначениеЯчейки = СокрЛП(ТекущаяОбласть.Текст);    // Строка, Булево. (Булево как строка "ИСТИНА"/"ЛОЖЬ")
Если ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
ЗначениеЯчейки = ПреобразоватьПростоеЗначениеИзСтрокиВТипизованноеЗначение1С(ЗначениеЯчейки);
Если ТипЗнч(ЗначениеЯчейки) = Тип("Строка") Тогда
ЗначениеЯчейки = СокрЛП(ЗначениеЯчейки);
КонецЕсли;
Иначе
ЗначениеЯчейки = Неопределено;
Если Область.Рисунки.Количество() > 0 Тогда    // Изображение.
ЗначениеЯчейки = ПолучитьЗначениеЯчейкиОбластиТабличногоДокументаСКартинками(Область, нСтрока, нКолонка, "УИД");
КонецЕсли;
КонецЕсли;
КонецПопытки;

ИмяКолонки = "N" + нКолонка;
НоваяСтрокаТФ[ИмяКолонки] = ЗначениеЯчейки;

// Используется при формировании таблицы на форме обработки.
ШиринаКолонки = ТаблицаРезультат.Колонки[ИмяКолонки].Ширина;
ДлинаСтроки    = СтрДлина(СокрЛП(НоваяСтрокаТФ[ИмяКолонки]));
ТаблицаРезультат.Колонки[ИмяКолонки].Ширина = ?(ШиринаКолонки < ДлинаСтроки, ДлинаСтроки, ШиринаКолонки);
КонецЦикла;
КонецЦикла;

// Юзабилити. Удалить пустые колонки.
УдалитьКолонкиСНулевойШириной(ТаблицаРезультат);

Возврат ТаблицаРезультат;

КонецФункции

&НаСервере
Процедура УдалитьКолонкиСНулевойШириной(ТаблицаРезультат)
Перем МассивПустыхКолонок;

// Найдем пустые колонки.
МассивПустыхКолонок = Новый Массив;
Для Каждого Колонка ИЗ ТаблицаРезультат.Колонки Цикл
Если Колонка.Ширина = 0 Тогда
МассивПустыхКолонок.Добавить(Колонка.Имя);
КонецЕсли;
КонецЦикла;

// Удалим пустые колонки.
Для Каждого ПустаяКолонка ИЗ МассивПустыхКолонок Цикл
ТаблицаРезультат.Колонки.Удалить(ПустаяКолонка);
КонецЦикла;

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

// ПРЕОБРАЗОВАНИЕ СТРОКИ К ТИПИЗОВАННОМУ ЗНАЧЕНИЮ 1С.

&НаСервере
Функция ПреобразоватьПростоеЗначениеИзСтрокиВТипизованноеЗначение1С(Знач ИсходноеЗначение)

Если НЕ ИсходноеЗначение = "" Тогда
Если ТолькоЦифрыИЗапятаяВСтроке(ИсходноеЗначение, Истина, Ложь) Тогда
Попытка
Возврат Число(ИсходноеЗначение);
Исключение
Возврат ИсходноеЗначение
КонецПопытки;
Иначе
Если ВРег(ИсходноеЗначение) = "ИСТИНА" ИЛИ ВРег(ИсходноеЗначение) = ("ИСТИНА"+Символы.ПС) ИЛИ ВРег(ИсходноеЗначение) = "TRUE" ИЛИ ВРег(ИсходноеЗначение) = ("TRUE"+Символы.ПС) Тогда
Возврат Истина;
ИначеЕсли ВРег(ИсходноеЗначение) = "ЛОЖЬ" ИЛИ  ВРег(ИсходноеЗначение) = ("ЛОЖЬ"+Символы.ПС) ИЛИ ВРег(ИсходноеЗначение) = "FALSE" ИЛИ ВРег(ИсходноеЗначение) = ("FALSE"+Символы.ПС) Тогда
Возврат Ложь;
Иначе
Возврат ПреобразоватьИзСтрокиВДату(ИсходноеЗначение);
КонецЕсли;
КонецЕсли;
КонецЕсли;

Возврат ИсходноеЗначение

КонецФункции

// Проверяет, содержит ли строка только цифры и запятую.
//
// Параметры:
//  СтрокаПроверки          - Строка - Строка для проверки
//  УчитыватьЛидирующиеНули - Булево - Флаг учета лидирующих нулей, если Истина, то ведущие нули пропускаются
//  УчитыватьПробелы        - Булево - Флаг учета пробелов, если Истина, то пробелы при проверке игнорируются
//
// Возвращаемое значение:
//   Булево - Истина - строка содержит только цифры или пустая, Ложь - строка содержит иные символы.
//
&НаСервере
Функция ТолькоЦифрыИЗапятаяВСтроке(Знач СтрокаПроверки, Знач УчитыватьЛидирующиеНули = Истина, Знач УчитыватьПробелы = Истина)

Если ТипЗнч(СтрокаПроверки) <> Тип("Строка") Тогда
Возврат Ложь;
КонецЕсли;

Если НЕ УчитыватьПробелы Тогда
СтрокаПроверки = СтрЗаменить(СтрокаПроверки, " ", "");
КонецЕсли;

Если Сред(СтрокаПроверки, 1, 1) = "-" Тогда
СтрокаПроверки = Сред(СтрокаПроверки, 2, СтрДлина(СтрокаПроверки));
КонецЕсли;

Если ПустаяСтрока(СтрокаПроверки) Тогда
Возврат Истина;
КонецЕсли;

Если НЕ УчитыватьЛидирующиеНули Тогда
Позиция = 1;
// Взятие символа за границей строки возвращает пустую строку
Пока Сред(СтрокаПроверки, Позиция, 1) = "0" Цикл
Позиция = Позиция + 1;
КонецЦикла;
СтрокаПроверки = Сред(СтрокаПроверки, Позиция);
КонецЕсли;

// Если содержит только цифры, то в результате замен должна быть получена пустая строка
// Проверять при помощи ПустаяСтрока нельзя, так как в исходной строке могут быть пробельные символы
Возврат СтрДлина(
СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить(
СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить( СтрЗаменить(
СтрокаПроверки, "0", ""), "1", ""), "2", ""), "3", ""), "4", ""), "5", ""), "6", ""), "7", ""), "8", ""), "9", ""), ",", "")
) = 0;

КонецФункции

// Преобразование строки вида "01.01.13" или "01.01.2013" к значению типа "дата".
// Возможны друние форматы даты в файле EXCEL.
&НаСервере
Функция ПреобразоватьИзСтрокиВДату(Знач СтрокаДаты)
Перем ScrptCtrl, OutDate;

Попытка
ScrptCtrl = Новый COMОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language="vbscript";
OutDate = ScrptCtrl.Eval("CDate(""" + СтрокаДаты + """)");
Возврат OutDate;
Исключение
//Сообщить(ОписаниеОшибки());
КонецПопытки;

Возврат СтрокаДаты;

КонецФункции

// ПОЛУЧЕНИЕ ЗНАЧЕНИЯ ДЛЯ РЕКВИЗИТА ТИПА "ФАЙЛ КАРТИНКИ".

&НаСервере
Функция ПолучитьЗначениеЯчейкиОбластиТабличногоДокументаСКартинками(Знач Область, Знач нСтрока, Знач нКолонка, Знач ПравилоИмяФайлаКартинки = "УИД")
Перем Рисунок, ит, ИмяФайлаРисунка;
Перем ЗначениеЯчейки;

ит = 0;
ЗначениеЯчейки = "";
Для Каждого Рисунок ИЗ Область.Рисунки Цикл
ит = ит + 1;
Если ПравилоИмяФайлаКартинки = "УИД" Тогда
ИмяФайлаРисунка = КаталогВременныхФайлов() + Новый УникальныйИдентификатор() + ".jpg";
Иначе
ИмяФайлаРисунка = КаталогВременныхФайлов() + "С" + нСтрока + "К" + нКолонка + ".jpg";
КонецЕсли;
Попытка
Рисунок.Картинка.Записать(ИмяФайлаРисунка);
ЗначениеЯчейки = ЗначениеЯчейки + ИмяФайлаРисунка + ?(ит < Область.Рисунки.Количество(), Символы.ПС, "");
Исключение
// Поле картинки недоступно для чтения.
КонецПопытки;
КонецЦикла;

Возврат ЗначениеЯчейки;

КонецФункции

// ОБЩЕГО НАЗНАЧЕНИЯ.

&НаКлиентеНаСервереБезКонтекста
Функция ВерсияБезНомераСборки(Знач Версия)
Перем Массив, Результат;

Массив = РазложитьСтрокуВМассивПодстрок(Версия, ".");

Если Массив.Количество() < 3 Тогда
Возврат Версия;
КонецЕсли;

Результат = "[Редакция].[Подредакция].[Релиз]";
Результат = СтрЗаменить(Результат, "[Редакция]",    Массив[0]);
Результат = СтрЗаменить(Результат, "[Подредакция]", Массив[1]);
Результат = СтрЗаменить(Результат, "[Релиз]",       Массив[2]);

Возврат Результат;
КонецФункции

&НаСервере
Функция ВерсияПриложенияМеньше8310()
Перем Версия;
Версия = СтрЗаменить(ВерсияПриложенияБезНомераСборки, ".", "");
Версия = Число(Версия);
Возврат Версия <= 839;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция РазложитьСтрокуВМассивПодстрок(Знач Стр, Разделитель = ",")
Перем МассивСтрок;

МассивСтрок = Новый Массив();
Если Разделитель = " " Тогда
Стр = СокрЛП(Стр);
Пока 1 = 1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз = 0 Тогда
МассивСтрок.Добавить(СокрЛП(Стр));
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(СокрЛП(Лев(Стр, Поз - 1)));
Стр = СокрЛ(Сред(Стр, Поз));
КонецЦикла;
Иначе
ДлинаРазделителя = СтрДлина(Разделитель);
Пока 1 = 1 Цикл
Поз = Найти(Стр, Разделитель);
Если Поз = 0 Тогда
Если (СокрЛП(Стр) <> "") Тогда
МассивСтрок.Добавить(СокрЛП(Стр));
КонецЕсли;
Возврат МассивСтрок;
КонецЕсли;
МассивСтрок.Добавить(СокрЛП(Лев(Стр,Поз - 1)));
Стр = Сред(Стр, Поз + ДлинаРазделителя);
КонецЦикла;
КонецЕсли;

Возврат МассивСтрок;

КонецФункции

ВерсияПриложенияБезНомераСборки = "";

72 Comments

  1. StepByStep

    УДАЧНОГО ПРИМЕНЕНИЯ …

    Reply
  2. jobkostya1c8

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

    Reply
  3. StepByStep

    (2) kostyaomsk,

    Почерпнул из описании нововведений к платформе 8.3.6.

    Reply
  4. qwinter

    Зачем здесь все кроме

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

    ?????

    Скоро синтаксис-помощник будут публиковать…

    Reply
  5. StepByStep

    (4) qwinter,


    В данной публикации приводится пример реализации функционала импорта из файлов EXCEL (xlsx, xls, ods) в таблицу значений в режиме 1С:Предприятие на платформе 8.3.6.

    Приведенный функционал вполне подходит для примера, о чем и написано выше в тексте публикации..

    Reply
  6. strangers

    Не считывает картинки из excel

    Reply
  7. StepByStep

    (6) strangers,

    Картинки должны находиться в пределах ячейки. В одной ячейке может быть несколько картинок.

    В результирующую таблицу значений записываются ссылки на файлы картинок.

    В ячейке, содержащей какртинки не должно быть ничего другого (текст, число и т.д.).

    Reply
  8. mostovaya

    Чем данный очередной загрузчик из эксель выделяется на фоне многих других?

    Reply
  9. StepByStep

    (8) mostovaya,

    Тем, что построен на возможностях новой платформы 8.3.6.

    Reply
  10. rasswet

    а заполнять именованные области без использования ком объекта Эксель можно будет?

    Reply
  11. StepByStep

    (10) rasswet,

    Можно, если формировать ТабличныйДокумент, а не ТаблицуЗначений как здесь.

    EXCEL не нужен.

    Reply
  12. tesseract

    КонечнаяКолонка = ТабличныйДокумент.ШиринаТаблицы; // 8.3.6.1760 некорректно определяет количество колонок (например, >=1025 для xlsx, =256 для xls).

    Все читается корректно. Просто ТД может содержать строки с разным количеством колонок. Поэтому правильный вариант :

    КоличествоКолонок = ТабличныйДокумент.ПолучитьОбласть(1,,1).ШиринаТаблицы;

    Так мы получим реальное количество колонок в строке.

    Reply
  13. StepByStep

    (12) tesseract,

    СПАСИБО.

    И в качестве развития мысли предлагаю:

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

    В этом случае получим реальное количество колонок, вне зависимости от заполнения 1-ой строки.

    (последние колонки, не имеющие заполненной 1-ой строки также будут учтены.)

    Reply
  14. shydla

    Из xlsx картинки грузится, из xls — на доступно для чтения(

    Reply
  15. GVasiliy

    Нашел маленькую ошибку.

    Переменная «СтрокаЗаголовка» не используется.

    Для цикла считывающего наименования колонок следует исправить на:

    НоваяСтрокаТФ[ИмяКолонки] = ТабличныйДокумент.ПолучитьОбласть(«R» + Формат(СтрокаЗаголовка,»») + «C»+нКолонка).ТекущаяОбласть.Текст;

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

    А почему никто не пишет, что при использовании директивы»&НаСервере» в клиент-серверном варианте файл должен располагаться либо по сетевому пути, либо на сервере, где установлен «Агент сервера 1С:Предприятия 8.3 (x86-64)»?

    Reply
  17. urbanist

    Нужно ли для корректной работы этого функционала у «старых» конфигураций изменять режим совместимости?

    А то не хочет работать в 8.3.6 (2076)

    {Форма.Форма.Форма(26)}: Ошибка при вызове метода контекста (Прочитать)

    ТабДок.Прочитать(«D:1.xls»);

    по причине:

    Ошибка при выполнении файловой операции.

    С любым параметром «СпособЧтенияЗначенийТабличногоДокумента» то же самое.

    Reply
  18. Samarin

    (17) urbanist, для использования данной возможности необходима платформа 8.3.6 с отключенным режимом совместимости.

    Сейчас подобные вещи можно тестировать и смотреть на тестовых ЗУП 3.0.23 и БП 3.0.41, которые переводят на 8.3.6 со снятием режима совместимости (БСП версия 2.3).

    Reply
  19. StepByStep

    (14) shydla,

    На платформе 8.3.6.2152 читает.

    Reply
  20. StepByStep

    (15) GVasiliy,

    Тоже вариант.

    Reply
  21. StepByStep

    (16) mamanelli,

    Да, так и есть. Это стандартно в клиент-серверном варианте.

    Reply
  22. StepByStep

    (17) urbanist, (18) Samarin,

    Режим совместимости не причем.

    Не открыт ли файл в EXCEL?

    Еще столкнулся с тем, что какая-то из версий LibreOffice коверкала файлы.

    Поэтому рекомендую использовать MS EXCEL.

    Reply
  23. nytlenc

    В Функции

    Функция ЗагрузитьМетодом_1C836(Знач ФайлEXCEL, Знач СтрокаЗаголовка = 1, НачСтрока = 0, КонСтрока = 0, КолвоСтрокФайла = 0)

    замени строку:

    Область = ТабличныйДокумент.ПолучитьОбласть(«R»+нСтрока + «C»+нКолонка);

    на:

    Область = ТабличныйДокумент.ПолучитьОбласть(«R»+Формат(нСтрока,»ЧГ=0») + «C»+Формат(нКолонка, «ЧГ=0»));

    В противном случае когда итератор нСтрока или нКолонка достигнет значения 1000 будет подставляться как «1 000» соответственно

    «R»+нСтрока + «C»+нКолонка

    например будет равен значению «C1 000R1» или «C1R1 000» а такой области не существует. Будет ошибка в общем.

    Reply
  24. StepByStep

    (23) nytlenc,

    СПАСИБО. Правильно.

    Reply
  25. kiv1c

    (16) mamanelli, то есть, в клиент-серверном варианте нет возможности прочитать файл с локального компьютера пользователя? и как быть?

    Reply
  26. TeMochkiN

    (25) kiv1c,

    ТабличныйДокумент (SpreadsheetDocument)

    Прочитать (Read)

    Доступность:

    Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).

    Reply
  27. kiv1c

    (26) TeMochkiN, да, я разобрался, с клиента на сервер можно передать прочитанные из файла двоичные данные, потом на сервере их записать во временный эксель-файл и читать табличным документом из него.

    Reply
  28. Morales

    Функция ТолькоЦифрыИЗапятаяВСтроке не отлавливает отрицательные числа

    Надо добавить условие:

    // Проверка на отрицательное число
    Если Сред(СтрокаПроверки, 1, 1) = «-» Тогда
    СтрокаПроверки = Сред(СтрокаПроверки, 2, СтрДлина(СтрокаПроверки));
    КонецЕсли;
    
    Reply
  29. StepByStep

    (28) Morales,

    СПАСИБО.

    Reply
  30. Lazerka

    Подскажите, а как загружать в 1с 8.3 из екселя формата xlsb это двоичные данные.

    Reply
  31. nofx

    (30) Lazerka, Также интересен этот вопрос.

    Reply
  32. StepByStep

    (30) Lazerka, (31) nofx,

    СПАСИБО.

    Загрузка из XLSXB возможна черз ADODB.

    Строка соединения = «Driver={Microsoft EXCEL Driver (*.xls, *.xlsx, *.xlsm, *.xlsb)};Dbq=» + ФайлEXCEL + «;ReadOnly=1;»

    Reply
  33. nofx

    Да.Я воль!

    Reply
  34. ram8291

    Считываются все Листы Excel. Не понятно как считать только один Лист?

    Наконец 1С родила долгожданный функционал!

    Reply
  35. StepByStep

    (34) ram8291,

    Из текста публикации:

    О файле EXCEL:

    В общем случае файл EXCEL содержит несколько листов с данными.

    Метод табличного документа «Прочитать» читает все листы в 1 (один) табличный документ.

    Поэтому в исходном файле EXCEL должен быть только один лист.

    Reply
  36. Гость

    Проблема: числовые значения заполняются в Таблицу Значений правильно (как числа) из файла Эксель (через Табличный Документ), только если числа не содержат десятичной (дробной) части. Если есть дробная часть, то они записываются как текстовые значения, либо как тип Дата.

    Пытался менять региональные настройки («,» или «.» в качестве разделителей дробной части) и Региональные настройки базы данных 1С — безрезультатно.

    Reply
  37. StepByStep

    (36) Гость,

    Рекомендовал бы Вам обратить внимание на обработку Импорт из внешнего источника в 1С: infostart.ru

    В ней механизм загрузки данным методом уточнен (несколько изменен функционал по типизации значений).

    Reply
  38. phil1n

    На платформе 8.3.6.2299 даты со временем в интервале 11:59:30 — 11:59:59 не считываются

    Reply
  39. StepByStep

    (38) phil1n,

    В том числе не берет и некоторые форматы даты (в общем-то «экзотические»), существующие в EXCEL.

    Reply
  40. borzyj

    Есть еще нюанс

    при работе с файлами эксель формата офис 95 вызывается исключение, учтите это на коммерческих проектах

    Reply
  41. StepByStep

    (40) borzyj,

    Старый формат.

    Можно пересохранить файл в более современном формате каким-либо офисом.

    Reply
  42. borzyj

    (41) StepByStep,

    Была у меня задача, когда было необходимо загружать заказы от покупателей, приходящие в формате XL 95, база в клиент-серверном варианте, обработка на сервере, где офис не установлен, и никакого автоконвертера я не нашел, пришлось использовать другой способ обработки файла без установки мс Офис на сервер

    Reply
  43. Soikalv

    Очень интересная и полезная обработка. На 8.2. очень часто была нужна и нужна на 8.3. переход на 8.3 — вынужденный. Объясните, почвему ядолжна выкладывать 1200 рублей, если переход на 8.3. был вынужден? Меня все устраивало..

    Reply
  44. olegmedvedev

    (43) Вы о чем? это не обработка, это бесплатная статья, в которой рассказывается как можно загрузить из Экселя в 1С, приводится метод который автор предлагает воспользоваться.

    Про переход с 8.2 на 8.3 тут ничего не говорится, денег автор тоже не требует за свою статью.

    Reply
  45. logarifm

    сделайте обработкой и залейте для скача. Спасибо!

    Reply
  46. lisrws

    с конструкцией для определения количества колонок «ОбластьФайла.ПолучитьРазмерОбластиДанныхПоГоризонтали()» будьте осторожны. она определяет количество колонок по первой строке. у меня в первой строке 6 колонок с данными, а с 7 строки уже 8 колонок. конструкция возвращает мне 6. если в первой строке добавить данные в 7 и 8 колонки, то вернет 8 как и должно быть. релиз «8.3.10.2252»

    Reply
  47. StepByStep

    (45)

    Практическое применение:

    «Импорт из EXCEL и других источников (xls, xlsx, xlsb, ods, sxc, dbf, mxl, csv, clipboard, sql) в 1С»

    http://infostart.ru/public/120961/

    Reply
  48. StepByStep

    (46)

    Совершенно верно, так и есть.

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

    Reply
  49. aleksey.kubovtsov

    Спасибо за публикацию .

    У меня была проблема, может кому поможет в решение:

    Строку вида «01.02.2017» при чтение excel табличным документом воспринималась как 01.ММ.2017

    помогло

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

    Reply
  50. abrafaks

    Единственное, я бы вместо «Пока 1=1 Цикл» (так писали в 7.7), написал бы «Пока Истина Цикл».

    Reply
  51. ilp06

    Как считать 1-ый лист?

    Опять в 1с всё через ..опу!

    Нафига области сортировать! Порядок листов — от балды.

    Жесть.

    Reply
  52. ilp06

    Есть решение:

    Нужно сортировать по реквизиту Верх области.

    Тогда порядок будет соответствовать порядку листов в Excel-файле.

    Reply
  53. Daniayr

    Коллеги, подскажите как закрывать тот файл с которым работаешь (импорт), у меня закрыает все что открыто

    использую LibreOffice

    Reply
  54. fedor40

    Вставил весь код в модуль внеш обработки. Работаю на 8.3.10.2580.

    Выдает ошибку:{ВнешняяОбработка.ВнешняяОбработка1.МодульОбъекта(8,36)}: Процедура или функция с указанным именем не определена (ВерсияБезНомераСборки)

    ВерсияПриложенияБезНомераСборки = <<?>>ВерсияБезНомераСборки(СистемнаяИнформация.ВерсияПриложения); (Проверка: Сервер).

    Странно. Я так и не понял в чем ошибка.

    Reply
  55. vis_tmp

    Спасибо, очень полезная публикация!

    Reply
  56. It-developer

    Хороший шаблон для своего модуля работа с Эксель. Спасибо

    Reply
  57. Stradivari

    Спасибо. Статья выручила!

    Reply
  58. premierex

    (0) Статья отличная. Плюс, несомненно. Но вот от объекта MSScriptControl.ScriptControl я бы всё же отказался, потому как существует только 32-х битная реализация этой библиотеки и она просто не загрузится в 64-х битный серверный процесс. Выход, конечно, есть, но он уж очень похож на танец с бубнами.

    Reply
  59. KAV2

    Есть такой нюанс с использованием ТабличногоДокумента в тонком клиенте: если файл уже открыт в Excel, то не получается передать его на сервер для обработки с помощью метода ПоместитьФайлы — файл оказывается заблокированным другим приложением

    Reply
  60. premierex

    (0) Функционал чтения многостраничного документа можно значительно упростить. Вместо того, чтобы дважды читать документ для определения количества листов и их имен:

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

    можно использовать конструкцию:

    ОбластьФайла = ТабличныйДокумент.Области[Мин(ИндексЛиста, ТабличныйДокумент.Области.Количество() — 1]);

    Reply
  61. vis_tmp

    (0)Не могу понять, загружается ли гиперссылка из ячейки Excel-а?

    Гиперссылка представляет из себя URL на картинку на сайте (прилагаю для примера кусочек такого файла).

    В блоке:

    Если ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
    ЗначениеЯчейки = ПреобразоватьПростоеЗначениеИзСтрокиВТипизованноеЗначение1С(ЗначениеЯчейки);
    Если ТипЗнч(ЗначениеЯчейки) = Тип(«Строка») Тогда
    ЗначениеЯчейки = СокрЛП(ЗначениеЯчейки);
    КонецЕсли;
    Иначе
    ЗначениеЯчейки = Неопределено;
    Если Область.Рисунки.Количество() > 0 Тогда    // Изображение.
    ЗначениеЯчейки = ПолучитьЗначениеЯчейкиОбластиТабличногоДокументаСКартинками(Область, нСтрока, нКолонка, «УИД»);
    КонецЕсли;
    КонецЕсли;

    Показать

    переменная «ЗначениеЯчейки» содержит просто текст «Изображение»…

    Кому-нибудь удалось получить URL гиперссылки из подобного файла?

    Reply
  62. Redhatych

    (61) как получить URL гиперссылки.

    может быть кому-то пригодится.

    предварительно в файле Excel создайте макрос, вытягивающий URL из таких ячеек. и с этим столбцом работайте

    подробности здесь: http://mindubaev.com/internet-marketing/seo/kak-vytashhit-giperssylku-iz-excel/

    Reply
  63. vis_tmp

    (62)Спасибо

    Reply
  64. N191119

    (8) ему не требуется драйвера майкрософта или установленный офис на компьютере

    Reply
  65. OlaIa

    Добрый день.

    А как быть с чтением файла Excel, который защищен паролем?

    В этом случае ТабличныйДокумент.Прочитать не работает.

    Reply
  66. vis_tmp

    (65)Тут уже, скорее всего, ничего не поделаешь…

    Reply
  67. DMSDeveloper

    По мне так механизм чтения Excel средствами платформы еще очень сырой.

    Вот вам живой пример

    Есть файл, формата Excel-97 (xls) с формой УПД, которую нам по почте присылает поставщик.

    Ячейка «Всего к оплате» имеет числовое значение 27 191,66

    Метод прочитать, табличного документа, с типом чтения «Значение» получает 27 192! Зачем это платформа 1С сделала округление?

    При выборе типа чтения «Текст» выдает еще более интересный вариант — «General27192»! Это вообще откуда?

    Все на скринах.

    Веселый файл тоже во вложении.

    З.Ы. Редактировать и пересохранять файл не предлагать! Он грузится автоматом при получении почты.

    Reply
  68. eact

    Странно преобразует числа… Например «16,9» преобразует в «16,899999999999999»…

    Или «35,09» в «35,090000000000003»

    Хотя в изначально в ексель четко число 35,09 и 16,9

    Reply
  69. kn

    Автору спасибо за пример работы с листами в 8.3.10

    (67) xls можно скриптом преобразовывать

    &НаСервере
    Процедура ЗагрузитьИзФайла(АдресФайла, ВыбИмяФайла)
    
    Расш = ПолучитьРасширениеФайла(ВыбИмяФайла);
    
    Если Расш = «xls»  Тогда
    
    Попытка
    лДвоичДанные = ПолучитьИзВременногоХранилища(АдресФайла);
    лФайл = ПолучитьИмяВременногоФайла(Расш);
    лДвоичДанные.Записать(лФайл);
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    
    Попытка
    Excel = Новый COMОбъект(«Excel.Application»);
    ОткрытаяКнига = Excel.WorkBooks.Open(лФайл);
    ИмяФайла = ПолучитьИмяВременногоФайла(«xlsx»);
    Excel.DisplayAlerts=0;
    ОткрытаяКнига.SaveAs(ИмяФайла, 51);
    Excel.DisplayAlerts = 1;
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    
    Excel.DisplayAlerts = 0;
    Excel.WorkBooks.Close();
    Excel.DisplayAlerts = 1;
    Excel.Quit();
    Excel = Неопределено;
    
    ТабличныйДокумент.Очистить();
    ТабличныйДокумент.Прочитать(ИмяФайла, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    
    Иначе
    
    Попытка
    лФайл = ПолучитьИмяВременногоФайла(Расш);
    лДвоичДанные = ПолучитьИзВременногоХранилища(АдресФайла);
    лДвоичДанные.Записать(лФайл);
    Исключение
    Сообщить(ОписаниеОшибки());
    Возврат;
    КонецПопытки;
    
    ТабличныйДокумент.Очистить();
    ТабличныйДокумент.Прочитать(лФайл, СпособЧтенияЗначенийТабличногоДокумента.Значение);
    
    КонецЕсли;
    
    КонецПроцедуры
    

    Показать

    Reply
  70. vis_tmp

    (69)Во что преобразуется?

    Какой файл получится в результате?

    Reply
  71. kn

    (70)xls в xlsx, тот можно Прочитать(). Раньше xls не читался.

    Reply
  72. kn

    (67)да неправа, выдает тоже 27 192.

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *