Многие знают, что Excel гораздо старше 1С. На мой взгляд, это очень успешный продукт, и нареканий о нем я не слышал. Excel прост и универсален. Он способен выполнять не только простые арифметические операции, но и сложные вычисления, построение графиков и т.п. Знаю примеры, когда организации до перехода на 1С вели часть бухгалтерии в Excel. Многие и сейчас параллельно используют две программы. В этой статье рассмотрим способы обмена данными между 1С и Excel.
Таблицы 1С и Excel.
Многие пользователи для удобства работы сохраняют таблицы 1С (печатные формы) в формате Excel (*.xls). После чего в полученном файле делают различные группировки, сортировки, вычисления и т.п. Связано это с тем, что в таблицах 1С нет такого огромного функционала как в таблицах Excel. Но в версии 1С 8.0 есть нововведения, делающих работу с таблицами более комфортной.
Замечание: В Excel разделителем дробной части считается символ «,». Поэтому перед сохранением таблицы 1С в формате Excel замените в ней другой разделитель (например «.») на «,». Иначе в Excel с этими числами не удастся произвести вычисления, или они вообще не будут отображаться как числа. Например, в таблице 1С «15.2» отобразится в Excel как «15.фев».
Получение данных из Excel.
Доступ из 1С к Excel производится посредством OLE. Например, код
Попытка
Эксель= СоздатьОбъект(«Excel.Application»);
Исключение
Сообщить(ОписаниеОшибки() + » Программа Exсel не установлена на данном компьютере!»);
Возврат;
КонецПопытки;
позволит нам получить доступ через переменную «Эксель» к запущенному приложению Excel. А далее уже можно получить доступ к книге (файлу), листу и ячейке с данными. Далее примеры кода.
Открытие книги (файла):
Книга=Эксель.WorkBooks.Open(ПутьКФайлу);
ПутьКФайлу — полный путь к файлу книги Excel.
Выбор листа книги для работы с ним:
Лист=Книга.WorkSheets(НомерЛиста);
или
Лист=Книга.WorkSheets(ИмяЛиста);
НомерЛиста — номер листа в книге, ИмяЛиста — имя листа в книге.
Получение значения ячейки листа:
Значение=Лист.Cells(НомерСтроки,НомерКолонки).Value;
НомерСтроки, НомерКолонки — номер строки и номер колонки, на пересечении которых находится ячейка.
Важно: не забывайте поле выполнения нужных действий добавлять кодЭксель.Quit();, иначе запущенный процесс останется незавершенным и будет занимать память и процессор компьютера.
Вывод данных в Excel.
Для вывода (выгрузки) данных в Excel необходимо либо открыть существующую книгу, либо
создать новую, и выбрать рабочий лист для вывода данных. Открытие существующей книги описано выше, а для создания новой книги нужно использовать следующий код:
Попытка
Эксель= СоздатьОбъект(«Excel.Application»);
Исключение
Сообщить(ОписаниеОшибки() + » Программа Exсel не установлена на данном компьютере!»);
Возврат;
КонецПопытки;
Книга=Эксель.WorkBooks.Add();
Так как при создании книги в Excel автоматически создаются листы (Сервис->Параметры->Общие->Листов в новой книге), то нужно лишь произвести выбор листа, с которым будет вестись работа:
Лист=Книга.WorkSheets(НомерЛиста);
либо добавить в книгу новый лист, если необходимо:
Лист=Книга.Sheets.Add();
Следующим шагом будет установка значения ячейки:
Лист.Cells(НомерСтроки,НомерКолонки).Value=Значение;
НомерСтроки, НомерКолонки — номер строки и номер колонки, на пересечении которых находится ячейка.
И в конце нужно произвести запись созданной книги:
Попытка
Книга.SaveAs(ПутьКФайлу);
Исключение
Сообщить(ОписаниеОшибки()+» Файл не сохранен!»);
Возврат;
КонецПопытки;
ПутьКФайлу — полный путь к файлу книги Excel (включая имя).
Важно: не забывайте, что в имени файлов не должно содержаться символов / : * ? » > < |.
Часто используемые методы для чтения/установки значений в Excel.
Эксель = СоздатьОбъект(«Excel.Application»); | Получение доступа к приложению Excel. |
Эксель.Visible = Видимость; |
0 — Excel не виден, 1 — виден. |
Книга = Эксель.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(НомерСтроки,НомерКолонки).Value = Значение; |
Ввод данных в ячейку. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Name = ИмяШрифта; |
Установка шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Size = РазмерШрифта; |
Установка размера шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Bold = Жирный; |
1 — жирный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Italic = Курсив; |
1 — наклонный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Underline = Подчеркнутый; |
2 — подчеркнутый, 1 — нет. |
Лист.Cells(НомерСтроки, НомерКолонки).NumberFormat = Формат; |
Установка формата данных ячейки. |
Лист.Cells(НомерСтроки,НомерКолонки).Borders.Linestyle = ТипЛинии; |
Установка рамок ячейки. 1 — тонкая сплошная. |
Постоянный адрес статьи http://exp-1c.narod.ru/articles/articl01.htm
На чтение 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.х и Excel
Чтение данных из Excel
Доступ из 1С к Excel производится посредством OLE. Создание COM-объекта:
Попытка Эксель = СоздатьОбъект("Excel.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки;
Теперь используя переменную Эксель можно управлять приложением Excel.
- Внимание! Microsoft Excel должен быть установлен на компьютере!
Следующая команда откроет книгу:
Книга = Эксель.WorkBooks.Open(ПутьКФайлу);
Перед тем, как начать считывание данных, укажем лист книги, с которого будем считывать данные:
Лист = Книга.WorkSheets(НомерЛиста);
Нумерация листов книги начинается с 1. Общее количество листов можно получить, используя
следующую команду:
КоличествоЛистов = Книга.Sheets.Count;
Лист можно выбрать по имени листа в книге:
Лист = Книга.WorkSheets(ИмяЛиста);
Имя листа в книге можно получить по номеру:
ИмяЛиста = Книга.Sheets(НомерЛиста).Name;
Итак, мы открыли книгу и выбрали лист, теперь посмотрим, сколько строк и колонок
на выбранном листе:
ВсегоКолонок = Лист.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.Application"); Исключение Сообщить(ОписаниеОшибки()); Возврат; КонецПопытки; Книга = Эксель.WorkBooks.Add();
При создании книги автоматически создаются листы (по умолчанию 3).
Нам остается только выбрать нужный:
Лист = Книга.WorkSheets(НомерЛиста);
Или добавить в книгу новый лист:
Лист = Книга.Sheets.Add();
Добавим в ячейку на листе значение:
Лист.Cells(НомерСтроки, НомерКолонки).Value = Значение;
Запишем книгу:
Попытка Книга.SaveAs(ПутьКФайлу); Исключение Сообщить(ОписаниеОшибки()+" Файл не сохранен!"); КонецПопытки;
Где ПутьКФайлу — полный путь к файлу книги Excel (включая имя).
После выполнения действий необходимо закрыть книгу:
Эксель.Application.Quit();
Часто используемые методы Excel
Эксель.Visible = Видимость; | 0 — Excel не виден, 1 — виден. |
Книга = Эксель.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(НомерСтроки, НомерКолонки).Value = Значение; | Ввод данных в ячейку. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Name = ИмяШрифта; | Установка шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Size = РазмерШрифта; | Установка размера шрифта в ячейке. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Bold = Жирный; | 1 — жирный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Italic = Курсив; | 1 — наклонный шрифт, 0 — нормальный. |
Лист.Cells(НомерСтроки,НомерКолонки).Font.Underline = Подчеркнутый; | 2 — подчеркнутый, 1 — нет. |
Лист.Cells(НомерСтроки, НомерКолонки).NumberFormat = Формат; | Установка формата данных ячейки. |
Лист.Cells(НомерСтроки,НомерКолонки).Borders.Linestyle = ТипЛинии; | Установка рамок ячейки. 1 — тонкая сплошная. |
Лист.Protect(); | Установка защиты на лист |
Лист.UnProtect(); | Снятие защиты с листа |
Лист.Cells(Строка, Столбец).Locked=0; | Ячейка будет доступной (и после установки защиты на лист) |
Хитрости Excel
Как выборочно разрешить / запретить редактирование ячеек листа
//Создаем объект EXCEL Эксель = СоздатьОбъект("Excel.Application"); Книга = Эксель.WorkBooks.Open(ФайлВыгрузки); Лист =Книга.Worksheets("Список сотрудников"); // Выбор листа Книга.ActiveSheet.UnProtect(); //делаем шаблон незащищенным // Заполняем лист ................................... // Снимаем защиту с области ввода сумм Для Перем = 1 По 10 Цикл // Прописываем, какие ячейки будут доступными Книга.ActiveSheet.Cells(Перем, 2).Locked=0; КонецЦикла; Книга.ActiveSheet.Protect(); // ставим защиту на лист
Как осуществить поиск / замену значений ячеек на листе
//Выбираем область поиска - весь лист ОбластьПоиска = Лист.Cells; // Укажем начало листа НачалоЛиста = Диапазон.Cells(1, 1); // Ищем ячейку с текстом, указанным в переменной ТекстДляПоиска, //укажем откуда искать - с начала листа ОбластьПараметр = ОбластьПоиска.Find(ТекстДляПоиска, НачалоЛиста); // Если нашли, заполняем значением из переменной Значение Если ОбластьПараметр <> неопределено Тогда ОбластьПараметр.Value = Значение; КонецЕсли;
Замечание. Текст для замены лучше выделять, например, в угловые скобки, аналогично
параметрам макета в 1С. Это улучшит наглядность, визуально отделит от рабочего текста.
Текст для поиска в этом случае будет выглядеть так:
ТекстДляПоиска = «<ИмяДляЗамены>»
Как скопировать / удалить строку
//Выбираем область поиска - весь лист ОбластьПоиска = Лист.Cells; // Найдем нужную нам ячейку // Если не указываем откуда искать - то с текущей ячейки, это первая ячейка на листе НайденнаяОбласть = ОбластьПоиска.Find("Текст для поиска"); // Выделяем всю строку НайденнаяОбласть.EntireRow.Select(); // Копируем выделенное НайденнаяОбласть.EntireRow.Copy(); // Вставляем (новая строка будет вставлена тут же) НайденнаяОбласть.EntireRow.Insert(); // Теперь как удалить строку. Найдем область НайденнаяОбласть = ОбластьПоиска.Find("Текст для поиска", НачалоЛиста); НайденнаяОбласть.EntireRow.Delete();
Замечание. Приведенные выше примеры позволят, например, организвать работу с шаблонами на основании листов 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.
Работа с excel из 1С
- Создание объекта приложение Excel
- Программное открытие файла Excel, либо его создание при отсутствии
- Обращение к листу открытого файла Excel
- Обойти все листы и скрыть их по условию
- Добавить лист в самый конец(по умолчанию он добавляется в самое начало)
- Очистить лист
- Получить указанную область листа.
- Скопировать область из одной книги в другу.
- Функция по переводу Адреса стиля ссылок Excel из A1 в R1C1 на языке 1С.
Многие программисты сталкиваются с необходимостью загрузки в 1С из Excel или выгрузки в этот формат. Это связано с тем, что большое количество бухгалтеров, а также менеджеров используют этот формат для хранения и обработки данных.
В этой статье приведу несколько листингов которые облегчат понимание этой связки и помогут в написании своего кода. Последующие листинги опираются на предыдущие, поэтому если в листинге, например, используется переменная «ПриложениеЭксель», но не инициализируется, значит это было в одном из предыдущих листингов.
1. Создание объекта приложение Excel
Попытка
ПриложениеЭксель = Новый COMОбъект("Excel.Application")
Исключение
Предупреждение("ОШИБКА создания приложения Excel, возможно программа не установлена!");
КонецПопытки;
2. Программное открытие файла Excel, либо его создание при отсутсвии
ПутьКФайлу = “C:obmenzagruzka.xls”;
ФайлЭксель = Новый Файл(ПутьКФайлу);
Если ФайлЭксель.Существует() Тогда
Результат = ПриложениеЭксель.WorkBooks.Open(ПутьКФайлу);
Иначе
РабочаяКнига=ПриложениеЭксель.Workbooks.Add();
РабочаяКнига=ПриложениеЭксель.ActiveWorkbook;
ПриложениеЭксель.ActiveWorkbook.SaveAs(ПутьКФайлу,-4143);
Результат = ПриложениеЭксель.WorkBooks.Open(ПутьКФайлу);
КонецЕсли;
3. Обращение к листу открытого файла Excel
ЛистЭксель = ПриложениеЭксель.WorkBooks.Open(ПутьКФайлу).WorkSheets.Item(ИмяЛиста);
4. Обойти все листы и скрыть их по условию
КоличествоЛистов = ПриложениеЭксель.ActiveWorkbook.Worksheets.Count;
КоллекцияЛистов = ПриложениеЭксель.ActiveWorkbook.Worksheets;Для ТекНомерЛиста = 1 По КоличествоЛистов Цикл
ТекЛист = КоллекцияЛистов(ТекНомерЛиста);
Если ТекЛист.Name = «Лист1» Тогда
ТекЛист.Visible = False;
КонецЕсли;
КонецЦикла;
5. Добавить лист в самый конец(по умолчанию он добавляется в самое начало)
НомерПоследнегоЛиста = ФайлЭксель.WorkSheets.Count;
ДобавленныйЛист = ФайлЭксель.WorkSheets.Add(,ФайлЭксель.WorkSheets(НомерПоследнегоЛиста));
ДобавленныйЛист.Name = ИмяЛиста;
6. Очистить лист
ДобавленныйЛист.Cells.Clear();
7. Получить указанную область листа. Здесь используются переменные НомСтрВерх, НомСтрНиз, НомКолВерх, НомКолНиз – они обозначают координаты самой левой верхней ячейки и самой правой нижней ячейки областей
ОбластьОграниченнаяСтроками = ЭксельФайл.WorkSheets.Item(ИмяЛиста).Rows(""+НомСтрВерх+":"+НомСтрНиз);ЯчейкаВерхняяЛевая = ЭксельФайл.WorkSheets.Item(ИмяЛиста).Cells(НомСтрВерх, НомКолВерх);
ЯчейкаНижняяПравая = ЭксельФайл.WorkSheets.Item(ИмяЛиста).Cells(НомСтрНиз, НомКолНиз);
ОбластьОграниченнаяЯчейками = ЭксельФайл.WorkSheets.Item(ИмяЛиста).Range(ЯчейкаВерхняяПравая,ЯчейкаНижняяЛевая);
8. Скопировать область из одной книги в другу. О константах Excel(используемых числах) читайте в разделе «В заключении» данной статьи.
НоваяКнига = ПриложениеЭксель.WorkBooks.Open(ПутьКНовомуФайлу);
ЛистПриемник = НоваяКнига.WorkSheets.Item(ИмяЛистаПриемника);
ОбластьОграниченнаяЯчейками.Copy(); //записали в буфер
ЛистПриемник.Range(ЛистПриемник.Cells(ТекСтрока, ТекСтолбец), ЛистПриемник.Cells(ТекСтрока+КоличСтрок-1, ТекСтолбец+КоличСтолбцов-1)).PasteSpecial();
ЛистПриемник.Range(ЛистПриемник.Cells(ТекСтрока, ТекСтолбец), ЛистПриемник.Cells(ТекСтрока+КоличСтрок-1, ТекСтолбец+КоличСтолбцов-1)).PasteSpecial(8);// цифра 8 означает сохранить ширину столбцов как в источнике.
9. Функция по переводу Адреса стиля ссылок Excel из A1 в R1C1 на языке 1С.
Чтобы конвертировать стиль ссылок Excel с буквенными колонками в числовые можно из кода ниже сделать функцию с параметром АдресA1
ДлинаАдресаА1 = СтрДлина(АдресА1);
Для с=1 По ДлинаАдресаА1 Цикл
ТекСимвол = Сред(АдресА1,с,1);
Если Найти("0123456789", ТекСимвол) > 0 Тогда //начался номер строки
БуквИндексКолонки = Лев(АдресА1, с-1);
ДлинаИндекса = СтрДлина(БуквИндексКолонки);
НомерКолонкиЧислом = 0;
Для с = 1 По ДлинаИндекса Цикл
ТекСимв = Сред(БуквИндексКолонки, с, 1);
ИндексБуквы = Найти(ВРег("abcdefghijklmnopqrstuvwxyz"), ВРег(ТекСимв));
НомерКолонкиЧислом = НомерКолонкиЧислом * 26 + ИндексБуквы;
КонецЦикла;
НомерСтроки = Прав(АдресА1, ДлинаАдресаА1 - с + 1);
НомерСтрокиЧислом = Число(НомерСтроки);
Прервать;
КонецЕсли;
КонецЦикла;
АдресR1C1 = "R" + НомерСтрокиЧислом + "C" + НомерКолонкиЧислом;
В заключении
В некоторых примерах параметрами в методы Excel передаются числа. Это происходит из-за того, что 1С не знает о константах Excel, например «xlCellTypeLastCell». Но к счастью эти константы имеют числовые значения. Чтобы узнать их откройте справку excel. Если справка не установлена, то можно посмотреть значение в режиме отладки Excel.
Недостаточно прав для комментирования
Примеры функций для работы Excel
// Функция получает данные из файла Excel // // Параметры: // пФайл - Имя файла // пЛист - Имя листа с данными // СтруктураКолонок - Структура вида "ИмяКолонки" - "НомерКолонки" // если не задано, созадуться колонки вида "К1", "К2" // // Возвращаемое значение: // ТаблицаЗначений // Функция Excel_ПолучитьДанные_ADO(пФайл, пЛист, СтруктураКолонок = Неопределено, Знач НачСтрока = 0, Знач КонСтрока = 0) Экспорт #Если Клиент Тогда Состояние("Установка соединения с Excel"); #КонецЕсли //ЗаголовкиВСтроке1 = "HDR=YES;" ЗаголовкиВСтроке1 = "HDR=NO;"; СтрокаСоединения ="Provider=Microsoft.Jet.OLEDB.4.0;Data Source= " + СокрЛП(пФайл) +" ;Extended Properties=""Excel 8.0;" +ЗаголовкиВСтроке1 + "IMEX=1;"""; Connection = Новый COMОбъект("ADODB.Connection"); Connection.ConnectionString = СтрокаСоединения; Попытка Connection.Open(); Исключение Сообщить ("Проблемы с подключением к Excel" ); Возврат Неопределено; КонецПопытки; RS = Новый COMОбъект("ADODB.Recordset"); ТекстЗапроса = "SELECT | Лист.* |FROM | [" + пЛист + "$] as Лист"; Попытка RS.Open(ТекстЗапроса, Connection); Исключение Сообщить ("Проблемы с выполнением запроса"); Возврат Неопределено; КонецПопытки; Таблица = Новый ТаблицаЗначений; Если СтруктураКолонок = Неопределено Тогда Для Счетчик = 1 По RS.Fields.Count Цикл Поле = RS.Fields.Item(Счетчик - 1); Колонка = Таблица.Колонки.Добавить("К" + Счетчик, , Поле.Name); КонецЦикла; Иначе Для каждого КлючИЗначение Из СтруктураКолонок Цикл Колонка = Таблица.Колонки.Добавить(КлючИЗначение.Ключ); КонецЦикла; КонецЕсли; НомерСтроки = 0; КолвоСтрок = RS.RecordCount; Пока RS.EOF() = 0 Цикл НомерСтроки = НомерСтроки + 1; #Если Клиент Тогда Состояние("Чтение файла: " + Формат(НомерСтроки) + " из " + Формат(КолвоСтрок)); ОбработкаПрерыванияПользователя(); #КонецЕсли Если НомерСтроки < НачСтрока Тогда RS.MoveNext(); Продолжить; КонецЕсли; Если КонСтрока > 0 И НомерСтроки > КонСтрока Тогда Прервать; КонецЕсли; НоваяСтрока = Таблица.Добавить(); Если СтруктураКолонок = Неопределено Тогда Для Счетчик = 1 По RS.Fields.Count Цикл Поле = RS.Fields.Item(Счетчик - 1); НоваяСтрока["К" + Счетчик] = Поле.Value; КонецЦикла; Иначе Для каждого КлючИЗначение Из СтруктураКолонок Цикл Поле = RS.Fields.Item(КлючИЗначение.Значение - 1); НоваяСтрока[КлючИЗначение.Ключ] = Поле.Value; КонецЦикла; КонецЕсли; // Обработка других полей RS.MoveNext(); КонецЦикла; // Завершение работы RS.Close(); Connection.Close(); Возврат Таблица; КонецФункции // Функция получает данные из файла Excel // // Параметры: // пФайл - Имя файла // пЛист - Имя листа с данными // СтруктураКолонок - Структура вида "ИмяКолонки" - "НомерКолонки" // если не задано, созадуться колонки вида "К1", "К2" // XLSОбъект - COM объект типа "Excel.Application" // // Возвращаемое значение: // ТаблицаЗначений // Функция Excel_ПолучитьДанные_COM(пФайл, пЛист, СтруктураКолонок = Неопределено, Знач НачСтрока = 0, Знач КонСтрока = 0, XLSОбъект = Неопределено) Экспорт #Если Клиент Тогда Состояние("Открытие Excel"); #КонецЕсли Если XLSОбъект = Неопределено Тогда XLSОбъект = Новый COMОбъект("Excel.Application"); XLSОбъект.Visible = Ложь; XLSОбъект.DisplayAlerts = Ложь; КонецЕсли; Попытка Book = XLSОбъект.Workbooks.Open(пФайл, , Истина); Исключение Сообщить ("Проблемы с подключением к Excel" ); Возврат Неопределено; КонецПопытки; Лист = Book.Sheets(1); КолвоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; КолвоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; Таблица = Новый ТаблицаЗначений; Если СтруктураКолонок = Неопределено Тогда Для Счетчик = 1 По КолвоКолонок Цикл Колонка = Таблица.Колонки.Добавить("К" + Счетчик); КонецЦикла; Иначе Для каждого КлючИЗначение Из СтруктураКолонок Цикл Колонка = Таблица.Колонки.Добавить(КлючИЗначение.Ключ); КонецЦикла; КонецЕсли; НачСтрока = ?(НачСтрока = 0, 1, НачСтрока); КонСтрока = ?(КонСтрока = 0, КолвоСтрок, КонСтрока); КонСтрока = Мин(КонСтрока, КолвоСтрок); Для НомерСтроки = НачСтрока По КонСтрока Цикл #Если Клиент Тогда Состояние("Чтение файла: " + Формат(НомерСтроки) + " из " + Формат(КонСтрока)); ОбработкаПрерыванияПользователя(); #КонецЕсли НоваяСтрока = Таблица.Добавить(); Если СтруктураКолонок = Неопределено Тогда Для НомерКолонки = 1 По КолвоКолонок Цикл Поле = Лист.Cells(НомерСтроки, НомерКолонки); НоваяСтрока["К" + Формат(НомерКолонки, "ЧГ=0")] = Поле.Value; КонецЦикла; Иначе Для каждого КлючИЗначение Из СтруктураКолонок Цикл Поле = Лист.Cells(НомерСтроки, КлючИЗначение.Значение); НоваяСтрока[КлючИЗначение.Ключ] = Поле.Value; КонецЦикла; КонецЕсли; КонецЦикла; XLSОбъект.Application.Quit(); Возврат Таблица; КонецФункции // Функция получает данные из файла Excel // // Параметры: // пФайл - Имя файла // пЛист - Имя листа с данными // СтруктураКолонок - Структура вида "ИмяКолонки" - "НомерКолонки" // если не задано, созадуться колонки вида "К1", "К2" // XLSОбъект - COM объект типа "Excel.Application" // // Возвращаемое значение: // ТаблицаЗначений // Функция Excel_ПолучитьДанные_COMArray(пФайл, пЛист, СтруктураКолонок = Неопределено, Знач НачСтрока = 0, Знач КонСтрока = 0, XLSОбъект = Неопределено) Экспорт #Если Клиент Тогда Состояние("Открытие Excel"); #КонецЕсли Если XLSОбъект = Неопределено Тогда XLSОбъект = Новый COMОбъект("Excel.Application"); XLSОбъект.Visible = Ложь; XLSОбъект.DisplayAlerts = Ложь; КонецЕсли; Попытка Book = XLSОбъект.Workbooks.Open(пФайл, , Истина); Исключение Сообщить ("Проблемы с подключением к Excel" ); Возврат Неопределено; КонецПопытки; Лист = Book.Sheets(1); КолвоКолонок = Лист.Cells(1,1).SpecialCells(11).Column; КолвоСтрок = Лист.Cells(1,1).SpecialCells(11).Row; Таблица = Новый ТаблицаЗначений; Если СтруктураКолонок = Неопределено Тогда Для Счетчик = 1 По КолвоКолонок Цикл Колонка = Таблица.Колонки.Добавить("К" + Счетчик); КонецЦикла; Иначе МаксимальныйНомерКолонки = 0; Для каждого КлючИЗначение Из СтруктураКолонок Цикл Колонка = Таблица.Колонки.Добавить(КлючИЗначение.Ключ); МаксимальныйНомерКолонки = Макс(МаксимальныйНомерКолонки, КлючИЗначение.Значение); КонецЦикла; КолвоКолонок = Мин(КолвоКолонок, МаксимальныйНомерКолонки); КонецЕсли; НачСтрока = ?(НачСтрока = 0, 1, НачСтрока); КонСтрока = ?(КонСтрока = 0, КолвоСтрок, КонСтрока); КонСтрока = Мин(КонСтрока, КолвоСтрок); // Массив типа COMSafeArray Массив = Лист.Range(Лист.Cells(НачСтрока, 1), Лист.Cells(КонСтрока, КолвоКолонок)).Value; КолвоСтрок = Массив.GetUpperBound(1); Для НомерСтроки = 1 По КолвоСтрок Цикл #Если Клиент Тогда Состояние("Чтение файла: " + Формат(НомерСтроки) + " из " + Формат(КолвоСтрок)); ОбработкаПрерыванияПользователя(); #КонецЕсли НоваяСтрока = Таблица.Добавить(); Если СтруктураКолонок = Неопределено Тогда Для НомерКолонки = 1 По КолвоКолонок Цикл НоваяСтрока["К" + Формат(НомерКолонки, "ЧГ=0")] = Массив.GetValue(НомерКолонки, НомерСтроки); КонецЦикла; Иначе Для каждого КлючИЗначение Из СтруктураКолонок Цикл НоваяСтрока[КлючИЗначение.Ключ] = Массив.GetValue(КлючИЗначение.Значение, НомерСтроки); КонецЦикла; КонецЕсли; КонецЦикла; XLSОбъект.Application.Quit(); Возврат Таблица; КонецФункции // Функция получает список листов Excel // // Параметры: // пФайл - Имя файла // XLSОбъект - COM объект типа "Excel.Application" // // Возвращаемое значение: // СписокЗначений // Функция Excel_ПолучитьСписокЛистов(пФайл, XLSОбъект = Неопределено) Экспорт Если XLSОбъект = Неопределено Тогда XLSОбъект = Новый COMОбъект("Excel.Application"); XLSОбъект.Visible = Ложь; XLSОбъект.DisplayAlerts = Ложь; КонецЕсли; Попытка Book = XLSОбъект.Workbooks.Open(пФайл, , Истина); Исключение Возврат Новый СписокЗначений; КонецПопытки; СписокЛистов = Новый СписокЗначений; Для каждого Лист Из XLSОбъект.Sheets Цикл СписокЛистов.Добавить(Лист.Name); КонецЦикла; XLSОбъект.Application.Quit(); Возврат СписокЛистов; КонецФункции
Блог об 1с и Битрикс для пользователей и программистов
СПОСОБ ПОИСКА НАИМЕНОВАНИЙ СВОЙСТВ И МЕТОДОВ VBA EXCEL С ПОМОЩЬЮ ЗАПИСИ МАКРОСОВ
На практике часто случается, что нужно решить какую-либо задачу, иногда довольно тривиальную с точки зрения пользователя Excel (к примеру изменить фон ячейки в Excel, добавить левую границу и т.д.), а решение в сети/документации искать не хочется или не получается, тогда можно попробовать начать запись макроса, выполнить нужную последовательность действий (изменить фон, добавить границу) , после чего записать макрос и открыть код VBA для анализа кода, названий свойств и методов. Такой способ довольно часто помогает быстро решить проблему.
1. Подключение к Excel
Попытка Excel = Новый COMОбъект("Excel.Application"); Исключение Сообщить(ОписаниеОшибки() + "Возможно программа Exсel не установлена на данном компьютере!"); Возврат Ложь; КонецПопытки; //Создание книги Книга = Excel.WorkBooks.Add(); //Открытие существующей книги Книга = Excel.WorkBooks.Open(ПутьКФайлу); //Выбор рабочего листа по номеру Лист = WorkBook.WorkSheets(НомерЛиста); //Выбор рабочего листа по имени Лист = WorkBook.WorkSheets(ИмяЛиста); //Сохранение книги Попытка Книга.SaveAs(ПутьКФайлу); Книга.Close(); Excel.Quit(); Исключение Книга.Close(); Excel.Quit(); КонецПопытки;
При подключении к Excel не забываем закрывать приложение после работы дабы не наплодить кучу ненужных процессов. Они также могут появиться если во время выполнения модуля выскочит ошибка до того как система дойдет до строк, где происходит закрытие Excel.
2. Запись значения в ячейку
ТекущийЛист.Cells(i, j).Value = «2»;
Количество листов книги
КоличествоЛистов = Книга.Sheets.Count;
3. Шрифт и размер шрифта
//Выделение области
Excel.Columns(«A:H»).Select();//Размер шрифта
Лист.Cells.Font.Size = 12;//Тип шрифта
Лист.Cells.Font.Name = «Calibri»;//1 — жирный шрифт, 0 — обычный.
Лист.Cells.Font.Bold = 1;//1 — наклонный шрифт, 0 — обычный.
Лист.Cells.Font.Italic = 1;//2 — подчеркнутый, 1 — нет.
Лист.Cells.Font.Underline = 1;
Как указать цвет шрифта в ячейке, цвет рамки, цвет фона
Книга.Sheets(1).Cells(1,1).Borders.Color = 25525124; // цвет рамки Книга.Sheets(1).Cells(1,1).Font.Color = 255000000; // цвет шрифта Книга.Sheets(1).Cells(1,1).Interior.Color = 255045; // цвет фона
4. Ширина колонки
Чтобы скрыть колонку, нужно установить ширину в значение 0.
Лист.Columns(НомерКолонки).ColumnWidth = Ширина;
Получение последней ячейки в используемом диапазоне
Например, при открытии таблицы нам нужно узнать до какой строки и/или до какого столбца присутствуют заполненные ячейки.
ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
4. Установка фильтра
Лист.Cells.AutoFilter();
5. Горизонтальное выравнивание ячейки
ТекущийЛист.Cells(i, j).HorizontalAlignment = -4130;
Режим выравнивания
|
Константа в Excel
|
Значение в ISBL
|
По центру
|
xlHAlignCenter
|
-4108
|
По центру выделения
|
xlHAlignCenterAcrossSelection
|
7
|
Распределенное
|
xlHAlignDistributed
|
-4117
|
С заполнением
|
xlHAlignFill
|
5
|
По значению
|
xlHAlignGeneral
|
1
|
По ширине
|
xlHAlignJustify
|
-4130
|
По левому краю
|
xlHAlignLeft
|
-4131
|
По правому краю
|
xlHAlignRight
|
-4152
|
6. Вертикальное выравнивание ячейки
ТекущийЛист.Cells(i, j).VerticalAlignment = -4130;
Режим выравнивания
|
Константа в Excel
|
Значение в ISBL
|
По нижнему краю
|
xlVAlignBottom
|
-4107
|
По центру
|
xlVAlignCenter
|
-4108
|
Распределенное
|
xlVAlignDistributed
|
-4117
|
По высоте
|
xlVAlignJustify
|
-4130
|
По верхнему краю
|
xlVAlignTop
|
-4160
|
7. Установка свойства ячейки «переносить по словам»
ТекущийЛист.Cells(i, j).WrapText = True;
8. Отключение/включение режима показа предупреждений
ExcelApp.DisplayAlerts = False; // отключение
ExcelApp.DisplayAlerts = True; // включение
9. Формулы
ТекущийЛист.Cells(i, j).Formula = «SUM(A1:A10)»;
Для формул с русскими названиями нужно использовать не Formula, а FormulaLocal. Таким образом правильными вариантами написания формул будут:
ТекущийЛист.Cells(i, j).FormulaLocal = «Сумм(A1:A10)»;
10. Таблица цветов с индексами
//Установка цвета текста ячейки
ТекущийЛист.Cells(i, j).Font.ColorIndex = 8;//Установка цвета фона ячейки
ТекущийЛист.Cells(i, j).Interior.Color = 49;//Установка цвета рамки
ТекущийЛист.Cells(i, j).Borders.Color = 8;
11. Установка границы ячейки и тип линии границы
Значения константы XlBordersIndex
Тип линии
|
Значение в Excel
|
Значение в ISBL
|
Нет линии
|
xlLineStyleNone
|
0
|
Непрерывная
|
xlContinuous
|
1
|
В виде тире и точек
|
xlDashDot
|
4
|
В виде тире и двойных точек
|
xlDashDotDot
|
5
|
В виде точек
|
xlDot
|
8
|
В виде двойной линии
|
xlDouble
|
9
|
В виде наклонной пунктирной
|
xlSlantDashDot
|
13
|
Свойство LineStyle (тип линии) может принимать следующие значения
Расположение линии
|
Значение в Excel
|
Значение в ISBL
|
Линия по диагонали сверху – вниз
|
xlDiagonalDown
|
5
|
Линия по диагонали снизу – вверх
|
xlDiagonalUp
|
6
|
Линия, обрамляющая диапазон слева
|
xlEdgeLeft
|
7
|
Линия, обрамляющая диапазон сверху
|
xlEdgeTop
|
8
|
Линия, обрамляющая диапазон снизу
|
xlEdgeBottom
|
9
|
Линия, обрамляющая диапазон справа
|
xlEdgeRight
|
10
|
Все вертикальные линии внутри диапазона
|
xlInsideVertical
|
11
|
Все горизонтальные линии внутри диапазона
|
xlInsideHorizontal
|
12
|
Получение порядкового номера колонки Excel по буквенному обозначению имени
Однажды столкнулся с тем, что нужно было получить буквенное обозначение колонки Excel по её порядковому номеру. Например, для колонки номер 3 буквенное обозначение равно «C». Так вот ниже приведены две замечательные функции, которые вполне справляются с решением данной проблемы.
// Функция - Имя колонки Excel в номер // // Параметры: // тИмяКолонки - строка - буквенное обозначение колонки Excel (Пример: A, AB, AAC и т.д.) // // Возвращаемое значение: // - число, порядковый номер колонки // Функция ExcelColumnNameToNumber(тИмяКолонки) тЛатАлфавит = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; тДлинаНомера = СтрДлина(тИмяКолонки); тНомерКолонки = 0; Для тСчет = 1 По тДлинаНомера Цикл тПоз = Найти(тЛатАлфавит, Сред(тИмяКолонки, (тДлинаНомера + 1 - тСчет), 1)); тНомерКолонки = тНомерКолонки + тПоз * Pow(26, тСчет - 1); КонецЦикла; Возврат тНомерКолонки; КонецФункции
Наоборот, получение буквенного обозначения имени колонки по номеру колонки
// Функция - Номер колонки Excel в буквенное обозначение // // Параметры: // тНомерКолонки - число - порядковый номер колонки // // Возвращаемое значение: // - строка, буквенное обозначение колонки // Функция NumberToExcelColumnName(Знач тНомерКолонки) тЛатАлфавит = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; тИмяКолонки = ""; Пока тНомерКолонки > 0 Цикл тОстаток = (тНомерКолонки - 1)%26; тБуква = Сред(тЛатАлфавит, тОстаток + 1, 1); тИмяКолонки = тБуква + тИмяКолонки; тНомерКолонки = Цел((тНомерКолонки - тОстаток)/26); КонецЦикла; Возврат тИмяКолонки; КонецФункции
Часто используемые методы 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
Лист можно выбрать по имени листа в книге:
Лист = Книга.WorkSheets(ИмяЛиста);
Имя листа в книге можно получить по номеру:
ИмяЛиста = Книга.Sheets(НомерЛиста).Name;
Точно так же можно задать имя листа:
Книга.Sheets(6).Name = «6 Резерв на отпуск»;
Итак, мы открыли книгу и выбрали лист, теперь посмотрим, сколько строк и колонок на выбранном листе:
ВсегоКолонок = Лист.Cells(1,1).SpecialCells(11).Column;
ВсегоСтрок = Лист.Cells(1,1).SpecialCells(11).Row;
Хитрости Excel
Как выборочно разрешить / запретить редактирование ячеек листа
//Создаем объект EXCEL Эксель = СоздатьОбъект("Excel.Application"); Книга = Эксель.WorkBooks.Open(ФайлВыгрузки); Лист =Книга.Worksheets("Список сотрудников"); // Выбор листа Книга.ActiveSheet.UnProtect(); //делаем шаблон незащищенным // Заполняем лист // ................................... // Снимаем защиту с области ввода сумм Для Перем = 1 По 10 Цикл // Прописываем, какие ячейки будут доступными Книга.ActiveSheet.Cells(Перем, 2).Locked=0; КонецЦикла; Книга.ActiveSheet.Protect(); // ставим защиту на лист
Как добавить лист 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 в 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»);
Смотрите также:
Электронный учебник по программированию в 1С
Рекомендации по изучению программирования 1С с нуля
Игра «Кто хочет стать миллионером?» с вопросами на определенную тематику (язык программирования JavaScript, английские, немецкие, французские, испанские, португальские, нидерландские, итальянские слова, электробезопасность, промышленная безопасность, бокс и т.п.), написанная на 1С
Программирование в 1С 8.3 с нуля — краткий самоучитель
Комплексная подготовка программистов 1С:Предприятие 8.2
Сайты с уроками программирования и со справочниками
Youtube-каналы с уроками программирования
Сайты для обучения программированию
Лекции и уроки
Загрузка данных из табличных документов, созданных в редакторе Microsoft Excel – довольно часто встречающаяся задача в работе любого программиста 1С. Программа эта широко распространена, любима пользователями и часто используется для хранения и обработки различного рода информации, будь то прайс-лист или данные по продажам за период.
Существует несколько различных методов работы с файлами Excel при загрузке данных в 1С, в том числе:
1. загрузка с помощью свойства Cells;
2. загрузка с помощью метода Range и последующим обращением к данным через метод GetValue();
3. загрузка с помощью метода Range и последующим обращением к данным через свойство Value;
4. загрузка с помощью технологии ADO [2] и использованием компоненты GameWithFire [3].
Рассмотрим вышеперечисленные методы подробнее.
1. Загрузка данных с помощью свойства Cells
Этот метод используется в обработке «ЗагрузкаДанныхИзТабличногоДокумента.epf», которая присутствует на диске ИТС, и основан он на обращении к объекту Excel.Application через технологию COM с последующим последовательным чтением данных в ячейках обращением к свойству Cells.
Значение = ExcelЛист.Cells(Row,Column).Text;
Собственно, здесь все достаточно просто:
а) подключаемся к Excel
Попытка
Excel = Новый COMОбъект("Excel.Application");
Excel.WorkBooks.Open(ИмяФайла);
ExcelЛист = Excel.Sheets(1);
Исключение
Сообщить("Ошибка. Возможно, неверно указан номер листа книги Excel.");
Возврат Неопределено;
КонецПопытки;
б) получаем диапазон данных на листе:
ActiveCell = Excel.ActiveCell.SpecialCells(11);
RowCount = ActiveCell.Row;
ColumnCount = ActiveCell.Column;
в) последовательно считываем данные из файла:
Для Row = 1 По RowCount-1 Цикл
Для Column = 0 По ColumnCount-1 Цикл
Значение = Я.item(Row,Column+1).Value;
// здесь код, который использует данное значение
КонецЦикла;
КонецЦикла;
Несомненно, такой способ гарантирует получение всех данных, содержащихся на листе Excel, однако он имеет весьма существенный недостаток – большую длительность работы при загрузке файлов больших объемов.
2. Загрузка данных с помощью метода Range и последующим обращением к данным через метод GetValue()
Этот метод так же основан на возможностях объекта Excel.Application, но, в отличие от загрузки с использованием свойства Cells, позволяет получить сразу все значения в виде двумерного массива. Работает следующим образом:
а) подключаемся к Excel (аналогично методу 1);
б) определяем диапазон используемых ячеек (аналогично методу 1)
в) считываем данные с помощью метода Range(начальнаяЯчейка, конечнаяЯчейка). Здесь начальная и конечная ячейки – это элементы свойства Cells, о котором шла речь выше.
Диапазон = ExcelЛист.Range(Я.item(1,1), Я.item(RowCount,ColumnCount)).Value;
В результате, в переменной Диапазон мы получим значение типа COMSafeArray, который представляет собой объектную оболочку над многомерным массивом SAFEARRAY. Иначе говоря, мы получаем массив, который, как известно, является областью памяти. А с областью в оперативной памяти работа всегда быстрее.
При этом надо учитывать, что массив этот многомерный. Для нашего случая это будет двумерный массив.
г) последовательно получаем значения из массива с помощью метода GetValue(столбец, строка)
Для Row = 1 По RowCount-1 Цикл
Для Column = 0 По ColumnCount-1 Цикл
Значение = Диапазон.getValue(Column+1, Row);
// здесь код, который использует данное значение
КонецЦикла;
КонецЦикла;
Данный метод работает значительно быстрее, чем чтение с помощью свойства Cells.
3. Загрузка данных с помощью метода Range и последующим обращением к данным через свойство Value
Этот метод отличается от предыдущего только тем, что вместо работы с объектом типа COMSafeArray мы сразу получаем набор значений в виде стандартного массива 1С (тип Массив).
Также, в приведенном листинге вместо метода Range используется свойство UsedRange, которое, по сути, идентично значению, возвращаемому методом Range для всей используемой области листа (это свойство не годится, если нужно прочитать только какую-то часть ячеек, в отличие от метода Range).
а) подключаемся к Excel (как и в предыдущих случаях)
б) считываем данные используя свойство UsedRange и метод Выгрузить()
Данные = ExcelЛист.UsedRange.Value.Выгрузить();
В результате, получаем двумерный массив типа Массив
в) последовательно получаем значения из массива
Для Row = 1 По RowCount-1 Цикл
Для Column = 0 По ColumnCount-1 Цикл
Значение = Данные[Column], [Row];
// здесь код, который использует данное значение
КонецЦикла;
КонецЦикла;
Еще одним преимуществом данного метода является то, что каждый элемент массива Данные представляет собой массив, содержащий значение одной колонки считанного файла. Тем самым, мы можем сразу получить все возможные значения определенной колонки в виде массива, просто обратившись к соответствующему элементу переменной Данные.
4. Загрузка данных с помощью технологии ADO и использованием компоненты GameWithFire
Данный способ использует технологию ADO [2], которая реализуется с помощью библиотеки ADOdb [4] и позволяет получать доступ к любым СУБД, реализующим технологию ODBC. Собственно, Excel попадает в данный список и, следовательно, мы можем получить данные, используя указанную технологию.
Также, для указанного метода используется компонента с оригинальным названием GameWithFire, которая перекладывает результат запроса через ADO в привычную таблицу значений.
Ниже приведен листинг части кода, который демонстрирует данную возможность. Пример во многом использует материал, описанный в источнике [1].
Запрос = "SEL ECT * FR OM [Лист1$]";
Попытка
ПодключитьВнешнююКомпоненту("GameWithFire.ADOUtils");
Исключение
ОбщегоНазначенияКлиентСервер.СообщитьПользователю("Компонента GameWithFire не подключена!");
КонецПопытки;
ADOUtils = Новый ("AddIn.ADOUtils");
Connection = Новый COMОбъект("ADODB.Connection");
СтрокаПодключения="Provider=Microsoft.Jet.OLEDB.4.0; Data Source = "+ИмяФайла;
СтрокаПодключения=СтрокаПодключения+"; Extended Properties = "+"""Excel 8.0"+";HDR=NO;IMEX=1"";";
Попытка
Connection.Open(СтрокаПодключения);
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Command =Новый COMОбъект("ADODB.Command");
//Создание объекта набора записей
RecordSet =Новый COMОбъект("ADODB.RecordSet");
//Указание активного соединения
Command.ActiveConnection = Connection;
//передает текст запроса
Command.CommandText = Запрос;
//определение типа команды
Command.CommandType =1;
//Выполнение и получение набора данных
RecordSet = Command.Execute();
ТЗ = ADOUtils.ADORecordsetToValueTable(Recordset);
// После того, как набор записей уже не нужен, его нужно закрыть
RecordSet.Close();
Connection.Close();
В результате, получаем таблицу значений ТЗ, которую можем обойти любым известным образом.
Заключение
В заключение, мы хотели бы привести таблицу сравнения скорости работы вышеописанных методов и рекомендации для использования.
Замеры производились на файле Excel с числом строк 16 000 и числом колонок 20. Таким образом, общее число ячеек в области составило 320 000. Значения в таблице говорят сами за себя.
Таблица 1. Время загрузки данных из Excel в 1С при использовании различных методов
Метод загрузки |
Длительность, с |
---|---|
С помощью Cells |
996 |
С помощью Range() и GetValue() |
38 |
С помощью Range() и свойство Value |
32 |
С помощью ADO |
3,3 |
Рекомендации по использованию:
1. Чтение с помощью Cells – когда нужно прочитать значения конкретных ячеек или небольших, несмежных областей.
2. Чтение с помощью Range – всегда, кроме случаев с очень большими файлами (сотни тысяч строк), так как в этом случае не нужно ничего, кроме Excel.
3. В случае, когда файлы очень большие, либо требуется особая выборка (связано это с тем, что технология ADO позволяет выполнять запрос на языке SQL к СУБД, а это весьма расширяет круг задач), так как требуется дополнительная компонента, да и строка соединения будет зависеть от версии используемого ПО.
You have no rights to post comments