1с закрыть файл excel программно

   LeoKeyn

8 — 07.12.17 — 15:10

Приведу полностью может так лучше будет, так как у меня что то не выходит понять

Функция открытия

&НаКлиенте

Функция ОткрытиеEXCEL()

    
    Попытка

        
        Excel = Новый COMОбъект(«Excel.Application»);

        БД = Excel.WorkBooks.Open(ИзначальнаяТаблица);

        Возврат БД;  

        
    Исключение

        
        Сообщить(«Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!»);

        Сообщить(ОписаниеОшибки());

        
    КонецПопытки;

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

Обработка

&НаКлиенте

Процедура ОбработкаИзEXCEL()

    
    БДНачальная = ОткрытиеEXCEL();

    БДКонечная = СозданиеDBF();

    КоличествоЛистов = БДНачальная.Sheets.Count;

    
    Для НомерЛиста = 1 ПО КоличествоЛистов Цикл

        Лист = БДНачальная.WorkSheets(НомерЛиста);

        ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;

        
        Для Строка = 1 ПО ВсегоСтрок Цикл

            Если ПроверкаСодержанияСтроки(Лист.Cells(Строка, 1).Value) = Истина Тогда

                
                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,Символы.ПС ,» «);

                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,Символы.ВК ,» «);

                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,»№» ,» № «);

                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,»г.» ,» г.»);

                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,»г .» ,» г.»);

                Лист.Cells(Строка, 3).Value = СтрЗаменить(Лист.Cells(Строка, 3).Value,»  «,» «);

                Лист.Cells(Строка, 3).Value = СокрЛП(Лист.Cells(Строка, 3).Value);

                ЗапомнитьКоммент = Лист.Cells(Строка, 3).Value;

                //БДКонечная.Добавить();

                //БДКонечная.COMMENT = «VID_DOC 0 — не известно, 1 — судебное решение; 2 — погашение; 3 — отмена судебного решения; 4 — формирование иска.»;

                //БДКонечная.Записать();

                
                
                
                БДКонечная.Добавить();

                БДКонечная.COMMENT = ЗапомнитьКоммент;

                БДКонечная.Z_DOC = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»Z_DOC»);

                Если СтрЧислоВхождений(Лист.Cells(Строка, 5).Value, «ОСР») > 0 Тогда

                    БДКонечная.VID_DOC = 3;

                ИначеЕсли СтрЧислоВхождений(Лист.Cells(Строка, 6).Value, «-«) > 0 Тогда

                    БДКонечная.VID_DOC = 1;

                ИначеЕсли СтрЧислоВхождений(Лист.Cells(Строка, 5).Value, «-«) > 0 Тогда

                    БДКонечная.VID_DOC = 2;

                Иначе

                    БДКонечная.VID_DOC = 0;

                КонецЕсли;

                
                БДКонечная.OPER_NUMB = Лист.Cells(Строка, 1).Value;

                ДатаНомер = Лист.Cells(Строка, 2).Value;

                БДКонечная.DATE = ОбработатьСтроку(Лист.Cells(Строка, 2).Value,»SUD_DATE»);

                БДКонечная.DOCUMENT = СокрЛП(СтрЗаменить(ДатаНомер, Лев(Строка(БДКонечная.DATE), 10), «»));

                БДКонечная.MISTK = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»MISTK»);

                
                Если СтрЗаменить(БДКонечная.MISTK,» «,»») = «» Тогда

                    БДКонечная.SUD_DOC = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»SUD_DOC»);

                    
                КонецЕсли;

                БДКонечная.LT = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»LT»);

                Если НЕ СтрЗаменить(БДКонечная.SUD_DOC,» «,»») = «» Тогда

                    
                    БДКонечная.SUD_DATE = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»SUD_DATE»,БДКонечная.VID_DOC);

                КонецЕсли;

                
                
                
                
                БДКонечная.PAI_NUMB = ОбработатьСтроку(БДНачальная.Sheets(НомерЛиста).Name,»PAI_NUMB»);

                
                
                Если СтрЧислоВхождений(Лист.Cells(Строка, 5).Value, «-«) > 0 Тогда

                    БДКонечная.DEBIT = Лист.Cells(Строка, 4).Value;

                ИначеЕсли СтрЧислоВхождений(Лист.Cells(Строка, 5).Value, «-«) = 0 И СтрЗаменить(Лист.Cells(Строка, 5).Value,» «,»») <> 0 Тогда

                    БДКонечная.DEBIT = «76/СРШ»;

                КонецЕсли;

                
                Если СтрЧислоВхождений(Лист.Cells(Строка, 6).Value, «-«) > 0 Тогда

                    БДКонечная.CREDIT = Лист.Cells(Строка, 4).Value;

                ИначеЕсли СтрЧислоВхождений(Лист.Cells(Строка, 6).Value, «-«) = 0 И СтрЗаменить(Лист.Cells(Строка, 6).Value,» «,»») <> 0 Тогда

                    БДКонечная.CREDIT = «76/СРШ»;

                КонецЕсли;

                
                Если СтрЧислоВхождений(БДКонечная.CREDIT, «76/СРШ») > 0 Тогда

                БДКонечная.SUM = Лист.Cells(Строка, 6).Value;

                ИначеЕсли СтрЧислоВхождений(БДКонечная.DEBIT, «76/СРШ») > 0 Тогда

                БДКонечная.SUM = Лист.Cells(Строка, 5).Value;

                КонецЕсли;

                БДКонечная.VALUE = Лист.Cells(Строка, 7).Value;

                Если СтрЗаменить(БДКонечная.MISTK,» «,»») = «» Тогда

                    БДКонечная.MISTK = ОбработатьСтроку(Лист.Cells(Строка, 3).Value,»MISTKOST»);

                КонецЕсли;

                Лист.Cells(Строка, 3).Value = ЗапомнитьКоммент;

                БДКонечная.Записать();

                
                
                ОбработкаПрерыванияПользователя();

                
                
                
            КонецЕсли;

            Состояние(«Обрабатывается » + Строка(НомерЛиста) + » лист из » + Строка(КоличествоЛистов), Строка/ВсегоСтрок*100);

            
        КонецЦикла;

        
        
    КонецЦикла;

    БДНачальная.Quit();

    БДКонечная.ЗакрытьФайл();    

    
    
    
    
    
    
    
    
КонецПроцедуры // ОткрытьИзEXCEL()

Программисту 1С часто приходится работать с таблицами Excel из 1С. Я постарался собрать небольшой FAQ и набор функций для работы с файлами Excel. Надеюсь, кому-то будет полезна данная статья.

Работать с файлами Excel можно тремя способами:

  1. Через OLE  объект;
  2. Через Табличный Документ 1С.
  3. Через ADODB

Разберем первый способ.

1. Подключаемся к  OLE и октрываем файл  Excel:

//Поключимся к Excel через OLE, откроем файл и вернем список страниц
//ИмяФайла = Полный путь к файлу Excel
Соотв = Новый Соответствие;
Попытка
Листы = Новый Массив;
Excel = Новый COMОбъект("Excel.Application");
Соотв.Вставить("Соединение",Excel);
ExcelФайл = Excel.WorkBooks.Open (ИмяФайла);
Соотв.Вставить("ExcelФайл",ExcelФайл);
Для Сч = 1 По ExcelФайл.Sheets.Count Цикл
Листы.Добавить(ExcelФайл.Sheets(Сч));
КонецЦикла;
Соотв.Вставить("Листы",Листы);
лРезультат = Соотв;
Исключение
Сообщить("Ошибка создания обьекта Microsoft Excel" + ОписаниеОшибки());
лРезультат = Неопределено;
КонецПопытки;

Возврат лРезультат;

Отсоединяемся от Excel и закрываем файл:

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

