Полезные приемы при работе с 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 не будет опубликован. Обязательные поля помечены *