Полезные приемы при работе с Excel из 1С (Версия 3.1)






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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

КонецЦикла;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

//Записать значение в ячейку
Лист.Cells(Сч,Сч2).Value =  Данные
Обращение к области ячеек
//В качестве параметров передаем ячейки по диогонали
Лист.Range(ЛистЭксель.Cells(1,1),ЛистЭксель.Cells(ВсегоСтрок,ВсегоКолонок))
Очень часто при чтении или записи значений в Excel ставятся лишние пробелы в числе, например, вместо 1502 он читает как 1 502 и в дальнейшем это значение не приводится к числу. Эту проблему можно решить заменой.
ЗначениеЯчейки = Лист.Cells(1,3).Value;
СтрЗаменить(Строка(ЗначениеЯчейки),Символы.НПП,"");
Объединение ячеек
Лист.Range(Лист.Cells(1,1),Лист.Cells(10,1)).Merge(); 

 
Работа с именованными ячейками в Excel
Обл = Лист.Range("Имя_Ячейки_В_Excel").Select();
Обл.Value = "Присваиваем значение";

 
Удаление ячейки 
Лист.Cells(1,3).Delete();
Удаление области ячеек
Лист.Range(Лист.Cells(1,1),Лист.Cells(10,1)).Delete();
 Обращение к строке
//Сч = Номер строки
Лист.Rows(Сч)
 Изменение ширины колонки
Лист.Columns(НомерКолонки).ColumnWidth = Ширина;
 Обращение к колонке
//Сч = Номер Колонки
Лист.Cols(Сч)
 Удаление Строки
Лист.Rows(Сч).Delete()
 Фон ячейки / области / Строки /  
//Фон Ячейки
Лист.Cells(1,1).Interior.Color = ПолучитьЦветExcelRGB(10,10,10);

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

//Фон строки
Лист.Rows(Сч).Interior.Color = ПолучитьЦветExcelRGB(10,10,10);

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

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

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

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

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

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

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

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

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

 

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2. Работа с Excel ADODB

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

 

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

ADODB.Connection
предназначен для соединения с ADO
Соединение = Новый COMОбъект("ADODB.Connection");

 

  ADOX.Table
для работы с таблицей
// Создаем таблицу и добавляем в неё два столбца
Table = Новый COMОбъект("ADOX.Table");
Table.Name = "Table";
Table.Columns.Append("Code");
Table.Columns.Append("Description");

 

ADODB.Command Для выполнения комманд на языке T-SQL
Комманды = Новый COMОбъект("ADODB.Command");
Комманды.ActiveConnection = Подключение["Соединение"];
Комманды.CommandType = 1;
Комманды.CommandText = ТекстЗапроса;
Комманды.Execute();

 

 ADODB.Recordset

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

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

 

 

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

 

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

 

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

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

