javascript

Внезапно: новая версия ONLYOFFICE с макросами

  • пятница, 12 января 2018 г. в 03:16:44
https://habrahabr.ru/company/teamlab/blog/346382/
  • Open source
  • JavaScript
  • API
  • Блог компании ONLYOFFICE


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

В этой статье мы расскажем, что у нас за макросы, чем они отличаются от макросов 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);
})();


В результате у вас должна получиться вот такая красота:

image

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

Это всё. Ждем ваших вопросов, предложений, пожеланий и мыслей. Если у вас есть интересные файлы с макросами, которыми вы можете поделиться, присылайте на files@onlyoffice.com. Если у вас есть файлы без макросов, но с интересными проблемами и ошибками, ждем их тоже.