У нас важные новости: вышла новая версия десктопов с макросами. Вы можете скачать её на официальном сайте и попробовать всё сами.
В этой статье мы расскажем, что у нас за макросы, чем они отличаются от макросов Microsoft и как с ними работать.

Макрос — это скрипт, с помощью которого можно автоматизировать рутинные операции и сэкономить целую кучу времени. Само понятие придумала компания Microsoft, поэтому эти скрипты предназначаются для Microsoft Office и работают на Windows.
«Когда вы сделаете макросы?» — это очень популярный вопрос. Поначалу мы отвечали: «Никогда. Но мы можем сделать то же самое с помощью плагинов» (и делали).
Так вот, за год наша система плагинов стала гораздо круче (и более подробно документированной). Теперь мы сами добавляем новую функциональность с помощью плагинов. Например, Symbol Table: в редакторах документов нужны спецсимволы, и добавить их через плагины в разы быстрее. Кроме того, у нас уже был готовый SDK для генерации и обработки документов, электронных таблиц и презентаций — ONLYOFFICE Document Builder.
В общем, когда речь в очередной раз зашла о макросах, мы поняли, что у нас всё сложилось. И сложилось довольно красиво. Мы берем Document Builder, оборачиваем его в плагин и пробрасываем в интерфейс. Теперь у нас есть возможность создавать и запускать макросы!

Сейчас макросы умеют делать всё, что умеет делать Builder. Документацию к нему можно найти тут. Отдельную документацию по макросам уже пишем.
Если вы видели наши плагины, то должны догадаться, в чём оно заключается, сразу же. В том, что вы будете писать не на Visual Basic, а на JavaScript.
«Почему не Visual Basic, а как же совместимость?!»
Предвидим этот вопрос и отвечаем на него заранее. Во-первых, VBA только для Windows, а у нас тут все платформы. Если бы у Microsoft был какой-то скриптовый язык, мы бы с радостью его поддержали. Но миллион лет писать компилятор очень старого языка и в результате получить макросы (такие же как у MS) — это не задача мечты. Мы предпочтем в этом время совершенствовать редакторы. К тому же, у нас всё готово с js.
Это классно, потому что:
— Будет работать со всеми платформами;
— Реально очень просто;
— Написав толковый скрипт, вы можете использовать его и как плагин, и как макрос. Ну и само собой как скрипт для Document Builder'а, конечно же.
Про последний пункт: макрос — это, по сути, частный случай плагина. Просто установленные плагины работают для всех документов (то есть, привязаны к редакторам), а макросы — только конкретного документа (то есть, привязаны к файлу).
Да, макросы из Microsoft так просто не откроются у нас. В то же время мы понимаем, что у многих уже есть целые библиотеки макросов, которые хотелось бы запустить в альтернативном офисе.
Пока мы можем предложить самый простой вариант: немного переписать макросы, написанные на VBA. Понимаем, возможно, это прозвучит как головная боль, но на самом деле это совсем несложно.
Вот пример заполнения нескольких ячеек данными (суммирование диапазона). Первый — вариант MS с Visual Basic, второй — наш.
Первый пример:
Второй:
Как видите, это довольно просто.
А теперь крутой пример:
В результате у вас должна получиться вот такая красота:

Вы можете скачать десктопное приложение ONLYOFFICE и всё попробовать. Кстати, макросы не единственное новшество вышедшей версии. Мы много всего пофиксили, добавили поддержку SSO, новые языки интерфейса (чешский и словацкий). Подробная информация о новой версии на GitHub.
Это всё. Ждем ваших вопросов, предложений, пожеланий и мыслей. Если у вас есть интересные файлы с макросами, которыми вы можете поделиться, присылайте на files@onlyoffice.com. Если у вас есть файлы без макросов, но с интересными проблемами и ошибками, ждем их тоже.
В этой статье мы расскажем, что у нас за макросы, чем они отличаются от макросов Microsoft и как с ними работать.

