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 можно тремя способами:
- Через OLE объект;
- Через Табличный Документ 1С.
- Через 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 и имеет ряд преимуществ:
- Не требует установки самой Excel, необходима лишь установить ODBC. Но как правило он уже установлен. Это особенность позволяет работать на стороне сервера без дополнительных установок Excel.
- Позволяет работать с таблицой 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 |
|
ADOX.Table для работы с таблицей |
|
ADODB.Command Для выполнения комманд на языке T-SQL |
|
ADODB.Recordset Похож на ADODB.Command предназначен для выполнения запросов и обработки результата |
|
В файле продемонстрированны оба варианта работы с запросами.
На этом пока все. По возможности буду дополнять статью 🙂
В архиве находится обработка, которая демонстрирует все описанные и другие возможности при работе с 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 основные кнопки):
- Выгрузка табличной части в подготовленный файл MS Excel
- Загрузка табличной части из файла.
Алгоритм выгрузки/загрузки в MS Excel
Алгоритм выгрузки следующий:
- Выгружаем табличную часть в таблицу значений
- Создаём новый COM-объект Excel.Application
- Выбираем файл, открываем файл книги MS Excel
- Переходим на заданный лист книги
- Выгружаем данные в файл
- Закрываем книгу, выходим из COM-объекта.
Алгоритм загрузки следующий:
- Создаём новый COM-объект Excel.Application
- Выбираем файл, открываем файл книги MS Excel
- Переходим на заданный лист книги
- Загружаем данные из файла в таблицу значений
- Закрываем книгу, выходим из COM-объекта
- Таблицу значений выгружаем в табличную часть.
Операция выгрузки и загрузки данных о номенклатуре происходит в заранее подготовленный шаблон 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С это сделано так).
Тэги:
Комментарии доступны только авторизированным пользователям