VBA (Office) и JavaScript (Adobe): можно ли заработать?


Стивен ОливерЭрик Шмидт .
Продукты и технологии:JavaScript API for Office. В статье рассматриваются:. Это первая статья в серии, посвященной рассмотрению JavaScript API for Office, появившемся в Microsoft Office 2013. Мы исходим из того, что вы знакомы с приложениями для Office. Если это не так, загляните на страницу документации MSDN «Overview of apps for Office» (bit.ly/12nBWHG).. Эта и другие статьи в данной серии хоть и не являются всеобъемлющими, дадут глубокое представление об этом API, затронув все ключевые аспекты. Благодаря этому вы будете хорошо понимать, как работают приложения для Office API..
В первой статье мы даем обзор объектной модели приложений для Office. Во второй части основное внимание будет уделено базовой задаче доступа к контенту файлов Office и описанию модели событий. В третьей части будут рассматриваться концепция связывания с данными и основы работы с собственными XML-фрагментами (XML parts). Наконец, в четвертой (последней) части мы изучим почтовые приложения.. На протяжении всей серии мы будем часто ссылаться на документацию по приложениям для Office API. Официальную документацию, примеры кода и ресурсы сообщества вы найдете в Apps for Office and SharePoint Developer Center в MSDN (dev.office.com).. JavaScript API for Office охватывает полную объектную модель.
Этот API содержится в наборе JavaScript-файлов, начиная с файла office.js. Приложение должно включать ссылку на файл office.js, чтобы задействовать JavaScript API for Office. При загрузке файл office.js загружает остальные скрипты, необходимые для его работы, в том числе скрипты для хост-среды и локализованные строки. К счастью, вы можете добавить ссылку на файл office.js, используя сеть доставки контента (content delivery network, CDN), поэтому вам нет нужды развертывать копию файла office.js вместе со своим приложением. Вот пример:. Объектная модель спроектирована с учетом нескольких целей.. Другой основной целью создания JavaScript API было стремление привлечь внимание веб-разработчиков к платформе Office.
Таким образом, объектная модель была построена с учетом современного веб-программирования. При создании приложений в комбинации с JavaScript API for Office вы можете использовать свои текущие навыки и знания других JavaScript-библиотек, таких как jQuery.. Как упоминалось, производительность была основной целью в проектировании Office API. Один из способов, которым проектировщики добились повышения производительности API, — интенсивное использование асинхронных функций.. Применение таких функций избавляет от блокирования приложения в том случае, если выполнение какой-либо функции занимает некоторое время. Асинхронная функция вызывается, но программа не ждет возврата управления от этой функции. Вместо этого она продолжает выполнение, пока асинхронная функция работает.
Это дает возможность пользователю продолжать работу с документом Office.. В этом разделе излагаются некоторые основные моменты, необходимые для понимания асинхронной архитектуры приложений, использующих Office API:. Обсудим по очереди каждый из этих моментов.. Общая сигнатура асинхронных функций в приложениях для Office API Все асинхронные функции в таких приложениях имеют одинаковое соглашение об именовании и одну и ту же базовую сигнатуру. Имя каждой асинхронной функции заканчивается «Async», например Document.getSelectedDataAsync.. Сигнатура всех асинхронных функций соответствует следующему базовому шаблону:. За обязательными параметрами следуют еще два параметра: объект, содержащий дополнительные параметры, и функция обратного вызова, причем оба эти параметры не обязательны..
Необязательные параметры в асинхронных функциях Дополнительный JavaScript-объект в сигнатуре асинхронных функций является набором пар «ключ-значение», разделяемых двоеточием, где ключ — это имя параметра, а значение — данные, которые вы хотите использовать для этого параметра. Порядок пар «ключ-значение» неважен при условии правильности имени параметра. В документации MSDN по каждой асинхронной функции детально описывается, какие параметры доступны в ней для использования в объекте options.. Например, метод Document.setSelectedDataAsync имеет ту же базовую сигнатуру, общую для всех асинхронных функций в приложениях для Office:. Один из способов, которым проектировщики добились повышения производительности API, — интенсивное использование асинхронных функций.. Как и все асинхронные функции в этом API, Document.setSelectedDataAsync принимает объект options, содержащий дополнительные параметры, но эти параметры для его объекта options отличаются от тех, которые используются для других асинхронных функций в API, так как предназначение этой функции — присваивать данные. Поэтому дополнительные параметры Document.setSelectedDataAsync связаны с присваиванием данных:.
Та же концепция применяется ко всем остальным асинхронным функциям.. Вы можете либо предоставить объект, содержащий дополнительные параметры, как объектный литерал, подставляемый в строку в вызове асинхронной функции, либо сначала создать объект, а потом передать его для возврата в параметре. Следующие два примера кода показывают оба способа предоставления объекта options, используя функцию Document.setSelectedDataAsync.. Передача параметра options, подставляемого в строку:. Передача параметра options в JavaScript-объекте:. Роль объекта AsyncResult в асинхронных функциях Третий параметр в общей сигнатуре асинхронных функций в JavaScript API for Office — необязательный callback. Смысл этого параметра callback точно соответствует тому, как он назван: это передаваемая вами функция, которая вызывается по окончании выполнения асинхронной операции.
Конечно, вы можете указать либо именованную функцию, либо анонимную функцию, подставляемую в строку вызова асинхронной функции. Здесь важно отметить роль объекта AsyncResult в отношении этой функции обратного вызова.. Когда исполняющая среда вызывает вашу функцию обратного вызова, она передает ей объект AsyncResult в качестве единственного аргумента. Объект AsyncResult содержит информацию об асинхронной операции, например, успешно ли выполнена операция, были ли ошибки и какие, возвращаемое значение асинхронной функции, если таковое есть. По сути, во всех асинхронных функциях, возвращающих какие-либо данные или объект, AsyncResult — единственный способ получения вами возвращаемого значения. Для этого используется свойство AsyncResult.value.. Так, в следующем фрагменте кода вы получаете размер документа и отображаете его в указанном HTML-элементе в UI приложения.
Чтобы получить размер файла, вы сначала получаете объект файла, возвращаемый методом Document.getFileAsync через свойство AsyncResult.value. Вот как это делается:. Функция getFileData вызывает метод Document.getFileAsync, указывая, что он должен вернуть контент файла как текст. Затем она использует свойство value объекта AsyncResult, переданного анонимной функции обратного вызова, чтобы получить ссылку на объект File. Далее она отображает размер файла в заданном элементе, используя свойство size объекта File. Аналогичным образом вы будете использовать свойство AsyncResult.value для получения возвращаемого значения любой асинхронной функции в приложениях для Office API.. Подробнее о методе Document.getFileAsync мы поговорим в следующей статье из этой серии..