Как у нас сделаны макросы?
Макрос — это скрипт, с помощью которого можно автоматизировать рутинные операции и сэкономить целую кучу времени. Само понятие придумала компания Microsoft, поэтому эти скрипты предназначаются для Microsoft Office и работают на Windows.
«Когда вы сделаете макросы?» — это очень популярный вопрос. Поначалу мы отвечали: «Никогда. Но мы можем сделать то же самое с помощью плагинов» (и делали).
Так вот, за год наша система плагинов стала гораздо круче (и более подробно документированной). Теперь мы сами добавляем новую функциональность с помощью плагинов. Например, Symbol Table: в редакторах документов нужны спецсимволы, и добавить их через плагины в разы быстрее. Кроме того, у нас уже был готовый SDK для генерации и обработки документов, электронных таблиц и презентаций — ONLYOFFICE Document Builder.
В общем, когда речь в очередной раз зашла о макросах, мы поняли, что у нас всё сложилось. И сложилось довольно красиво. Мы берем Document Builder, оборачиваем его в плагин и пробрасываем в интерфейс. Теперь у нас есть возможность создавать и запускать макросы!

Сейчас макросы умеют делать всё, что умеет делать Builder. Документацию к нему можно найти тут. Отдельную документацию по макросам уже пишем.
Наши макросы не такие, как у Microsoft
Если вы видели наши плагины, то должны догадаться, в чём оно заключается, сразу же. В том, что вы будете писать не на Visual Basic, а на JavaScript.
«Почему не Visual Basic, а как же совместимость?!»
Предвидим этот вопрос и отвечаем на него заранее. Во-первых, VBA только для Windows, а у нас тут все платформы. Если бы у Microsoft был какой-то скриптовый язык, мы бы с радостью его поддержали. Но миллион лет писать компилятор очень старого языка и в результате получить макросы (такие же как у MS) — это не задача мечты. Мы предпочтем в этом время совершенствовать редакторы. К тому же, у нас всё готово с js.
Это классно, потому что:
— Будет работать со всеми платформами;
— Реально очень просто;
— Написав толковый скрипт, вы можете использовать его и как плагин, и как макрос. Ну и само собой как скрипт для Document Builder'а, конечно же.
Про последний пункт: макрос — это, по сути, частный случай плагина. Просто установленные плагины работают для всех документов (то есть, привязаны к редакторам), а макросы — только конкретного документа (то есть, привязаны к файлу).
Так что всё-таки с совместимостью?
Да, макросы из Microsoft так просто не откроются у нас. В то же время мы понимаем, что у многих уже есть целые библиотеки макросов, которые хотелось бы запустить в альтернативном офисе.
Пока мы можем предложить самый простой вариант: немного переписать макросы, написанные на VBA. Понимаем, возможно, это прозвучит как головная боль, но на самом деле это совсем несложно.
Вот пример заполнения нескольких ячеек данными (суммирование диапазона). Первый — вариант MS с Visual Basic, второй — наш.
Первый пример:
Sub Example() Dim myRange Dim result Dim Run As Long For Run = 1 To 3 Select Case Run Case 1 result = "=SUM(A1:A100)" Case 2 result = "=SUM(A1:A300)" Case 3 result = "=SUM(A1:A25)" End Select ActiveSheet.range("B" & Run) = result Next Run End Sub
Второй:
(function() { for (let run = 1; run <= 3; run++) { var result = ""; switch (run) { case 1: result = "=SUM(A1:A100)"; break; case 2: result = "=SUM(A1:A300)"; break; case 3: result = "=SUM(A1:A25)"; break; default: break; } Api.GetActiveSheet().GetRange("B" + run).Value = result; } })();
Как видите, это довольно просто.
А теперь крутой пример:
Здесь у нас длинный скрипт
(function() { var oSheet = Api.GetActiveSheet(); oSheet.SetName('Medal Number'); oSheet.SetColumnWidth(0, 7.57); oSheet.SetColumnWidth(1, 12.43); oSheet.SetColumnWidth(2, 32.50); oSheet.SetColumnWidth(3, 13.86); oSheet.SetColumnWidth(4, 13.86); oSheet.SetColumnWidth(5, 13.86); oSheet.SetColumnWidth(6, 13.86); var range = oSheet.GetRange('C1'); range.SetFontSize(56); range = oSheet.GetRange('B2:G29'); range.SetFontName('Calibri'); range.SetFontSize(13); range.SetFontColor(Api.CreateColorFromRGB(0, 0, 0)); range.SetAlignHorizontal('center'); oSheet.GetRange('B2').SetValue('Rank'); oSheet.GetRange('C2').SetValue('Country'); oSheet.GetRange('D2').SetValue('Gold'); oSheet.GetRange('E2').SetValue('Silver'); oSheet.GetRange('F2').SetValue('Bronze'); oSheet.GetRange('G2').SetValue('Total'); for (var nCell = 0; nCell < 25; ++nCell) { oValue = nCell + 1; oCellNumber = nCell + 3; oSheet.GetRange('B' + oCellNumber.toString()).SetValue(oValue.toString()); } oSheet.GetRange('C3:C27').SetAlignHorizontal('left'); oSheet.GetRange('C3').SetValue('USA'); oSheet.GetRange('C4').SetValue('China'); oSheet.GetRange('C5').SetValue('Great Britain'); oSheet.GetRange('C6').SetValue('Russia'); oSheet.GetRange('C7').SetValue('Germany'); oSheet.GetRange('C8').SetValue('Japan'); oSheet.GetRange('C9').SetValue('France'); oSheet.GetRange('C10').SetValue('South Korea'); oSheet.GetRange('C11').SetValue('Italy'); oSheet.GetRange('C12').SetValue('Australia'); oSheet.GetRange('C13').SetValue('Netherlands'); oSheet.GetRange('C14').SetValue('Hungary'); oSheet.GetRange('C15').SetValue('Brazil'); oSheet.GetRange('C16').SetValue('Spain'); oSheet.GetRange('C17').SetValue('Kenya'); oSheet.GetRange('C18').SetValue('Jamaica'); oSheet.GetRange('C19').SetValue('Croatia'); oSheet.GetRange('C20').SetValue('Cuba'); oSheet.GetRange('C21').SetValue('New Zealand'); oSheet.GetRange('C22').SetValue('Canada'); oSheet.GetRange('C23').SetValue('Uzbekistan'); oSheet.GetRange('C24').SetValue('Kazakhstan'); oSheet.GetRange('C25').SetValue('Colombia'); oSheet.GetRange('C26').SetValue('Switzerland'); oSheet.GetRange('C27').SetValue('Iran'); oSheet.GetRange('D3').SetValue('46'); oSheet.GetRange('D4').SetValue('27'); oSheet.GetRange('D5').SetValue('26'); oSheet.GetRange('D6').SetValue('19'); oSheet.GetRange('D7').SetValue('17'); oSheet.GetRange('D8').SetValue('12'); oSheet.GetRange('D9').SetValue('10'); oSheet.GetRange('D10').SetValue('9'); oSheet.GetRange('D11').SetValue('8'); oSheet.GetRange('D12').SetValue('8'); oSheet.GetRange('D13').SetValue('8'); oSheet.GetRange('D14').SetValue('8'); oSheet.GetRange('D15').SetValue('7'); oSheet.GetRange('D16').SetValue('7'); oSheet.GetRange('D17').SetValue('6'); oSheet.GetRange('D18').SetValue('6'); oSheet.GetRange('D19').SetValue('5'); oSheet.GetRange('D20').SetValue('5'); oSheet.GetRange('D21').SetValue('4'); oSheet.GetRange('D22').SetValue('4'); oSheet.GetRange('D23').SetValue('4'); oSheet.GetRange('D24').SetValue('3'); oSheet.GetRange('D25').SetValue('3'); oSheet.GetRange('D26').SetValue('3'); oSheet.GetRange('D27').SetValue('3'); oSheet.GetRange('E3').SetValue('37'); oSheet.GetRange('E4').SetValue('23'); oSheet.GetRange('E5').SetValue('18'); oSheet.GetRange('E6').SetValue('18'); oSheet.GetRange('E7').SetValue('10'); oSheet.GetRange('E8').SetValue('8'); oSheet.GetRange('E9').SetValue('18'); oSheet.GetRange('E10').SetValue('3'); oSheet.GetRange('E11').SetValue('12'); oSheet.GetRange('E12').SetValue('11'); oSheet.GetRange('E13').SetValue('7'); oSheet.GetRange('E14').SetValue('3'); oSheet.GetRange('E15').SetValue('6'); oSheet.GetRange('E16').SetValue('4'); oSheet.GetRange('E17').SetValue('6'); oSheet.GetRange('E18').SetValue('3'); oSheet.GetRange('E19').SetValue('3'); oSheet.GetRange('E20').SetValue('2'); oSheet.GetRange('E21').SetValue('9'); oSheet.GetRange('E22').SetValue('3'); oSheet.GetRange('E23').SetValue('2'); oSheet.GetRange('E24').SetValue('5'); oSheet.GetRange('E25').SetValue('2'); oSheet.GetRange('E26').SetValue('2'); oSheet.GetRange('E27').SetValue('1'); oSheet.GetRange('F3').SetValue('38'); oSheet.GetRange('F4').SetValue('17'); oSheet.GetRange('F5').SetValue('26'); oSheet.GetRange('F6').SetValue('19'); oSheet.GetRange('F7').SetValue('15'); oSheet.GetRange('F8').SetValue('21'); oSheet.GetRange('F9').SetValue('14'); oSheet.GetRange('F10').SetValue('9'); oSheet.GetRange('F11').SetValue('8'); oSheet.GetRange('F12').SetValue('10'); oSheet.GetRange('F13').SetValue('4'); oSheet.GetRange('F14').SetValue('4'); oSheet.GetRange('F15').SetValue('6'); oSheet.GetRange('F16').SetValue('6'); oSheet.GetRange('F17').SetValue('1'); oSheet.GetRange('F18').SetValue('2'); oSheet.GetRange('F19').SetValue('2'); oSheet.GetRange('F20').SetValue('4'); oSheet.GetRange('F21').SetValue('5'); oSheet.GetRange('F22').SetValue('15'); oSheet.GetRange('F23').SetValue('7'); oSheet.GetRange('F24').SetValue('9'); oSheet.GetRange('F25').SetValue('3'); oSheet.GetRange('F26').SetValue('2'); oSheet.GetRange('F27').SetValue('4'); for (var nCell = 0; nCell < 25; ++nCell) { oCellNumber = nCell + 3; oSheet.GetRange('G' + oCellNumber.toString()).SetValue('=SUM(D' + oCellNumber.toString() + ':F' + oCellNumber.toString() + ')'); } oSheet.GetRange('C29').SetValue('Total:'); oSheet.GetRange('C29').SetAlignHorizontal('right'); oSheet.GetRange('D29').SetValue('=SUM(D3:D27)'); oSheet.GetRange('E29').SetValue('=SUM(E3:E27)'); oSheet.GetRange('F29').SetValue('=SUM(F3:F27)'); oSheet.GetRange('G29').SetValue('=SUM(G3:G27)'); oSheet.GetRange('D29:F29').SetFontColor(Api.CreateColorFromRGB(67, 67, 67)); oSheet.GetRange('G29').SetFontColor(Api.CreateColorFromRGB(49, 133, 154)); oSheet.GetRange('C29:G29').SetFontSize(14); oSheet.FormatAsTable('B2:G29'); var oChart = oSheet.AddChart("'Medal Number'!$C$2:$F$27", false, 'barStacked3D', 18, 8, 1, 16, 14); oChart.SetVerAxisTitle("Medals", 10); oChart.SetHorAxisTitle("Countries", 10); oChart.SetLegendPos("right"); oChart.SetShowDataLabels(false, false, false); oChart.SetTitle("Total Medal Count", 18); var oChart2 = oSheet.AddChart("'Medal Number'!$C$2:$E$12", false, 'lineStacked', 2, 8, 15, 16, 27); oChart2.SetVerAxisTitle("Medals", 10); oChart2.SetHorAxisTitle("Top 10 Countries", 10); oChart2.SetLegendPos("right"); oChart2.SetShowDataLabels(false, false, false); oChart2.SetTitle("Gold&Silver Medals Count", 18); })();
В результате у вас должна получиться вот такая красота:

Вы можете скачать десктопное приложение ONLYOFFICE и всё попробовать. Кстати, макросы не единственное новшество вышедшей версии. Мы много всего пофиксили, добавили поддержку SSO, новые языки интерфейса (чешский и словацкий). Подробная информация о новой версии на GitHub.
Это всё. Ждем ваших вопросов, предложений, пожеланий и мыслей. Если у вас есть интересные файлы с макросами, которыми вы можете поделиться, присылайте на files@onlyoffice.com. Если у вас есть файлы без макросов, но с интересными проблемами и ошибками, ждем их тоже.

