По оценкам специалистов, в 2025 году объём рынка бизнес-аналитики составит $32,4 млрд, а к 2035 году достигнет $64,3 млрд, при этом среднегодовой темп роста за прогнозируемый период составит 7,1%.

Business Intelligence — это не одна или несколько программ, а целые комплексы аналитических инструментов, собранные, как сейчас любят говорить, в «экосистемы». В последние годы бизнес-аналитика переживает беспрецедентную революцию.

Главными задачами BI были сбор и систематизация данных, поступающих из разных источников. На основе визуализации этих данных затем принимались управленческие решения.

Крупные BI-системы и их разработчики известны: Oracle BI, SAP BusinessObjects, IBM Cognos. Это классические BI-системы: дорогие, трудные во внедрении, сложные в использовании, требуют найма специалистов для обслуживания, развития и техподдержки. Стоимость их лицензирования постоянно растёт, а эффективность использования снижается.

В то же время такие сервисы для сбора и систематизации данных, как онлайн-таблицы, считались инструментами вторичными, предполагающими лишь несложные быстрые расчёты «на коленке», или даже вообще не рассматривались. Но, после появления искусственного интеллекта мир стал меняться. В обычных табличных онлайн-редакторах появились ИИ-ассистенты, которые уже могут решать часть проблем. Они сделали таблицы ближе к человеку и проще в использовании, здорово снизив порог входа в рабочие процессы. С этого момента онлайн-таблицы стали понемногу «отъедать» у крупных, дорогих и ожиревших от модулей BI-систем часть рынка в зоне «быстрой аналитики».

Вместо того, чтобы постоянно бегать к инженерам, сидеть в приёмной руководителя или ждать, пока обработается тикет, теперь бухгалтер сам может попросить ИИ «человеческим языком», «на лету» изменить логику какого-то документа, добавить новый срез или дополнительную выборку. И при этом ему не потребуется вникать в SQL, C++ или Java. Да и платить предприятию большие деньги за внедрение сложных BI не придётся. Достаточно будет завести корпоративный аккаунт в онлайн-таблицах, расшарить его для пары-тройки коллег и вести простые расчёты прямо там.

BI-системы сегодня находятся в сложной ситуации. Компании переходят от аналитики на основе сложных разработок к анализу данных с помощью ИИ. Конечно, BI-системы не исчезнут. Они останутся там, где необходима автономная обработка и структурирование огромных массивов данных. Но в сферах, где расчёты относительно просты и нужно делать их очень быстро, онлайн-таблицы с ИИ-ассистентами могут вытеснить BI, помогая сэкономить важнейшие для бизнеса ресурсы — время от вопроса до ответа или решения и деньги.

Как автоматизировать простые задачи

Ассистент, встроенный в Google-таблицы представляет собой отдельный чат, в котором можно задавать вопросы искусственному интеллекту. Никакой волшебной кнопки, которая решала бы все проблемы здесь, конечно же нет. Но помощник может подсказать способы решения множества разных задач, с которыми приходится сталкиваться пользователю. Ты задаёшь вопросы — он отвечает и подсказывает, как действовать дальше. Происходит почти то же, что и в окне чата ИИ, но только ассистент «заточен» под специфику работы с таблицами и, при необходимости не только ответит на конкретный вопрос, но и поможет с формулой или синтаксисом, выдаст в окне нужные данные, проведёт «по шагам», если потребуется сделать что-то очень сложное. Удобное решение.

Благодаря ИИ современные таблицы перестали быть просто «сеткой ячеек». Обладая подобными инструментами, они постепенно превращаются в умные аналитические системы, которые в недалёком будущем смогут самостоятельно загружать, очищать, агрегировать и визуализировать данные. А пользователь будет только наблюдать и управлять их действиями.

Но и без ИИ, таблицы — штука мощная. При большом желании с их помощью можно кое-что автоматизировать, используя только встроенные инструменты. Давайте создадим скрипт, который будет загружать данные, группировать и выводить срез клиентов по странам из найденного в Сети примера. Так в идеале и должен работать ИИ — как автономный аналитик, встроенный в привычный интерфейс. Такой подход будет особенно ценен для бизнеса, поскольку, как я уже писал выше, сэкономит время и ресурсы.