Процедура  ОтключатьсяОтExcel(Соответстие)
Попытка
Соответстие["Соединение"].DisplayAlerts = 0;
Соответстие["ExcelФайл"].Close();
Соответстие["Соединение"].DisplayAlerts = 1;
Соответстие["Соединение"].Quit();
Соответстие["Соединение"] = Неопределено;
Исключение
Сообщить("Не удалось отключиться от Excel - "+ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры

Клиент-Серверный вариант в управляемых формах.

При работе в клиент-серверном варианте основная трудность заключается в том, что обычно файл мы загружаем на стороне клиента, а данные, как правило, обрабатываем на стороне сервера. Причем, таблицу значений нельзя передать от клиента на сервер (точнее, передать таблицу значений можно, но только в толстом клиенте. На тонком — 1С выдаст вам сообщение об ошибке). Есть два пути решения данной задачи:

1. Считываем данные из файла в массив из структур и затем этот массив передаем на сервер для дальнейших манипуляций с данными.

&НаКлиенте
Процедура Загрузить1(Команда)
Если Объект.ИмяФайла = "" Тогда
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не указан файл для загрузки";
Сообщение.Поле = "Объект.ИмяФайла";
Сообщение.Сообщить();
Возврат;
КонецЕсли;

Соединение = ПоключитьсяКExcel(Объект.ИмяФайла);
Если Соединение = Неопределено Тогда
Возврат;
КонецЕсли;

Лист = Соединение["Листы"][0];
//Создаем Массив для строк
МассивДанных = Новый Массив;

ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;

Для Сч = 1 по ВсегоСтрок Цикл

//Создаем структуру для текущей строки
Строка = Новый Структура;
Для Сч2 = 1 по ВсегоКолонок Цикл
Строка.Вставить("Колонка"+Строка(Сч2),Лист.Cells(Сч,Сч2).Value);
КонецЦикла;

МассивДанных.Добавить(Строка);
КонецЦикла;

Загрузить1НаСервере(МассивДанных);
КонецПроцедуры

&НаСервере
Процедура Загрузить1НаСервере(МассивДанных)
//Создадим колонки
Если МассивДанных.Количество() = 0 Тогда
Возврат;
КонецЕсли;

Таб = РеквизитФормыВЗначение("Результат");

МассивРеквизитов = Новый Массив;

Для Каждого Кл Из МассивДанных[0] Цикл
Мас = Новый Массив;
Мас.Добавить(ТипЗнч(Кл.Значение));

Таб.Колонки.Добавить(Кл.Ключ,Новый ОписаниеТипов(Мас),Кл.Значение);
КонецЦикла;

Первая = Истина;
Для Каждого Ст ИЗ МассивДанных Цикл
Если Первая Тогда
Первая = Ложь;
Продолжить;
КонецЕсли;
ТБ = Таб.Добавить();
Для Каждого Кл из СТ Цикл
ТБ[Кл.Ключ] = Кл.Значение;
КонецЦикла;

КонецЦикла;

ОтобразитьТабНаФорме(Таб);

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

2-ой способ — это передать файл Excel на сервер через хранилище данных и далее работать с ним уже на сервере.

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

Соединение = ПоключитьсяКExcelСервер(Объект.ИмяФайла);
Если Соединение = Неопределено Тогда
Возврат;
КонецЕсли;
/// Обработка Excel
ОтключатьсяОтExcelСервер(Соединение);
КонецПроцедуры

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

Очень часто приходится работать с очень большими  файлами Excel, и его обработка путем перебора строк занимает огромное количество времени. 

В таких случаех удобно в одно действие загрузить всю таблицу в массив и в потом работать уже непосредственно с  массивом.

Лист = Соединение["Листы"][0];

ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;

Область = Лист.Range(ЛистЭксель.Cells(1,1), ЛистЭксель.Cells(ВсегоСтрок,ВсегоКолонок));
Данные = Область.Value.Выгрузить();

На выходе получаем двумерный массив, который содержит все данные указанного листа Excel

Полезные функции при работе с Excel:

 Устанавливает видимость Excel при работе
//0 - Excel не виден, 1 - виден.
Соединение.Visible = Видимость;
 Добавление новой книги в файл Excel
Книга = Соединение.WorkBooks.Add();
 Сохранение книги Excel
Книга.SaveAs(ИмяФайла);
 Добавление нового листа к книге
Лист = Книга.WorkSheets.Add();
 Переименование листа
Лист.Name = ИмяЛиста;
 Изменение маштаба листа
//"Масштаб" (от 10 до 400).
Лист.PageSetup.Zoom = Масштаб;
 Изменение ориентации листа
//1 - книжная, 2 - альбомная.
Лист.PageSetup.Orientation = Ориентация;
 Отступы листа
//Левый отступ
Лист.PageSetup.LeftMargin = Соединение.CentimetersToPoints(Сантиметры);
//Верхний отступ
Лист.PageSetup.TopMargin = Соединение.CentimetersToPoints(Сантиметры);
//Правый отступ
Лист.PageSetup.RightMargin = Соединение.CentimetersToPoints(Сантиметры);
//Нижний отступ
Лист.PageSetup.BottomMargin = Соединение.CentimetersToPoints(Сантиметры);
Обращение к ячейки
чтение/запись 
//Прочитать значение ячейки
//Сч = Номер строки
//Сч2 = Номер колонки
Данные = Лист.Cells(Сч,Сч2).Value

//Записать значение в ячейку
Лист.Cells(Сч,Сч2).Value =  Данные
Обращение к области ячеек
//В качестве параметров передаем ячейки по диогонали
Лист.Range(ЛистЭксель.Cells(1,1),ЛистЭксель.Cells(ВсегоСтрок,ВсегоКолонок))
Очень часто при чтении или записи значений в Excel ставятся лишние пробелы в числе, например, вместо 1502 он читает как 1 502 и в дальнейшем это значение не приводится к числу. Эту проблему можно решить заменой.
ЗначениеЯчейки = Лист.Cells(1,3).Value;
СтрЗаменить(Строка(ЗначениеЯчейки),Символы.НПП,"");
Объединение ячеек
Лист.Range(Лист.Cells(1,1),Лист.Cells(10,1)).Merge(); 
 
Работа с именованными ячейками в Excel
Обл = Лист.Range("Имя_Ячейки_В_Excel").Select();
Обл.Value = "Присваиваем значение";
 
Удаление ячейки 
Лист.Cells(1,3).Delete();
Удаление области ячеек
Лист.Range(Лист.Cells(1,1),Лист.Cells(10,1)).Delete();
 Обращение к строке
//Сч = Номер строки
Лист.Rows(Сч)
 Изменение ширины колонки
Лист.Columns(НомерКолонки).ColumnWidth = Ширина;
 Обращение к колонке
//Сч = Номер Колонки
Лист.Cols(Сч)
 Удаление Строки
Лист.Rows(Сч).Delete()
 Фон ячейки / области / Строки /  
//Фон Ячейки
Лист.Cells(1,1).Interior.Color = ПолучитьЦветExcelRGB(10,10,10);

//Фон Области
Лист.Range(Лист.Cells(1,1),Лист.Cells(10,1)).Interior.Color = ПолучитьЦветExcelRGB(10,10,10);

//Фон строки
Лист.Rows(Сч).Interior.Color = ПолучитьЦветExcelRGB(10,10,10);
 
 Функция переводит цвет из формата RGB в формат Excel
Функция ПолучитьЦветExcelRGB(R,G,B)
Возврат ((B*256) + G) * 256 + R;
КонецФункции
 Управление шрифтом в ячейки/строке/области
//Изменение шрифта
Лист.Cells(НомерСтроки,НомерКолонки).Font.Name = ИмяШрифта;

//Изменение размера шрифтв
Лист.Cells(НомерСтроки,НомерКолонки).Font.Size = РазмерШрифта;

//Управление жирностью шрифта
//1-жирный шрифт (bold)
//0-нормальный шрифт (normal)
Лист.Cells(НомерСтроки,НомерКолонки).Font.Bold = Жирный;

//Управление курсивом шрифта
//1-Курсив
//0-Нормальный
Лист.Cells(НомерСтроки,НомерКолонки).Font.Italic = Курсив;

//2 - Подчеркнутый шрифт
//1- нет
Лист.Cells(НомерСтроки,НомерКолонки).Font.Underline = Подчеркнутый;
 Разрешает переносить по словам в ячейке
//1-Переносить
Лист.Cells(1, 1).WrapText = 1;
 Управление рамкой ячейки
//1 - Тонкая сплошная линия
Лист.Cells(НомерСтроки,НомерКолонки).Borders.Linestyle = ТипЛинии;
 Устанавливаем формат ячейки
//"@" - текстовый
//"0.00" - числовой
Лист.Cells(НомерСтроки, НомерКолонки).NumberFormat = Формат;
 Формула в ячейки 
Лист.Cells(Сч,Сч2).FormulaLocal = "=ОКРУГЛ(135,46456;0)";
 Формула в ячейки 
Лист.Cells(Сч,Сч2).FormulaLocal = "=ОКРУГЛ(135,46456;0)";
 Формула в ячейки 
Лист.Cells(Сч,Сч2).FormulaLocal = "=ОКРУГЛ(135,46456;0)";
 Формула в ячейки 
Лист.Cells(Сч,Сч2).FormulaLocal = "=ОКРУГЛ(135,46456;0)";
 Функция для получения ширины колонки Excel 
Спасибо пользователю goodwill
&НаКлиенте
Функция ПолучитьШиринуКолнкиЭксель(ПараметрШиринаВПикселях)

Если ПараметрШиринаВПикселях > 9 Тогда
ШиринаВСимволах = (ПараметрШиринаВПикселях/0.75-5)/7;
Иначе
ШиринаВСимволах = ПараметрШиринаВПикселях/9;
КонецЕсли;

Возврат ШиринаВСимволах;

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

Лист.Columns("A").ColumnWidth = ПолучитьШиринуКолнкиЭксель(РазмерШиринаВПикселях);
 Разрешить перенос слов в ячейке  
Спасибо пользователю roofless
Лист.Cells(1, 1).WrapText = 1;
 Группировки данных на листе  
Спасибо пользователю dr-wit, ignor
1. Развернуть все группы (строки и колонки):
Excel.ActiveSheet.Outline.ShowLevels(3, 3);
2. Сернуть все группы (строки и колонки) до первого уровня:
Excel.ActiveSheet.Outline.ShowLevels(1, 1);
3. Вернуть глубину дерева
Лист.Rows(Инд).OutlineLevel

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

Функция ПреобразоватьНомерСтолбцаВФорматExcel(Столбец)
стСтолбец = "";
А = Окр(Столбец/27,0);
В = Столбец - (А*26);
Если А>0 Тогда
стСтолбец = Символ(А+64);
КонецЕсли;
Если В>0 Тогда
стСтолбец = стСтолбец + Символ(В+64);
КонецЕсли;

Возврат стСтолбец;
КонецФункции

2. Работа с Excel через ТабличныйДокумент 1С

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

Итак, приступим: загрузка из Excel:

1. Загружаем файл Excel в табличный документ

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

 2. Производим манипуляции уже с ТабличнымДокументом

//Создадим ТЗ куда будем собирать инфу
Таб = Новый ТаблицаЗначений;
Таб.Колонки.Добавить("Номенклатура",Новый ОписаниеТипов("Строка"));
Таб.Колонки.Добавить("Количество",Новый ОписаниеТипов("Число"));
Таб.Колонки.Добавить("Цена",Новый ОписаниеТипов("Число"));

//Определяем количество строк
КолСтр = ТабДок.ВысотаТаблицы;
Для Сч = 2 по КолСтр Цикл
Попытка
ТБ = Таб.Добавить();
//Обращаемся к ячейки и забираем данные
ТБ.Номенклатура = Строка(ТабДок.ПолучитьОбласть("R" + Формат(Сч, "ЧГ=0") + "C" + 1).ТекущаяОбласть.Текст);
ТБ.Количество = Число(ТабДок.ПолучитьОбласть("R" + Формат(Сч, "ЧГ=0") + "C" + 2).ТекущаяОбласть.Текст);
ТБ.Цена = Число(ТабДок.ПолучитьОбласть("R" + Формат(Сч, "ЧГ=0") + "C" + 3).ТекущаяОбласть.Текст);
Исключение
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "Не удалось загрузить строку "+Строка(Сч);
Сообщение.Сообщить();
КонецПопытки;
КонецЦикла;

Давайте теперь разберем сохранение в Excel с помощью данного метода:

Тут все очень просто сначала мы формируем обычный Табличный документ и затем записываем его в Excel

//ТабДок - Табличный документ
ТабДок.Записать(Объект.ИмяФайла,ТипФайлаТабличногоДокумента.XLSX);

2. Работа с Excel ADODB

Выражаю особую благодарность коллеги Fragster за хороший комментарий

Данный метод позволяет работать с Excel через ODBC и имеет ряд преимуществ:

  1. Не требует установки самой Excel, необходима лишь установить ODBC.  Но как правило  он уже установлен. Это особенность позволяет работать на стороне сервера без дополнительных установок Excel.
  2. Позволяет работать с таблицой Excel как с БД и строить к ней запросы на T-SQL. Таким образом мы можем делать отборы еще на этапе чтения данных и другие преимущества что дает  Т-SQL. Что на мой взгляд огромный плюс.

Подключение к ADO

Функция СоединитьсяСADO(ИмяФайла)
//Поз = СтрНайти(ИмяФайла,"",НаправлениеПоиска.СКонца);
Поз = 0;
Найден = 1;
ТмпСтр = ИмяФайла;
Пока Найден <> 0 Цикл
Найден = Найти(ТмпСтр,"");
ТмпСтр = Прав(ТмпСтр,СтрДлина(ТмпСтр) - Найден);
Если Найден <> 0 Тогда
Поз = Найден;
КонецЕсли;
КонецЦикла;
Путь = Лев(ИмяФайла,Поз-1);

Данные = Новый Структура;
СтрокаСоединения = "
| Provider=Microsoft.ACE.OLEDB.12.0;Data Source="+СокрЛП(ИмяФайла)+";
| Extended Properties=""Excel 12.0 Xml;HDR=YES""";
Соединение = Новый COMОбъект("ADODB.Connection");
Попытка
Соединение.Open(СтрокаСоединения);
Исключение
Сообщить ("Не возможно подключится к Microsoft Excel Driver!!!
|Возможно файл ["+ИмяФайла+"] открыт другим пользователем.");
Возврат Неопределено;
КонецПопытки;
Данные.Вставить("Соединение",Соединение);

Возврат Данные;
КонецФункции

Строка подключения зависит от версии ODBC. И вызывает наибольшие трудности при подключение поэтомя я рекомендую ее сгенерировать на сайте http://www.connectionstrings.com

Отключение от ADO

Процедура ОтключитьсяОтADO(Подключение)
Попытка
Подключение["Соединение"].Close();
Подключение = Неопределено;
Исключение
КонецПопытки;
КонецПроцедуры

Выполнение запроса

Функция ВыполнитьЗапросADO(ТекстЗапроса,Подключение)
Попытка
Записи = Новый COMОбъект("ADODB.Recordset");
Исключение
Сообщить ("Не удалось Создать к Microsoft Excel Driver!!!");
Возврат Неопределено;
КонецПопытки;
Попытка
Записи.Open(ТекстЗапроса, Подключение["Соединение"]);
Возврат Записи;
Исключение
Сообщить ("Проблемы с выполнением запроса");
КонецПопытки;
КонецФункции

Пример запроса:

//Сразу отбираем только не пустые номенклатуры
ТекстЗапроса = "SELECT * FROM [Лист1$] WHERE `Номенклатура`<>""""";

Запись в  Excel тоже производится в виде запроса:

ТекстЗапроса = "
|INSERT INTO [Лист1$] (`Номенклатура`,`Количество`,`Цена`,`Сумма`) VALUES ('"
+ТБ.Номенклатура+"','"+ТБ.Количество+"','"+ТБ.Цена+"','"+ТБ.Сумма+"')";

Хочу отметить что наименование полей производится по первой строке в таблице

ADODB предоставляет ряд объектов, с которыми мы работаем

ADODB.Connection
предназначен для соединения с ADO
Соединение = Новый COMОбъект("ADODB.Connection");
  ADOX.Table
для работы с таблицей
// Создаем таблицу и добавляем в неё два столбца
Table = Новый COMОбъект("ADOX.Table");
Table.Name = "Table";
Table.Columns.Append("Code");
Table.Columns.Append("Description");
ADODB.Command Для выполнения комманд на языке T-SQL
Комманды = Новый COMОбъект("ADODB.Command");
Комманды.ActiveConnection = Подключение["Соединение"];
Комманды.CommandType = 1;
Комманды.CommandText = ТекстЗапроса;
Комманды.Execute();

 ADODB.Recordset

Похож на ADODB.Command предназначен для выполнения запросов и обработки результата 

Записи = Новый COMОбъект("ADODB.Recordset");
Записи.Open(ТекстЗапроса, Подключение["Соединение"]);

В файле продемонстрированны оба варианта работы с запросами.

На этом пока все. По возможности буду дополнять статью 🙂

В архиве находится обработка, которая демонстрирует все описанные и другие возможности при работе с Excel.

И тренировочный файл Excel.

1С 8.3 и Excel совместимы с самых первых версий платформы: любую печатную форму можно сохранить в электронную таблицу (*.xls,*.xlsx) через Меню (Еще..) -> Сохранить. Некоторые документы в типовых конфигурациях имеют встроенную функцию выгрузки в электронную таблицу. Загрузить информацию в 1С из Excel штатными средствами до последнего времени было невозможно. Только в крайних релизах 1С 8.3 была реализована возможность загрузки информации в документы закупок и продаж из excel-файла (*.xls,*.xlsx) через буфер обмена (кнопка над табличной частью «Загрузить из внешнего файла»).  Однако, типовые механизмы подходят только для узкого круга задач. Для решения более широкого спектра задач по экспорту/импорту данных в/из Excel средствами 1С 8.3 создаются команды, в которых используется палитра встроенного языка.

  • Для работы 1С 8.3 с Excel используется COM объект типа «Excel.Application» (через OLE, нужен установленный MS Excel) или «ADODB.Connection» (ActiveX Data Object, нужен установленный драйвера ODBC) или «COMSafeArray» (через OLE, нужен установленный драйвер ADODB).
  • При загрузке из Excel в управляемом приложении можно выполнять как &НаКлиенте так и на &НаСервере. Используется временный каталог стандартного пользователя USR1CV82.
  • На дисках ИТС и на портале 1С, в меню «Технологическая поддержка» -> «Универсальные отчеты и обработки» -> есть типовая обработка «Загрузка данных из табличного документа».
  • У табличного документа есть метод «Прочитать». Отличная альтернатива COM объекту — актуально для файлов больших объемов.

Выбор Excel файла в 1С 8.3:

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

    Если

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

    Если

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

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

Загрузка из Excel файла (через COMОбъект) в 1С 8.3:

&НаСервере
Процедура ЗагрузитьИзXLS()// в документ Поступление материалов

    // Попытка открытия файла Excel

Попытка
       
Excel_App = Новый COMОбъект(«Excel.Application»);
       
Excel_App.WorkBooks.Open(Объект.Файл);
    Исключение
       
Сообщить(«Произошла ошибка при открытии файла «+СокрЛП(ОписаниеОшибки())+«! Операция прервана!»);
        Возврат;
    КонецПопытки;
// Попытка выбрать первый лист (можно указать другой)
   
Попытка
       
Excel_App.Sheets(1).Select();
    Исключение
       
// Если первый лист не найден — закрываем файл
       
Excel_App.ActiveWorkbook.Close();
       
Excel_App = 0;
       
Сообщить(«Первый лист не найден!»);
       
ОтменитьТранзакцию();
        Возврат;
    КонецПопытки;
// Вычисление количества строк и колонок в зависимости от версии Excel
   
version_Ex = Лев(Excel_App.Version, Найти(Excel_App.Version,«.»)-1);
    Если
version_Ex = «8» тогда
       
Колич_Строк = Excel_App.Cells.CurrentRegion.Rows.Count;
       
Колич_Колонок = Макс(Excel_App.Cells.CurrentRegion.Columns.Count, 13);
    Иначе
       
Колич_Строк = Excel_App.Cells(1,1).SpecialCells(11).Row;
       
Колич_Колонок = Excel_App.Cells(1,1).SpecialCells(11).Column;
    Конецесли;
// Имена колонок в файле должны совпадать с именами реквизитов табличной части, в которую загружаются данные
    // Переменная ТЗ_Колонки содержит список номеров колонок, которые будут перегружаться
   
ТЗ_Колонки = Новый ТаблицаЗначений;
   
ТЗ_Колонки.Колонки.Добавить(«НомерКолонки»);
   
ТЗ_Колонки.Колонки.Добавить(«НазваниеКолонки»);

    Для

Каждая_Колонка = 1 по Колич_Колонок ЦиклИмяКолонки = Excel_App.Cells(1, Каждая_Колонка).Text;
       
ИмяБезПробелов = СтрЗаменить(ИмяКолонки,» «,«»); // Удаление лишних пробелов из имен колонок

        // Проверка наличия реквизитов табличной части «Материалы» в документе «ПоступлениеМатериалов»

Если НЕ ПроверкаРеквизитаТЧ(ИмяБезПробелов, Метаданные.Документы.ПоступлениеМатериалов, «Материалы») Тогда
           
Сообщить(«Не найден реквизит с именем » + ИмяБезПробелов + «! Колонка не будет загружена!»);
        Иначе
           
Новая_Строка = ТЗ_Колонки.Добавить();
           
Новая_Строка.НомерКолонки = Каждая_Колонка;
           
Новая_Строка.НазваниеКолонки = ИмяБезПробелов;
        КонецЕсли;

    КонецЦикла;

// Если есть колонки для загрузки и есть колонка «Материалы» (обязательная к заполнению)
   
Если ТЗ_Колонки.Количество() <> 0 и
       
ТЗ_Колонки.НайтиСтроки(Новый Структура(«НазваниеКолонки», «Материалы»)).Количество() <> 0 Тогда// Создание документа и заполнение реквизитов шапки
       
Тек_Документ = Документы.ПоступлениеМатериалов.СоздатьДокумент();
       
Тек_Документ.Комментарий = «Загружено из файла » + Объект.Файл;
       
Тек_Документ.Дата = ТекущаяДата();
       
Тек_Документ.Ответственный = ПараметрыСеанса.ТекущийПользователь;

        Для

Тек_Строка = 1 по Колич_Строк Цикл // Заполнение табличной части «Материалы»Строка_Док = Тек_Документ.Материалы.Добавить();
           
Строка_Док.Валюта = Тек_Документ.ТипЦен.ВалютаЦены;

            Для каждого

Тек_ТЗ из ТЗ_Колонки ЦиклТек_Значение = Excel_App.Cells(Тек_Строка, Тек_ТЗ.НомерКолонки).Text;// Получение имени колонки
               
ИмяКолонкиДокумента = Excel_App.Cells(1, Тек_ТЗ.НомерКолонки).Text;// Заполнение строки данными
               
Если ИмяКолонкиДокумента = «Материалы» Тогда
                   
Строка_Док.Номенклатура = Справочники.Материалы.НайтиПоНаименованию(Тек_Значение, Истина);
                ИначеЕсли
ИмяКолонкиДокумента = «Цена» Тогда
                   
Строка_Док.Цена = Тек_Значение;
                ИначеЕсли
ИмяКолонкиДокумента = «Ставка_НДС» Тогда
                   
Строка_Док.Ставка_НДС = Тек_Значение;
                КонецЕсли;

            КонецЦикла;

        КонецЦикла;

Тек_Документ.Записать(РежимЗаписиДокумента.Проведение); // Запись и проведение документа
       
Сообщить(«Записан документ » + СокрЛП(Тек_Документ));
    Иначе
       
Сообщить(«В файле «+СокрЛП(Объект.Файл)+» не достаточно данных для заполнения документа!»);
    КонецЕсли;
Excel_App.DisplayAlerts = 0;
   
Excel_App.Quit();
   
Excel_App.DisplayAlerts = 1;

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

&НаСервере
Функция ПроверкаРеквизитаТЧ(ИмяРекв, МетаданныеДок, ИмяТЧ)// Проверка наличия ТЧ
   
ТаблЧасть = МетаданныеДок.ТабличныеЧасти.Найти(ИмяТЧ);
    Если
ТаблЧасть = Неопределено Тогда // Нет такой таб. части в документе
       
Возврат Ложь; //реквизит не найден
   
Иначе
        Возврат НЕ (
ТаблЧасть.Реквизиты.Найти(ИмяРекв) = Неопределено);//реквизит найден
   
КонецЕсли;

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

Выгрузка в Excel файл (через COMОбъект) в 1С 8.3:

&НаСервере
Процедура ВыгрузитьВXLS(Выб_Таблица)

    Если

Выб_Таблица.Количество() = 0 Тогда
       
Сообщить(«Пустая таблица! Операция прервана!»);
        Возврат;
    КонецЕсли;

    Попытка

Excel_App = Новый COMОбъект(«Excel.Application»);  // Подключение к Excel
   
Исключение
       
Сообщить(«Произошла ошибка при открытии файла «+СокрЛП(ОписаниеОшибки())+«! Операция прервана!»);
        Возврат;
    КонецПопытки;

    Попытка

Book_Excel = Excel_App.WorkBooks.Add();Sheet_Excel = Book_Excel.WorkSheets(1);
       
Sheet_Excel.Name = «Test Sheet»; // Присваиваем имя первому листуExcel_App.ActiveWindow.View             = 2;    // Режим страничного просмотра
       
Excel_App.ActiveWindow.Zoom             = 100// Масштаб
       
Sheet_Excel.PageSetup.Orientation       = 2;    // Альбомная ориентация
       
Sheet_Excel.Columns(1).ColumnWidth      = 20;   // Ширина первой колонки
       
Sheet_Excel.Columns(2).ColumnWidth      = 40;   // Ширина второй колонки
       
Sheet_Excel.Columns(10).ColumnWidth     = 15;
       
Sheet_Excel.Columns(11).ColumnWidth     = 15;Sheet_Excel.Cells(1, 1).Value           = «№ ПП»; //Создаем шапку 1
       
Sheet_Excel.Cells(1, 2).Value           = «Текст»;
       
Sheet_Excel.Cells(1, 3).Value           = «Числа»;
       
Sheet_Excel.Cells(1, 10).Value          = «Дата»;
       
Sheet_Excel.Cells(1, 11).Value          = «Формула»;Sheet_Excel.Cells(2, 3).Value           = «Число 1»;//Создаем шапку 2
       
Sheet_Excel.Cells(2, 4).Value           = «Число 2»;
       
Sheet_Excel.Cells(2, 5).Value           = «Число 3»;
       
Sheet_Excel.Cells(2, 6).Value           = «Число 4»;
       
Sheet_Excel.Cells(2, 7).Value           = «Число 5»;
       
Sheet_Excel.Cells(2, 8).Value           = «Число 6»;
       
Sheet_Excel.Cells(2, 9).Value           = «Число 7»;Sheet_Excel.Range(«A1:A2»).MergeCells = Истина;  Sheet_Excel.Range(«A1:A2»).WrapText = Истина;
       
Sheet_Excel.Range(«B1:B2»).MergeCells = Истина;  Sheet_Excel.Range(«B1:B2»).WrapText = Истина;
       
Sheet_Excel.Range(«J1:J2»).MergeCells = Истина;  Sheet_Excel.Range(«J1:J2»).WrapText = Истина;
       
Sheet_Excel.Range(«K1:K2»).MergeCells = Истина;  Sheet_Excel.Range(«K1:K2»).WrapText = Истина;
       
Sheet_Excel.Range(«C1:I1»).MergeCells = Истина;  Sheet_Excel.Range(«C1:I1»).WrapText = Истина;Sheet_Excel.Range(«A1:K2»).Borders.Linestyle    = 1//Линия границы
       
Sheet_Excel.Range(«A1:K2»).HorizontalAlignment  = 3//Выравнивание по горизонтали
       
Sheet_Excel.Range(«A1:K2»).VerticalAlignment    = 2//Выравнивание по вертикали
       
Sheet_Excel.Range(«A1:K2»).Font.Bold            = 1//Установим жирный шрифт в шапке

        // Выгружаем данные в таблицу

Количество_Строк = 3; //Заполнение ТЧ начинаем с третьей строки
       
Для Каждого ТекСтрока Из Выб_Таблица Цикл
           
Sheet_Excel.Cells(Количество_Строк, 1).Value            = ТекСтрока.НомерПоПорядку;
           
Sheet_Excel.Cells(Количество_Строк, 2).Value            = ТекСтрока.Табл_Текст;
           
Sheet_Excel.Cells(Количество_Строк, 3).Value            = ТекСтрока.Табл_Число1;
           
Sheet_Excel.Cells(Количество_Строк, 4).Value            = ТекСтрока.Табл_Число2;
           
Sheet_Excel.Cells(Количество_Строк, 5).Value            = ТекСтрока.Табл_Число3;
           
Sheet_Excel.Cells(Количество_Строк, 6).Value            = ТекСтрока.Табл_Число4;
           
Sheet_Excel.Cells(Количество_Строк, 7).Value            = ТекСтрока.Табл_Число5;
           
Sheet_Excel.Cells(Количество_Строк, 8).Value            = ТекСтрока.Табл_Число6;
           
Sheet_Excel.Cells(Количество_Строк, 9).Value            = ТекСтрока.Табл_Число7;
           
Sheet_Excel.Cells(Количество_Строк, 10).Value           = ТекСтрока.Табл_Дата;
           
Sheet_Excel.Cells(Количество_Строк, 11).Formula         = «=F» + Строка(Количество_Строк)
            +
«+G» + Строка(Количество_Строк);Количество_Строк = Количество_Строк + 1;
        КонецЦикла;
Количество_Строк = Количество_Строк 1; //Последняя строка для форматированияSheet_Excel.Range(«A3:K» + Строка(Количество_Строк)).Borders.Linestyle  = 1//Линия границы
       
Sheet_Excel.Range(«A3:K» + Строка(Количество_Строк)).VerticalAlignment  = 2//Выравнивание по вертикалиДля НомерСтроки = 3 По Количество_Строк Цикл                              // Установка числового формата
           
Для Столбец = 4 По 9 Цикл
               
Sheet_Excel.Cells(НомерСтроки, Столбец).NumberFormat    = «0.00»;
            КонецЦикла;
           
Sheet_Excel.Cells(НомерСтроки, 11).NumberFormat     = «0.00»;
        КонецЦикла;

    Исключение

Excel_App.Quit();
       
Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;

    Попытка

Book_Excel.SaveAs(Объект.Файл);
       
Сообщить(«Файл » + Объект.Файл + » успешно сохранен»);
    Исключение
       
Сообщить(ОписаниеОшибки() + » Файл не сохранен!»);
        Возврат;
    КонецПопытки;

    Попытка

Excel_App.Quit();
    Исключение
       
Сообщить(ОписаниеОшибки());
        Возврат;
    КонецПопытки;

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

Справочно: Основные свойства и методы для работы с Excel через OLE в 1С 8.3:

        Действия с приложением:

  • Установка видимости окна приложения …… Excel_App.Visible = Ложь;
  • Установка режима вывода предупреждений (выводить/не выводить) …… Excel_App.DisplayAlerts = Ложь;
  • Закрытие приложения …… Excel_App.Quit();

         Действия с книгой:

  • Создание новой книги …… Book_Excel = Excel_App.WorkBooks.Add();
  • Открытие существующей книги …… Book_Excel = Excel_App.WorkBooks.Open(ИмяФайла);
  • Сохранение книги …… Book_Excel.SaveAs(ИмяФайла);
  • Закрытие книги …… Book_Excel .Close(0);

        Действия с листом:

  • Установка текущего листа …… Sheet_Excel = Book_Excel.WorkSheets(НомерSheet_Excelа);
  • Установка имени …… Sheet_Excel.Name = Имя;
  • Установка защиты …… Sheet_Excel.Protect();
  • Снятие защиты …… Sheet_Excel.UnProtect();
  • Установка ориентации страницы …… Sheet_Excel.PageSetup.Orientation = 2; 1 — книжная, 2 — альбомная
  • Установка левой границы …… Sheet_Excel.PageSetup.LeftMargin = Excel_App.CentimetersToPoints(Сантиметры);
  • Установка верхней границы …… Sheet_Excel.PageSetup.TopMargin = Excel_App.CentimetersToPoints(Сантиметры);
  • Установка правой границы …… Sheet_Excel.PageSetup.RightMargin = Excel_App.CentimetersToPoints(Сантиметры);
  • Установка нижней границы …… Sheet_Excel.PageSetup.BottomMargin = Excel_App.CentimetersToPoints(Сантиметры);

         Действия со строками, колонками, ячейками:

  • Установка ширины колонки …… Sheet_Excel.Columns(НомерКолонки).ColumnWidth = Ширина;
  • Удаление строки …… Sheet_Excel.Rows(НомерСтроки).Delete();
  • Удаление колонки …… Sheet_Excel.Columns(НомерКолонки).Delete();
  • Удаление ячейки …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Delete();
  • Установка значения …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Value = Значение;
  • Объединение ячеек …… Sheet_Excel.Range(Sheet_Excel.Cells(НомерСтроки, НомерКолонки),

                                           Sheet_Excel.Cells(НомерСтроки1, НомерКолонки1)).Merge();

  • Установка шрифта …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Font.Name = ИмяШрифта;
  • Установка размера шрифта …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Font.Size = РазмерШрифта;
  • Установка жирного шрифта …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Font.Bold = 1; 1 — жирный шрифт, 0 — нормальный
  • Установка курсива …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Font.Italic = 1; 1 — курсив, 0 — нормальный
  • Установка подчеркнутого шрифта …… Sheet_Excel.Cells(НомерСтроки, НомерКолонки).Font.Underline = 2; 2 — подчеркнутый, 1 — нет

Загрузка из Excel файла (через ADODB.Connection) в 1С 8.3:

&НаСервере
Процедура ЗагрузитьИзXLS_ADODB()// Создание COM-объекта для соединения
   
ADODB_conn = Новый COMОбъект(«ADODB.Connection»);// Установка строки соединения
   
ADODB_conn.ConnectionString = «Provider=Microsoft.ACE.OLEDB.12.0;
    |Data Source=»
+ИмяФайла+«;
    |Extended Properties=»»Excel 12.0 XML;HDR=YES»»;»
;
   
ADODB_conn.Open(); // Открытие соединения

    // Создание COM-объекта для получения выборки

ADODB_rec = Новый COMОбъект(«ADODB.Recordset»);
   
ТекстЗапроса = «SELECT * FROM [ЛистN1$]»;// Выборка (запрос)
   
ADODB_rec.Open(ТекстЗапроса, ADODB_conn);// Обход результата выборки
   
Пока НЕ ADODB_rec.EOF() Цикл
       
ЗначениеКолонки1 = ADODB_rec.Fields.Item(«КолонкаN1»).Value; // Обращение по имени колонки
       
ЗначениеКолонки2 = ADODB_rec.Fields.Item(0).Value; // Обращение по индексу колонки
       
ADODB_rec.MoveNext();
    КонецЦикла;
ADODB_rec.Close();
   
ADODB_rec = Неопределено;
   
ADODB_conn.Close();
   
ADODB_conn = Неопределено;

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

Выгрузка в Excel файла (через ADODB.Connection) в 1С 8.3:

&НаСервере
Процедура ВыгрузитьВXLS_ADODB()// Создание COM-объекта для соединения
   
ADODB_conn = Новый COMОбъект(«ADODB.Connection»);// Установка строки соединения
   
ADODB_conn.ConnectionString = «Provider=Microsoft.ACE.OLEDB.12.0;
    |Data Source=»
+ИмяФайла+«;
    |Extended Properties=»»Excel 12.0 XML;HDR=YES»»;»
;
   
ADODB_conn.Open(); // Открытие соединения

    // Создание COM-объекта для команды

ADODB_com = Новый COMОбъект(«ADODB.Command»);
   
ADODB_com.ActiveConnection = ADODB_conn;// Присвоение текста команды для создания таблицы
   
ADODB_com.CommandText = «CREATE TABLE [ЛистN1] (КолонкаN1 char(255), КолонкаN2 date, КолонкаN3 int, КолонкаN4 float)»;
   
ADODB_com.Execute(); // Выполнение команды

    // Присвоение текста команды для добавления строки таблицы

ADODB_com.CommandText = «INSERT INTO [ЛистN1] (КолонкаN1, КолонкаN2, КолонкаN3, КолонкаN4) values (‘абвгдеё’, ‘8/11/2017’, ‘12345’, ‘12345,6789’)»;
   
ADODB_com.Execute(); // Выполнение команды

    // Удаление команды и закрытие соединения

ADODB_com = Неопределено;
   
ADODB_conn.Close();
   
ADODB_conn = Неопределено;

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

Создание нового листа Excel со структурой (через ADODB.Connection) в 1С 8.3:

&НаСервере
Процедура СозданиеНовогоЛистаВXLS_ADODB()// Создание COM-объекта для работы с книгой
   
Book_Excel = Новый COMОбъект(«ADOX.Catalog»);
   
Book_Excel.ActiveConnection = Соединение;// Создание COM-объекта для работы со структурой данных на листе
   
Excel_App = Новый COMОбъект(«ADOX.Table»);
   
Excel_App.Name = «ЛистN1»;
   
Excel_App.Columns.Append(«КолонкаN1», 202);
   
Excel_App.Columns.Append(«КолонкаN2», 7);
   
Excel_App.Columns.Append(«КолонкаN3», 5);
   
//  Тип колонки (необязательный параметр):
    //  5 — adDouble;
    //  6 — adCurrency;
    //  7 — adDate;
    //  11 — adBoolean;
    //  202 — adVarWChar;
    //  203 — adLongVarWChar.

    // Создание в книге листа с описанной структурой

Book_Excel.Tables.Append(Excel_App);
   
Excel_App = Неопределено;
   
Book_Excel = Неопределено;

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

Справочно: Объекты ADO для работы с Excel в 1С 8.3:

  • Connection
  • Command
  • Errors
  • Fields
  • Parameters
  • Properties
  • Recordset
  • Record
  • Stream

В строке соединения параметр HDR определяет как будет восприниматься первая строка на листе.

NO — первая строка воспринимается как данные. К значениям можно обращаться только по индексу колонки.

YES — первая строка воспринимается как названия колонок. К значениям можно обращаться по имени и по индексу колонки.

Выгрузка в Excel файл (через COMSafeArray) в 1С 8.3:

&НаСервере
Процедура ВыгрузитьВXLS_COMSafeArray(Выб_Таблица)

    Если

Выб_Таблица.Количество() = 0 Тогда
       
Сообщить(«Пустая таблица! Операция прервана!»);
        Возврат;
    КонецЕсли;

    Если НЕ

ЗначениеЗаполнено(Объект.Файл) Тогда
       
Сообщить(«Выберите файл! Операция прервана!»);
        Возврат;
    КонецЕсли;

    Попытка

Excel_App = Новый COMОбъект(«Excel.Application»);
       
Excel_App.Interactive = Ложь;
       
Excel_App.DisplayAlerts = Ложь;
    Исключение
       
Сообщить(«Не удалось подключиться к Excel, возможно программа на компьютере не установлена! Операция прервана!»);
        Возврат;
    КонецПопытки;
КолонкиТаблицы = Выб_Таблица.Колонки;СтартМассив = Новый Массив;
    Для каждого
Колонка Из КолонкиТаблицы Цикл
       
СтартМассив.Добавить(Выб_Таблица.ВыгрузитьКолонку(Колонка.Имя));
    КонецЦикла;
РазмерМассив = Новый Массив;
   
РазмерМассив.Добавить(КолонкиТаблицы.Количество());
   
РазмерМассив.Добавить(Выб_Таблица.Количество());МассивArray = Новый COMSafeArray(СтартМассив, «VT_VARIANT», РазмерМассив);НачальнаяСтрока = 2;Book_Excel = Excel_App.Workbooks.Add();
   
Sheet_Excel = Book_Excel.Sheets(1);
   
Кол_Строк = Выб_Таблица.Количество()+1;
   
Кол_Колонок = КолонкиТаблицы.Количество();
   
Sheet_Excel.Range(Sheet_Excel.Cells(2,1), Sheet_Excel.Cells(Кол_Строк, Кол_Колонок)).Value = МассивArray;
   
a=0;
    Для каждого
Колонка Из КолонкиТаблицы Цикл
       
a=a+1;
       
Sheet_Excel.Cells(1,a).Value = Колонка.Имя;
       
Sheet_Excel.Columns(a).EntireColumn.AutoFit();
    КонецЦикла;

    Попытка

Book_Excel.SaveAs(Объект.Файл);
    Исключение
       
Book_Excel.Close();
       
Book_Excel = Неопределено;
       
Сообщить(«Ошибка при записи файла! Операция прервана!»);
        Возврат;
    КонецПопытки;
Excel_App.Interactive = Истина;
   
Excel_App.DisplayAlerts = Истина;
   
Excel_App.Application.Quit();
   
Excel_App = Неопределено;

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

Загрузка из Excel файла (напрямую через табличный документ) в 1С 8.3:

&НаСервере
Процедура ЗагрузитьИзXLSНапрямую()// Начиная с версии 1С 8.3.8 (только &НаСервере)ТабличныйДокумент.Прочитать(Объект.Файл, СпособЧтенияЗначенийТабличногоДокумента.Значение); //Способ чтения: Значение, ТекстКонецПроцедуры

Выгрузка в Excel файл (напрямую через табличный документ) в 1С 8.3:

&НаСервере
Процедура ВыгрузитьВXLSНапрямую()// Начиная с версии 1С 8.3.8 (можно и &НаКлиенте и на &НаСервере)ТабличныйДокумент.Записать(Объект.Файл, ТипФайлаТабличногоДокумента.XLSX); //Тип файла: XLS95, XLS97, XLSXКонецПроцедуры

💡 Готовые модели кода (шаблоны) с «Excel» 1С:

Copyright©, «Программист 1С в г.Минске», 13.09.2020

Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник

Вообще COM-объекты используют для соединения информационной базы 1С с файлом Word, Excel, Outlook или любой другой программой, поддерживающей данный интерфейс обмена данными. В этой статье рассмотрим задачу выгрузки/загрузки данных из/в MS Excel. Чтобы это осуществить воспользуемся COM-соединением и объектом Excel.Application. Для примера возьмём задачу выгрузки/загрузки данных о номенклатуре. Пример рассмотрим ниже.

COM-соединение

Что же такое COM-соединение? Component Object Model (или COM) – это технология (фирмы Microsoft) взаимодействующих компонентов, которые одновременно могут быть использованы в разных приложениях. При этом весь функционал соответствующего компонента наследуется внутрь разрабатываемого приложения. В нашем случае COM-объект Excel.Application используется внутри кода 1С для операций с файлом книги MS Excel.

Объект Excel.Application

У объекта Excel.Application существует ряд методов, которые нам могут пригодиться для реализации нижепоставленной задачи:

  • ОбъектExcel.WorkBooks.Open(ИмяФайла) – Открытие книги MS Excel
  • ОбъектExcel.ActiveWorkbook.Close() – Закрытие текущей книги
  • ОбъектExcel.Quit() – Закрытие COM-объекта
  • ОбъектExcel.Sheets(ИмяЛиста) – Получает лист книги
  • ЛистExcel.Cells(НачалоСтрока, НачалоСтолбец) – Ячейка таблицы на данном листе
  • ЛистExcel.Range(Ячейка1, Ячейка2) – Выделенная область
  • ЯчейкаExcel.Value – Значение ячейки таблицы
  • ЯчейкаExcel.Text – Текст ячейки таблицы

Постановка задачи

Итак, предположим, что в обработке 1С у нас имеется табличная часть, состоящая из следующих колонок:

  • Номенклатура
  • Количество
  • Цена
  • Сумма.

Необходимо реализовать 2 функционала (сделать на форме 2 основные кнопки):

  1. Выгрузка табличной части в подготовленный файл MS Excel
  2. Загрузка табличной части из файла.


Алгоритм выгрузки/загрузки в MS Excel

Алгоритм выгрузки следующий:

  1. Выгружаем табличную часть в таблицу значений
  2. Создаём новый COM-объект Excel.Application
  3. Выбираем файл, открываем файл книги MS Excel
  4. Переходим на заданный лист книги
  5. Выгружаем данные в файл
  6. Закрываем книгу, выходим из COM-объекта.

Алгоритм загрузки следующий:

  1. Создаём новый COM-объект Excel.Application
  2. Выбираем файл, открываем файл книги MS Excel
  3. Переходим на заданный лист книги
  4. Загружаем данные из файла в таблицу значений
  5. Закрываем книгу, выходим из COM-объекта
  6. Таблицу значений выгружаем в табличную часть.

Операция выгрузки и загрузки данных о номенклатуре происходит в заранее подготовленный шаблон MS Excel.


Пример кода 1С

Код 1С я постарался разделить на отдельные функции, чтобы, скопировав, с ними можно было работать где угодно. На форме обработки 1С были созданы 3 кнопки:

  • Выгрузить
  • Загрузить
  • Очистить.


В итоге в реализации алгоритма получились следующие основные процедуры и функции 1С:

  • ПолучитьExcel – Получает COM-объект MS Excel;
  • ЗакрытьExcel – Закрывает использование COM-объекта MS Excel;
  • ПолучитьЛистExcel – Получает лист книги Excel;
  • ДобавитьТабличныйДокументВExcel – Добавляет табличный документ на лист Excel (нужно для выгрузки данных);
  • ПрочитатьОбластьИзExcel – Читает область ячеек с листа Excel (нужно для загрузки данных);
  • ШиринаЛистаExcel – Ширина листа Excel;
  • ВысотаЛистаExcel – Высота листа Excel;
  • ПреобразоватьТДвТЗ – Преобразует табличный документ в таблицу значений;
  • ПреобразоватьТЗвТД – Преобразует таблицу значений в табличный документ;

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#Если Клиент Тогда
// Функция выбора файла.
//
// Параметры:
// 	РежимВыбора - <РежимДиалогаВыбораФайла> - Выбор каталога, открытие или сохранение файла;
//	Расширение - <Строка>, <Массив> - Список расширений файла.
//
// Возвращаемое значение:
//	<Строка> - Путь к выбранному файлу.
//
Функция ВыбратьФайлДокумента(РежимВыбора, Расширение = "*") Экспорт
 
	ИмяФайла = "";
	//ФорматМассив = РазобратьСтрокуВМассивПоРазделителю(Расширение);
	ФорматМассив = ПреобразоватьВМассив(Расширение);
 
	ДиалогФайла = Новый ДиалогВыбораФайла(РежимВыбора);
	Если РежимВыбора = РежимДиалогаВыбораФайла.Открытие Тогда
		ДиалогФайла.Заголовок = "Открыть документ";
	ИначеЕсли РежимВыбора = РежимДиалогаВыбораФайла.Сохранение Тогда
		ДиалогФайла.Заголовок = "Сохранить документ";
	ИначеЕсли РежимВыбора = РежимДиалогаВыбораФайла.ВыборКаталога Тогда
		ДиалогФайла.Заголовок = "Выбрать каталог";
	КонецЕсли;
 
	Фильтр = "";
	Для Каждого ЭлементМассив Из ФорматМассив Цикл
		Если ЭлементМассив = "*" Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""Все файлы""; en = ""All files""");
		ИначеЕсли ВРег(ЭлементМассив) = ВРег("TXT") Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""Текстовый документ""; en = ""Text document""");
		ИначеЕсли ВРег(ЭлементМассив) = ВРег("MXL") Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""Табличный документ""; en = ""Table document""");
		ИначеЕсли ВРег(ЭлементМассив) = ВРег("XLS") ИЛИ ВРег(ЭлементМассив) = ВРег("XLSX") ИЛИ ВРег(ЭлементМассив) = ВРег("XLSM") Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""Табличный документ MS Excel""; en = ""Table document MS Excel""");
		ИначеЕсли ВРег(ЭлементМассив) = ВРег("XML") Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""Документ XML""; en = ""Document XML""");
		ИначеЕсли ВРег(ЭлементМассив) = ВРег("HTML") ИЛИ ВРег(ЭлементМассив) = ВРег("HTM") Тогда
			Фильтр = Фильтр + "|" + НСтр("ru = ""HTML документ""; en = ""HTML document""");
		Иначе
			Фильтр = Фильтр + "|" + НСтр("ru = ""Файл " + ВРег(ЭлементМассив) + """; en = ""File " + ВРег(ЭлементМассив) + """");
		КонецЕсли;
		Фильтр = Фильтр + " (*." + НРег(ЭлементМассив) + ")|*." + НРег(ЭлементМассив);
	КонецЦикла;
	Фильтр = Сред(Фильтр, 2);
 
	ДиалогФайла.Фильтр = Фильтр;
	ДиалогФайла.МножественныйВыбор = Ложь;
 
	Если ДиалогФайла.Выбрать() Тогда
		ИмяФайла = ?(РежимВыбора = РежимДиалогаВыбораФайла.ВыборКаталога, ДиалогФайла.Каталог, ДиалогФайла.ПолноеИмяФайла);
	Иначе
		Текст = "ru = ""Файл не выбран!""; en = ""File(s) not selected!""";
		Предупреждение(НСтр(Текст));
	КонецЕсли;
 
	Возврат ИмяФайла;
КонецФункции	
#КонецЕсли

Также в реализации алгоритма были задействованы следующие вспомогательные функции:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Преобразует в массив переменную любого типа данных.
//
// Параметры:
//	Объект - Произвольный - произвольный объект данных;
//	Проверка - <Булево> - Осуществление проверки на заполненное значение.
//
// Возвращаемое значение:
//	<Массив> - Массив с теми же данными.
//
Функция ПреобразоватьВМассив(Объект, Проверка = Ложь) Экспорт
 
	ОбъектМассив = Новый Массив;
 
	Если НЕ Проверка ИЛИ ЗначениеЗаполнено(Объект) Тогда
		Если ТипЗнч(Объект) = Тип("Массив") Тогда
			ОбъектМассив = Объект;
		ИначеЕсли ТипЗнч(Объект) = Тип("СписокЗначений") Тогда
			ОбъектМассив = Объект.ВыгрузитьЗначения();
		ИначеЕсли ТипЗнч(Объект) = Тип("Строка") Тогда
			ОбъектМассив = РазобратьСтрокуВМассивПоРазделителю(Объект);
		ИначеЕсли ТипЗнч(Объект) = Тип("Структура") Тогда
			Для Каждого Элемент Из Объект Цикл
				ОбъектМассив.Добавить(Элемент.Значение);
			КонецЦикла;
		Иначе
			ОбъектМассив.Добавить(Объект);
		КонецЕсли;
	КонецЕсли;
 
	Возврат ОбъектМассив;
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// Разбирает строку в массив подстрок по разделителю. 
// При этом пробелы между подстроками не учитываются.
//
// Параметры:
//	Стр - исходная строка;
//	СтрРазделитель - разделитель, по умолчанию ",";
//	ИгнорироватьПустые - игнорировать ли пустые места между разделителями.
//
// Возвращаемое значение:
//	Массив строк
//
Функция РазобратьСтрокуВМассивПоРазделителю(Знач Стр, СтрРазделитель = ",", ИгнорироватьПустые = Ложь) Экспорт
 
	Результат = Новый Массив;
 
	ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	Пока ВхождениеРазделителя <> 0 Цикл
		ЧастьДоРазделителя = СокрЛП(Лев(Стр, ВхождениеРазделителя - 1));
		Если НЕ (ИгнорироватьПустые И ПустаяСтрока(ЧастьДоРазделителя)) Тогда
			Результат.Добавить(ЧастьДоРазделителя);
		КонецЕсли;
		Стр = СокрЛП(Сред(Стр, ВхождениеРазделителя + 1));
		ВхождениеРазделителя = Найти(Стр, СтрРазделитель);
	КонецЦикла;
 
	Если НЕ (ИгнорироватьПустые И ПустаяСтрока(Стр)) Тогда
		Результат.Добавить(СокрЛП(Стр));
	КонецЕсли;
 
	Возврат Результат;	
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Создаёт новую таблицу значений с заданными колонками.
//
// Параметры:
//	пКолонки - <Строка>, <Структура>, <Массив>, <СписокЗначений>, <ТаблицаЗначений> - 
//	 Набор колонок для таблицы значений.
//	
// Возвращаемое значение:
//	<ТаблицаЗначений> - Созданная таблица.
//
Функция ПолучитьТаблицуВывода(пКолонки) Экспорт
 
	ТЗ = Новый ТаблицаЗначений;
 
	Если пКолонки <> Неопределено Тогда 
 
		Если ТипЗнч(пКолонки) = Тип("Строка") Тогда
			пКолонки = РазобратьСтрокуВМассивПоРазделителю(пКолонки);
		КонецЕсли;
 
		Если ТипЗнч(пКолонки) = Тип("Структура") Тогда
			Для Каждого Поле Из пКолонки Цикл	
				СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Ключ, Поле.Значение);	
			КонецЦикла;
		ИначеЕсли ТипЗнч(пКолонки) = Тип("СписокЗначений") Тогда
			Для Каждого Поле Из пКолонки Цикл	
				Если Поле.Пометка Тогда
					СтрокаТабл = ТЗ.Колонки.Добавить(Поле.Значение, пКолонки.ТипЗначения, Поле.Представление);
				КонецЕсли;
			КонецЦикла;
		ИначеЕсли ТипЗнч(пКолонки) = Тип("ТаблицаЗначений") Тогда
			ЕстьНаименование = (пКолонки.Колонки.Найти("Наименование") <> Неопределено);
			ЕстьТипЗначения = (пКолонки.Колонки.Найти("ТипЗначения") <> Неопределено);
			ЕстьЗаголовок = (пКолонки.Колонки.Найти("Заголовок") <> Неопределено);
			ЕстьШирина = (пКолонки.Колонки.Найти("Ширина") <> Неопределено);
			Для Каждого Поле Из пКолонки Цикл
				СтрокаТабл = ТЗ.Колонки.Добавить(?(ЕстьНаименование, Поле.Наименование, ""), ?(ЕстьТипЗначения, Поле.ТипЗначения, Новый ОписаниеТипов), ?(ЕстьЗаголовок, Поле.Заголовок, ""), ?(ЕстьШирина, Поле.Ширина, 0));	
			КонецЦикла;
		Иначе
			Для Каждого Поле Из пКолонки Цикл	
				СтрокаТабл = ТЗ.Колонки.Добавить(Поле);	
			КонецЦикла;
		КонецЕсли;
 
	КонецЕсли;
 
	Возврат ТЗ;	
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Создаёт структуру колонок из таблицы значений.
//
// Параметры:
//	ТабЗначений - <ТаблицаЗначений> - Любая таблица.
//	
// Возвращаемое значение:
//	<Структура> - Созданная таблица.
//
Функция ПолучитьСтруктуруКолонокИзТаблицы(ТабЗначений) Экспорт
 
	СтруктураКолонок = Новый Структура;
	Для Каждого ЭлементКолонка Из ТабЗначений.Колонки Цикл
		СтруктураКолонок.Вставить(ЭлементКолонка.Имя, ЭлементКолонка.ТипЗначения);
	КонецЦикла;
 
	Возврат СтруктураКолонок;