JavaScript API for Office нацелен на обеспечение совместимости между разными версиями Office и разными хост-приложениями. Для достижения этих целей JavaScript API предоставляет компактную объектную модель с четкой иерархией, не связанную напрямую ни с одним конкретным хост-приложением. Вместо этого объектная модель содержит адресный набор средств для взаимодействия с документами Office, соответствующих типу использующего данные документы приложения (область задач, контент или почтовое приложение).. На рис. 1 дана сокращенная схема иерархии объектов верхнего уровня в JavaScript API for Office (заметьте, что здесь не показана полная объектная модель). В частности, эта схема демонстрирует взаимосвязи между объектами Office, Context, Document, Settings, Mailbox и RoamingSettings.. Рис. 1.
Иерархия объектной модели в JavaScript API for Office. Каждое хост-приложение (Word, Excel, Excel Web App, PowerPoint, Project, Outlook и Outlook Web App) может использовать подмножество возможностей, включенных в этот API. Например, около 40% объектной модели отводится исключительно почтовым приложениям, которые могу быть задействованы только в Outlook и Outlook Web App. Другая часть объектной модели позволяет взаимодействовать с Custom XML Parts (собственными XML-фрагментами), доступными лишь в Word 2013.. В табл. 1 перечислены возможности, доступные в конкретных хост-приложениях.. Табл.
1. Возможности JavaScript API for Office, доступные в конкретных хост-приложениях. Общие объекты в объектной модели В JavaScript API for Office есть строго определенная точка входа — объект Office, доступный приложениям всех типов и во всех хост-приложениях. Объект Office представляет определенный экземпляр приложения и вставляется в документ, рабочую книгу, презентацию, проект, почтовое сообщение или назначение (appointment). Ему доступны привязки между приложением и документом через метод select. (О привязках мы поговорим подробнее в следующей статье.) Самое важное, что объект Office предоставляет событие initialize для приложения, которое позволяет вам создавать логику инициализации приложения (об этом — тоже в следующей статье). Наконец, объект Office содержит ссылку на объект Context для приложения..
Объект Context, также доступный приложениям всех типов и во всех хост-приложениях, содержит информацию об исполняющей среде, в которой размещено приложение. Помимо хранения языковых настроек для приложения, объект Context предоставляет точку входа для использования возможностей JavaScript API for Office, специфичных для хоста, в котором было активировано приложение.. Например, вы можете обращаться к документу (объекту Document), сопоставленному с приложением, через свойство Context.document. Однако это свойство возвращает значение, только когда вызывается из хост-приложения, которое поддерживает его, т. е. из приложения области задач или контента. Если попытаться обратиться к свойству Context.document из почтового приложения, будет получена ошибка «undefined object» (неопределенный объект). Аналогично дело обстоит и со свойством Context.mailbox: в почтовом приложении оно возвращает почтовый ящик (объект Mailbox), открытый в хост-приложении.
В приложении области задач оно будет неопределенным.. Поддержка приложений области задач и контента в объектной модели В случае приложений области задач и контента объект Document представляет документ, рабочую книгу, презентацию или проект, в который было вставлено приложение. Объект Document обеспечивает высший уровень доступа к контенту файла — фактически это основная точка контакта между приложением и документом Office.. Почти все способы доступа к контенту в документе Office требуют использования объекта Document. По этой причине вам может понадобиться получение ссылки на объект Document при инициализации приложении, как показано на рис. 2.. Рис. 2.
Сохранение ссылки на объект Document при инициализации приложения. Когда приложение активируется в файле Project, объект Document предоставляет дополнительные специфические возможности, ориентированные на файлы Project. Через объект Document приложение может получать данные для специфических задач, представлений, полей и ресурсов в проекте. Приложение также может добавлять слушатели событий, чтобы отслеживать изменения (вносимые пользователем) в представление, задачу или ресурс, выбранную в проекте. (Подробнее о применении объекта Document в приложении для Project будет рассказано в следующей статье.). Объектом Document также предоставляется объект Settings, который представляет «контейнер свойств» («property bag») для приложения. Приложение может хранить и сохранять собственные свойства между сеансами выполнения в том же документе, используя объект Settings.
Эти свойства «путешествуют» вместе с документом: если вы используете какой-то файл Office, содержащий приложение, совместно с кем-то еще, то собственные свойства, хранящиеся в приложении, будут доступны, когда другое лицо откроет этот файл.. Сохранять и получать настройки с помощью контейнера свойств довольно просто. Метод Settings.set создает настройку в памяти как пару «ключ-значение». Чтобы получить свойства из контейнера, мы используем метод Settings.get, передавая имя (ключ) настройки; это дает нам соответствующее значение. Оба метода (set и get) синхронные. Для сохранения настроек между сеансами нужно вызывать метод Settings.saveAsync, который сохраняет все собственные свойства, содержащиеся в приложении, при сохранении документа.. В образце кода «Apps for Office: Persist custom settings» (bit.ly/UEiZff) вы найдете дополнительные примеры того, как использовать объект Settings и как сохранять данные в приложении..
Поддержка почтовых приложений в объектной модели Объект Mailbox предоставляет точку входа для доступа к данным и функциональности, специфичным для почтовых приложений. Как и подразумевает его имя, объект Mailbox соответствует почтовому ящику текущего пользователя и передается любым пользователям, читающим его сообщения электронной почты либо в клиентском приложении Outlook, либо в Outlook Web App. Кроме доступа к индивидуальным сообщениям электронной почты и назначениям (через свойство Mailbox.item), объект Mailbox обеспечивает приложению возможность создавать новые назначения, обращаться к профилю локального пользователя и даже получать местное время для этого пользователя.. Как и в случае объекта Document для приложений области задач и контента, вам может потребоваться получение ссылки на объект Mailbox при инициализации приложения (рис. 3).. Рис. 3. Сохранение ссылки на объект Mailbox в глобальной переменной при инициализации приложения.
Объект RoamingSettings, также доступный только в почтовых приложениях, аналогичен объекту Settings для приложений, ориентированных на документы (приложений области задач и контента). Он позволяет приложениям сохранять собственные свойства между сеансами как пары «имя-значение». Однако в отличие от объекта Settings, который сохраняет собственные свойства в файле хоста Office, объект RoamingSettings сохраняет настройки в почтовом ящике текущего пользователя. Благодаря этому собственные свойства доступны приложению независимо от того, какое сообщение просматривает пользователь или каким способом пользователь обращается к своему почтовому ящику (в Outlook или Outlook Web App).. Подробнее об иерархии объектной модели в JavaScript API for Office см. страницу «Understanding the JavaScript API for Office» (bit.ly/UV2POY) в документации MSDN.. Как мы ранее упоминали, одна из сильных сторон JavaScript API for Office заключается в основном принципе приложений для Office: «Пишется один раз, работает везде».
Например, одно и то же приложение области задач можно активировать в Word, Excel, Project и PowerPoint (при условии, что его манифест разрешает все эти возможности).. Однако, поскольку не всем приложениям доступен одинаковый список возможностей, в хост-приложение могло бы быть включено приложение, требующее тех возможностей, которых нет в этом хосте. Так, Project в настоящее время не предоставляет доступа к объекту Settings. Приложение, которое пытается обратиться к объекту Settings, при вставке в Project приведет к ошибке «undefined object».. Таким образом, разработчики должны включать в свои приложения логику для проверки доступности необходимых им возможностей. В примере с Project лучший способ обнаружения возможностей в хост-приложении — использование простого блока if:. Подробнее о том, как распознавать доступность возможности в хост-приложении см.
страницу «How to: Determine host application support for specific API members» (bit.ly/TR5ZlB) в документации MSDN.. Итак, в этой статье мы обсудили суть JavaScript API for Office. Мы описали высокоуровневую иерархию объектной модели и рассмотрели асинхронный шаблон, реализованный в этой модели. Мы также объяснили, как проверять доступность той или иной возможности в хост-приложении.. В следующей статье из этой серии мы подробнее рассмотрим простейшие, но эффективные способы работы с данными в приложении для Office. Мы детально поясним, как получать и присваивать выбранные данные. Кроме того, мы поговорим о получении всего содержимого файла и его последующего разбора, обсудим приложения в Project и то, как считывать данные задачи, ресурса и представления.