function refreshFromCsvAndSummarize() {
  const CSV_URL = 'https://drive.google.com/uc?export=download&id=1zO8ekHWx9U7mrbx\_0Hoxxu6od7uxJqWw';
  const RAW_SHEET = 'Raw';
  const SUMMARY_SHEET = 'Summary';
  const DASHBOARD_SHEET = 'Dashboard';
  const groupCol = 6;

  const ss = SpreadsheetApp.getActive();
  const raw = ss.getSheetByName(RAW_SHEET) || ss.insertSheet(RAW_SHEET);
  const summary = ss.getSheetByName(SUMMARY_SHEET) || ss.insertSheet(SUMMARY_SHEET);
  const dashboard = ss.getSheetByName(DASHBOARD_SHEET) || ss.insertSheet(DASHBOARD_SHEET);

  const resp = UrlFetchApp.fetch(CSV_URL);
  const csv = resp.getContentText('UTF-8');
  if (csv.trim().startsWith('<')) throw new Error('Получен HTML, а не CSV');

  const data = Utilities.parseCsv(csv);
  raw.clear();
  raw.getRange(1, 1, data.length, data[0].length).setValues(data);

  const rows = raw.getDataRange().getValues();
  const header = rows[0];
  const cleaned = [header].concat(rows.slice(1).filter(r => r.some(c => String(c).trim() !== '')));
  raw.clear();
  raw.getRange(1, 1, cleaned.length, cleaned[0].length).setValues(cleaned);

  const agg = new Map();
  cleaned.slice(1).forEach(r => {
    const key = String(r[groupCol]).trim();
    if (key) agg.set(key, (agg.get(key) || 0) + 1);
  });

  const out = [['Страна', 'Клиентов']].concat(Array.from(agg.entries()).sort((a, b) => b[1] - a[1]));
  summary.clear();
  summary.getRange(1, 1, out.length, out[0].length).setValues(out);

  dashboard.clear();
  dashboard.getRange(1, 1, out.length, out[0].length).setValues(out);
  const chart = dashboard.newChart()
    .asColumnChart()
    .addRange(dashboard.getRange(1, 1, out.length, 2))
    .setOption('title', 'Клиенты по странам')
    .setOption('height', 400)
    .setOption('width', 800)
    .setPosition(5, 1, 0, 0)
    .build();
  dashboard.insertChart(chart);
}

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

Лидеры рынка тоже пытаются не отстать от жизни. Microsoft внедряет аналогичные решения в свои облачные сервисы, но работать с ними сложнее, так как они являются частью экосистемы Microsoft 365. Google Sheets с Apps Script намного доступнее.

Доступный ИИ-ассистент появился  и в Яндекс Таблицах. Встроенные нейросетевые возможности помогут получить краткий пересказ текста, ужать его до тезисов, перевести на другой язык или вообще придумать, определить тональность (полезная функция, во всю используемая в чатах служб поддержки), извлечь из массива данных нужную информацию, распределить по категориям, исправить ошибки, составить формулы для расчётов. ИИ поможет навести порядок в данных — убрать двойные пробелы, привести все даты к единому формату и т. д.

И его ключевая фишка – нативная поддержка русского языка, которая позволяет “общаться” с таблицами простым языком: без формул, без скриптов и всего того, что пугает людей в таблицах (хотя, если нужно, все это имеется). ИИ в Таблицах выступают в роли ассистента, который выполнит поставленные задачи. 

Сервис, как и современный Excel, также является частью экосистемы (в данном случае, Яндекс 360), но пользоваться ИИ можно с некоторыми ограничениями без подписки и без дополнительных трудностей. Сервис можно считать неплохим входным билетом в табличный ИИ. 