КонецФункции;

Основные функции обработки алгоритма следующие:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// Получает объект файла MS Excel.
//
// Параметры:
//	ИмяФайла - <Строка> - Путь к файлу XLS.
//	
// Возвращаемое значение:
//	<COMОбъект> - Полученный объект. Если объект не найден, то возвращается "Неопределено".
//
Функция ПолучитьExcel(ИмяФайла) Экспорт
 
	ФайлНаДиске = Новый Файл(ИмяФайла);
 
	Excel = Неопределено;
	Если нРег(ФайлНаДиске.Расширение) = ".xls" 
	 ИЛИ нРег(ФайлНаДиске.Расширение) = ".xlsx"
	 ИЛИ нРег(ФайлНаДиске.Расширение) = ".xlsm"
	Тогда
 
		Если НЕ ФайлНаДиске.Существует() Тогда
			Сообщить("Файл не существует!", СтатусСообщения.Внимание);
			Возврат Неопределено;
		КонецЕсли;
 
		Попытка
			Excel = Новый COMОбъект("Excel.Application");
			Excel.WorkBooks.Open(ИмяФайла);
		Исключение
			Сообщить("Не удалось инициализировать Excel!", СтатусСообщения.Внимание);
			Возврат Неопределено;
		КонецПопытки;
 
	КонецЕсли;	
 
	Возврат Excel;
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Закрывает файл MS Excel.
//
// Параметры:
//	Excel - <COMОбъект> - Объект файла MS Excel;
//	Сохранить - <Булево> - Указывает сохранять файл при закрытии или нет. По умолчанию
//	 пользователю предлагается выбрать это самому.
//
Процедура ЗакрытьExcel(Excel, Сохранить = Неопределено) Экспорт
 
	Попытка
		#Если Клиент Тогда
		Состояние("Закрытие файла Microsoft Excel...");
		#КонецЕсли
		Если Сохранить = Неопределено Тогда
			Excel.ActiveWorkbook.Close();
		Иначе
			Excel.ActiveWorkbook.Close(Сохранить);
		КонецЕсли;
		Excel.Quit();
	Исключение
		Сообщить("Ошибка закрытия Excel!", СтатусСообщения.Внимание);
	КонецПопытки;
 
	Excel = Неопределено;	
