Заполнение формул в файлах Excel (кроссплатформенное решение)

30.10.25

Интеграция - Загрузка и выгрузка в Excel

Описанный ниже подход позволяет в три шага заполнять формулы в Excel файлы, вне зависимости от ОС сервера (MS Windows Server или Linux). Подход подразумевает отказ от работы с COM-объектом в пользу работы через "объектную модель документа" (DOM).

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

Основная идея в том, что файл Excel по сути является zip-архивом с файлами внутри. Файлы, в свою очередь, можно редактировать с помощью объекта платформы ДокументDOM.

В данном примере приводится заполнение формул со стилем ссылок "по умолчанию", так называемый ссылочный стиль A1. Например: "=A1+B2".

Важно: Предварительно, сам файл должен быть корректно сформирован (корректный формат данных в ячейках).

Есть куча статей, в которых описано, как это сделать для числовых значений (настройка в макете).

 

Итак, алгоритм действий следующий:

1. Распаковка файла Excel как zip-архива

ВременныйКаталог = КаталогВременныхФайлов() + "\excel_temp\";
	
СоздатьКаталог(ВременныйКаталог);
	
ИзвлечьАрхив(ПутьДоФайла, ВременныйКаталог);

2. Работа с XML файлом листа документа Excel и заполнение формул

ПутьДоXMLФайлаЛист1 = ВременныйКаталог + "xl\worksheets\sheet1.xml";

// Чтение распакованного xml-файла листа 1 в ДокументDOM
ДокументDOM = ПолучитьDOMДокументИзXMLФайла(ПутьДоXMLФайлаЛист1);
	
ВсеЯчейки = ДокументDOM.ПолучитьЭлементыПоИмени("c");
ВсеСтроки = ДокументDOM.ПолучитьЭлементыПоИмени("row");
ВсегоСтрок = ВсеСтроки.Количество();

// Обход ячеек и определение формул по произвольному алгоритму
Для Каждого Ячейка Из ВсеЯчейки Цикл
	Формула = Неопределено;
		
	ИмяЯчейки = Ячейка.ПолучитьАтрибут("r");
	Если ИмяЯчейки = Неопределено Тогда
		Продолжить;
	КонецЕсли;
		
	ИмяСтолбца = Сред(ИмяЯчейки, 1, 1);
	ИмяСтроки = Сред(ИмяЯчейки, 2);
		
	НомерСтроки = Число(ИмяСтроки);
	
	// Сборка формулы по условиям для ячейки в формате "=A1+B2"
	// Тут необходимо прописать логику по определению формулы
	Формула = "=A1+B2";
		
	Если Формула = Неопределено Тогда
		Продолжить;
	КонецЕсли;
		
	Пока Ячейка.ЕстьДочерниеУзлы() Цикл
		Ячейка.УдалитьДочерний(Ячейка.ПервыйДочерний);
	КонецЦикла;
		
	// Заполнение формулы
	ЭлФормула = ДокументDOM.СоздатьЭлемент("f");
	ЭлФормула.ТекстовоеСодержимое = Формула;
	
	Ячейка.ДобавитьДочерний(ЭлФормула);
	
КонецЦикла;
	
// Запись модифицированного объекта ДокументDOM в xml-файл листа 1
СохранитьDOMДокументКАКXMLФайл(ДокументDOM, ПутьДоXMLФайлаЛист1);

3. Запаковка измененных файлов обратно в архив (Excel-файл) и удаление временных файлов

УдалитьФайлы(ПутьДоФайла);
	
СобратьАрхив(ВременныйКаталог, ПутьДоФайла);
	
УдалитьФайлы(ВременныйКаталог);

Для удобства, все вынесено в отдельный общий модуль, привожу его листинг:

 
 Листинг общего модуля

Вступайте в нашу телеграмм-группу Инфостарт

Excel Формулы Экспорт Linux Windows кроссплатформенность ZIP XML ДокументDOM

Вы можете заказать платную адаптацию этой статьи под ваши задачи на «Бирже заказов».

  • 0% комиссии — оплата напрямую исполнителю;
  • Исполнители любого масштаба — от отдельных специалистов до команд под проект;
  • Прямой обмен контактами между заказчиком и исполнителем;
  • Безопасная сделка — при необходимости;
  • Рейтинги, кейсы и прозрачная система откликов.

См. также

Загрузка и выгрузка в Excel Маркетплейсы Программист Бухгалтер Пользователь 1С:Предприятие 8 1С:Розница 2 1С:Управление нашей фирмой 1.6 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Бухгалтерский учет Управленческий учет Платные (руб)

