В данном примере хочу привести несколько универсальных функций по выгрузке таблицы значений в файл и дальнейшего чтения из файла:
П орядок программных действий при выгрузке в файл выглядит так:
Подготавливаем таблицу значений (выгружаем из табличной части, выбираем колонки); Конвертируем таблицу значений в табличный документ; Сохраняем табличный документ в MXL.
При загрузке таблицы порядок действий такой:
Читаем из файла табличный документ; Конвертируем табличный документ в таблицу значений; Используем эту таблицу значений в своих целях (загружаем в табличную часть).
Соответственно файл для хранения данных таблицы имеет расширение *.mxl.
Основные функции для реализации поставленной задачи следующие:
ПреобразоватьТДвТЗ – Функция преобразования табличного документа в таблицу значений.
ПреобразоватьТЗвТД – Функция обратного преобразования таблицы значений в табличный документ.
ПрочитатьТЗИзMXL – Читает из файла данные, определяет колонки таблицы и преобразует эти данные в таблицу значений.
ЗаписатьТЗВMXL – Преобразует таблицу значений в табличный документ и записывает его в файл.
Код 1C v 8.3
Функция ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, Знач КонецСтрока = Неопределено, Знач КонецСтолбец = Неопределено) Экспорт
Если НачалоСтрока = Неопределено И НачалоСтолбец = Неопределено Тогда
НачалоСтрока = 1 ;
НачалоСтолбец = 1 ;
КонецЕсли ;
Если НачалоСтрока = Неопределено Тогда
НачалоСтрока = 1 ;
Пока НЕ ТабДок. Область( НачалоСтрока, НачалоСтолбец) . СодержитЗначение
И НачалоСтрока < ТабДок. ВысотаТаблицы
Цикл
НачалоСтрока = НачалоСтрока + 1 ;
КонецЦикла ;
ИначеЕсли НачалоСтолбец = Неопределено Тогда
НачалоСтолбец = 1 ;
Пока НЕ ТабДок. Область( НачалоСтрока, НачалоСтолбец) . СодержитЗначение
И НачалоСтолбец < ТабДок. ШиринаТаблицы
Цикл
НачалоСтолбец = НачалоСтолбец + 1 ;
КонецЦикла ;
КонецЕсли ;
КонецСтрока = ? ( КонецСтрока = Неопределено , ТабДок. ВысотаТаблицы, КонецСтрока) ;
КонецСтолбец = ? ( КонецСтолбец = Неопределено , ТабДок. ШиринаТаблицы, КонецСтолбец) ;
ЭтоТаблица = ( ТипЗнч( СтруктураКолонок) = Тип( "ТаблицаЗначений" ) ) ;
ТабЗначений = ПолучитьТаблицуВывода( СтруктураКолонок) ;
Для ИндексСтроки = НачалоСтрока По КонецСтрока Цикл
СтрокаТЗ = ТабЗначений. Добавить( ) ;
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из СтруктураКолонок Цикл
НаименованиеКолонки = ? ( ЭтоТаблица, Колонка. Наименование, Колонка. Ключ) ;
пИндексКолонки = ? ( ЭтоТаблица, Колонка. СтолбецОтчёт, ИндексКолонки) ;
Если ТабДок. Область( ИндексСтроки, пИндексКолонки) . СодержитЗначение Тогда
СтрокаТЗ[НаименованиеКолонки] = ТабДок. Область( ИндексСтроки, пИндексКолонки) . Значение;
Иначе
СтрокаТЗ[НаименованиеКолонки] = ТабДок. Область( ИндексСтроки, пИндексКолонки) . Текст;
КонецЕсли ;
ИндексКолонки = ИндексКолонки + 1 ;
КонецЦикла ;
КонецЦикла ;
Возврат ТабЗначений;
КонецФункции ;
Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт
Если ТабДок = Неопределено Тогда
ТабДок = Новый ТабличныйДокумент;
КонецЕсли ;
НачалоСтрока = ? ( НачалоСтрока = Неопределено , 1 , НачалоСтрока) ;
НачалоСтолбец = ? ( НачалоСтолбец = Неопределено , 1 , НачалоСтолбец) ;
ИндексСтроки = НачалоСтрока;
Если ВыводитьЗаголовки Тогда
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений. Колонки Цикл
ТабДок. Область( ИндексСтроки, ИндексКолонки) . Текст = ? ( ПустаяСтрока( Колонка. Заголовок) , Колонка. Имя, Колонка. Заголовок) ;
ИндексКолонки = ИндексКолонки + 1 ;
КонецЦикла ;
ИндексСтроки = ИндексСтроки + 1 ;
КонецЕсли ;
Для Каждого Элемент Из ТабЗначений Цикл
ИндексКолонки = НачалоСтолбец;
Для Каждого Колонка Из ТабЗначений. Колонки Цикл
ТабДок. Область( ИндексСтроки, ИндексКолонки) . СодержитЗначение = Истина ;
ТабДок. Область( ИндексСтроки, ИндексКолонки) . ТипЗначения = Новый ОписаниеТипов( Колонка. ТипЗначения) ;
ТабДок. Область( ИндексСтроки, ИндексКолонки) . Значение = Элемент[Колонка. Имя];
ИндексКолонки = ИндексКолонки + 1 ;
КонецЦикла ;
ИндексСтроки = ИндексСтроки + 1 ;
КонецЦикла ;
Возврат ТабДок;
КонецФункции ;
Функция ПрочитатьТЗИзMXL(ИмяФайла, СтруктураКолонок = Неопределено, ЕстьЗаголовок = Истина) Экспорт
ТабДок = Новый ТабличныйДокумент;
ТабДок. Прочитать( ИмяФайла) ;
Если СтруктураКолонок = Неопределено И ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок. ШиринаТаблицы Цикл
Обл1 = ТабДок. Область( 1 , ИндексКолонки) ;
Обл2 = ТабДок. Область( 2 , ИндексКолонки) ;
ИмяКолонки = СокрЛП( Обл1 . Текст) ;
ИмяКолонки = ? ( Найти( ИмяКолонки, " " ) > 0 , СтрЗаменить( ТРег( ИмяКолонки) , " " , "" ) , ИмяКолонки) ;
СтруктураКолонок. Вставить( ИмяКолонки, ? ( Обл2 . СодержитЗначение, Обл2 . ТипЗначения, Новый ОписаниеТипов) ) ;
КонецЦикла ;
ИначеЕсли СтруктураКолонок = Неопределено И НЕ ЕстьЗаголовок Тогда
СтруктураКолонок = Новый Структура;
Для ИндексКолонки = 1 По ТабДок. ШиринаТаблицы Цикл
Обл2 = ТабДок. Область( 1 , ИндексКолонки) ;
ИмяКолонки = "К" + Формат( ИндексКолонки, "ЧДЦ=0; ЧН=0; ЧГ=0" ) ;
СтруктураКолонок. Вставить( ИмяКолонки, ? ( Обл2 . СодержитЗначение, Обл2 . ТипЗначения, Новый ОписаниеТипов) ) ;
КонецЦикла ;
КонецЕсли ;
Таблица = ПреобразоватьТДвТЗ( ТабДок, СтруктураКолонок, ? ( ЕстьЗаголовок, 2 , 1 ) , 1 ) ;
Возврат Таблица;
КонецФункции ;
Процедура ЗаписатьТЗВMXL(ИмяФайла, ТабЗначений, ЕстьЗаголовок = Истина) Экспорт
ТабДок = ПреобразоватьТЗвТД( ТабЗначений, Неопределено , 1 , 1 , ЕстьЗаголовок) ;
ТабДок. Записать( ИмяФайла, ТипФайлаТабличногоДокумента. MXL) ;
КонецПроцедуры ;
Еще небольшой набор функций для вывода таблицы значений в табличный документ. После формирования табличного документа, - сохраняем его в файл mxl.
Табличный документ можно сохранить a файлы следующих типов:
ANSITXT - Текстовый документ DOCX - документ MS Word HTML HTML3 HTML4 HTML5 MXL MXL7 ODS - Файл Open Office PDF - файл Acrobat Readr TXT - Текстовый документ XLS - файл Excel XLS95 - файл Excel95 XLS97 - файл Excel97 XLSX - файл Excel2010
Код 1C v 8.3
Функция ЗагрузитьТЗизФайла(ИмяФайла)
Путь = КаталогВременныхФайлов( ) + ИмяФайла;
Текст = Новый ЧтениеТекста( Путь, КодировкаТекста. UTF8) ;
стрТЗ = Текст. Прочитать( ) ;
Текст. Закрыть( ) ;
ТЗ = ЗначениеИзСтрокиВнутр( стрТЗ) ;
Возврат ТЗ;
КонецФункции
Функция ЗаписьТЗ2ТабДок(записьТЗ,НомерСтроки,ТабличныйДокумент)
НомерКолонки = 1 ;
Символ160 = Символ( 160 ) ;
Для каждого полеТЗ из ЗаписьТЗ цикл
типПоляТЗ = ТипЗнч( полеТЗ) ;
если типПоляТЗ = Тип( "Число" ) тогда
полеТЗ= Строка( полеТЗ) ;
полеТЗ= СтрЗаменить( полеТЗ, Символ160 , "" ) ;
полеТЗ= СтрЗаменить( полеТЗ, "," , "." ) ;
иначеесли типПоляТЗ = Тип( "Строка" ) тогда
иначе
полеТЗ = строка( полеТЗ) ;
КонецЕсли ;
имяОбласти = "R" + номерСтроки + "C" + НомерКолонки;
имяОбласти = СтрЗаменить( имяОбласти, Символ( 160 ) , "" ) ;
Ячейка = ТабличныйДокумент. Область( имяОбласти) ;
Ячейка. Текст = полеТЗ;
НомерКолонки = НомерКолонки + 1 ;
КонецЦикла ;
КонецФункции
Функция НаимКолонок2Mxl(ТаблицаЗначений,ТабличныйДокумент)
номерСтроки= 1 ;
номКолонки= 1 ;
ТабличныйДокумент = новый ТабличныйДокумент;
Для НомКол= 0 по ТаблицаЗначений. Колонки. Количество( ) - 1 Цикл
имяКолонки= ТаблицаЗначений. Колонки[НомКол]. Имя;
имяОбласти = "R" + номерСтроки + "C" + номКолонки;
имяОбласти = СтрЗаменить( имяОбласти, Символ( 160 ) , "" ) ;
Ячейка = ТабличныйДокумент. Область( имяОбласти) ;
Ячейка. Текст = имяКолонки;
ЖирныйШрифт = ? ( ЖирныйШрифт = Неопределено , Новый Шрифт( Ячейка. Шрифт, , , Истина ) , ЖирныйШрифт) ;
Ячейка. Шрифт = ЖирныйШрифт;
номКолонки = номКолонки + 1 ;
КонецЦикла ;
КонецФункции
Функция Таблица2Mxl(ТаблицаЗначений,ТабличныйДокумент)
НомСтр= 1 ;
Для каждого записьТЗ из ТаблицаЗначений Цикл
НомСтр = НомСтр + 1 ;
ЗаписьТЗ2 ТабДок( записьТЗ, НомСтр, ТабличныйДокумент) ;
КонецЦикла ;
КонецФункции
Функция ТаблицаЗначений2Mxl(ТаблицаЗначений,ФайлMxl)
ТабличныйДокумент = новый ТабличныйДокумент;
НаимКолонок2 Mxl( ТаблицаЗначений, ТабличныйДокумент) ;
Таблица2 Mxl( ТаблицаЗначений, ТабличныйДокумент) ;
ТабличныйДокумент. Записать( ФайлMxl, ТипФайлаТабличногоДокумента. MXL) ;
ТабличныйДокумент. Показать( ФайлMxl, ФайлMxl) ;
Возврат 0 ;
КонецФункции
Функция Тест_ВыгрузитьТЗвMxl() ;
файл_мТЗИсходныеДанные = "мТЗИсходныеДанные.dat" ;
ТЗ = ЗагрузитьТЗизФайла( файл_мТЗИсходныеДанные) ;
ФайлMxl = КаталогВременныхФайлов( ) + СтрЗаменить( файл_мТЗИсходныеДанные, ".dat" , ".mxl" ) ;
ТаблицаЗначений2 Mxl( ТЗ, ФайлMxl) ;
КонецФункции
Тест_ВыгрузитьТЗвMxl( ) ;
Пример выгруженной таблицы значений в файл:
Доброго времени суток!
Обработку ЗагрузкаданныхизТабличногоДокументаконечно должен знать каждый 1С-ник. И сколько бы обработок такого плана не появлялось, эта остается классикой. Даже претензии можно предъявлять если вы в ней что-то не понимаете к самой 1С. Хотя какие претензии, исходный код открыть – изучай, не хочу…
Еще чем мне нравится эта обработка – тем что вы читаете данные из внешнего источника, показываете их с помощью объекта табличное поле и только затем выбираете алгоритм загрузки в 1С. При чем загрузка у Вас происходит в среде 1С без привлечения дополнительных компонентов. Без всяких выпадов в неизвестный объект OLE, полей которые не прочитались в обработке загрузки. Если вы видете данные в табличном поле, то они и будут грузиться по вашему алгоритму.
Но что-то в ней не хватает. Конечно стандарта офисных документов ODF (Open Document Format и между прочим ГОСТ Р ИСО/МЭК 26300-2010). Как говаривал мой начальник – есть чем себя занять. Из всех внешних загрузок, которые сейчас есть к сожалению самыми распостраненными являются OLE(Com+) технологии. Возможно что-то еще появиться, но пока примемся за них.
Залезаем в код и видим несколько однотипных функуций
Функция мПрочитатьТабличныйДокументИзExcel(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
Функция мПрочитатьТабличныйДокументИзТекста(ТабличныйДокумент, ИмяФайла, НомерЛистаExcel = 1) Экспорт
Пора добавить свою:
Код 1C v 8.х
Функция мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент, ИмяФайла, НомерЛистаCalc = 1) Экспорт
ВыбФайл = Новый Файл( ИмяФайла) ;
Если НЕ ВыбФайл. Существует( ) Тогда
Сообщить( “Файл не существует!”) ;
Возврат Ложь ;
КонецЕсли ;
Попытка
ServiceManager = Новый COMОбъект( “com. sun. star. ServiceManager”) ;
Desktop = ServiceManager. CreateInstance( “com. sun. star. frame. Desktop”) ;
Desktop. getCurrentFrame( ) . getContainerWindow( ) . setVisible( Ложь ) ;
Параметры = Новый COMSafeArray( “VT_DISPATCH”, 1 ) ;
Свойство = ServiceManager. Bridge_GetStruct( “com. sun. star. beans. PropertyValue”) ;
Свойство. Name = “Hidden”;
Свойство. Value = true;
Параметры. SetValue( 0 , Свойство) ;
Document = Desktop. LoadComponentFromURL( “file:
Состояние( “Обработка файла Office Calc …”) ;
Листы = Document. getSheets( ) ;
Лист = Листы. getByIndex( НомерЛистаCalc- 1 ) ;
Исключение
Сообщить( “Ошибка загрузки данных. Возможно неверно указан номер листа книги Calc. ”) ;
Возврат ложь ;
КонецПопытки ;
ТабличныйДокумент. Очистить( ) ;
НульЯчейка = Лист. GetCellbyPosition( 0 , 0 ) ;
НульКурсор = Лист. createCursorByRange( НульЯчейка) ;
НульКурсор. GotoEndOfUsedArea( 1 ) ;
НульАдрес = НульКурсор. RangeAddress;
ПослСтрока = НульАдрес. EndRow;
ПослКолонка = НульАдрес. EndColumn;
Для Row = 1 По ПослСтрока + 1 Цикл
Если Лист. getCellByPosition( Column- 1 , Row- 1 ) . getType( ) = 0 Или Лист. getCellByPosition( Column- 1 , Row- 1 ) . getType( ) = 1 Тогда ТабличныйДокумент. Область( “R” + Формат( Row, “ЧГ= ”) + ”C” + Формат( Column, “ЧГ= ”) ) . Текст = Лист. getCellByPosition( Column- 1 , Row- 1 ) . value;
ИначеЕсли Лист. getCellByPosition( Column- 1 , Row- 1 ) . getType( ) = 2 Тогда ТабличныйДокумент. Область( “R” + Формат( Row, “ЧГ= ”) + ”C” + Формат( Column, “ЧГ= ”) ) . Текст = Лист. getCellByPosition( Column- 1 , Row- 1 ) . string;
КонецЕсли ;
КонецЦикла ;
Document. Dispose( ) ;
Document = 0 ;
Параметры = 0 ;
Desktop = 0 ;
ServiceManager = 0 ;
Возврат Истина ;
КонецФункции
И добавим в форму выбора файла ods по тексту.
Код 1C v 8.х ДиалогВыбораФайла. Фильтр = “Табличный документ ( * . mxl) |*.mxl|Лист Calc (*.ods)|*.ods|Лист Excel (*.xls)|*.xls|Текстовый документ (*.txt)|*.txt|dBase III (*.dbf)|*.dbf|”;
И выбор функции для ods
ИначеЕсли нРег(ФайлНаДиске.Расширение) = “.ods” Тогда
мПрочитатьТабличныйДокументИзCalc(ТабличныйДокумент,ДиалогВыбораФайла.ПолноеИмяФайла);
Вот так лучше.
Сайт
sikuda.ru Конвертация таблиц из Excel в MXL - скачать Converter Excel v MXL:
Для 8.х -
Скачивать файлы может только зарегистрированный пользователь!
Для 7.7 -
Скачивать файлы может только зарегистрированный пользователь!
Код 1C v 8.х
Procedure FileNameStartChoice( Element, StdProcessing)
StdProcessing = False;
DialogFile = New FileDialog( FileDialogMode. Open) ;
DialogFile. Filter = "Файлы Microsoft Excel (*.xls)|*.xls" ;
DialogFile. DefaultExt = "xls" ;
If DialogFile. Choose( ) Then
FileName = DialogFile. FullFileName;
EndIf;
EndProcedure
Function GetSheets( ExcelApplication)
ListS_electSheet = New ValueList;
ListS_electSheet. Add( 0 , "Все листы" ) ;
NumberSheet = 0 ;
For FirstSheet = 1 To ExcelApplication. Worksheets. Count Do
NumberSheet = NumberSheet + 1 ;
ListS_electSheet. Add(
NumberSheet, ExcelApplication. WorkSheets( NumberSheet) . Name
) ;
EndDo;
Return ListS_electSheet;
EndFunction
Procedure ButtonExecuteClick( )
If IsBlankString( FileName) Then
DoMessageBox( "Не указано имя файла" ) ;
Return;
EndIf;
Try
ExcelApplication = GetCOMObject( FileName) ;
Except
DoMessageBox( "Ошибка чтения файла: " + FileName + " возможно защищен паролем." ) ;
Return;
EndTry;
S_electSheet = 0 ;
S_electSheet = GetSheets( ExcelApplication) . ChooseItem( "Выберите лист" , S_electSheet) ;
If S_electSheet = Undefined Then
Return;
EndIf;
S_electNumberSheet1 = S_electSheet. Value;
S_electNumberSheet2 = S_electNumberSheet1;
If S_electNumberSheet1 = 0 Then
S_electNumberSheet1 = 1 ;
S_electNumberSheet2 = ExcelApplication. Worksheets. Count
EndIf;
frmProgressBar = GetForm( "FormProgressBar" ) ;
frmProgressBar. Caption = "Обрабатывается файл: " + FileName;
frmProgressBar. Controls. ProgressBarAll. MaxValue = S_electNumberSheet2;
frmProgressBar. Controls. ProgressBarAll. Value = 0 ;
For NumberSheet = S_electNumberSheet1 To S_electNumberSheet2 Do
frmProgressBar. Open( ) ;
SprDoc = New SpreadsheetDocument;
Try
WorkSheet = ExcelApplication. Sheets( NumberSheet) . UsedRange;
Except
DoMessageBox( ErrorDescription( ) ) ;
Return;
EndTry;
AllStrings = WorkSheet. Rows. Count;
AllColumns = WorkSheet. Columns. Count;
AllCells = AllStrings * AllColumns;
frmProgressBar. Controls. InfoProgressBarAll. Value = "Обрабатывается лист № " +
NumberSheet + " из " +
S_electNumberSheet2;
frmProgressBar. Controls. ProgressBarAll. Value = frmProgressBar. Controls. ProgressBarAll. Value + 1 ;
If AllCells < 2 Then
Continue;
EndIf;
frmProgressBar. Controls. ProgressBarCur. MaxValue = AllStrings;
frmProgressBar. Controls. ProgressBarCur. Value = 0 ;
For CurrentString = 1 To AllStrings Do
For CurrentColumn = 1 To AllColumns Do
frmProgressBar. Controls. InfoProgressBarCur. Value = "Обрабатывается строка №: " +
TrimAll( CurrentString) +
" из " + AllStrings +
", колонка №: " +
TrimAll( CurrentColumn) +
" из " + AllColumns;
Try
CurrentCell = WorkSheet. Cells(
CurrentString,
CurrentColumn
) ;
SlcCell = SprDoc. Area(
CurrentString,
CurrentColumn,
CurrentString,
CurrentColumn
) ;
SlcCell. RowHeight = CurrentCell. RowHeight;
SlcCell. ColumnWidth = CurrentCell. ColumnWidth;
SlcCell. HorizontalAlign = mListHorizontalAlign. Get(
Format( CurrentCell. HorizontalAlignment, "NG=0" )
) ;
SlcCell. VerticalAlign = mListVerticalAlign. Get(
Format( CurrentCell. VerticalAlignment, "NG=0" )
) ;
SlcCell. TextPlacement = ? (
CurrentCell. WrapText = 0 ,
SpreadsheetDocumentTextPlacementType. Auto,
SpreadsheetDocumentTextPlacementType. Wrap
) ;
FontCell = CurrentCell. Font;
SlcCell. BackColor = mColorRGB(
CurrentCell. Interior. Color
) ;
SlcCell. TextColor = mColorRGB(
FontCell. Color
) ;
SlcCell. Font = New Font(
FontCell. Name,
Number( FontCell. Size) ,
? ( Number( FontCell. Bold) = 0 ,
False, True) ,
? ( Number( FontCell. Italic) = 0 ,
False, True) ,
? ( Format( Number( FontCell. Underline) , "NG=0" ) = "-4142" ,
False, True) ,
? ( FontCell. Strikethrough,
True, False)
) ;
SlcCell. Text = CurrentCell. Value;
Try
SlcCell. LeftBorder = mStyleBorder( CurrentCell, 7 ) ;
SlcCell. TopBorder = mStyleBorder( CurrentCell, 8 ) ;
SlcCell. RightBorder = mStyleBorder( CurrentCell, 10 ) ;
SlcCell. BottomBorder = mStyleBorder( CurrentCell, 9 ) ;
Except
EndTry;
SlcCell. Details = CurrentCell. Formula;
If ( CurrentCell. MergeCells < > 0 ) and
( Find( CurrentCell. MergeArea. Rows. Address( , , 2 ) ,
CurrentCell. Address( , , 2 ) ) = 1 ) Then
SlcCell = SprDoc. Area(
CurrentString,
CurrentColumn,
( CurrentString + CurrentCell. MergeArea. Rows. Count - 1 ) ,
( CurrentColumn + CurrentCell. MergeArea. Columns. Count - 1 )
) ;
SlcCell. Merge( ) ;
EndIf;
Except
Message( ErrorDescription( ) ) ;
EndTry;
EndDo;
frmProgressBar. Controls. ProgressBarCur. Value = frmProgressBar. Controls. ProgressBarCur. Value + 1 ;
UserInterruptProcessing( ) ;
EndDo;
SprDoc. Show( "" + TrimAll( FileName) + ", лист " + NumberSheet, "" ) ;
EndDo;
frmProgressBar. Close( ) ;
ExcelApplication = "" ;
EndProcedure