КонецПроцедуры;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Получает лист из файла книги MS Excel.
//
// Параметры:
//	Excel - <COMОбъект> - Объект файла MS Excel;
//	ИмяЛиста - <Строка> - Имя листа книги MS Excel.
//	
// Возвращаемое значение:
//	<COMОбъект> - Полученный лист. Если объект не найден, то возвращается "Неопределено".
//
Функция ПолучитьЛистExcel(Excel, ИмяЛиста) Экспорт
 
	Попытка
		ExcelЛист = Excel.Sheets(ИмяЛиста);
	Исключение
		Сообщить("Не удалось прочитать лист Excel!", СтатусСообщения.Внимание);
		Возврат Неопределено;
	КонецПопытки;
 
	Возврат ExcelЛист;	
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Записывает данные из табличного документа в файл MS Excel.
//
// Параметры:
//	ЛистExcel - <COMОбъект> - Лист из файла MS Excel;
//	Таблица - <ТабличныйДокумент> - Документ, по порядку следования колонок и строк 
//	 соответствующий листу файла MS Excel;
//	Шапка - <Число> - Количество первых строк для шапки в файле MS Excel;
//	СписокСтолбцов - <Строка>, <Массив> - Список номеров столбцов, которые будут выгружены 
//	 в файл MS Excel;
//	СписокСтрокЗапрета - <Строка>, <Массив> - Список номеров строк, которые не должны
//	 выгружаться в файл MS Excel. Если этот параметр не задан, то выгружаются все строки;
//	ПроверятьЗначения - <Булево> - Определяет будут ли проверяться ячейки табличного 
//	 документа на содержание в них значения, а не текстовое представление этого значения. 
//	 По умолчанию этот параметр "Ложь".
//
Процедура ДобавитьТабличныйДокументВExcel(ЛистExcel, Таблица, Шапка, СписокСтолбцов, СписокСтрокЗапрета = Неопределено, ПроверятьЗначения = Ложь) Экспорт
 
	Если ТипЗнч(СписокСтолбцов) = Тип("Строка") Тогда
		СписокСтолбцов = РазобратьСтрокуВМассивПоРазделителю(СписокСтолбцов);
	КонецЕсли;
	Если ТипЗнч(СписокСтрокЗапрета) = Тип("Строка") Тогда
		СписокСтрокЗапрета = РазобратьСтрокуВМассивПоРазделителю(СписокСтрокЗапрета);
	КонецЕсли;
 
	ЕстьМассив = (СписокСтрокЗапрета = Неопределено);
	Если ЕстьМассив Тогда
		Попытка
			МассивCOM = Новый COMSafeArray("VT_VARIANT", 1, Таблица.ВысотаТаблицы - Шапка);
		Исключение
			ЕстьМассив = Ложь;
		КонецПопытки;
	КонецЕсли;
 
	Для Каждого НомерСтолбца Из СписокСтолбцов Цикл
 
		Для НомерСтроки = Шапка+1 По Таблица.ВысотаТаблицы Цикл 
 
			Если СписокСтрокЗапрета = Неопределено 
				ИЛИ (СписокСтрокЗапрета.Найти(Строка(НомерСтроки)) = Неопределено И СписокСтрокЗапрета.Найти(Число(НомерСтроки)) = Неопределено) 
			Тогда
				Область = Таблица.Область(НомерСтроки, Число(НомерСтолбца));
				Значение = ?(ПроверятьЗначения И Область.СодержитЗначение, Область.Значение, Область.Текст);
				Если ЕстьМассив Тогда
					МассивCOM.SetValue(0, НомерСтроки-Шапка-1, Значение);
				Иначе
					ЛистExcel.Cells(НомерСтроки, Число(НомерСтолбца)).Value = Значение;
				КонецЕсли;
			КонецЕсли;
 
		КонецЦикла;
 
		Если ЕстьМассив Тогда 
			ЛистExcel.Range(ЛистExcel.Cells(Шапка+1, Число(НомерСтолбца)), ЛистExcel.Cells(Таблица.ВысотаТаблицы, Число(НомерСтолбца))).Value = МассивCOM;
		КонецЕсли;
 
	КонецЦикла;
 
