Одним из полезных нововведений на платформе 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
<СпособЧтенияЗначений> (необязательный)
Тип: СпособЧтенияЗначенийТабличногоДокумента.
Определяет, каким образом нужно интерпретировать значения, считываемые из исходного документа XLS, XLSX или ODS.
При загрузке табличного документа из формата Excel 97 - 2010 и OpenOffice Calc, в случае если в ячейке исходного документа содержалось значение типа Дата или Число, то в ячейку результирующего табличного документа это значение попадает в зависимости от значения этого параметра.
Значение по умолчанию: Текст.
Построитель = Новый ПостроительОтчета;
Построитель.ИсточникДанных = Новый ОписаниеИсточникаДанных(тз);
Построитель.Выполнить();
Построитель.Вывести();
Так вот. И в excel и в mxl ячейка может содержать значение и иметь формат представления. Проблема в том, что СКД при выводе значений в табличный документ выводит только представление...
Проблема при сохранении табличного документа в файл xlsx
Если в ячейке будет код номенклатуры с лидирующими нулями - при экспорте в эксель значение ячейки их обрежет,
например было "00246100" стало "246100":
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.Область(1,1).Текст = "Номенклатура";
ТабДокумент.Область(1,2).Текст = "Артикул";
ТабДокумент.Область(2,1).Текст = "NSIN0001130294";
ТабДокумент.Область(2,2).Текст = "00246100";
ИмяФайлаXLSX = ПолучитьИмяВременногоФайла("xlsx");
ТабДокумент.Записать(ИмяФайлаXLSX, ТипФайлаТабличногоДокумента.XLSX);
ЗапуститьПриложение(ИмяФайлаXLSX);
Выведет:
При этом в представлении всё верно...
И да, если переименовать xlsx в zip и открыть архиватором sheet1.xml - то там будет именно "246100".
Конечно, есть ещё вариант ручной установки значения ячейки таб. документа, и он работает.
На клиенте...
#Если ТолстыйКлиентОбычноеПриложение Тогда
// В экселе значение ячейки отличается от представления (обрезает лидирующие нули и т.п.)
Область = ТабДок.Область(1,1,ТабДок.ВысотаТаблицы, ТабДок.ШиринаТаблицы);
Область.Защита = Ложь;
Область.СодержитЗначение = Истина;
#КонецЕсли
Но #НаСервере установка свойства СодержитЗначение приводит к очистке. И в справке про это ничего нет...
Для регламентных не годится.
Проблема при загрузке табличного документа из файла xlsx
При загрузке файла экселя, сформированного в других языках программирования, содержимое может вообще не прочитаться (если верить гуглу при поиске заголовков этого файла выдаёт Open XML SDK 2.5),
например:
ИмяФайлаXLSX = ПолучитьИмяВременногоФайла("xlsx");
Ссылка = "https://raw.githubusercontent.com/kuzyara/ConvertCSV/master/priceberg.xlsx";
КопироватьФайл(Ссылка, ИмяФайлаXLSX);
//ЗапуститьПриложение(ИмяФайлаXLSX);
ТабДокумент = Новый ТабличныйДокумент;
ТабДокумент.Прочитать(ИмяФайлаXLSX, СпособЧтенияЗначенийТабличногоДокумента.Значение);
ЗаполненоЯчеек = 0;
Для НомерСтроки = 1 По ТабДокумент.ВысотаТаблицы Цикл
Для НомерСтолбца = 1 По ТабДокумент.ШиринаТаблицы Цикл
ТекЗначение = ТабДокумент.Область(НомерСтроки,НомерСтолбца).Текст;
Если НЕ ПустаяСтрока(ТекЗначение) Тогда
ЗаполненоЯчеек = ЗаполненоЯчеек + 1;
КонецЕсли;
КонецЦикла;
КонецЦикла;
Сообщить("Заполнено ячеек: " + ЗаполненоЯчеек);
// Выведет:
//
// Заполнено ячеек: 0
В режиме предприятия (меню Файл - Открыть) это пустой таб. документ
с 1026 столбца...
Хотя в экселе файл открывается прекрасно:
Нюансы (различия) чтения методом OLE и ТабДок
//COM
Excel = Новый COMОбъект("Excel.Application");
Excel.Visible=0;
Excel.FileValidation = 1;
Excel.Workbooks.Open(ИмяФайла, , Истина);
Book = Excel.Workbooks(1);
Sheet = Book.Sheets(1);
МассивМассивовXLS = Sheet.UsedRange.Value.Выгрузить();
//ТАБ
ТабДокумент= Новый ТабличныйДокумент;
ТабДокумент.Прочитать(ИмяФайлаXLSX);
ПостроительОтчета = Новый ПостроительОтчета;
ПостроительОтчета.ИсточникДанных = Новый ОписаниеИсточникаДанных(ТабДокумент.Область());
ПостроительОтчета.Выполнить();
// Результат выгружаем в таблицу значений.
ТабЗначений = ПостроительОтчета.Результат.Выгрузить();
Часть кода для сравнения этих методов:
ИначеЕсли СтрНайти(Стр, ",") > 0 Тогда
//СтрокаCOM[КиЗ.Ключ] "0,00002" Строка
//СтрокаТАБ[КиЗ.Значение] "0,000020" Строка
// ...
ДобавитьНюанс(Нюансы, "Нюанс1", СтрокаCOM[КиЗ.Ключ], СтрокаТАБ[КиЗ.Значение]);
ИначеЕсли ТолькоЦифрыВСтроке(Стр) Тогда
//СтрокаCOM[КиЗ.Ключ] "58198119" Строка
//СтрокаТАБ[КиЗ.Значение] "058198119" Строка
// ...
ДобавитьНюанс(Нюансы, "Нюанс2", СтрокаCOM[КиЗ.Ключ], СтрокаТАБ[КиЗ.Значение]);
ИначеЕсли КиЗ.Значение = "Колонка4" И СтрНайти(Стр, ".") > 0 Тогда
//СтрокаCOM[КиЗ.Ключ] "835,2" Строка
//СтрокаТАБ[КиЗ.Значение] "835.2000000000001" Строка
// ...
ДобавитьНюанс(Нюансы, "Нюанс3", СтрокаCOM[КиЗ.Ключ], СтрокаТАБ[КиЗ.Значение]);
ИначеЕсли СодержимоеПервых100СтрокПусто(ТабДокумент) Тогда
// если платформа не смогла прочитать и выдала пустые строки
// ...
ДобавитьНюанс(Нюансы, "Нюанс4", "Пустые строки: NativeXLSX", "", Истина);
ИначеЕсли СокрЛП(СтрокаОбразец[КиЗ.Ключ]) = СокрЛП(Стр) Тогда
//СтрокаCOM[КиЗ.Ключ] "уп.10" Строка
//СтрокаТАБ[КиЗ.Значение] "уп.10 " Строка
// ...
ДобавитьНюанс(Нюансы, "Нюанс5", СтрокаCOM[КиЗ.Ключ], СтрокаТАБ[КиЗ.Значение]);
ИначеЕсли ТабДокумент.ШиринаТаблицы > 1024 Тогда
ДобавитьНюанс(Нюансы, "Нюанс6", "ШиринаТаблицы > 1024", "");
// и т.д.
Я конечно буду рад ошибаться, но, по-моему, нативные средства платформы по работе с Excel совсем далекоооооо не всегда применимы на практике.