В 2026 году появятся и десктопные приложения Документов и Таблиц от Яндекс 360 для Windows, macOS и Linux, которые будут совместимы с MS Office. Разработчики обещают, что новые приложения справятся даже со сложными документами и нестандартным форматированием. И уже с самого начала пользователям будут доступны редактирование, комментирование и рецензирование, а чуть позднее — синхронизация с облаком. ИИ, судя по косвенным признакам, также будет доступен. Но официально это не подтверждали.

Старый Exсel без ИИ, но умные задачи решать умеет

Почти то же самое — загрузку файлов, очистку данных, формирование отчётов, построение диаграмм — можно выполнить в старом Excel, не вкладывая ни рубля в облачные подписки. Любой Excel, даже весьма преклонных лет выпуска, представляет собой крепкую платформу для несложной автоматизации: он умеет работать с UTF-8, корректно парсит сложные CSV, выбирает необходимые данные — и делает всё это локально, без подключения жадных облачных сервисов, вроде Microsoft 365. Excel используют более 750 млн пользователей во всём мире.

Правда, хозяева Microsoft, похоже, окончательно «зажрались»: вместо развития встроенного, доступного всем инструментария, компания всё больше толкает пользователей в платные экосистемы Power Platform, Office Scripts и облако, превращая решение достаточно простых задач в привилегию подписчиков. А между тем — Excel, под рукой, без интернета и ежемесячных платежей и ещё может «задать жару».

Создадим в нём скрипт, который, хоть и не будет использовать нейросети, но покажет те же возможности, которые мы уже использовали в таблицах Google. Он найдёт и скачает нужный файл, сделает необходимую выборку и должным образом её оформит (группируем пользователей по значению из колонки address в найденном примере). При желании скрипт можно расширить, добавив нужные функции.

Option Explicit

' === НАСТРОЙКИ ===
Private Const CSV_URL As String = "https://template-builder.net/test-data/csv-files/10kb.csv"
Private Const RAW_SHEET As String = "Raw"
Private Const SUMMARY_SHEET As String = "Summary"
Private Const CHART_NAME As String = "SummaryChart"

Private Const DELIMITER As String = ","
Private Const GROUP_BY_HEADER As String = "address"
Private Const AGG_HEADER As String = ""   ' "" = COUNT

Public Sub RefreshFromCsvAndSummarize_ByHeader()
    Dim oldCalc As XlCalculation, oldSU As Boolean
    oldCalc = Application.Calculation
    oldSU = Application.ScreenUpdating

    On Error GoTo Cleanup
    Application.ScreenUpdating = False
    Application.Calculation = xlCalculationManual

    Dim csvText As String
    csvText = HttpGetUtf8(CSV_URL)

    Dim data As Variant
    data = CsvTo2DArray(csvText, DELIMITER)

    If IsEmpty(data) Then Err.Raise vbObjectError + 9001, , "CSV parsed as empty."

    Dim cleaned As Variant
    cleaned = RemoveCompletelyBlankRows(data)
    If IsEmpty(cleaned) Then Err.Raise vbObjectError + 9002, , "All rows are blank after cleaning."

    Dim wb As Workbook: Set wb = ThisWorkbook
    Dim wsRaw As Worksheet: Set wsRaw = GetOrCreateSheet(wb, RAW_SHEET)
    Dim wsSum As Worksheet: Set wsSum = GetOrCreateSheet(wb, SUMMARY_SHEET)

    ' 1) Raw
    wsRaw.Cells.Clear
    wsRaw.Range("A1").Resize(UBound(cleaned, 1), UBound(cleaned, 2)).Value = cleaned

    ' 2) Find columns by header
    Dim keyCol As Long
    keyCol = FindColumnIndexByHeader(cleaned, GROUP_BY_HEADER)
    If keyCol = 0 Then Err.Raise vbObjectError + 2001, , "GROUP_BY_HEADER not found: " & GROUP_BY_HEADER

    Dim sumCol As Long
    If Trim$(AGG_HEADER) <> "" Then
        sumCol = FindColumnIndexByHeader(cleaned, AGG_HEADER)
        If sumCol = 0 Then Err.Raise vbObjectError + 2002, , "AGG_HEADER not found: " & AGG_HEADER
    Else
        sumCol = 0
    End If

    ' 3) Summarize
    Dim summary As Variant
    summary = GroupAgg(cleaned, keyCol, sumCol)

    wsSum.Cells.Clear
    wsSum.Range("A1").Resize(UBound(summary, 1), UBound(summary, 2)).Value = summary
    wsSum.Columns("A:B").AutoFit

    ' 4) Chart
    UpsertSummaryChart wsSum, CHART_NAME, UBound(summary, 1)