КонецПроцедуры;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// Читает область ячеек из MS Excel в табличный документ.
//
// Параметры:
//	ЛистExcel - <COMОбъект> - Лист из файла MS Excel;
//	ТабДок - <ТабличныйДокумент> - Исходный табличный документ, поле табличного 
//	 документа или таблица значений. Если этот параметр не задан, то создаётся
//	 новый табличный документ;
//	НачалоСтрока - <Число> - Начальная строка в файле MS Excel;
//	НачалоСтолбец - <Число> - Начальный столбец в файле MS Excel;
//	КонецСтрока - <Число> - Конечная строка в файле MS Excel;
//	КонецСтолбец - <Число> - Конечный столбец в файле MS Excel.
//	
// Возвращаемое значение:
//	<ТабличныйДокумент> - Возвращает прочитанный из области в MS Excel табличный 
//	 документ, который передавался в эту функцию параметром "ТабДок".
//
Функция ПрочитатьОбластьИзExcel(ЛистExcel, ТабДок = Неопределено, НачалоСтрока, НачалоСтолбец, КонецСтрока, КонецСтолбец) Экспорт
 
	Если ТабДок = Неопределено Тогда
		ТабДок = Новый ТабличныйДокумент;
	КонецЕсли;
 
	Попытка
		МассивCOM = Новый COMSafeArray("VT_VARIANT", КонецСтолбец - НачалоСтолбец + 1, КонецСтрока - НачалоСтрока + 1);
		ЕстьМассив = Истина;
	Исключение
		ЕстьМассив = Ложь;
	КонецПопытки;
 
	Если ЕстьМассив Тогда
		МассивCOM = ЛистExcel.Range(ЛистExcel.Cells(НачалоСтрока, НачалоСтолбец), ЛистExcel.Cells(КонецСтрока, КонецСтолбец)).Value;
 
		Для ИндексКолонка = НачалоСтолбец По КонецСтолбец Цикл
			Для ИндексСтрока = НачалоСтрока По КонецСтрока Цикл
				Значение = МассивCOM.GetValue(ИндексКолонка - НачалоСтолбец + 1, ИндексСтрока - НачалоСтрока + 1);
				ТабДок.Область(ИндексСтрока, ИндексКолонка).СодержитЗначение = Истина;
				ТабДок.Область(ИндексСтрока, ИндексКолонка).Значение = Значение;
			КонецЦикла;
		КонецЦикла;	
	Иначе
		Для ИндексКолонка = НачалоСтолбец По КонецСтолбец Цикл
			Для ИндексСтрока = НачалоСтрока По КонецСтрока Цикл
				Значение = ЛистExcel.Cells(ИндексСтрока, ИндексКолонка).Value;
				ТабДок.Область(ИндексСтрока, ИндексКолонка).СодержитЗначение = Истина;
				ТабДок.Область(ИндексСтрока, ИндексКолонка).Значение = Значение;
			КонецЦикла;
		КонецЦикла;
	КонецЕсли;
 
	Возврат ТабДок;
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Определяет ширину листа MS Excel.
//
// Параметры:
//	ЛистExcel - <COMОбъект> - Лист из файла MS Excel.
//	
// Возвращаемое значение:
//	<Число> - Количество столбцов в таблице.
//
Функция ШиринаЛистаExcel(ЛистExcel) Экспорт
 
	ЕстьЗащита = ЛистExcel.ProtectContents;
	Возврат ?(ЕстьЗащита, ЛистExcel.UsedRange.Columns.Count, ЛистExcel.Cells.SpecialCells(11).Column);
 
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
// Определяет высоту листа MS Excel.
//
// Параметры:
//	ЛистExcel - <COMОбъект> - Лист из файла MS Excel.
//	
// Возвращаемое значение:
//	<Число> - Количество строк в таблице.
//
Функция ВысотаЛистаExcel(ЛистExcel) Экспорт
 
	ЕстьЗащита = ЛистExcel.ProtectContents;
	Возврат ?(ЕстьЗащита, ЛистExcel.UsedRange.Rows.Count, ЛистExcel.Cells.SpecialCells(11).Row);
 
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// Преобразовать табличный документ в таблицу значений.
//
// Параметры:
//	ТабДок - <ТабличныйДокумент> - Исходный табличный документ;
//	СтруктураКолонок - <Структура>, <ТаблицаЗначений> - Структура колонок;
//	НачалоСтрока - <Число> - Строка начала области;
//	НачалоСтолбец - <Число> - Столбец начала области;
//	КонецСтрока - <Число> - Строка конца области;
//	КонецСтолбец - <Число> - Столбец конца области.
//	
// Возвращаемое значение:
//	<ТаблицаЗначений> - Полученная таблица значений.
//
Функция ПреобразоватьТДвТЗ(ТабДок, СтруктураКолонок, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, Знач КонецСтрока = Неопределено, Знач КонецСтолбец = Неопределено) Экспорт
 
	// Определение габаритов таблицы
	Если НачалоСтрока = Неопределено И НачалоСтолбец = Неопределено Тогда
		НачалоСтрока = 1;
		НачалоСтолбец = 1;
	КонецЕсли;
 
	Если НачалоСтрока = Неопределено Тогда
		НачалоСтрока = 1;
		Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение 
		 И НачалоСтрока < ТабДок.ВысотаТаблицы 
		Цикл
			НачалоСтрока = НачалоСтрока + 1;
		КонецЦикла;
	ИначеЕсли НачалоСтолбец = Неопределено Тогда
		НачалоСтолбец = 1;
		Пока НЕ ТабДок.Область(НачалоСтрока, НачалоСтолбец).СодержитЗначение 
		 И НачалоСтолбец < ТабДок.ШиринаТаблицы
		Цикл
			НачалоСтолбец = НачалоСтолбец + 1;
		КонецЦикла;
	КонецЕсли;
 
	КонецСтрока = ?(КонецСтрока = Неопределено, ТабДок.ВысотаТаблицы, КонецСтрока);
	КонецСтолбец = ?(КонецСтолбец = Неопределено, ТабДок.ШиринаТаблицы, КонецСтолбец);
 
	// Преобразование
	ЭтоТаблица = (ТипЗнч(СтруктураКолонок) = Тип("ТаблицаЗначений"));
	ТабЗначений = ПолучитьТаблицуВывода(СтруктураКолонок);
 
	Для ИндексСтроки = НачалоСтрока По КонецСтрока Цикл
		СтрокаТЗ = ТабЗначений.Добавить();
 
		ИндексКолонки = НачалоСтолбец;
		Для Каждого Колонка Из СтруктураКолонок Цикл
			НаименованиеКолонки = ?(ЭтоТаблица, Колонка.Наименование, Колонка.Ключ);
			пИндексКолонки = ?(ЭтоТаблица, Колонка.СтолбецОтчёт, ИндексКолонки);
 
			Если ТабДок.Область(ИндексСтроки, пИндексКолонки).СодержитЗначение Тогда
				СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Значение;
			Иначе
				СтрокаТЗ[НаименованиеКолонки] = ТабДок.Область(ИндексСтроки, пИндексКолонки).Текст;
			КонецЕсли;
 
			ИндексКолонки = ИндексКолонки + 1;
		КонецЦикла;
	КонецЦикла;
 
	Возврат ТабЗначений;
