+4
Процедура сохраняет табличный документ в файл excel и открывает его
Код 1C v 8.х
Процедура ОткрытьТабличныйДокументВExcel(ТабДокумент,ИмяФайла) Экспорт
ИмяФайла = Строка(ИмяФайла) + ".xls";
Каталог = КаталогВременныхФайлов();
ПолныйПутьКФайлу = Каталог + ИмяФайла;
Попытка
ТабДокумент.Записать(ПолныйПутьКФайлу,ТипФайлаТабличногоДокумента.XLS);
Сообщить("Записан новый файл " + ПолныйПутьКФайлу);
ЗапуститьПриложение(ПолныйПутьКФайлу);
Исключение
СообщитьОбОшибке(ОписаниеОшибки());
КонецПопытки;
КонецПроцедуры
Сохранение табличной части в ексель программно. |
Я |
01.08.13 — 14:26
Добрый день!
В документе есть табличная часть и есть кнопочка «сохранить».
Подскажите пожалуйста синтаксис для того чтобы при нажатии на эту кнопку программа предложила выбрать директорию на жестком диске и записала туда эту табличную часть в формате ексель.
Заранее спасибо!
1 — 01.08.13 — 14:27
точный синтаксис не подскажу, но каждая инструкция должная завершаться символом «;»
2 — 01.08.13 — 14:28
(1) и правда кэп
3 — 01.08.13 — 14:29
(1) +1
4 — 01.08.13 — 15:06
Ну хоть примерно.
5 — 01.08.13 — 15:33
6 — 01.08.13 — 15:51
Режим = РежимДиалогаВыбораФайла.Сохранение;
Диалог = Новый ДиалогВыбораФайла(Режим);
Диалог.Заголовок = «Выбор файла для сохранения»;
Диалог.Фильтр = «Excel (*.xls)|*.xls»;
Если Не Диалог.Выбрать() Тогда
Возврат ;
Иначе
ИмяФайла= Диалог.ПолноеИмяФайла;
КонецЕсли
Как теперь мне сохранить в этот выбранный файл мою таблицу «ЭтотОбъект.Выгрузка» ?
7 — 01.08.13 — 15:54
Почему то даже пустой файл не создается
8 — 01.08.13 — 15:59
(7) всё правильно, записи в файл нет, значит, файл не создаётся
9 — 01.08.13 — 16:00
(6) предлагаю вывести что-нибудь как-нибудь в ТабДок и записать его
10 — 01.08.13 — 16:56
Вообщем получил я ТабДок, а как мне дальше его записать на диск в файл?
ТабДок = моя таблица «Выгрузка»
11 — 01.08.13 — 16:56
(10) ты не поверишь..
12 — 01.08.13 — 17:00
ТабДок.Записать(<ИмяФайла>, <ТипФайлаТаблицы>)
какие сюда параметры нужны?
13 — 01.08.13 — 17:01
(12) <ИмяФайла>, <ТипФайлаТаблицы>
14 — 01.08.13 — 17:04
А по подробнее нельзя?
15 — 01.08.13 — 17:06
(14) ты ж откуда скопипастил? попобней, чем там, вряд ли выйдет
16 — 01.08.13 — 17:07
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет(«Макет»);
облСтрока = Макет.ПолучитьОбласть(«Строка»);
Для каждого стр Из ЭтотОбъект.Выгрузка Цикл
облСтрока.Параметры.Дата = стр.Дата;
облСтрока.Параметры.Номер = стр.Номер;
облСтрока.Параметры.КомпанияИНН = стр.КомпанияИНН;
облСтрока.Параметры.КомпанияНазвание = стр.КомпанияНазвание;
облСтрока.Параметры.СрокОплаты = стр.СрокОплаты;
облСтрока.Параметры.Сумма = стр.Сумма;
ТабДок.Вывести(облСтрока);
КонецЦикла;
ТабДок.Записать(«D:Клиентские базыScheta_postavschikov.xls»,»xls»);
//ТабДок.Показать();
Сделал так,файл записался как надо, как теперь сделать так чтобы путь зашивался не на програмном уровне? чтобы файлик пользователь мог выбирать?
17 — 01.08.13 — 17:11
(16) из типовой не судьба выбрать? Например, возьми клиент-банк, там файл выбирается.
18 — 01.08.13 — 17:16
скрести первый кусок кода со вторым и будет тебе щастье
19 — 01.08.13 — 17:19
(18) будет только до тех пор, пока он не попытается открыть этот ексельный документ
20 — 01.08.13 — 17:19
(19) а или вру
21 — 01.08.13 — 17:24
22 — 01.08.13 — 17:25
(19) (20) сохраняется красиво но только в жестко заданную папку.
23 — 01.08.13 — 17:31
(22) плавно возвращаемся в (6)
24 — 01.08.13 — 17:44
Процедура КнопкаВыполнитьНажатие(Кнопка)
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет(«Макет»);
облСтрока = Макет.ПолучитьОбласть(«Строка»);
Для каждого стр Из ЭтотОбъект.Выгрузка Цикл
облСтрока.Параметры.Дата = Формат(стр.Дата, «ДЛФ=Д»);
облСтрока.Параметры.Номер = стр.Номер;
облСтрока.Параметры.КомпанияИНН = стр.КомпанияИНН;
облСтрока.Параметры.КомпанияНазвание = стр.КомпанияНазвание;
облСтрока.Параметры.СрокОплаты = Формат(стр.СрокОплаты, «ДЛФ=Д»);
облСтрока.Параметры.Сумма = стр.Сумма;
ТабДок.Вывести(облСтрока);
КонецЦикла;
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.Фильтр = «Файл Эксель(*.xls)|*.xls»;
Если ДиалогОткрытияФайла.Выбрать() Тогда
ПолеВвода1 = ДиалогОткрытияФайла.ПолноеИмяФайла;
КонецЕсли;
ИмяФайла = ЭтаФорма.ФайлВыгрузки;
ТабДок.Записать(ИмяФайла,»xls»);
//ТабДок.Показать();
КонецПроцедуры
Процедура КоманднаяПанель1Заполнить(Кнопка)
Если ЗначениеЗаполнено(ЭтотОбъект.ДатаНачала) И ЗначениеЗаполнено(ЭтотОбъект.ДатаОкончания) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| СчетНаОплатуПокупателю.Номер,
| СчетНаОплатуПокупателю.Дата,
| СчетНаОплатуПокупателю.Контрагент,
| СчетНаОплатуПокупателю.Контрагент.ИНН КАК ИНН,
| СчетНаОплатуПокупателю.ДоговорКонтрагента.СрокОплаты КАК СрокОплаты,
| СчетНаОплатуПокупателю.СуммаДокумента,
| СчетНаОплатуПокупателю.ДоговорКонтрагента
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
|ГДЕ
| СчетНаОплатуПокупателю.Дата >= &ДатаНачала
| И СчетНаОплатуПокупателю.Дата <= &ДатаОкончания»;
Запрос.УстановитьПараметр(«ДатаНачала», ЭтотОбъект.ДатаНачала);
Запрос.УстановитьПараметр(«ДатаОкончания», ЭтотОбъект.ДатаОкончания);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
ТекстВопроса = «Перед заполнением табличные части будут очищены. Заполнить?»;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да,);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
ЭтотОбъект.Выгрузка.Очистить();
Пока РезультатЗапроса.Следующий() Цикл
ДобавитьЭлементТаблицы = ЭтотОбъект.Выгрузка.Добавить();
ДобавитьЭлементТаблицы.Дата = РезультатЗапроса.Дата;
ДобавитьЭлементТаблицы.Номер = РезультатЗапроса.Номер;
ДобавитьЭлементТаблицы.КомпанияНазвание = РезультатЗапроса.Контрагент;
ДобавитьЭлементТаблицы.КомпанияИНН = РезультатЗапроса.ИНН;
ДобавитьЭлементТаблицы.Сумма = РезультатЗапроса.СуммаДокумента;
Если РезультатЗапроса.ДоговорКонтрагента.Наименование = «» Тогда
Продолжить
Иначе
ДобавитьЭлементТаблицы.СрокОплаты = РезультатЗапроса.Дата + 60*60*24*РезультатЗапроса.СрокОплаты;
КонецЕсли;
КонецЦикла;
Иначе
ТекстВопроса = «Ошибка! Не заполнены поля: дата начала, дата окончания.»;
Вопрос(ТекстВопроса, РежимДиалогаВопрос.Ок, , КодВозвратаДиалога.Ок,);
КонецЕсли;
КонецПроцедуры
Процедура ФайлВыгрузкиНачалоВыбора(Элемент, СтандартнаяОбработка)
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.Фильтр = «Файл Эксель(*.xls)|*.xls»;
Если ДиалогОткрытияФайла.Выбрать() Тогда
ФайлВыгрузки = ДиалогОткрытияФайла.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
вообщем все работает как надо но файл приходится два раза выбирать в поле ввода и при нажатии на кнопку не пойму почему ….
25 — 01.08.13 — 17:46
(24) рассказать? ты дважды просишь юзера сохранить файл
26 — 01.08.13 — 17:46
Где это? в каком фрагменте кода?
27 — 01.08.13 — 17:46
+(25) ну и дважды интерактивно пытаешься это сделать
28 — 01.08.13 — 17:47
А, нашел.
29 — 01.08.13 — 17:47
О чудо! Оно работает!
30 — 01.08.13 — 17:48
Если РезультатЗапроса.ДоговорКонтрагента.Наименование = «» Тогда
Продолжить
хлобысь по рукам!
31 — 01.08.13 — 17:48
а ещё предупреждение имеется у платформы
32 — 01.08.13 — 17:49
(30) а как тут лучше сделать?
33 — 01.08.13 — 17:49
Вообщем вот итоговый вариант
Процедура КнопкаВыполнитьНажатие(Кнопка)
ТабДок = Новый ТабличныйДокумент;
Макет = ПолучитьМакет(«Макет»);
облСтрока = Макет.ПолучитьОбласть(«Строка»);
Для каждого стр Из ЭтотОбъект.Выгрузка Цикл
облСтрока.Параметры.Дата = Формат(стр.Дата, «ДЛФ=Д»);
облСтрока.Параметры.Номер = стр.Номер;
облСтрока.Параметры.КомпанияИНН = стр.КомпанияИНН;
облСтрока.Параметры.КомпанияНазвание = стр.КомпанияНазвание;
облСтрока.Параметры.СрокОплаты = Формат(стр.СрокОплаты, «ДЛФ=Д»);
облСтрока.Параметры.Сумма = стр.Сумма;
ТабДок.Вывести(облСтрока);
КонецЦикла;
ИмяФайла = ЭтаФорма.ФайлВыгрузки;
ТабДок.Записать(ИмяФайла,»xls»);
//ТабДок.Показать();
КонецПроцедуры
Процедура КоманднаяПанель1Заполнить(Кнопка)
Если ЗначениеЗаполнено(ЭтотОбъект.ДатаНачала) И ЗначениеЗаполнено(ЭтотОбъект.ДатаОкончания) Тогда
Запрос = Новый Запрос;
Запрос.Текст =
«ВЫБРАТЬ
| СчетНаОплатуПокупателю.Номер,
| СчетНаОплатуПокупателю.Дата,
| СчетНаОплатуПокупателю.Контрагент,
| СчетНаОплатуПокупателю.Контрагент.ИНН КАК ИНН,
| СчетНаОплатуПокупателю.ДоговорКонтрагента.СрокОплаты КАК СрокОплаты,
| СчетНаОплатуПокупателю.СуммаДокумента,
| СчетНаОплатуПокупателю.ДоговорКонтрагента
|ИЗ
| Документ.СчетНаОплатуПокупателю КАК СчетНаОплатуПокупателю
|ГДЕ
| СчетНаОплатуПокупателю.Дата >= &ДатаНачала
| И СчетНаОплатуПокупателю.Дата <= &ДатаОкончания»;
Запрос.УстановитьПараметр(«ДатаНачала», ЭтотОбъект.ДатаНачала);
Запрос.УстановитьПараметр(«ДатаОкончания», ЭтотОбъект.ДатаОкончания);
РезультатЗапроса = Запрос.Выполнить().Выбрать();
ТекстВопроса = «Перед заполнением табличные части будут очищены. Заполнить?»;
Ответ = Вопрос(ТекстВопроса, РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Да,);
Если Ответ <> КодВозвратаДиалога.Да Тогда
Возврат;
КонецЕсли;
ЭтотОбъект.Выгрузка.Очистить();
Пока РезультатЗапроса.Следующий() Цикл
ДобавитьЭлементТаблицы = ЭтотОбъект.Выгрузка.Добавить();
ДобавитьЭлементТаблицы.Дата = РезультатЗапроса.Дата;
ДобавитьЭлементТаблицы.Номер = РезультатЗапроса.Номер;
ДобавитьЭлементТаблицы.КомпанияНазвание = РезультатЗапроса.Контрагент;
ДобавитьЭлементТаблицы.КомпанияИНН = РезультатЗапроса.ИНН;
ДобавитьЭлементТаблицы.Сумма = РезультатЗапроса.СуммаДокумента;
Если РезультатЗапроса.ДоговорКонтрагента.Наименование = «» Тогда
Продолжить
Иначе
ДобавитьЭлементТаблицы.СрокОплаты = РезультатЗапроса.Дата + 60*60*24*РезультатЗапроса.СрокОплаты;
КонецЕсли;
КонецЦикла;
Иначе
ТекстВопроса = «Ошибка! Не заполнены поля: дата начала, дата окончания.»;
Вопрос(ТекстВопроса, РежимДиалогаВопрос.Ок, , КодВозвратаДиалога.Ок,);
КонецЕсли;
КонецПроцедуры
Процедура ФайлВыгрузкиНачалоВыбора(Элемент, СтандартнаяОбработка)
Режим = РежимДиалогаВыбораФайла.Открытие;
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(Режим);
ДиалогОткрытияФайла.Фильтр = «Файл Эксель(*.xls)|*.xls»;
Если ДиалогОткрытияФайла.Выбрать() Тогда
ФайлВыгрузки = ДиалогОткрытияФайла.ПолноеИмяФайла;
КонецЕсли;
КонецПроцедуры
34 — 01.08.13 — 17:50
(32) запросом сразу вынуть только нужное
35 — 01.08.13 — 17:50
+(34) не ориентируясь на наименование
36 — 01.08.13 — 17:51
Складывать и умножать внутри запроса?
37 — 01.08.13 — 17:51
да и расчет срока оплаты тоже можно в запрос засунуть
38 — 01.08.13 — 17:51
и пустых контрагентов исключить из выборки, кстати почему они пустые?
39 — 01.08.13 — 17:51
(37) согласен. сейчас он будет даты с числами складывать. посмотрим..
40 — 01.08.13 — 17:52
и вообще вставить в цикл ЗаполнитьЗначенияСвойств()
41 — 01.08.13 — 17:53
пофиг пускай так будет, надоели эти буквы уже О_о
42 — 01.08.13 — 17:53
а при установке даты начала и даты окончания навеное следует применить функции НачалоДня() и КонецДня()
43 — 01.08.13 — 17:54
(41) вы не программист?
44 — 01.08.13 — 17:54
А запросом как то можно вытащить внутренний индефикатор объекта?
45 — 01.08.13 — 17:55
(43) начинающий
46 — 01.08.13 — 17:55
+(44) идентификатор
Капитан О
47 — 01.08.13 — 18:02
(44) на зачем? иногда можно
На чтение 9 мин Просмотров 26.4к. Опубликовано 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С сохранить табличный документ в pdf, xlsx, docx, txt, html файл программно
Пример процедуры
&НаСервере Процедура СохранитьВPDFНаСервере() ТабДок = Новый ТабличныйДокумент; Макет = Обработки.ТабличныйДокументСохранитьВPDF.ПолучитьМакет("Макет"); ОбластьМакета = Макет.ПолучитьОбласть("Шапка"); ТабДок.Вывести(ОбластьМакета); МестоположениеФайла = "G:ProverkaZapisiТест.pdf"; ТабДок.Записать(МестоположениеФайла , ТипФайлаТабличногоДокумента.PDF); //Запись в Excel //МестоположениеФайла = "G:ProverkaZapisiТест.XLSX"; //ТабДок.Записать(МестоположениеФайла , ТипФайлаТабличногоДокумента.XLSX); //Запись в Word //МестоположениеФайла = "G:ProverkaZapisiТест.docx"; //ТабДок.Записать(МестоположениеФайла , ТипФайлаТабличногоДокумента.DOCX); //Прочие форматы //ТипФайлаТабличногоДокумента поддерживает множество форматов //html5, mxl, txt, ods, можете поэксперементировать с различными форматами Сообщить("Файл успешно сохранен"); КонецПроцедуры
Обратите внимание, если возникла ошибка (нет доступа для записи в папку, при этом с правами у данного пользователя windows все в порядке) при выполнении строки с кодом «ТабДок.Записать ()». Выполните данную строку кода «&НаКлиенте».
Перед запуском обработки убедитесь, что на вашем компьютере существует директория «G:ProverkaZapisiТест.pdf»
Связанные статьи
Для удобства использования я создам процедуру в общем глобальном модуле.
Для ее вызова нам необходимо знать только название табличного документа, т.е. имя элемета.
Процедура имеет 3 параметра:
ИмяФайла — строка, содержит имя файла. Имя можно поменять в окне сохранения.
ОткрытьФайл — булево, если Истина то будет открывать автоматически сохраненный документ.
ИмяТабДок — сам табличный документ.
Процедура СохраненитьТабличныйДокументВExcel (ИмяФайла, ОткрытьФайл, ИмяТабДок) Экспорт ИмяФайла = ИмяФайла + ".xls"; ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение); ДиалогОткрытияФайла.ПолноеИмяФайла = ИмяФайла; ДиалогОткрытияФайла.Каталог = ПутьКрабочемуСтолу(); ДиалогОткрытияФайла.Фильтр = "Файлы Microsoft Excel (*.xls)|*.xls|Все файлы (*.*)|*.*"; ДиалогОткрытияФайла.МножественныйВыбор = Ложь; Если ДиалогОткрытияФайла.Выбрать() тогда ИмяТабДок.Записать(ДиалогОткрытияФайла.ПолноеИмяФайла,ТипФайлаТабличногоДокумента.XLS); Если ОткрытьФайл = истина тогда ДокExcel = ПолучитьCOMОбъект("", "Excel.Application"); ДокExcel.Workbooks.Open(ДиалогОткрытияФайла.ПолноеИмяФайла); ДокExcel.Visible = 1; КонецЕсли; КонецЕсли; КонецПроцедуры
Пример:
ТабДок = Новый ТабличныйДокумент;
// формируем документ ТабДок.Показать();
// сохраним в файл Отчет.xls не открывая его СохраненитьТабличныйДокументВExcel ("Отчет", Ложь, ТабДок);
Описание
Создали новый диалог (окно) сохранения
ДиалогОткрытияФайла = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Указали имя
ДиалогОткрытияФайла.ПолноеИмяФайла = ИмяФайла;
Указали путь, я использую функцию (ссылка на описание)
ДиалогОткрытияФайла.Каталог = ПутьКрабочемуСтолу();
Создаем фильтр расширений
ДиалогОткрытияФайла.Фильтр = "Файлы Microsoft Excel (*.xls)|*.xls|Все файлы (*.*)|*.*"; ДиалогОткрытияФайла.МножественныйВыбор = Ложь;
Если выбрали путь сохраняем
Если ДиалогОткрытияФайла.Выбрать() тогда ИмяТабДок.Записать(ДиалогОткрытияФайла.ПолноеИмяФайла,ТипФайлаТабличногоДокумента.XLS);
Открываем файл если передано истина
Если ОткрытьФайл = истина тогда ДокExcel = ПолучитьCOMОбъект("", "Excel.Application"); ДокExcel.Workbooks.Open(ДиалогОткрытияФайла.ПолноеИмяФайла); ДокExcel.Visible = 1; КонецЕсли; КонецЕсли; КонецПроцедуры
- Главная
- О сайте
- Главная
- Содержание
Категории
—>
рубрики: Excel | Дата: 15 июня, 2017
Если провести опрос среди программистов 1С на тему «Как сохранить информацию из 1С в файл ексель», то большинство голосов, как мне кажется займет вариант с созданием объекта Excel.Application с последующим заполнением листа с помощью методов и свойств встроенного в Excel языка VBA. Но многие ли из вас помнят вышеупомянутые методы и свойства? А ведь между тем есть способ который позволяет сделать это гораздо проще, только с использованием языка программирования 1С.
Для этого достаточно сформировать ТабличныйДокумент (сделать это можно как с использованием макета табличного документа, так и программно), а потом просто записать его с помощью метода Записать() сразу в файл Excel, благо платформа без проблем позволяет это сделать. Напомню, что синтаксис этого метода выглядит следующим образом
Записать(ИмяФайла, ТипФайлаТаблицы)
ИмяФайла — строка в которой указан путь к файлу;
ТипФайлаТаблицы — тип файла в который мы будем записывать табличный документ.
Платформа 1С предоставляет следующие типы файлов:
- ANSITXT (ANSITXT)
- DOCX (DOCX)
- HTML (HTML)
- HTML3 (HTML3)
- HTML4 (HTML4)
- HTML5 (HTML5)
- MXL (MXL)
- MXL7 (MXL7)
- ODS (ODS)
- PDF (PDF)
- TXT (TXT)
- XLS (XLS)
- XLS95 (XLS95)
- XLS97 (XLS97)
- XLSX (XLSX)
Пример использования
В качестве примера создадим процедуру в которую в качестве параметра будет передаваться таблица значений, которую будем выводить в табличный документ, который в свою очередь будем сохранять в ексель.
Вот код этой процедуры
&НаСервере
Процедура ЗаписатьТаблицуЗначенийВФайлЕксель(Таблица)
ТабДок = Новый ТабличныйДокумент;
КоличествоКолонок = Таблица.Колонки.Количество();
//Формируем строку с заголовками
Для Счетчик = 1 По КоличествоКолонок Цикл
ТекущаяКолонка = Таблица.Колонки[Счетчик - 1];
ТабДок.Область("R1C" + Счетчик).Текст = ТекущаяКолонка.Имя;
КонецЦикла;
//Добавляем строки из таблицы
НомерСтроки = 2;
Для каждого СтрокаТаблицы Из Таблица Цикл
Для НомерКолонки = 1 По КоличествоКолонок Цикл
ТабДок.Область("R" + НомерСтроки + "C" + НомерКолонки).Текст = Строка(СтрокаТаблицы[НомерКолонки - 1]);
КонецЦикла;
НомерСтроки = НомерСтроки + 1;
КонецЦикла;
//Записываем табличный документ в файл Excel
ТабДок.Записать("D:musorTest.xlsx", ТипФайлаТабличногоДокумента.XLSX);
КонецПроцедуры
В общем то все элементарно. Пусть у нас есть вот такая таблица значений:
Товар | Количество |
---|---|
Яблоки | 5 |
Груши | 10 |
После того как прогнал ее через процедуру выше, получил вот такой результат в ексель
Достоинства метода
- Простота. Не требуется знаний VBA. Доступны синтаксический контроль и отладка кода в процессе написания.
- Не требуется наличия установленного Excel.
Недостатки метода
- Если макет достаточно сложный, есть вероятность, что он может сохраниться недостаточно корректно. Плюс могут возникать проблемы с форматом данных.
Для анализа способов записи мы создали обработку, которая записывает файл Excel в двух вариантах. Форма обработки показана ниже:
Обработка выполняет запись 3 строк, в каждой строке 5 значений и одна картинка. Код обработки может выполняться как на клиенте, так и на сервере.
Вы можете скачать обработку и ознакомиться с ее работой по ссылке:
Выгрузка через Табличный документ
Это один из самых простых способов записи в xlsx и xls. В 1С в этом варианте Вы будете работать с объектом ТабличныйДокумент. Ниже показан пример записи в табличный документ, который Вы также можете найти в прилагаемой выше обработке:
&НаКлиенте Процедура ВыполнитьЗаписьЧерезТабличныйДокумент() ТабДок = Новый ТабличныйДокумент; Для СтрокаНомер = 1 По 3 Цикл //Записываем значения строки Для КолонкаНомер = 1 По 5 Цикл Область = ТабДок.Область(СтрокаНомер, КолонкаНомер); Область.Текст = СтрокаНомер * КолонкаНомер; КонецЦикла; //Записываем изображение Область = ТабДок.Область(СтрокаНомер, 6); Область.Картинка = Элементы["Изображение" + СтрокаНомер].Картинка; КонецЦикла; ТипФайла = ТипФайлаТабличногоДокумента.XLSX; //Если запись в формате xls - тип файла ТипФайлаТабличногоДокумента.XLS97 ТабДок.Записать(Каталог + "Тест.xlsx", ТипФайла); КонецПроцедуры
Плюсы данного метода записи:
- Не нужно устанавливать Excel на клиенте/сервере.
- Не нужно реализовывать масштабирование изображений — Вы устанавливаете только ширину/высоту ячейки.
- Высокая скорость записи т.к. не используется прослойка в виде COMОбъекта.
Минусы:
- Нет возможности устанавливать формулы для ячеек.
- Неконтролируемая конвертация табличного документа в документ Excel. Как пример — могут смещаться изображения.
Замер производительности показывает общее время записи 0,28 сек.
Выгрузка через Excel
В этом варианте запись выполняется с помощью COMОбъекта Excel — устанавливаем соединение с Excel, создаем книгу и размещаем данные на ее листах. Обязательно закрываем книгу и соединение!
&НаКлиенте Процедура ВыполнитьЗаписьЧерезExcel() Эксель = Новый COMОбъект("Excel.Application"); Эксель.DisplayAlerts = 0; Эксель.ScreenUpdating = 0; Эксель.EnableEvents = 0; Книга = Эксель.WorkBooks.Add(); Лист = Книга.WorkSheets(1); Для СтрокаНомер = 1 По 3 Цикл //Записываем значения строки Для КолонкаНомер = 1 По 5 Цикл Лист.Cells(СтрокаНомер, КолонкаНомер).Value = СтрокаНомер * КолонкаНомер; КонецЦикла; //Записываем изображение СтрокаКартинка = Элементы["Изображение" + СтрокаНомер].Картинка; ВременныйФайл = ПолучитьИмяВременногоФайла("" + СтрокаКартинка.Формат()); СтрокаКартинка.Записать(ВременныйФайл); ЛистИзображение = Лист.Shapes.AddPicture(ВременныйФайл, Ложь, Истина, Лист.Cells(СтрокаНомер, 6).Left + 1, Лист.Cells(СтрокаНомер, 6).Top + 1, -1, -1); ЛистИзображение.Placement = 1; ЛистИзображение.LockAspectRatio = 0; //Масштабирование изображения ЛистИзображение.Width = 47; ЛистИзображение.Height = 29; Лист.Rows(СтрокаНомер).RowHeight = 33; ЛистИзображение.Height = 29; УдалитьФайлы(ВременныйФайл); КонецЦикла; ТипФайла = 51; //Если запись в формате xls - тип файла -4143 Книга.SaveAs(Каталог + "Тест.xlsx", ТипФайла); Попытка Книга.Close(Ложь); Эксель.DisplayAlerts = 1; Эксель.Quit(); Исключение Информация = ИнформацияОбОшибке(); Сообщить(Информация.Описание); КонецПопытки; КонецПроцедуры
Плюсы данного метода записи:
- Полный контроль над процессом записи.
- Доступ практически ко всем возможностям Excel.
Минусы:
- Нужно устанавливать Excel на клиенте/сервере.
- Нужно реализовывать масштабирование изображений. Алгоритм записи должен позиционировать изображение в ячейке устанавливая ширину и высоту. Также нужно настраивать высоту строки.
- Низкая скорость записи.
Замер производительности показывает общее время записи 0,86 сек. Это в 3 раза медленнее чем запись через Табличный документ. По своему опыту можем отметить — медленнее может быть в 10 и более раз!
Итоги
При выборе варианта выгрузки лучше смотреть на поставленную задачу. Оптимально использовать запись через Табличный документ — многие моменты записи будут упрощены. Можно объединять 2 варианта записи — основу записывать через Табличный документ, а формулы добавлять с использованием Excel. Такая запись будет производительнее чем полная запись через Excel.