Cleanup:
    Application.Calculation = oldCalc
    Application.ScreenUpdating = oldSU
    If Err.Number <> 0 Then Err.Raise Err.Number, Err.Source, Err.Description
End Sub

' =========================
' HTTP GET with UTF-8 decode (WinHTTP)
' =========================
Private Function HttpGetUtf8(ByVal url As String) As String
    Dim req As Object: Set req = CreateObject("WinHttp.WinHttpRequest.5.1")
    req.Option(6) = True ' follow redirects

    req.Open "GET", url, False
    req.SetRequestHeader "User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
    req.SetRequestHeader "Accept", "text/csv,text/plain,*/*;q=0.8"
    req.SetRequestHeader "Referer", "https://template-builder.net/"
    req.Send

    If req.Status < 200 Or req.Status >= 300 Then
        Err.Raise vbObjectError + 1000, , "HTTP " & req.Status & vbCrLf & Left$(req.ResponseText, 800)
    End If

    Dim stm As Object: Set stm = CreateObject("ADODB.Stream")
    stm.Type = 1: stm.Open
    stm.Write req.ResponseBody
    stm.Position = 0
    stm.Type = 2: stm.Charset = "utf-8"
    HttpGetUtf8 = stm.ReadText
    stm.Close
End Function

' ==========================================================
' CSV parser (supports quotes + embedded newlines in quotes)
' ==========================================================
Private Function CsvTo2DArray(ByVal csvText As String, ByVal delim As String) As Variant
    If Len(delim) <> 1 Then Err.Raise vbObjectError + 3001, , "Delimiter must be 1 character"
    csvText = Replace(csvText, ChrW(&HFEFF), "")

    Dim rows As Collection: Set rows = New Collection

    Dim inQuotes As Boolean
    Dim field As String: field = ""
    Dim fields As Collection: Set fields = New Collection

    Dim i As Long, ch As String
    Dim L As Long: L = Len(csvText)

    i = 1
    Do While i <= L
        ch = Mid$(csvText, i, 1)

        If ch = """" Then
            If inQuotes Then
                If i < L And Mid$(csvText, i + 1, 1) = """" Then
                    field = field & """"
                    i = i + 1
                Else
                    inQuotes = False
                End If
            Else
                inQuotes = True
            End If

        ElseIf (Not inQuotes) And (ch = delim) Then
            fields.Add field
            field = ""

        ElseIf (Not inQuotes) And (ch = vbCr Or ch = vbLf) Then
            fields.Add field
            field = ""

            rows.Add FieldsToArray(fields)
            Set fields = New Collection

            If ch = vbCr And i < L And Mid$(csvText, i + 1, 1) = vbLf Then
                i = i + 1
            End If

        Else
            field = field & ch
        End If

        i = i + 1
    Loop

    If fields.Count > 0 Or Len(field) > 0 Then
        fields.Add field
        rows.Add FieldsToArray(fields)
    End If

    CsvTo2DArray = RowsTo2DArray(rows)
End Function

Private Function FieldsToArray(ByVal fields As Collection) As Variant
    Dim arr() As Variant, j As Long
    ReDim arr(1 To fields.Count) As Variant
    For j = 1 To fields.Count
        arr(j) = fields(j)
    Next j
    FieldsToArray = arr
End Function

Private Function RowsTo2DArray(ByVal rows As Collection) As Variant
    If rows.Count = 0 Then
        RowsTo2DArray = Empty
        Exit Function
    End If

    Dim r As Long, c As Long, maxCols As Long
    maxCols = 0

    For r = 1 To rows.Count
        Dim rowArr As Variant
        rowArr = rows(r)
        If Not IsEmpty(rowArr) Then
            If UBound(rowArr) > maxCols Then maxCols = UBound(rowArr)
        End If
    Next r

    Dim out() As Variant
    ReDim out(1 To rows.Count, 1 To maxCols) As Variant

    For r = 1 To rows.Count
        rowArr = rows(r)
        For c = 1 To UBound(rowArr)
            out(r, c) = rowArr(c)
        Next c
    Next r

    RowsTo2DArray = out
End Function

' =========================
' Cleaning: remove blank rows (keeps header)
' =========================
Private Function RemoveCompletelyBlankRows(ByVal data As Variant) As Variant
    If IsEmpty(data) Then
        RemoveCompletelyBlankRows = Empty
        Exit Function
    End If

    Dim rowsCount As Long: rowsCount = UBound(data, 1)
    Dim colsCount As Long: colsCount = UBound(data, 2)

    Dim temp() As Variant
    ReDim temp(1 To rowsCount, 1 To colsCount) As Variant

    Dim r As Long, c As Long, outR As Long
    outR = 1

    For c = 1 To colsCount
        temp(outR, c) = data(1, c)
    Next c

    For r = 2 To rowsCount
        Dim hasAny As Boolean: hasAny = False
        For c = 1 To colsCount
            If Len(Trim$(CStr(data(r, c)))) > 0 Then
                hasAny = True
                Exit For
            End If
        Next c

        If hasAny Then
            outR = outR + 1
            For c = 1 To colsCount
                temp(outR, c) = data(r, c)
            Next c
        End If
    Next r

    ReDim Preserve temp(1 To outR, 1 To colsCount) As Variant
    RemoveCompletelyBlankRows = temp
End Function

' =========================
' Header lookup (case-insensitive + trims + BOM)
' =========================
Private Function FindColumnIndexByHeader(ByVal data As Variant, ByVal headerName As String) As Long
    Dim colsCount As Long: colsCount = UBound(data, 2)
    Dim c As Long, target As String
    target = LCase$(Trim$(headerName))

    For c = 1 To colsCount
        Dim h As String
        h = Replace(CStr(data(1, c)), ChrW(&HFEFF), "")
        h = LCase$(Trim$(h))
        If h = target Then
            FindColumnIndexByHeader = c
            Exit Function
        End If
    Next c

    FindColumnIndexByHeader = 0
End Function

' =========================
' Aggregation: COUNT or SUM
' =========================
Private Function GroupAgg(ByVal data As Variant, ByVal keyCol As Long, ByVal sumCol As Long) As Variant
    Dim dict As Object: Set dict = CreateObject("Scripting.Dictionary")

    Dim r As Long
    For r = 2 To UBound(data, 1)
        Dim key As String
        key = Trim$(CStr(data(r, keyCol)))
        If key = "" Then GoTo NextRow

        If sumCol = 0 Then
            If dict.Exists(key) Then dict(key) = dict(key) + 1 Else dict.Add key, 1
        Else
            Dim v As Double
            v = ToDoubleSafe(data(r, sumCol))
            If dict.Exists(key) Then dict(key) = dict(key) + v Else dict.Add key, v
        End If
NextRow:
    Next r

    Dim out() As Variant
    ReDim out(1 To dict.Count + 1, 1 To 2) As Variant
    out(1, 1) = "Group"
    out(1, 2) = IIf(sumCol = 0, "Count", "Sum")

    Dim i As Long: i = 0
    Dim k As Variant
    For Each k In dict.Keys
        i = i + 1
        out(i + 1, 1) = k
        out(i + 1, 2) = dict(k)
    Next k

    GroupAgg = out
End Function

Private Function ToDoubleSafe(ByVal v As Variant) As Double
    On Error GoTo Fail
    Dim s As String: s = Trim$(CStr(v))
    If s = "" Then ToDoubleSafe = 0: Exit Function

    s = Replace(s, " ", "")
    Dim decSep As String: decSep = Application.International(xlDecimalSeparator)
    If decSep = "," Then s = Replace(s, ".", ",") Else s = Replace(s, ",", ".")
    ToDoubleSafe = CDbl(s)
    Exit Function
Fail:
    ToDoubleSafe = 0
End Function

' =========================
' Chart: create/update
' =========================
Private Sub UpsertSummaryChart(ByVal ws As Worksheet, ByVal chartName As String, ByVal lastRow As Long)
    If lastRow < 2 Then Exit Sub

    Dim rng As Range
    Set rng = ws.Range("A1:B" & lastRow)

    Dim co As ChartObject
    On Error Resume Next
    Set co = ws.ChartObjects(chartName)
    On Error GoTo 0

    If co Is Nothing Then
        Set co = ws.ChartObjects.Add(Left:=300, Top:=10, Width:=520, Height:=320)
        co.Name = chartName
    End If

    With co.Chart
        .ChartType = xlColumnClustered
        .SetSourceData Source:=rng
        .HasTitle = True
        .ChartTitle.Text = "Summary (" & GROUP_BY_HEADER & ")"
        On Error Resume Next
        .Legend.Delete
        On Error GoTo 0
    End With
End Sub

' =========================
' Utilities
' =========================
Private Function GetOrCreateSheet(ByVal wb As Workbook, ByVal name As String) As Worksheet
    On Error Resume Next
    Set GetOrCreateSheet = wb.Worksheets(name)
    On Error GoTo 0

    If GetOrCreateSheet Is Nothing Then
        Set GetOrCreateSheet = wb.Worksheets.Add(After:=wb.Worksheets(wb.Worksheets.Count))
        GetOrCreateSheet.Name = name
    End If
End Function

Итог: таблица клиентов, разбитая по адресам. Может и неидеально, зато информативно.

А можно ли, допустим, интегрировать Exсel и ИИ (построить собственное маленькое королевство, где-нибудь на частной фирме), минуя все препятствия, вроде корпоративных интересов компаний, платной подписки и прочего раздражающего мусора? Да. можно. Хотя, это не так просто.

На GitHub есть проект xlsm-llm, который предлагает готовый набор функций для решения таких задач. Разработчики пишут, что их система работает в Windows, Linux и MacOs и есть даже гайд по установке.

Она позволяет отправлять ИИ, обрабатывать тексты, обобщать, переводить и генерировать код в Exсel. Причём xlsm-llm поддерживает как локальные модели, так и внешние API (OpenAI, Gemini и Upstage). В случае использования локальных моделей будут, конечно, огромные «подводные камни», в виде запуска языковой модели на локальном сервере. Но при желании и наличии некоторых ресурсов возможно и не такое.

Вывод

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

Экономический эффект от перехода в эру ИИ впечатляет: компании смогут сократить затраты на аналитику, одновременно повысив скорость принятия решений. Полный контроль над данными, ранее сосредоточенный в руках инженеров, теперь станет доступен и сотрудникам из смежных отраслей: бухгалтерам, экономистам, маркетологам, что даст бизнесу большую гибкость. Через год-два году мы сможем наблюдать дальнейшую эволюцию этого тренда: появление десктопных приложений с ИИ-возможностями, и дальнейшее снижение барьеров для входа в аналитику. Мы видим, что об этом задумались как мировые гиганты, так и локальные вендоры. В России первый шаг в этом направлении сделал Яндекс 360. Скорее всего, за ним последуют и другие компании. 

Будущее бизнес-аналитики — за гибридными решениями, где ИИ-ассистенты в привычных инструментах, вроде Google Sheets и Excel станут первым шагом в аналитику, а традиционные BI-платформы будут использоваться для решения ресурсоёмких задач другого уровня. Этот переход не просто сэкономит деньги и время — он сделает данные доступным стратегическим ресурсом для любого специалиста, независимо от его технической подготовки.