КонецФункции;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// Преобразовать таблицу значений в табличный документ.
//
// Параметры:
//	ТабЗначений - <ТаблицаЗначений> - Исходная таблица значений;
//	ТабДок - <ТабличныйДокумент> - Полученный табличный документ. Если параметр не задан, 
//	 то документ создаётся заново и возвращается функцией;
//	НачалоСтрока - <Число> - Строка начала области;
//	НачалоСтолбец - <Число> - Столбец начала области;
//	ВыводитьЗаголовки - <Булево> - Определяет выводить ли имена колонок или нет.
//	
// Возвращаемое значение:
//	<ТабличныйДокумент> - Полученный табличный документ (возвращает параметр "ТабДок").
//
Функция ПреобразоватьТЗвТД(ТабЗначений, ТабДок = Неопределено, Знач НачалоСтрока = Неопределено, Знач НачалоСтолбец = Неопределено, ВыводитьЗаголовки = Ложь) Экспорт
 
	Если ТабДок = Неопределено Тогда
		ТабДок = Новый ТабличныйДокумент;
	КонецЕсли;
 
	// Определение габаритов таблицы
	НачалоСтрока = ?(НачалоСтрока = Неопределено, 1, НачалоСтрока);
	НачалоСтолбец = ?(НачалоСтолбец = Неопределено, 1, НачалоСтолбец);
 
	// Преобразование
	ИндексСтроки = НачалоСтрока;
	Если ВыводитьЗаголовки Тогда
		ИндексКолонки = НачалоСтолбец;
		Для Каждого Колонка Из ТабЗначений.Колонки Цикл
			ТабДок.Область(ИндексСтроки, ИндексКолонки).Текст = ?(ПустаяСтрока(Колонка.Заголовок), Колонка.Имя, Колонка.Заголовок);
			ИндексКолонки = ИндексКолонки + 1;
		КонецЦикла;
		ИндексСтроки = ИндексСтроки + 1;
	КонецЕсли;
 
	Для Каждого Элемент Из ТабЗначений Цикл
		ИндексКолонки = НачалоСтолбец;
		Для Каждого Колонка Из ТабЗначений.Колонки Цикл
			ТабДок.Область(ИндексСтроки, ИндексКолонки).СодержитЗначение = Истина;
			ТабДок.Область(ИндексСтроки, ИндексКолонки).ТипЗначения = Новый ОписаниеТипов(Колонка.ТипЗначения);
			ТабДок.Область(ИндексСтроки, ИндексКолонки).Значение = Элемент[Колонка.Имя];
			ИндексКолонки = ИндексКолонки + 1;
		КонецЦикла;
		ИндексСтроки = ИндексСтроки + 1;
	КонецЦикла;
 
	Возврат ТабДок;