Реальный помощник, с помощью которого Вы преобразуете необходимые документы для Wildberries, OZON, ЯндексМаркет, Мегамаркет, Aliexpress, Детский мир, Магнит Маркет (быв.МагнитЭкспресс), Лемана про, ЭНФАНТА (Акушерство), ЛаМода, Летуаль, Твой дом, Золотое Яблоко, Каспи в документы "Отчет комиссионера (агента) о продажах" и другие. Работает в 1С:БП 3.0, 1С:БП 3.0 КОРП, 1С:УТ 11, 1С:УНФ, 1С:ERP.

5490 руб.

12.08.2021    45504    571    71    

218

Загрузка и выгрузка в Excel Розничная торговля Логистика, склад и ТМЦ Ценообразование, анализ цен Прайсы Системный администратор Программист 1С:Предприятие 8 1С:Комплексная автоматизация 1.х 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Управленческий учет Платные (руб)

Загрузка номенклатуры из файлов Excel (xls, xlsx, ods, csv, mxl) в УТ11, КА 2, ERP 2, Розница 2. Задействованы все возможности конфигурации - заполнение реквизитов номенклатуры, дополнительных реквизитов и сведений, характеристики, доп.реквизиты и сведения характеристик. Дополнительные обработки для расширения возможностей.

12444 руб.

29.10.2014    231424    745    532    

495

WEB-интеграция Загрузка и выгрузка в Excel Программист Пользователь 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 Розничная и сетевая торговля (FMCG) Россия Платные (руб)

Расширение освободит вас от необходимости вручную обновлять информацию о товарах в группах ВКонтакте. Достаточно задать правила один раз, и система автоматически формирует файлы yml для дальнейшей загрузки в группы в ВК. Вы сможете легко выбирать, какие товары публиковать, создавая гибкие критерии отбора. Например, можно добавить важные для покупателей параметры: цвет, размер или другие характеристики.

12200 руб.

29.08.2025    2542    7    6    

8

Загрузка и выгрузка в Excel Маркетплейсы Программист Бухгалтер Пользователь 1С:Предприятие 8 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Управление нашей фирмой 3.0 1С:Розница 3.0 Бухгалтерский учет Управленческий учет Платные (руб)

Загружает данные из Акта приемки товара от ООО «Вайлдберриз», полученный из личного кабинета в формате *.xlsx или API в документ "Реализация (акты, накладные, УПД)" для конфигурации: Бухгалтерия предприятия, редакция 3.0, в документ "Реализация товаров и услуг" для Управление торговлей, редакция 11; Комплексная автоматизация 2; ERP 2 Управление предприятием и в документ "Расходная накладная" для Управление нашей фирмой 3.0; Розница 3.0

6100 руб.

24.01.2021    24662    121    0    

63
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. Трактор 1279 30.10.25 10:55 Сейчас в теме
Добавил в избранное. Благодарю за публикацию. Зело красиво.
user1638771; XilDen; Abysswalker; +3 Ответить
2. XilDen 792 30.10.25 15:42 Сейчас в теме
Отличное решение, спасибо, что поделились!
3. partizand 145 30.10.25 18:51 Сейчас в теме
Осторожнее с Dom в 1с. Он может прочитать не все корректно, и записать немножечко не такой XML, который ожидает office.
ЧтениеXml в этом плане надёжно, работает даже с битыми файлами. Но неудобно
4. Abysswalker 45 30.10.25 21:41 Сейчас в теме
(3) Спасибо, буду наблюдать за поведением.
Были попытки с ФабрикаXDTO, но быстро не получилось и пришлось отказаться от этого пути
5. Mdanko 03.11.25 09:20 Сейчас в теме
А если ячеек с формула и несколько тысяч, это получается все формулы писать в коде? А когда документ меняется несколько раз за год. Такое себе решение.
Пишем формулы как текст в формате А1, потом в Excel делаем замена = на =, для Р7 плагин перекладывающий текст в формулы.
6. Abysswalker 45 03.11.25 10:42 Сейчас в теме
(5) Это не готовое решение, а лишь описание подхода (шаблон)
7. Mdanko 05.11.25 11:29 Сейчас в теме

