Расчет формул в офисных редакторах. Часть 1

2a8d7d9e08e94b59a8ba8232fe87ea82.jpg


Картинка для привлечения внимания. Механический калькулятор

Здравствуйте. Сегодня мы хотим представить вашему вниманию вводную статью о формулах в офисных редакторах. Также коснемся того, как задачу представления и расчета формул мы решаем в ядре редактора МойОфис, и наметим план будущих статей по этой теме.

Популярные стандарты


На сегодняшний день существуют два наиболее популярных стандарта, которые используются в редакторах. С одной стороны это редактор электронных таблиц MS Excel и его стандарт ECMA OOXML. С другой стороны располагаются семейство редакторов LibreOffice/OpenOffice Calc и стандарт OpenFormula. К чести последнего, разрабатывался он с учетом того, чтобы его можно было использовать не только в офисных приложениях.

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

Различия стандартов в редакторах электронных таблиц


Что касается функций, в обоих стандартах достаточно много различий. Они могут иметь разное количество параметров. В свою очередь параметры могут иметь разные типы входных значений. Может отличаться даже точность вычислений. Но не меньше, а на самом деле даже намного больше различий в самом синтаксисе формул. Ниже в таблице приведем буквально несколько примеров различий записи для английской локали (формат записи формул в разных локалях также может существенно различаться):

55d0f5fc89fe4f43ba90b0d924108fd7.jpg


В последнем примере пробел в синтаксисе MS Excel между двумя диапазонами является значащим и это бинарный оператор пересечения диапазонов.

В синтаксисе формул действительно есть отличия, но они не настолько велики, чтобы помешать разработать единое внутреннее представление для обеих записей языка формул. Внутреннее представление – это синтаксическое дерево разбора, в котором уже не существует различий между разными синтаксисами формул. Конечно, не все конструкции можно однозначно сконвертировать из одной записи в другую и есть определенный уровень несовместимости. Поэтому в случае кардинальных отличий приходится выбирать сторону одной записи и чаще всего это запись MS Excel. Мы поддерживаем оба формата для открытия документов, но основной формат – это OOXML. Все, что мы открываем, конвертируется в единое представление, которое не зависит от формата. Сохранять это представление можно в оба формата. Мы постарались свести различия к минимуму, чтобы представить оба формата в единой модели. К примеру, все представленные выше примеры в таблице для обоих форматов будут иметь абсолютно идентичное дерево разбора в нашей модели представления.

Кроме различий между записями, существуют проблемы использования токенов в рамках одной записи. Речь идет об операторе пробел в OOXML. Не всегда пробел в записи формулы – это безобидное пустое место. Иногда это оператор пересечения диапазонов ячеек.

7fb66952dafc45c0a1c1629de7af24f5.png


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

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

= SUM(A1, A2, A3)
= SUM (A1, A2, A3)

В первом случае это вызов функции SUM со списком параметров из трех элементов. Во втором случае это бинарный оператор пробел между двумя параметрами, первым из которых является строковый идентификатор, который расценивается как именованный диапазон ячеек, а второй – это список параметров из трех элементов. Второй случай является валидной записью с точки зрения синтаксиса языка формул OOXML. И результатом будет кумулятивный результат пересечения между именованным диапазоном и списком параметров.

Стоит упомянуть, что вот такая запись имеет смысл: ‘= SUM A1’. К примеру, SUM является именованным диапазоном A1:B2, в этом случае результатом приведенного примера будет значение из ячейки A1.

В качестве заключения скажем, что мы изначально поставили перед собой задачу дать нашим пользователям полноценный функционал по работе с формулами. Функционал, который будет не уступать, а где-то и превосходить продукты – лидеры рынка. Таким образом мы сможем поднять планку качества офисных продуктов. А здоровая конкуренция окажет позитивное влияние на всю экосистему редакторов в мире.

В следующих статьях мы расскажем


  • Как определить зависимости между ячейками в документе и произвести расчет формул с учетом циклических зависимостей.
  • Как можно реализовать контекстно зависимый оператор пробел. Рассмотрим создание синтаксического дерева разбора на примере оператора пробел.
  • О локализации имен функций и синтаксиса формул.
  • Что такое Array формулы и как производится расчет таких структур в ядре нашего редактора.


Спасибо и желаю вам ни #DIV/0!, ни #NULL!

© Habrahabr.ru