КонецФункции;

В реализации алгоритма был дополнительно использован объект COMSafeArray с типом VT_VARIANT. Этот COM-объект выступает в качестве двумерного массива, в котором удобно хранить значения ячеек. Также использование данного объекта повышает быстродействие операций чтения/записи для ячеек таблицы.

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

Указанные здесь процедуры и функции я постарался сделать универсальными. Они могут быть применены для широкого круга прикладных задач.

Скачать

Файл открыт программно из 1С. Если сделать так Excel.Workbooks.Close, то появляется вопрос о сохранении. В документации по VBA говорится сделать так Workbooks(«BOOK1.XLS»).Close SaveChanges:=False Но как «засунуть» этот параметр «SaveChanges:=False» в конструкцию языка 1С?

Alert или DisplayAlert или как то так …. см хелп ВБА

А куда этот параметр сувать надо? В скобки после Close?

Как открыть файл Excel, на который повешен пароль программно из 1С без запроса ввода пароля?

Просто напиши Quit и ексель выйдет без запроса

jek 1С обходит мимо пароля

True = -1 (как ни странно) Еще надо учесть, что в Бейсике параметры функций именованные (что имхо очень правильно и хорошо), а в 1С — надо просто перечислить их через запятую (что мне лично не нравится, ибо это зло, но в 1С это сделано так).

Тэги:

Комментарии доступны только авторизированным пользователям

Like this post? Please share to your friends:
  • 2 cursors in word
  • 2 columns in one cell excel
  • 2 column chart in word
  • 2 and 3 word scrabble words
  • 2 and 3 letter word dictionary