Вообще 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С, а также шаблон для загрузки/выгрузки можно скачать по ссылке ниже.
Указанные здесь процедуры и функции я постарался сделать универсальными. Они могут быть применены для широкого круга прикладных задач.
Как осуществить чтение/запись данных из/в Excel на языке 1с (используя COM-объект)
Здесь можно скачать шаблонную обработку, разработанную в среде «1С:Предприятие v8″ для работы с файлами Excel: [download id=»5»] В обработке осуществляются все основные действия с файлом Excel. Даны подробные комментарии. Можно использовать в качестве шаблона для разработки собственных выгрузок/загрузок в/из Excel.
Чтение данных из Excel
Доступ из 1С к Excel производится посредством OLE. Создание COM-объекта:
Попытка Эксель =Новый COMОбъект("Excel.Application"); // для v7 код будет: Эксель = СоздатьОбъект("Excel.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки;
Теперь используя переменную Эксель можно управлять приложением Excel.
- Внимание! Microsoft Excel должен быть установлен на компьютере!
Следующая команда откроет книгу:
Книга = Эксель.WorkBooks.Open(ПутьКФайлу);
Перед тем, как начать считывание данных, укажем лист книги, с которого будем считывать данные:
Лист = Книга.WorkSheets(НомерЛиста);
Нумерация листов книги начинается с 1. Общее количество листов можно получить, используя следующую команду:
КоличествоЛистов = Книга.Sheets.Count;
Лист можно выбрать по имени листа в книге:
Лист = Книга.WorkSheets(ИмяЛиста);
Имя листа в книге можно получить по номеру:
ИмяЛиста = Книга.Sheets(НомерЛиста).Name;
Точно так же можно задать имя листа:
Книга.Sheets(6).Name = "6 Резерв на отпуск";
Итак, мы открыли книгу и выбрали лист, теперь посмотрим, сколько строк и колонок на выбранном листе:
ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
Получим значения ячейки листа в строке НомерСтроки и в колонке НомерКолонки:
Значение = Лист.Cells(НомерСтроки, НомерКолонки).Value;
Ниже приведен отрывок кода, запустив который мы прочитаем все данные с первой страницы:
Эксель = СоздатьОбъект("Excel.Application"); Книга = Эксель.WorkBooks.Open(ПутьКФайлу); Лист = Книга.WorkSheets(1); ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; Для Строка = 1 По ВсегоСтрок Цикл Для Колонка = 1 По ВсегоКолонок Цикл Значение = СокрЛП(Лист.Cells(Строка,Колонка).Value); КонецЦикла; КонецЦикла;
Где ПутьКФайлу — полный путь к файлу книги Excel (включая имя).
После выполнения действий необходимо закрыть книгу:
Эксель.Application.Quit();
Выгрузка данных в Excel
Для вывода (выгрузки) данных в Excel необходимо либо открыть существующую книгу, либо создать новую, и выбрать рабочий лист для вывода данных.
Для создания новой книги можно использовать следующий код:
Книга = Excel.WorkBooks.Add();
При создании книги автоматически создаются листы (по умолчанию 3). Нам остается только выбрать нужный:
Лист = Книга.WorkSheets(НомерЛиста);
Или добавить в книгу новый лист:
Лист = Книга.Sheets.Add();
Добавим в ячейку на листе значение:
Лист.Cells(НомерСтроки, НомерКолонки).Value = Значение;
Запишем книгу:
Попытка Книга.SaveAs(ПутьКФайлу); Исключение Сообщить(ОписаниеОшибки()+" Файл не сохранен!"); КонецПопытки;
Где ПутьКФайлу — полный путь к файлу книги Excel (включая имя).
После выполнения действий необходимо закрыть книгу:
Эксель.Application.Quit();
Как программно сохранить файл Excel в формате 2003 года
Синтаксис команды «SaveAs» во втором параметре разрешает указать формат сохраняемого файла.
Числовое значение фрмата файла Excel 2003: FileFormatNum = -4143
Т.е. команду сохранения для этого можно написатьтак:
Книга.SaveAs(ПутьДляЗаписиФайла, -4143);
Часто используемые методы Excel
Эксель.Visible = Видимость; | 0 — Excel не виден, 1 — виден. |
Книга = Эксель.WorkBooks.Add(); | Создание новой книги (файла) Excel. |
Книга = Эксель.WorkBooks.Add(ИмяФайлаШаблона); | Создание новой книги (файла) Excel по шаблону «ИмяФайлаШаблона» |
Книга.SaveAs(ИмяФайла); | Сохранение книги Excel. |
Лист = Книга.WorkSheets.Add(); | Добавление нового листа в книгу. |
Книга = Эксель.WorkBooks.Open(ИмяФайла); | Открытие существующей книги (файла) Excel. |
Лист = Книга.WorkSheets(НомерЛиста); | Установка листа в качестве рабочего с номером НомерЛиста. |
Лист.Name = ИмяЛиста; | Задание рабочему листу имени ИмяЛиста |
Лист.PageSetup.Zoom = Масштаб; | Задание параметра страницы «Масштаб» (от 10 до 400). |
Лист.PageSetup.Orientation = Ориентация; | Ориентация: 1 — книжная, 2 — альбомная. |
Лист.PageSetup.LeftMargin = Эксель.CentimetersToPoints(Сантиметры); | Задание левой границы (в сантиметрах). |
Лист.PageSetup.TopMargin = Эксель.CentimetersToPoints(Сантиметры); | Задание верхней границы (в сантиметрах). |
Лист.PageSetup.RightMargin = Эксель.CentimetersToPoints(Сантиметры); | Задание правой границы (в сантиметрах). |
Лист.PageSetup.BottomMargin = Эксель.CentimetersToPoints(Сантиметры); | Задание нижней границы (в сантиметрах). |
Лист.Columns(НомерКолонки).ColumnWidth = Ширина; | Задание ширины колонке. |
Лист.Cells(НомерСтроки,НомерКолонки).ColumnWidth = 0; | Скрыть всю колонку, в которой расположена ячейка |
Лист.Cells(НомерСтроки, НомерКолонки).Value = Значение; | Ввод данных в ячейку. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Name = ИмяШрифта; | Установка шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Color = ЦветШрифта; | Установка цвета шрифта в ячейке. Тип переменной ЦветШрифта — число десятичное. |
Лист.Cells(НомерСтроки,НомерКолонки).Borders.Color = ЦветРамки; | Установка цвета рамки в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Interior.Color = ЦветФона; | Установка цвета фона в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Size = РазмерШрифта; | Установка размера шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Bold = Жирный; | 1 — жирный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Italic = Курсив; | 1 — наклонный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Underline = Подчеркнутый; | 2 — подчеркнутый, 1 — нет. |
Лист.Cells(НомерСтроки, НомерКолонки).NumberFormat = Формат; | Установка формата данных ячейки. |
Лист.Cells(НомерСтроки,НомерКолонки).Borders.Linestyle = ТипЛинии; | Установка рамок ячейки. 1 — тонкая сплошная. |
Лист.Cells(НомерСтроки,НомерКолонки).WrapText = Истина; | Осуществлять перенос по словам в указанной ячейке |
Лист.Protect(); | Установка защиты на лист |
Лист.UnProtect(); | Снятие защиты с листа |
Лист.Cells(Строка, Столбец).Locked=0; | Ячейка будет доступной (и после установки защиты на лист) |
ПолучитьCOMОбъект(<Имя файла>, <Имя класса COM>); | Основное применение функции ПолучитьCOMОбъект — это получение COM-объекта, соответствующего файлу. |
Хитрости Excel
Как выборочно разрешить / запретить редактирование ячеек листа
//Создаем объект EXCEL Эксель = СоздатьОбъект("Excel.Application"); Книга = Эксель.WorkBooks.Open(ФайлВыгрузки); Лист =Книга.Worksheets("Список сотрудников"); // Выбор листа Книга.ActiveSheet.UnProtect(); //делаем шаблон незащищенным // Заполняем лист // ................................... // Снимаем защиту с области ввода сумм Для Перем = 1 По 10 Цикл // Прописываем, какие ячейки будут доступными Книга.ActiveSheet.Cells(Перем, 2).Locked=0; КонецЦикла; Книга.ActiveSheet.Protect(); // ставим защиту на лист
Как запретить появление на экране всяких вопросов от Excel
Excel, чтоб вопрос не задавал:
Excel.DisplayAlerts = False;
Как добавить лист Excel в конец списка листов книги или после конкретного листа (а не в начало книги)
Метод работает для платформ 1С v8.
Файл = Новый COMОбъект("Excel.Application"); Файл.DisplayAlerts = False; Попытка ОбщаяКнига = Файл.WorkBooks.Open(Объект.ПутьКОбщемуФайлу); Исключение Сообщить("Excel: Неудачная попытка открытия файла Excel" + ОписаниеОшибки()); //ЗаписьЖурналаРегистрации("Excel: Неудачная попытка открытия файла Excel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки()); Возврат; КонецПопытки; КоличествоЛистов = ОбщаяКнига.Sheets.Count; //2 ПоследнийЛист = ОбщаяКнига.Worksheets(КоличествоЛистов); // необходимо получить сам лист (не его номер) Если КоличествоЛистов < 8 Тогда // к примеру, нужно сделать так, чтобы в книге было 8 листов, если листов меньше, то добавляем их Пока 8 - КоличествоЛистов > 0 Цикл ОбщаяКнига.Sheets.Add(Null,ПоследнийЛист,Null,Null); // добавляем лист в конец книги КоличествоЛистов = КоличествоЛистов +1; ПоследнийЛист = ОбщаяКнига.Worksheets(КоличествоЛистов); // получаем ссылку на очередной последний лист книги КонецЦикла; КонецЕсли;
Как программно скрыть колонку файла Excel
// ПРИМЕР как скрыть колонку программно - скроется колонка №2: ЛистОшибок.Cells(ПозицияШапкиФайла, 2).ColumnWidth = 0; // скрыть колонку №2
Как программно назначить ячейке файла Excel перенос по словам
// ПРИМЕР как осуществлять перенос в ячейке по словам программно ячейка в строке ПозицияШапкиФайла, колонке №2: ЛистОшибок.Cells(ПозицияШапкиФайла, 2).WrapText = Истина; // осуществлять перенос в ячейке по словам
Как обработать файл xls, если Excel не установлен на компьютере
Для этого можно использовать метод
СоздатьОбъект("ADODB.Connection");
Код для 7.7, решающий такую задачу, будет выглядеть примерно так:
db = СоздатьОбъект("ADODB.Connection"); ConectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="+ИмяФайла+";Extended Properties="+"Excel 8.0;"; rs=CreateObject("ADODB.Recordset"); db.Open(ConectionString); rs.ActiveConnection = db; rs.CursorType = 3; rs.LockType = 2; //Чтобы задать Область, надо выделить область в екселе и нажать Вставка-Имя-Присвоить... rs.Source = "Select * from [Лист$1]"; rs.Open(); КоличествоПолей = rs.Fields.Count; Сообщить(КоличествоПолей); КоличествоЗаписей = rs.RecordCount; Сообщить(КоличествоЗаписей); Если rs.Eof()=0 Тогда Сообщить(rs.Fields(0).Value); rs.MoveNext(); Иначе ТЗ.УстановитьЗначение(1,1,rs.Fields(1).Value); КонецЕсли; rs.Close(); db.Close();
Как указать цвет шрифта в ячейке, цвет рамки, цвет фона
Книга.Sheets(1).Cells(1,1).Borders.Color = 25525124; // цвет рамки Книга.Sheets(1).Cells(1,1).Font.Color = 255000000; // цвет шрифта Книга.Sheets(1).Cells(1,1).Interior.Color = 255045; // цвет фона
Организация автоматической обработки файлов xls из выбранной папки
// В v8 код обработки файлов выглядит примерно так: // примеры задания пути к файлам: ПримерПапкиВСети = "Adsf01PublicЗАГРУЗКА ЗАКАЗОВ"; ПримерПапкиЛокал = "C:1сОбмен"; // задаем путь загрузки: ПутьЗагрузки = ПримерПапкиЛокал; // Файлы - Массив из значений типа Файл, содержащий найденные файлы: Файлы = НайтиФайлы(ПутьЗагрузки,"*.xls*"); // организовываем перебор файлов: Для Каждого Файл ИЗ Файлы Цикл // обрабатываем файлы.... // ... // В конце можно удалить бработанный файл: Попытка УдалитьФайлы(Файл.ПолноеИмя); Исключение Сообщить("Не удалось удалить файл " + ОписаниеОшибки()); КонецПопытки; // или в конце можно переместить обработанный файл в специально предназначенную подпапку исходной папки: Попытка ПереместитьФайл(Файл.ПолноеИмя, ПутьЗагрузки+"Arhiv" + Файл.Имя); // папка архива: "C:1сОбменArhiv" Исключение Сообщить("Не удалось переместить файл " + ОписаниеОшибки()); КонецПопытки; КонецЦикла; // в 7.7 для аналогичных действий используются команды: ФС.НайтиПервыйФайл() ФС.НайтиСледующийФайл() ФС.УдалитьФайл() ФС.ПереименоватьФайл(,,);
Создание кнопки в Excel в 7.7
ТекущийЛист.Shapes("CommandButton").Select ТекущийЛист.OLEObjects("CommandButton").Object.Caption = "Кнопуля";
Процедура открывает Эксель, втавляет на первый лист кнопку «Очистить» и назначает ей макрос,
устанавливающий автофильтр на колонку Е по не нулевым значениям. Текст макроса любой,
главное разделять Симв(13) строки
Попытка Ex=CreateObject("Excel.Application"); Исключение Сообщить(ОписаниеОшибки(),"!!!"); Предупреждение("Не удалось запустить MS Excel!"); Возврат; КонецПопытки; Состояние("Открытие файла..."); Попытка Wb=Ex.WorkBooks.Add(); Исключение Возврат; КонецПопытки; Ex.Visible=-1; Wb.Sheets(1).OLEObjects.Add("Forms.CommandButton.1",,,10, 99.75, 120.75, "Очистить");//27.75 st = "Private Sub CommandButton1_Click()" + Chr(13) + " ThisWorkbook.Sheets(1).Columns(""E:E"").AutoFilter Field:=1, Criteria1:="">0"", Operator:=xlAnd" + Chr(13) + "End Sub"; Ex.VBE.ActiveVBProject.VBComponents(Wb.Sheets(1).Name).CodeModule.AddFromString(st)
текст макроса пишется в переменную st
Как подключиться к запущенному Excel-евскому файлу в реальном времени, изменить его и даже не сохранять, а просто переключить окно на 1С и сразу же выгружать данные в табличную часть, лишь переключив окна
Excel = ПолучитьCOMОбъект(, "Excel.Application");
При этом первый параметр нужно оставить пустым. В этом случае при этом подцепится тот файл экселя, который был открыт последним, даже если порядок переключения окон был таким:
Excel1, Excel2, IE, Проводник, 1С (т.е. что-то и было открытым между 1с и экселевским файлом) — все равно откроется Excel2, потому что он был активен последним.
Описание команды ПолучитьCOMОбъект
Глобальный контекст
ПолучитьCOMОбъект (GetCOMObject)
Синтаксис:
ПолучитьCOMОбъект(<Имя файла>, <Имя класса COM>)
Параметры:
<Имя файла> (необязательный)
Тип: Строка. Имя файла, включающее полный путь.
<Имя класса COM> (необязательный)
Тип: Строка. Имя класса COM, экземпляр которого должен быть создан или получен. Если расширение имени файла, указанное в первом параметре полностью идентифицирует класс объекта, то параметр может быть опущен.
Возвращаемое значение:
Тип: COMОбъект.
Описание:
Основное применение функции ПолучитьCOMОбъект — это получение COM-объекта, соответствующего файлу. Для этого следует в качестве первого параметра функции задать имя файла, который будет определять COM-объект. Например, фрагмент кода
Таб = ПолучитьCOMОбъект("C:DATADATA.XLS");
создает объект Excel.Application и открывает с его помощью файл документа «C:DATADATA.XLS». Если указанный файл во время выполнения данного фрагмента уже открыт с помощью MS Excel, то будет получена ссылка на уже существующий объект.
Для файлов, указываемых в качестве параметра данной функции, должно быть установлено соответствие расширения имени файла и класса COM.
Если в качестве имени файла указана пустая строка, то будет создан новый экземпляр объекта. В этом случае необходимо указать имя класса COM.
Например, фрагмент кода
Таб = ПолучитьCOMОбъект("", "Excel.Application");
создает новый документ Excel. В дальнейшем этот документ может быть программно заполнен и сохранен в файл.
Если первый параметр функции пропущен, то будет произведена попытка получить активный объект указанного типа. Если активного объекта указанного типа в настоящий момент не существует, то будет вызвано исключение. Например, в результате выполнения оператора
П = ПолучитьCOMОбъект( , "Excel.Application");
Переменная П получит значение типа COMОбъект, соответствующее активному приложению MS Excel, если таковое имелось, или будет вызвано исключение, если активных экземпляров MS Excel не было.
Пример:
// Получение объекта COM, соответствующего файлу Таб = ПолучитьCOMОбъект("C:DATADATA.XLS"); // Создание нового экземпляра объекта Таб = ПолучитьCOMОбъект("", "Excel.Application"); // Получение активного объекта Таб = ПолучитьCOMОбъект( , "Excel.Application");
Ниже приведена сравнительная таблица команд — один и тот же код на 7.7 и v8 с небольшими дополнениями
Отличия:
- команда создания самого объекта в 7.7 и v8 различна;
- в v8 выводится запись в журнал регистрации (просто для примера, например, когда вывод сообщения на экран невозможен из-за выполнения кода в фоновом задании);
- в v8 параллельно создается, заполняется и сохраняется копия исходного файла с комментариями об ошибках
1C 7.7 | 1C v8 |
Доступ из 1С к Excel производится посредством OLE. Создание COM-объекта: | |
Попытка Эксель = СоздатьОбъект("Excel.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; |
Попытка Эксель = Новый COMОбъект("Excel.Application"); Исключение ЗаписьЖурналаРегистрации("Excel: Неудачная попытка подключения компоненты Excel. | Возможно, программа Excel не установлена на данном компьютере!", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки()); Возврат Ложь; КонецПопытки; |
Теперь, используя переменную «Эксель», можно управлять приложением Excel. * Внимание! Microsoft Excel должен быть установлен на компьютере! Следующая команда откроет книгу: |
|
Книга = Эксель.WorkBooks.Open(ПутьКФайлу); |
Попытка Книга = Эксель.WorkBooks.Open(ИмяФЗагрузки); Исключение ЗаписьЖурналаРегистрации("Excel: Неудачная попытка открытия файла Excel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки()); Возврат; КонецПопытки; |
Перед тем, как начать считывание данных, укажем лист книги, с которого будем считывать данные: | |
Лист = Книга.WorkSheets(НомерЛиста) |
|
Нумерация листов книги начинается с 1. Общее количество листов можно получить, используя следующую команду: | |
КоличествоЛистов = Книга.Sheets.Count; |
КоличествоЛистов = Книга.Sheets.Count; |
// создание файла для записи проблем | |
КнигаОшибок = Эксель.WorkBooks.Add(); |
КнигаОшибок = Эксель.WorkBooks.Add(); |
// читаем книгу по листам: | |
Для СчетчикПоЛистам = 1 По КоличествоЛистов Цикл //цикл по листам // если листов больше 3, то потребуется добавить лист в книгу Если СчетчикПоЛистам > 3 Тогда ЛистОшибок = КнигаОшибок.Sheets.Add(); Иначе ИмяЛистаОшибок = КнигаОшибок.Sheets(СчетчикПоЛистам).Name; ЛистОшибок = КнигаОшибок.WorkSheets(ИмяЛистаОшибок); КонецЕсли; |
|
//Имя листа в книге можно получить по номеру: | |
ИмяЛиста = Книга.Sheets(НомерЛиста).Name; |
ИмяЛиста = Книга.Sheets(СчетчикПоЛистам).Name; |
//Лист можно выбрать по имени листа в книге: | |
Лист = Книга.WorkSheets(ИмяЛиста); |
Лист = Книга.WorkSheets(ИмяЛиста); |
//Итак, мы открыли книгу и выбрали лист, теперь посмотрим, сколько строк и колонок на выбранном листе: | |
ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; |
Попытка ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; // используем для перебора строк Исключение ЗаписьЖурналаРегистрации("Excel: Неудачная попытка получения количества колонок и строк Excel", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки()); Возврат; КонецПопытки; |
// получение значения из конкретной ячейки файла экселя: | |
Значение = Лист.Cells(НомерСтроки, НомерКолонки).Value; |
Для счетчикПоКолонкам = 1 По ВсегоКолонок Цикл //цикл по колонкам ЗначениеВЯчейке=Книга.Sheets(СчетчикПоЛистам).Cells(ПозицияШапкиФайла,счетчикПоКолонкам).Value; ... |
// установка нового значения ячейки экселя: | |
Лист.Cells(НомерСтроки, НомерКолонки).Value = Значение; |
ЛистОшибок.Cells(ПозицияШапкиФайла, счетчикПоКолонкам).Value = ЗначениеВЯчейке; |
// сохранение изменений в новом файле экселя: | |
// если такой файл уже был записан, удалим его, чтобы эксель не спросил интерактивно про перезапись Попытка ИмяФайлаОшибок = ВыбФайл.Путь + ВыбФайл.ИмяБезРасширения + "_bad.xls"; ФайлОш = Новый Файл(ИмяФайлаОшибок); Если ФайлОш.Существует() Тогда УдалитьФайлы(ИмяФайлаОшибок); КонецЕсли; КнигаОшибок.SaveAs(ИмяФайлаОшибок); // файл с ошибочными данными Исключение ДобавитьСообщениеВОшибки("Не удалось записать в файл сообщения об ошибках!"+ ОписаниеОшибки(),,, "Важно"); КонецПопытки; |
|
// После выполнения действий закрываем книгу: | |
Эксель.Quit(); |
Эксель.Quit(); |
Для работы с Excel файлами в системе 1C существуют определенные технологии. Организовать взаимодействие системы 1C с внешней программой MS Excel можно через COM-объект «Excel.Application». Также есть возможность наладить взаимодействие с Excel из 1C используя технологию ADO.
Данный пример демонстрирует работу с использованием «Excel.Application». Для работоспособности данного примера на компьютере обязательно должно быть установлено программное обеспечение MS Excel.
Прочитать из существующего Excel Файла
Процедура ПрочитатьСуществующийExcelФайл(ПутьКФайлу)Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = 0;
Excel.Visible = 0;
Исключение
Сообщить(ОписаниеОшибки() + " Программа Exсel не установлена");
Возврат;
КонецПопытки; Книга
= Excel.Workbooks.Open(ПутьКФайлу);
КоличествоЛистов = Книга.Sheets.Count;//Перебор листов
Для НомерЛиста = 1 По КоличествоЛистов Цикл Лист
= Книга.Sheets(НомерЛиста);
КоличествоСтрок = Лист.Cells(1, 1).SpecialCells(11).Row;
КоличествоКолонок = Лист.Cells(1, 1).SpecialCells(11).Column;//Перебор строк
Для НомерСтроки = 1 По КоличествоСтрок Цикл//Перебор колонок
Для НомерКолонки = 1 По КоличествоКолонок Цикл
ЗначениеЯчейки = Лист.Cells(НомерСтроки, НомерКолонки).Value;
//Выполнение действий с полученным значением
//...
//...
КонецЦикла;КонецЦикла;КонецЦикла; Excel
.Workbooks.Close();
Excel.Application.Quit();КонецПроцедуры
Записать в существующий Excel Файл
Процедура ЗаписатьСуществующийExcellФайл(ПутьКФайлу)Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = 0;
Excel.Visible = 0;
Исключение
Сообщить(ОписаниеОшибки() + " Программа Exсel не установлена");
Возврат;
КонецПопытки; Книга
= Excel.Workbooks.Open(ПутьКФайлу); Лист
= Книга.Sheets(1);
//Установить значение в ячейку
Лист.Cells(1, 1).Value = "Тестовое значение";
Книга.Save(); Excel
.Workbooks.Close();
Excel.Application.Quit();КонецПроцедуры
Создать новый Excel Файл
Процедура СоздатьНовыйExcellФайл(ПутьКФайлу)Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.DisplayAlerts = 0;
Excel.Visible = 0;
Исключение
Сообщить(ОписаниеОшибки() + " Программа Exсel не установлена");
Возврат;
КонецПопытки; //Автоматически будут созданы три листа
Книга = Excel.WorkBooks.Add();
//Получить первый лист
Лист = Книга.Sheets(1);
//Установить значение в ячейку
Лист.Cells(1, 1).Value = "Тестовое значение";Попытка
Книга.SaveAs(ПутьКФайлу);
Исключение
Сообщить(ОписаниеОшибки() + " не удалось сохранить файл");
КонецПопытки; Excel
.Workbooks.Close();
Excel.Application.Quit();КонецПроцедуры
Содержание:
1. Листы книги Microsoft Excel
2. Поля ячеек Excel
3. Объекты Range
Нередко многие сталкиваются с задачей перенесения большого количества данных и выгрузкой в Excel из 1С. В данной статье мы не будем рассматривать создание обработки для этих целей, а просто разберем некоторые методы для COM объектов, которые можно использовать при программном создании файла Excel.
Создавать объект данного типа следует при помощи конструкции «Попытка-Исключение» в Excel.Applications. Данная конструкция поможет предотвратить лишние ошибки, а также будет выводить на экран описание, если ошибка, все же, случится.
Использование конструкции Попытка-Исключение
Когда файл типа Excel создан можно перейти непосредственно к работе с ним.
Для более удобной работы можно изменить видимость (0 — Excel не виден, 1 – виден)
Видимость файла типа Excel
1. Листы книги Microsoft Excel
Данное свойство позволяет изменять способ работы Excel (в фоновом режиме или в обычном).
После установки видимости производим создание книги Excel.
Создание книги Excel
Данный метод добавит в файл новую книгу в Excel и сохранит ее в переменную.
Далее можно обратиться к листу книги Microsoft Excel.
Добавление в файл новой книги в Excel
Или добавить новый.
Добавление листа книги Microsoft Excel
У листа книги Microsoft Excel есть свойства, которые можно изменять. Вот некоторые из них:
· Name – Имя листа;
· PageSetup.Zoom– Масштаб (принимает значения от 10 до 400);
· PageSetup.Orientation – ориентация листа (1 — книжная, 2 – альбомная);
· PageSetup.LeftMargin – управляет отступом слева;
· PageSetup.TopMargin — управляет отступом сверху;
· PageSetup.RightMargin- управляет отступом справа;
· PageSetup.BottomMargin- управляет отступом снизу.
Для получения значения названия ячейки листа или записи в ячейку какого-либо значения нужно обратиться к ней по номеру:
Процедура получения значения названия ячейки листа
Таким же образом можно обратиться и к любому другому полю ячейки Excel:
Обращение к полю ячейки Excel
2. Поля ячеек Excel
Ниже приведен основной список полей ячеек Excel с указанием назначений.
· NumberFormat – формат ячейки («@» – текстовый, «0.00» – числовой);
· Value – Содержимое ячейки (то что увидит пользователь, открыв файл);
· Borders.Linestyle – Рамка вокруг ячейки;
· Height – Высота ячейки в пикселях;
· WrapText – перенос текста по словам (1 – переносить, 0 – не переносить);
· VerticalAlignment – Вертикальное положение текста в ячейки;
· HorizontalAlignment – Горизонтальное положение текста в ячейки;
· FormulaLocal – формула ячейки;
· Font.Name – наименование шрифта текста;
· Font.Size – Размер текста;
· Font.Bold – жирность текста (1 – жирный, 0 – нормальный);
· Font.Italic – курсив текста (1 – курсив, 0 – нормальный);
· Font.Underline – подчеркивание текста (1 – подчеркнутый, 0 – нормальный);
· Delete () – удаляет ячейку;
· Interior.Color – отвечает за фон ячейки, чтобы Excel «понял» цвет его необходимо передать в формате Excel. Для этого можно использовать следующую функцию.
Форматирование цвета в Excel
Форматирование цвета в Excel принимает на вход параметры R, G, B – номера цвета в стандартном формате и возвращает номер цвета в формате, подходящем для Excel.
Аналогичным образом можно обращаться к колонкам и строкам:
Обращение к строке
Методы для COM объекта – обращение к колонке
3. Объекты Range
Следует заметить, что свойства Cells, Columns и Rows возвращают не наборы объектов Cell, Column и Row, а наборы объектов Range. На использовании объекта Range построена в Excel почти вся работа с ячейками и их значениями.
К наборам объектов Range так же можно обращаться при помощи ячеек:
Обращение к объектам Range
А также назначать областям имя:
Назначение имен областям объектов Range
Обращение к области можно использовать, например, для объединения группы ячеек:
Объединение ячеек объектов Range
Колонки, строки и области в Excel имеют такие же свойства, как и ячейки, поэтому, например, можно без проблем изменить оформление сразу всей строки.
По окончании редактирования файла его необходимо сохранить при помощи специального метода.
Сохранение файла типа Excel
Где имя файла — это полный путь к файлу типа Excel.
После сохранения необходимо завершить транзакцию.
Завершение транзакции с файлом типа Excel
Специалист компании «Кодерлайн»
Айдар Фархутдинов
На чтение 9 мин Просмотров 27.1к. Опубликовано 09.11.2017
MS Excel давно стал стандартом для работы с электронными таблицами. В статье рассматриваются способы программной выгрузки и загрузки из 1С в файлы Excel.
Существует несколько способов программной работы с файлами Excel из 1С. Каждый из них имеет свои преимущества и недостатки.
Содержание
- Обмен через табличный документ
- Обмен через OLE
- Использование COMSafeArray
- Обмен через ADO
- Выгрузка без программирования
Обмен через табличный документ
Данный способ простой. Его суть заключается в том, что объект ТабличныйДокумент имеет методы:
- Записать(<ИмяФайла>, <ТипФайлаТаблицы>) для выгрузки данных в файл;
- Прочитать(<ИмяФайла>, <СпособЧтенияЗначений>) для загрузки данных из файла.
Внимание!
Метод Записать() доступен как на клиенте, так и на сервере. Метод Прочитать() доступен только на стороне сервера. Необходимо помнить об этом
при планировании клиент-серверного взаимодействия.
Рассмотрим пример сохранения табличного документа в файл. Необходимо любым способом создать и заполнить объект ТабличныйДокумент, а выгрузка в файл осуществляется всего лишь одной строкой:
ТабДок.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.XLSX);
Здесь ТабДок — сформированный табличный документ, ПутьКФайлу — имя файла для выгрузки, ТипФайлаТабличногоДокумента.XLSX — формат создаваемого файла. Поддерживаются следующие форматы Excel:
- XLS95 — формат Excel 95;
- XLS97 — формат Excel 97;
- XLSX — формат Excel 2007.
Загрузка из файла осуществляется также достаточно просто:
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
Здесь ПутьКФайлу — путь к загружаемому файлу Excel. СпособЧтенияЗначенийТабличногоДокумента.Значение определяет, каким образом нужно интерпретировать данные, считываемые из исходного документа. Доступны варианты:
- Значение;
- Текст.
Обмен через OLE
Обмен через технологию OLE automation, пожалуй, самый распространенный вариант программной работы с файлами Excel. Он позволяет использовать весь функционал, предоставляемый Excel, но отличается медленной скоростью работы по сравнению с другими способами. Для обмена через OLE требуется установка MS Excel:
- На компьютере конечного пользователя, если обмен происходит на стороне клиента;
- На компьютере сервера 1С:Предприятие, если обмен происходит на стороне сервера.
Пример выгрузки:
// Создание COM-объекта
Эксель = Новый COMОбъект(«Excel.Application»);
// Отключение вывода предупреждений и вопросов
Эксель.DisplayAlerts = Ложь;
// Создание новой книги
Книга = Эксель.WorkBooks.Add();
// Позиционирование на первом листе
Лист = Книга.Worksheets(1);// Запись значения в ячейку
Лист.Cells(НомерСтроки, НомерКолонки).Value = ЗначениеЯчейки;// Сохранение файла
Книга.SaveAs(ИмяФайла);// Закрытие Эксель и освобождение памяти
Эксель.Quit();
Эксель = 0;
Примеры чтения:
// —— ВАРИАНТ 1 ——
// Создание COM-объекта
Эксель = Новый COMОбъект(«Excel.Application»);
// Открытие книги
Книга = Эксель.Workbooks.Open(ПутьКФайлу);
// Позиционирование на нужном листе
Лист = Книга.Worksheets(1);// Чтение значения ячейки, обычно здесь располагается цикл обхода ячеек
ЗначениеЯчейки = Лист.Cells(НомерСтроки, НомерКолонки).Value;// Закрытие книги
Книга.Close(0);// Закрытие Эксель и освобождение памяти
Эксель.Quit();
Эксель = 0;// —— ВАРИАНТ 2 ——
// Открытие книги
Книга = ПолучитьCOMОбъект(ПутьКФайлу);
// Позиционирование на нужном листе
Лист = Книга.Worksheets(1);// Чтение значения ячейки, обычно здесь располагается цикл обхода ячеек
ЗначениеЯчейки = Лист.Cells(НомерСтроки, НомерКолонки).Value;// Закрытие книги
Книга.Application.Quit();
Для обхода всех заполненных строк листа Excel можно использовать следующие приемы:
// —— ВАРИАНТ 1 ——
КоличествоСтрок = Лист.Cells(1, 1).SpecialCells(11).Row;
Для НомерСтроки = 1 По КоличествоСтрок Цикл
ЗначениеЯчейки = Лист.Cells(НомерСтроки, НомерКолонки).Value;
КонецЦикла;// —— ВАРИАНТ 2 ——
НомерСтроки = 0;
Пока Истина Цикл
НомерСтроки = НомерСтроки + 1;
ЗначениеЯчейки = Лист.Cells(НомерСтроки, НомерКолонки).Value;
Если НЕ ЗначениеЗаполнено(ЗначениеЯчейки) Тогда
Прервать;
КонецЕсли;
КонецЦикла;
Вместо последовательного обхода всех строк листа можно выгрузить все данные в массив и работать с ним. Такой подход будет быстрее при чтении большого объема данных:
ВсегоКолонок = Лист.Cells(1, 1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1, 1).SpecialCells(11).Row;Область = Лист.Range(Лист.Cells(1, 1), Лист.Cells(ВсегоСтрок, ВсегоКолонок));
Данные = Область.Value.Выгрузить();
В таблице ниже приведены наиболее востребованные свойства и методы для работы с Excel через OLE:
Действие | Код | Комментарий |
Работа с приложением | ||
Установка видимости окна приложения | Эксель.Visible = Ложь; | |
Установка режима вывода предупреждений (выводить/не выводить) | Эксель.DisplayAlerts = Ложь; | |
Закрытие приложения | Эксель.Quit(); | |
Работа с книгой | ||
Создание новой книги | Книга = Эксель.WorkBooks.Add(); | |
Открытие существующей книги | Книга = Эксель.WorkBooks.Open(ИмяФайла); | |
Сохранение книги | Книга.SaveAs(ИмяФайла); | |
Закрытие книги | Книга.Close(0); | |
Работа с листом | ||
Установка текущего листа | Лист = Книга.WorkSheets(НомерЛиста); | |
Установка имени | Лист.Name = Имя; | |
Установка защиты | Лист.Protect(); | |
Снятие защиты | Лист.UnProtect(); | |
Установка ориентации страницы | Лист.PageSetup.Orientation = 2; | 1 — книжная, 2 — альбомная |
Установка левой границы | Лист.PageSetup.LeftMargin = Эксель.CentimetersToPoints(Сантиметры); | |
Установка верхней границы | Лист.PageSetup.TopMargin = Эксель.CentimetersToPoints(Сантиметры); | |
Установка правой границы | Лист.PageSetup.RightMargin = Эксель.CentimetersToPoints(Сантиметры); | |
Установка нижней границы | Лист.PageSetup.BottomMargin = Эксель.CentimetersToPoints(Сантиметры); | |
Работа со строками, колонками, ячейками | ||
Установка ширины колонки | Лист.Columns(НомерКолонки).ColumnWidth = Ширина; | |
Удаление строки | Лист.Rows(НомерСтроки).Delete(); | |
Удаление колонки | Лист.Columns(НомерКолонки).Delete(); | |
Удаление ячейки | Лист.Cells(НомерСтроки, НомерКолонки).Delete(); | |
Установка значения | Лист.Cells(НомерСтроки, НомерКолонки).Value = Значение; | |
Объединение ячеек | Лист.Range(Лист.Cells(НомерСтроки, НомерКолонки), Лист.Cells(НомерСтроки1, НомерКолонки1)).Merge(); | |
Установка шрифта | Лист.Cells(НомерСтроки, НомерКолонки).Font.Name = ИмяШрифта; | |
Установка размера шрифта | Лист.Cells(НомерСтроки, НомерКолонки).Font.Size = РазмерШрифта; | |
Установка жирного шрифта | Лист.Cells(НомерСтроки, НомерКолонки).Font.Bold = 1; | 1 — жирный шрифт, 0 — нормальный |
Установка курсива | Лист.Cells(НомерСтроки, НомерКолонки).Font.Italic = 1; | 1 — курсив, 0 — нормальный |
Установка подчеркнутого шрифта | Лист.Cells(НомерСтроки, НомерКолонки).Font.Underline = 2; | 2 — подчеркнутый, 1 — нет |
Для того, чтобы узнать какое свойство нужно менять или какой метод вызвать можно воспользоваться макросами Excel. Если записать макрос с требуемыми действиями, то после можно посмотреть программный код на VBA записанного макроса.
Использование COMSafeArray
При выгрузке больших объемов данных из 1С в Excel для ускорения можно использовать объект COMSafeArray. Согласно определению из синтакс-помощника, COMSafeArray — объектная оболочка над многомерным массивом SafeArray из COM. Позволяет создавать и использовать SafeArray для обмена данными между COM-объектами. Проще говоря, это массив значений, который можно использовать для обмена между приложениями по технологии OLE.
// Создание COMSafeArray
МассивКом = Новый COMSafeArray(«VT_Variant», ВсегоКолонок, ВсегоСтрок);
// Заполнение COMSafeArray
Для Стр = 0 По ВсегоСтрок — 1 Цикл
Для Кол = 0 По ВсегоКолонок — 1 Цикл
МассивКом.SetValue(Кол, Стр, Значение);
КонецЦикла;
КонецЦикла;
// Присвоение области листа Excel значений из COMSafeArray
Лист.Range(Лист.Cells(1, 1), Лист.Cells(ВсегоСтрок, ВсегоКолонок)).Value = МассивКом;
Обмен через ADO
Файл Excel при обмене через ADO представляет собой базу данных, к которой можно обращаться при помощи SQL-запросов. Установка MS Excel не требуется, но обязательно наличие драйвера ODBC, при помощи которого будет осуществляться доступ. Используемый драйвер ODBC определяется при указании строки соединения к файлу. Обычно требуемый драйвер уже установлен на компьютере.
Обмен через ADO заметно быстрее обмена через OLE, но при выгрузке нет возможности использовать функционал Excel для оформления ячеек, разметки страниц, задания формул и т.д.
Пример выгрузки:
// Создание COM-объекта для соединения
Соединение = Новый COMОбъект(«ADODB.Connection»);// Установка строки соединения
Соединение.ConnectionString = «
|Provider=Microsoft.ACE.OLEDB.12.0;
|Data Source=»+ИмяФайла+«;
|Extended Properties=»»Excel 12.0 XML;HDR=YES»»;»;
Соединение.Open(); // Открытие соединения// Создание COM-объекта для команды
Команда = Новый COMОбъект(«ADODB.Command»);
Команда.ActiveConnection = Соединение;// Присвоение текста команды для создания таблицы
Команда.CommandText = «CREATE TABLE [Лист1] (Колонка1 char(255), Колонка2 date, Колонка3 int, Колонка4 float)»;
Команда.Execute(); // Выполнение команды// Присвоение текста команды для добавления строки таблицы
Команда.CommandText = «INSERT INTO [Лист1] (Колонка1, Колонка2, Колонка3, Колонка4) values (‘абвгдеё’, ‘8/11/2017’, ‘12345’, ‘12345,6789’)»;
Команда.Execute(); // Выполнение команды// Удаление команды и закрытие соединения
Команда = Неопределено;
Соединение.Close();
Соединение = Неопределено;
Для создания нового листа и формирования его структуры можно воспользоваться объектами ADOX.Catalog и ADOX.Table. В этом случае код примет вид:
// Создание COM-объекта для работы с книгой
Книга = Новый COMОбъект(«ADOX.Catalog»);
Книга.ActiveConnection = Соединение;// Создание COM-объекта для работы со структурой данных на листе
Таблица = Новый COMОбъект(«ADOX.Table»);
Таблица.Name = «Лист1»;
Таблица.Columns.Append(«Колонка1», 202);
Таблица.Columns.Append(«Колонка2», 7);
Таблица.Columns.Append(«Колонка3», 5);
Таблица.Columns.Append(«Колонка4», 5);// Создание в книге листа с описанной структурой
Книга.Tables.Append(Таблица);
Таблица = Неопределено;
Книга = Неопределено;
В приведенном примере в методе
Таблица.Columns.Append(«Колонка1», 202);
во втором параметре указывается тип колонки. Параметр необязательный, вот некоторые значения типа колонки:
- 5 — adDouble;
- 6 — adCurrency;
- 7 — adDate;
- 11 — adBoolean;
- 202 — adVarWChar;
- 203 — adLongVarWChar.
Пример чтения:
// Создание COM-объекта для соединения
Соединение = Новый COMОбъект(«ADODB.Connection»);// Установка строки соединения
Соединение.ConnectionString = «
|Provider=Microsoft.ACE.OLEDB.12.0;
|Data Source=»+ИмяФайла+«;
|Extended Properties=»»Excel 12.0 XML;HDR=YES»»;»;
Соединение.Open(); // Открытие соединения// Создание COM-объекта для получения выборки
Выборка = Новый COMОбъект(«ADODB.Recordset»);
ТекстЗапроса = «SELECT * FROM [Лист1$]»;// Выполнение запроса
Выборка.Open(ТекстЗапроса, Соединение);// Обход результата выборки
Пока НЕ Выборка.EOF() Цикл
ЗначениеКолонки1 = Выборка.Fields.Item(«Колонка1»).Value; // Обращение по имени колонки
ЗначениеКолонки2 = Выборка.Fields.Item(0).Value; // Обращение по индексу колонки
Выборка.MoveNext();
КонецЦикла;Выборка.Close();
Выборка = Неопределено;
Соединение.Close();
Соединение = Неопределено;
В строке соединения параметр HDR определяет как будет восприниматься первая строка на листе. Возможны варианты:
- YES — первая строка воспринимается как названия колонок. К значениям можно обращаться по имени и по индексу колонки.
- NO — первая строка воспринимается как данные. К значениям можно обращаться только по индексу колонки.
В приведенных примерах рассмотрено лишь несколько объектов ADO. Объектная модель ADO состоит из следующих объектов:
- Connection;
- Command;
- Recordset;
- Record;
- Fields;
- Stream;
- Errors;
- Parameters;
- Properties.
Выгрузка без программирования
Для сохранения данных из 1С в 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
Перепечатка текста и фотографий разрешена при наличии прямой ссылки на источник
- Главная
- О сайте
- Главная
- Содержание
Категории
—>
рубрики: Excel | Дата: 19 июня, 2017
Скачать обработку с примерами из статьи: professia1c_ExcelApplication.epf
Платформа: 8.3; Тип формы: управляемая.
Одним из самых распространенных методов при работе с файлами Excel из 1С является использование COM соединения, т.е создание объекта Excel.Application и дальнейшая работа с ним средствами встроенного в ексель языка VBA. При помощи этого метода можно как записывать данные в файл Excel, так и читать их из файла.
Рассмотрим обе эти возможности на небольших примерах.
Запись данных в Excel
В прошлой статье про формирование файла Excel из табличного документа был показан пример записи в файл вот такой простенькой таблицы
Товар | Количество |
---|---|
Яблоки | 5 |
Груши | 10 |
Проделаем то же самое (запишем таблицу значений в файл ексель), но уже с использованием объекта Excel.Application. Сделать это можно с помощью следующей процедуры
&НаСервере
Процедура ЗаписатьТаблицуЗначенийВФайлЕксель(Таблица)
ДокументЕксель = Новый COMОбъект("Excel.Application");
КнигаЕксель = ДокументЕксель.WorkBooks.Add(); //Создаем книгу ексель
ЛистЕксель = КнигаЕксель.WorkSheets(1); //Позиционируемся на 1-м листе
КоличествоКолонок = Таблица.Колонки.Количество();
//Формируем строку с заголовками
Для Счетчик = 1 По КоличествоКолонок Цикл
ТекущаяКолонка = Таблица.Колонки[Счетчик - 1];
ЛистЕксель.Cells(1, Счетчик).Value = ТекущаяКолонка.Имя;
КонецЦикла;
//Добавляем строки из таблицы
НомерСтроки = 2;
Для каждого СтрокаТаблицы Из Таблица Цикл
Для НомерКолонки = 1 По КоличествоКолонок Цикл
ЛистЕксель.Cells(НомерСтроки, НомерКолонки).Value = Строка(СтрокаТаблицы[НомерКолонки - 1]);
КонецЦикла;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
КнигаЕксель.SaveAs("D:musorTest.xlsx"); // Сохраняем файл ексель
ДокументЕксель.Application.Quit(); // Закрываем COM соединение
КонецПроцедуры
Здесь необходимо сделать несколько пояснений. Поскольку процедура серверная (клиентскую в данном случае сделать не получиться, т.к. тонкий клиент не работает с таблицей значений) необходимо понимать, что Excel должен быть установлен на сервере, т.е. там же где установлен сервер 1С:Предприятия. В других ситуациях запись файла ексель возможна и на клиенте. И тут уже Excel должен быть установлен на каждой клиентской машине, где будет выполняться эта процедура.
Для простоты кода не стал использовать конструкции Попытка — Исключение. Хотя в реальном коде они конечно же должны использоваться при создании COM объекта и т.д. В случае выполнения кода на клиенте мы можем после сохранения файла, дать возможность пользователю просмотреть его и при необходимости отредактировать. Для этого достаточно установить видимость объекта Excel в 1. Закрывать программно объект в этом случае не требуется. Его потом закроет пользователь вручную.
КнигаЕксель.SaveAs("D:musorTest.xlsx"); // Сохраняем файл ексель
ДокументЕксель.Visible = 1;
//ДокументЕксель.Application.Quit(); // Закрываем COM соединение
Чтение данных из Excel
Теперь посмотрим как реализуется обратная задача по чтению данных из файла Excel. Для этого воспользуемся файлом созданным в первом примере и прочитаем его в табличный документ с помощью вот такой процедуры:
&НаКлиенте
Процедура ПрочитатьФайлЕксель(Команда)
ДокументЕксель = Новый COMОбъект("Excel.Application");
КнигаЕксель = ДокументЕксель.WorkBooks.Open("D:musorTest.xlsx"); //Открываем файл ексель
ЛистЕксель = КнигаЕксель.WorkSheets(1); //Позиционируемся на 1-м листе
ТабДок = Новый ТабличныйДокумент;
Для НомерСтроки = 1 По ЛистЕксель.UsedRange.Rows.Count Цикл
Для НомерКолонки = 1 По ЛистЕксель.UsedRange.Columns.Count Цикл
ТабДок.Область("R" + НомерСтроки + "C" + НомерКолонки).Текст = ЛистЕксель.Cells(НомерСтроки, НомерКолонки).Value;
КонецЦикла;
КонецЦикла;
ТабДок.Показать();
ДокументЕксель.Application.Quit(); // Закрываем COM соединение
КонецПроцедуры
Как видим на клиенте можно также успешно создавать объект Excel.Application. А для подсчета количества строк и колонок на листе применяем свойство UsedRange — используемый диапазон.
Заключение
Таким образом при необходимости записать данные в файл Excel или наоборот прочитать их из файла и при минимальном знании VBA мы можем воспользоваться COM объектом Excel.Application. Конечно сейчас были рассмотрены самые примитивные свойства и методы, но при необходимости можно воспользоваться справкой по VBA в Excel и программно создать файл с достаточно сложным оформлением. Хотя в этом случае наверное проще будет заранее создать файл с шаблоном и заполнять уже его. Данный метод требует установленного приложения Excel и является не очень производительным. По крайней мере чтение и запись в Excel c помощью ADO работает гораздо быстрее.