62 Comments

  1. Krasnyj

    Дельная подборка. Полезная. Спасибо.

    Reply
  2. Fragster

    Забыто про UsedRange, а также про то, что передача через ComSafeArray работает в обе стороны.

    Reply
  3. Fragster

    Ну и про вариант через ADO с плюшками SQL запросов типа фильтрации, группировок и джоинов данных с разных листов

    Reply
  4. Zerocl

    Спасибо за очень полезные комментарии. В ближайшее время добавлю по работе с Excel через Табличный документ и потом постараюсь осветить ваши темы.

    Reply
  5. roofless

    отлично, добавьте

    Лист.Cells(1, 1).WrapText = 1;

    разрешает переносить по словам в ячейке

    Reply
  6. Zerocl

    (5) roofless, Спасибо большое! Добавил

    Reply
  7. spy-83

    помоему конструкция

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

    на сервере не взлетит. не?

    Reply
  8. roofless

    (7) spy-83, если апликейшен будет на сервере, то взлетит

    Reply
  9. Zerocl

    (3) Fragster, Добавил небольшое описание ADO

    Reply
  10. malets

    Спасибо большое, очень полезная статья!

    Reply
  11. volit

    Спасибо все очень понятно и подробно!

    Reply
  12. rasswet

    опыта работы с именованными ячейками у вас нет?

    если есть может есть смысл добавить сюда в статью?

    Reply
  13. Zerocl

    (12) rasswet, Добавил. Смотрите табличку

    Reply
  14. Shokei

    Спасибо автору ,попробуем

    Reply
  15. skif47

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

    Reply
  16. dwarkin

    Очень хорошая статья, сильно помогла, особенно ссылка на connectionstrings.com. Спасибо большое.

    Для ADO, если система 64 бит, а 1Ска — 32, то надо ставить Microsoft Access Database Engine 2010 Redistributable (16/12/2010) 32 и 64 — разрядные версии.

    В моем случае помогла 32бит версия (система 64бит (Вин 7, Вин2008Ент), 1Ска — 32 бит).

    На Вин7 стоял Офис 2010, но видать какой-то резанный. Все равно пришлось так же ставить Access Database Engine 32 бит.

    Reply
  17. tormozit

    Для редактирования и отладки запросов к ADO можно использовать консоль запросов из подсистемы Инструменты разработчика на обычных формах 8.2.13+. Нужно выбрать тип запроса ADO, для которого будет доступен конструктор запросов (непохожий на штатный), дерево запроса, контекстная подсказка и 1с-ная подсветка синтаксиса.

    Reply
  18. Чародей

    Скачал «Демонстрация работы с Excel через Табличный документ 1С» а он тоже только для управляемых форм ((

    Может дополните описание?

    Reply
  19. Zerocl

    (18) Чародей, Так на алгоритм работы через табличный документ не влияет.

    Я учту и дополню описание. Спасибо.

    Reply
  20. igormiro

    Спасибо за статью.

    Единственное, что я хотел уточнить, для тех кто не знает, где можно скачать ODBC ODBC .

    Reply
  21. babys

    Автор:

    Вот это что за шняга:

    //Сразу отбираем только не пустые номенклатуры

    ТекстЗапроса = «SELECT * FROM [Лист1$] WHERE `Номенклатура`<>»»»»»;

    Вы когда что-то пишите, пытайтесь думать не как 80-ти летний профессор и член-корр АН.

    Reply
  22. Zerocl

    (21) babys, Не пойму суть вашей претензии. Это SQL запрос к Excel он вроде как по Русски не понимает

    Reply
  23. Yashazz

    На самом деле обзорчик не полный. С экселем можно работать ещё множеством разных способов. Можно, если современная версия, xml парсить, а можно SafeArray юзать. Ну и так далее.

    Reply
  24. spy-83

    (8) roofless, а если сервер на линуксе?

    Reply
  25. babys

    (22) слово «Номенклатура» не смущает, в предложении where? Меня очень. Я привык писать

    [F2] <> «»НДФЛ»»
    Reply
  26. Zerocl

    он берет(25) babys, Он берет название из первой строки. Вариант в поле рабочий. Может конечно не привычный но это просто пример 🙂

    Reply
  27. Zerocl

    (24) spy-83, На линуксе я не пробовал, но он там где то же временные файлы хранит

    Reply
  28. Sirruf

    Подскажите, кто знает — как быстро вставить гиперссылки в экселевский файл?

    Через COMОбъект(«Excel.Application») при большом количестве строк, в которые нужно добавить Hyperlinks очень долго работает…

    Reply
  29. Sirruf

    Есть вообще какие-нибудь хорошие библиотеки для работы с файлами в формате xlsx помимо COMОбъект(«Excel.Application»), который использовать вроде как не рекомендует Майкрософт?

    Reply
  30. dr-wit

    Спасибо, отличная статья!

    Еще по группировкам данных на листе, если требуется заполнить подготовленный шаблон листа:

    1. Развернуть все группы (строки и колонки):

    Excel.ActiveSheet.Outline.ShowLevels(3, 3);

    2. Сернуть все группы (строки и колонки) до первого уровня:

    Excel.ActiveSheet.Outline.ShowLevels(1, 1);

    Reply
  31. Rustam1984

    Спасибо,

    Взял на вооружение!

    Reply
  32. skyvixen

    Коллеги, кто может подсказать, как сохранить в Excel гиперссылку (например, в расшифровке ячейки табличного документа 1C у меня указан WEB-адрес)

    Reply
  33. goodwill

    Ширина в Excel задается в символах, что не очень удобно при выводе картинок. Вот функция для перевода ширины в пикселя в ширину в символах.

    &НаКлиенте
    Функция ПолучитьШиринуКолнкиЭксель(ПараметрШиринаВПикселях)
    
    Если ПараметрШиринаВПикселях > 9 Тогда
    ШиринаВСимволах = (ПараметрШиринаВПикселях/0.75-5)/7;
    Иначе
    ШиринаВСимволах = ПараметрШиринаВПикселях/9;
    КонецЕсли;
    
    Возврат ШиринаВСимволах;
    
    КонецФункции
    
    Лист.Columns(«A»).ColumnWidth = ПолучитьШиринуКолнкиЭксель(РазмерШиринаВПикселях);

    Показать

    Reply
  34. panovisp

    Спасибо за полезную информацю!

    Reply
  35. Gasilin

    Хорошая статья. Но вот пытаюсь на сервере рисовать диаграммы в Excel и при попытке соединения ПодключитьсяКExcelСервер(ИмяВременногоФайла) ругается: …Open. Произошла исключительная ситуация (MS Excel). К сожалению, нам не удалось найти файл … . Возможно, он был перемещен, переименован или удален?

    Это проблема с отсутствием папки C:WindowsSysWOW64configsystemprofileDesktop?

    Reply
  36. ImHunter

    Еще есть способ чтения Excel 2007-выше (*.xlsx) через XML. Ведь это зазипованный XML. В БСП это подсмотрел в обработке ЗагрузкаДанныхИзФайла.

    Reply
  37. Gasilin

    Во втором случае на сервере в строке разве в качестве параметре должно выступать Объект.ИмяФайла?

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

    Reply
  38. roofless

    (37) код этой процедуры тут не приведен, так что вполне может быть и имя файла, если параметры подключения жестко заданы в коде

    Reply
  39. Gasilin

    Код процедуры есть в файле публикации.

    Даю фрагмент:

    &НаСервере

    Процедура Загрузить2НаСервере(пФайл)

    лФайл = ПолучитьИмяВременногоФайла(«xlsx»);

    лДвоичДанные = ПолучитьИзВременногоХранилища(пФайл);

    лДвоичДанные.Записать(лФайл);

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

    Если Соединение = Неопределено Тогда

    Возврат;

    КонецЕсли;

    Reply
  40. KazanKokos

    Народ. А как в Запросе T-SQL вытащить уровень группировки? При строчном переборе я уже научился и пользуюсь, но на больших файлах сами понимаете тормоза. Буду переходить на ODBC и хотелосьбы раскидывать по папкам

    Reply
  41. su_mai

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

    Есть более удобный метод получения Com объекта: «ПолучитьCOMОбъект». Из СП: Основное применение функции ПолучитьCOMОбъект — это получение COM-объекта, соответствующего файлу. Доступность: Тонкий клиент, веб-клиент, сервер, толстый клиент, внешнее соединение.

    Reply
  42. su_mai

    (36) Структура файлов docx, xlsx и пр., соответствует спецификации Microsoft Open Packaging Convention, сокращенно OPC: https://en.wikipedia.org/wiki/Open_Packaging_Conventions.

    По такому же принципу построены файлы комплектов бюджетной бухгалтерской отчетности 1С, для конфигураций БГУ и Свод отчетов (repx).

    Reply
  43. BigBoss

    Полезно достаточно. Спасибо

    Reply
  44. spezc

    Approved.

    Reply
  45. XelOla

    Скажите, а можно с Эксель проработать как в статье http://infostart.ru/public/237032/

    Reply
  46. XelOla

    (42) Скажите, а можно с Эксель проработать как в статье http://infostart.blog-buh.ru/public/237032/

    Reply
  47. =Kollega=

    (39) Сразу скажу — полный бред. Смотрите вы получаете имя временого файла в лФайл, куда и сохраняется сам файл. А потом пытаетесь открыть файл, который задан в реквизите объекта ИмяФайла. Я так полагаю это файл который пользователь выбрал на КЛИЕНТЕ. Соответственно открывать нужно именно лФайл, который сохранен во временном каталоге сервера.

    Да и после окончания работы с ним, неплохо бы почистить за собой — удалить временный файл с сервера.

    Reply
  48. su_mai

    (45) Можно только с форматом xslx.

    Reply
  49. pekus

    Можете еще добавить про установку сквозных строк:

    ActiveSheet.PageSetup.PrintTitleRows = «$1:$4»

    где $1 — номер первой строки, $4 — номер последней строки.

    Была задача, чтобы шапка таблицы excel при выводе на печать отображалась на каждой странице. Пробовал использовать шаблон файла excel с настроенными сквозными строками, но после обработки в 1С и сохранения файла эта настройка пропадала. Долго искал как сделать эту настройку на стороне 1С — и вот нашел) Задача решена.

    Reply
  50. Key-Zed

    Подскажите, не могу найти метод как выделить несколько листов в книге, и сохранить к примеру в PDF.

    Reply
  51. creatermc

    Большой плюс автору и goodwill за материал, многое собрано в одном месте, все очень доступно и грамотно прописано

    Reply
  52. Bene_Valete

    Спасибо за публикацию, очень наглядно и содержательно

    Reply
  53. user609516_rrustam11983

    Спасибо большое

    Reply
  54. strelec13

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

    Reply
  55. user790109

    Как определить какие строки ексель заполнены? Мне требуется зачищать ексель кроме 1 строки(т.к там наименования столбцов) и загружать туда новые данные

    Reply
  56. user790109
    Попытка
    Excel = Новый COMОбъект(«Excel.Application»);
    Excel.Application.DisplayAlerts = False;
    Excel.WorkBooks.Open(ИмяФайла);
    Excel.visible = Истина;
    
    Excel.Sheets(«LRU_LET»).Select();
    НС = 1;
    НК = 1;
    Excel.Range(Excel.Cells(2, 1), Excel.Cells(100, 3)).Delete();
    Для каждого стр Из ТЗ Цикл
    НС = НС + 1;
    Excel.Cells(НС, НК).Value = стр.ITEM;
    Excel.Cells(НС, НК+1).Value = стр.DSCA;
    Excel.Cells(НС, НК+2).Value = стр.QHND;
    КонецЦикла;
    Excel.ActiveWorkBook.Save();
    
    Excel.DisplayAlerts = 0;
    Excel.ActiveWorkbook.Close();
    Excel.DisplayAlerts = 1;
    Excel.Application.Quit();
    Excel = Неопределено;
    Исключение
    Сообщить(«Ошибка при открытии файла с помощью Excel! Загрузка не будет произведена!»);
    Сообщить(ОписаниеОшибки());
    КонецПопытки;
    

    Показать

    После выполнения, файл доступен только для чтения. В процессе заметил что visible остается Ложь, и процесс екселя остается активным(не удает удалить файл, пока не грохнешь процесс). Что я делаю не так?

    Reply
  57. dobrynin.i.s

    (24) на линуксе не взлетит , так как нет ком объектов там

    Reply
  58. Alex_1066

    Вопрос, а в примере клиент-серверного варианта строчка «ОтобразитьТабНаФорме(Таб);» что обозначает? Или другими словами — что там и как реализовано в этой процедуре/функции дальше?

    Reply
  59. Zerocl

    (58) Эта процедура отображает произвольную таблицу значений на форме

    Reply
  60. semx800

    Долго боролся с проблемой, не читался эксель в серверном варианте и проблема оказалась не в коде, а в экселе.

    Решение тут https://infostart.ru/public/196323/ спасибо этому челу, и тебе конечно за статью.

    Reply
  61. ignor

    Лист.Rows(Инд).OutlineLevel

    Возвращает глубину для деревьев, то есть для сворачиваемых и разворачиваемых строк

    Reply
  62. kotov2000

    Коллеги, подскажите.

    Раз есть команда Область.Value.Выгрузить(), то, наверное, есть что-то наподобие загрузить в лист Excel?

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

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

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

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

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

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

    Данные = Область.Value.Выгрузить();

    Reply

Leave a Comment

Ваш адрес email не будет опубликован. Обязательные поля помечены *