Процедура ЗаполнитьФормулыВФайлеНазваниеВашейПечатнойФормы(ПутьДоФайла)
	
	ВременныйКаталог = КаталогВременныхФайлов() + "\excel_temp\";
	
	СоздатьКаталог(ВременныйКаталог);
	
	ИзвлечьАрхив(ПутьДоФайла, ВременныйКаталог);
	
	ПутьДоXMLФайлаЛист1 = ВременныйКаталог + "xl\worksheets\sheet1.xml";

	// Чтение распакованного xml-файла листа 1 в ДокументDOM
	ДокументDOM = ПолучитьDOMДокументИзXMLФайла(ПутьДоXMLФайлаЛист1);
    СтроковыеЗначения = ПолучитьDOMДокументИзXMLФайла(ВременныйКаталог + "xl\sharedStrings.xml");
	
	ВсеЯчейки = ДокументDOM.ПолучитьЭлементыПоИмени("c");
	ВсеСтроки = ДокументDOM.ПолучитьЭлементыПоИмени("row");
	ВсегоСтрок = ВсеСтроки.Количество();
    ВсеСтроковыеЗначения = СтроковыеЗначения.ЭлементДокумента.ДочерниеУзлы;
    
	// Обход ячеек и определение формул по произвольному алгоритму
	Для Каждого Ячейка Из ВсеЯчейки Цикл
		
		ИмяЯчейки = Ячейка.ПолучитьАтрибут("r");
		Если ИмяЯчейки = Неопределено Тогда
			Продолжить;
		КонецЕсли;
		
		ИмяСтолбца = Сред(ИмяЯчейки, 1, 1);
		ИмяСтроки = Сред(ИмяЯчейки, 2);
		
		НомерСтроки = Число(ИмяСтроки);
	
        ТипЯчейки = Ячейка.ПолучитьАтрибут("t");
        Если ТипЯчейки="s" Тогда 
           // здесь лежит какое-то значение  
           Если Ячейка.ПервыйДочерний.ИмяУзла = "v" Тогда 
           // надо найти значение в строках SharedStrings    
              ЗначениеЯчейки = ВсеСтроковыеЗначения[Число(Ячейка.ПервыйДочерний.ТекстовоеСодержимое)];
                	//	Формула начинается с "="
                    ЭтоФормула=СтрНачинаетсяС(ЗначениеЯчейки.ТекстовоеСодержимое,"=");
                    Если ЭтоФормула Тогда 
                        формула=ЗначениеЯчейки.ТекстовоеСодержимое;
                		Пока Ячейка.ЕстьДочерниеУзлы() Цикл
                			Ячейка.УдалитьДочерний(Ячейка.ПервыйДочерний);
                		КонецЦикла;
                		
                		// Заполнение формулы
                		ЭлФормула = ДокументDOM.СоздатьЭлемент("f");
                		ЭлФормула.ТекстовоеСодержимое = Формула;
                	
                		Ячейка.ДобавитьДочерний(ЭлФормула);
                    КонецЕсли;
           КонецЕсли;
        КонецЕсли;
	КонецЦикла;
	
	// Запись модифицированного объекта ДокументDOM в xml-файл листа 1
	СохранитьDOMДокументКАКXMLФайл(ДокументDOM, ПутьДоXMLФайлаЛист1);
	
	УдалитьФайлы(ПутьДоФайла);
	
	СобратьАрхив(ВременныйКаталог, ПутьДоФайла);
	
	УдалитьФайлы(ВременныйКаталог);
	
КонецПроцедуры
Показать


Немного поправил процедуру, перекладывает формулы из текста в формулу.
Имена функций должны быть написаны на английском СУММ(SUM), иначе будет ошибка #ИМЯ.
Могут быть ещё нюансы, но так уже более менее терпимо.
Abysswalker; +1 Ответить
8. q4a 103 24.12.25 18:08 Сейчас в теме
(7) Да, ещё есть нюансы: обычные формулы пишутся с символом "=" (например, "=A1+B2"), а для того, чтобы получить формулу "=ЕСЛИ(C2>0;0;C2)" приходится писать "IF(C2>0,0,C2)" (без символа "=", а также запятые вместо ";")
9. Mdanko 12.01.26 15:57 Сейчас в теме
1) я писал, что имена функций должны быть по английски, и да разделители - ; .
2) знак "=" в конечной формуле вообще не нужен, Excel ставит его самостоятельно если надо, а Р7 всегда добавляет ещё один :) я его использую только для определения, что должна быть формула
ЭтоФормула=СтрНачинаетсяС(ЗначениеЯчейки.ТекстовоеСодержимое,"=");
                    Если ЭтоФормула Тогда 
                        формула= Сред(ЗначениеЯчейки.ТекстовоеСодержимое,2);
.....................
10. 101422 25.02.26 20:12 Сейчас в теме
// Заполнение формулы
	ЭлФормула = ДокументDOM.СоздатьЭлемент("f");
	ЭлФормула.ТекстовоеСодержимое = Формула;
	
	Ячейка.ДобавитьДочерний(ЭлФормула);


Кто подскажет как вставить не формулу, а обычный текст?
11. Abysswalker 45 10.03.26 21:09 Сейчас в теме
(10) Для этого необходимо редактировать отдельный файл sharedStrings.xml, именно в нем хранятся строковые значения ячеек
Для отправки сообщения требуется регистрация/авторизация