Перейти к основному содержимому

Минфин: краткая информация об исполнении консолидированных бюджетов субъектов РФ

ПризнакЗначение
Уровень и охватКонсолидированные бюджеты субъектов РФ, уже сведённые в один агрегированный ряд по Российской Федерации; в проверенных файлах нет строк отдельных субъектов
Тип доступаФайлы по ссылке: HTML-страница раздела «Статистика → Бюджеты субъектов РФ» со списком документов и кнопкой «Скачать» для каждого XLSX
Основные форматыXLSX; обёртка — HTML
ОператорМинфин России
Режим доступаОткрытый (типовое скачивание без регистрации с официальной страницы)

Коротко: это три официальных временных ряда агрегированных показателей исполнения консолидированных бюджетов субъектов — месячный, квартальный и годовой. Они пригодны для анализа общей динамики по РФ, но не для сравнения регионов: в трёх проверенных XLSX отсутствуют названия субъектов, ОКТМО, ОКАТО, КБК, ИНН и строки по отдельным регионам. Для регламентированной отчётности по субъектам используйте консолидированные бюджеты субъектов на сайте Казначейства и форму 0503317.

Описание​

Карточка описывает витрину Краткая информация об исполнении бюджетов субъектов Российской Федерации: на странице перечислены документы с датами публикации и ссылками на выгрузки. На дату проверки 18.07.2026 HTML-каталог содержал ровно три карточки — ежемесячную, ежеквартальную и ежегодную; элемента постраничной навигации в полученном HTML нет. Каждая карточка даёт один XLSX с накопленным историческим рядом, а не новый файл на каждую дату.

  • ежемесячная краткая информация: накопленный с начала года ряд за 2011–июнь 2026;
  • ежеквартальная краткая информация: накопленный с начала года ряд от 1 квартала 2011 до 1 квартала 2026;
  • ежегодная краткая информация: финансовые годы 2006–2025.

Сюда не входят открытые наборы Минфина из каталога с list.csv и паспортами meta.csv — раздел subbud/execute — отдельная статистическая подборка на сайте ведомства, без включения в машинный реестр открытых данных того же формата.

Оператор​

Минфин России — канонический URL раздела: https://minfin.gov.ru/ru/statistics/subbud/execute/

URL и точки доступа​

Тип доступаURLФормат
Страница раздела (список документов, «Скачать» для каждого файла)https://minfin.gov.ru/ru/statistics/subbud/execute/HTML; вложения XLSX
Родительский раздел «Бюджеты субъектов Российской Федерации»https://minfin.gov.ru/ru/statistics/subbud/HTML (навигация по смежным материалам)

Прямые URL файлов XLSX при обновлении вложений меняются; для автоматизации ориентируйтесь на актуальную ссылку «Скачать» в карточке документа на странице раздела.

Объекты данных и показатели​

Проверка трёх вложений 18.07.2026 показала, что строка данных — не субъект РФ, а показатель × отчётный период в общероссийском агрегированном ряду. В каждом XLSX один лист: месяц, квартал или год.

  • В колонке B находятся русские подписи показателей, например «Доходы, всего», «Расходы, всего» и «Дефицит (-)/Профицит (+)»; в строке 3 после колонок A:B идут периоды.
  • Разделы I–IV отделяют доходы, расходы, дефицит/профицит и источники финансирования дефицита. Строки «РАЗДЕЛ I» и «в т.ч.» — служебные заголовки, не наблюдения.
  • В заголовке A2 всех трёх файлов указано млрд руб.. Долей в процентах, темпов роста и сравниваемой даты отдельными полями нет.
  • В проверенных файлах нет 89 строк субъектов, ОКТМО, ОКАТО, кодов субъектов, ИНН, КБК или регистрационных номеров. Поэтому это не микроданные и не таблица «субъект × статья».

Структура данных​

Ниже зафиксирован фактически проверенный шаблон трёх XLSX, скачанных 18.07.2026. Он описывает агрегированные временные ряды; не следует подменять им структуру построчной отчётности Казначейства.

Что является записью​

Логический объектГранулярность и строкаПоля, реально видимые в XLSXПодтверждение (лист, ячейка)
Агрегированный показатель исполненияОдна числовая ячейка на показатель × период для всей РФ; географическое измерение фиксировано№ п/п, русская подпись показателя, значение в млрд руб., период из строки 3месяц: B5 «Доходы, всего», GF3 июнь.26 *, GF5 12438.5516441863
Годовой агрегированный показательТа же строка показателя, столбец — финансовый год№ п/п, показатель, год, значениегод: B13 «Расходы, всего», V3 2025, V13 27397.247380059198
Раздел таблицыЗаголовок перед группой строк; не нормализуется как запись«РАЗДЕЛ I» … «РАЗДЕЛ IV», «в т.ч.»месяц: B4, B8, B12, B28, B30
Субъект РФВ проверенных XLSX отсутствует: нет строки, отдельного листа или кодового столбцаотсутствуетвсе три листа имеют только колонки A:B и временные колонки; например, месяц!A3:GF3

Следовательно, ожидаемая гранулярность «субъект × статья × дата» здесь не подтверждается. Субъектный уровень заложен в предмете агрегации («консолидированные бюджеты субъектов»), но не представлен как ось данных.

Поля записи​

Русское полеЛатинский slugТипЕдиница / значенияПримечание
Имя файлаsource_filestringимя XLSXНапример, Prilozhenie_6_dannye_112-114_—_mes.xlsx; URL берётся из каталога.
Отчётная дата / периодreporting_datedateYYYY-MM-DDИз строки 3: июнь.26 * → 2026-06-01; 1 кв.2026 → 2026-03-31; 2025 → 2025-12-31.
Сравнительная датаcomparison_datenullотсутствуетВ трёх листах нет отдельной второй даты или сравнительной колонки.
Тип периодаperiod_kindstringyear_to_date, financial_yearмесяц и квартал — накопленный итог; год — финансовый год. stock_as_of не встречался.
Уровень и имя географииgeography_level, geography_namestringтолько russia, Российская ФедерацияНативного разреза субъектов нет.
Уровень бюджетаbudget_levelstringconsolidated_subjectИз A2: «консолидированных бюджетов субъектов РФ».
Код субъекта / ОКТМО / ОКАТО / ИННsubject_code, oktmo, okato, innnullотсутствуютНе придумывайте их из названия: названий субъектов также нет.
Наименование показателяmetric_name_rustringисходная подпись BНапример, месяц!B5 — «Доходы, всего».
Нормализованный показатель и группаmetric_slug, metric_groupstringrevenue_total, expenditure_total, budget_balance; revenue, expenditure, balance, financing, otherНормализация подписи, не опубликованный Минфином код.
Значениеvaluenumberrub_billionsЗначение конкретной ячейки, например месяц!GF5.
Значение сравнения / темп / доляcomparison_value, growth_percent, share_percentnullотсутствуютФайл содержит ряд периодов, а не отдельное поле сравнения, процентов или долей.
Единицаunitstringrub_billionsУказана в A2: «млрд руб.».
Происхождение ячейкиsource_sheet, source_header, source_cellstringмесяц / квартал / год, исходная подпись, адрес ExcelНапример, месяц, июнь.26 *, GF5.
Статус извлеченияextraction_statusstringnative_xlsx_cell, manual_reviewДля проверенной числовой ячейки — native_xlsx_cell.
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Нормализованное наблюдение из XLSX subbud/execute",
"type": "object",
"additionalProperties": false,
"required": ["source_file", "reporting_date", "period_kind", "geography_level", "geography_name", "budget_level", "metric_name_ru", "metric_slug", "metric_group", "value", "unit", "source_sheet", "source_header", "source_cell", "extraction_status"],
"properties": {
"source_file": {"type": "string", "description": "Имя скачанного XLSX; URL хранится в записи HTML-каталога."},
"reporting_date": {"type": "string", "format": "date", "description": "Период из строки 3: например месяц!GF3 «июнь.26 *» → 2026-06-01."},
"comparison_date": {"type": "null", "description": "В листах месяц, квартал и год отдельная сравниваемая дата отсутствует."},
"period_kind": {"enum": ["year_to_date", "financial_year"], "description": "year_to_date для месяц/квартал с текстом A2 «накопленным итогом с начала года»; financial_year для год."},
"geography_level": {"const": "russia", "description": "Фиксированный охват листа; субъектных строк в месяц!A3:GF3 нет."},
"geography_name": {"const": "Российская Федерация", "description": "Нормализованное имя охвата агрегированного ряда."},
"budget_level": {"const": "consolidated_subject", "description": "Уровень из A2: консолидированные бюджеты субъектов РФ."},
"subject_code": {"type": "null", "description": "В XLSX отсутствует код субъекта."},
"oktmo": {"type": "null", "description": "В XLSX отсутствует ОКТМО."},
"okato": {"type": "null", "description": "В XLSX отсутствует ОКАТО."},
"inn": {"type": "null", "description": "В XLSX отсутствует ИНН."},
"metric_name_ru": {"type": "string", "description": "Исходная подпись из B, например месяц!B5 «Доходы, всего»."},
"metric_slug": {"type": "string", "description": "Нормализация русской подписи без приписывания КБК."},
"metric_group": {"enum": ["revenue", "expenditure", "balance", "financing", "other"], "description": "Группа по подписи и разделу, не код классификации."},
"value": {"type": "number", "description": "Число из исходной ячейки; например 12438.5516441863 из месяц!GF5, млрд руб."},
"comparison_value": {"type": "null", "description": "Отдельного значения сравнения нет."},
"growth_percent": {"type": "null", "description": "Отдельного темпа роста нет."},
"share_percent": {"type": "null", "description": "Отдельной доли в процентах нет."},
"unit": {"const": "rub_billions", "description": "Единица из A2 проверенных листов: «млрд руб.»."},
"source_sheet": {"enum": ["месяц", "квартал", "год"], "description": "Русское имя единственного листа XLSX."},
"source_header": {"type": "string", "description": "Исходная подпись периода из строки 3, например квартал!BK3 «1 кв.2026»."},
"source_cell": {"type": "string", "pattern": "^[A-Z]+[1-9][0-9]*$", "description": "Адрес ячейки значения, например год!V33."},
"extraction_status": {"enum": ["native_xlsx_cell", "manual_review"], "description": "Прямое чтение числовой ячейки либо проверка изменившегося макета вручную."}
}
}

Измерения, период и категории​

  • Заголовок A2 задаёт уровень «консолидированных бюджетов субъектов Российской Федерации». Консолидированный бюджет субъекта сводит бюджет субъекта и включённые по методике местные бюджеты с исключением внутренних перечислений; здесь этот уровень уже представлен суммарно по РФ, не по регионам.
  • Реальные доходные строки: «Доходы, всего», «Безвозмездные поступления от других бюджетов бюджетной системы Российской Федерации», «Собственные доходы», «Налог на прибыль», «Налог на доходы физических лиц», «Прочие». Самостоятельных строк «дотации», «субсидии» и «субвенции» в проверенных XLSX нет.
  • В расходах есть «Расходы, всего» и функциональные статьи от «Общегосударственных вопросов» до «Межбюджетных трансфертов общего характера…»; отдельно показаны баланс и источники финансирования дефицита.
  • месяц и квартал прямо названы накопленными с начала года. Их заголовки — месяцы/кварталы, не две даты для сравнения. год содержит финансовые годы 2006–2025. Исходная подпись периода должна сохраняться наряду с нормализованной датой.
  • Единица абсолютных значений — млрд руб.; процентных столбцов, долей и темпов роста нет.

Ключи связки​

Нативных ключей для региональной стыковки здесь нет: ОКТМО, ОКАТО, subject_code, ИНН, КБК, регномер и русское название отдельного субъекта отсутствуют. Автоматическая стыковка с региональными наборами по нативному ключу невозможна, а внешний справочник названий субъектов применять не к чему.

Эвристики имени файла и шапки​

Имена текущих вложений (…_mes.xlsx, …_Kvartal.xlsx, …_god.xlsx) не содержат отчётной даты: её нужно брать из строки 3. Функции ниже сначала распознают дату, если она всё же есть в имени/URL, затем подтверждают тип и единицу реальной шапкой. При нераспознанном заголовке извлечение должно остановиться.

from datetime import date
from pathlib import Path
from urllib.parse import unquote, urlparse
import re

DATE_RE = re.compile(
r"(?<!\d)(?P<day>0[1-9]|[12]\d|3[01])[._-](?P<month>0[1-9]|1[0-2])[._-](?P<year>20\d{2})(?!\d)"
r"|(?<!\d)(?P<compact>(?:0[1-9]|[12]\d|3[01])(?:0[1-9]|1[0-2])20\d{2})(?!\d)", re.I
)

def date_from_filename_or_url(value: str) -> date | None:
name = unquote(Path(urlparse(value).path).name) if "://" in value else value
match = DATE_RE.search(name)
if not match:
return None
if match.group("compact"):
text = match.group("compact")
return date(int(text[4:]), int(text[2:4]), int(text[:2]))
return date(int(match.group("year")), int(match.group("month")), int(match.group("day")))

def document_kind(filename_or_url: str, catalog_title: str = "") -> str:
text = f"{unquote(filename_or_url)} {catalog_title}".lower()
if any(x in text for x in ("ежемесяч", "_mes", "месяц")):
return "monthly"
if any(x in text for x in ("ежекварт", "kvartal", "квартал")):
return "quarterly"
if any(x in text for x in ("ежегод", "_god", "год")):
return "annual"
return "unknown"

def header_hints(sheet) -> dict[str, str | None]:
text = " ".join(str(sheet.cell(row, 1).value or "") for row in (1, 2)).lower()
return {
"budget_scope": "consolidated_subject_budgets" if "консолидированных бюджетов субъектов" in text else None,
"unit": "rub_billions" if "млрд" in text and "руб" in text else None,
"sheet_kind": document_kind(sheet.title),
}

Примеры работы с данными​

Инвентаризация каталога​

HTML-снимок, полученный при проверке, сохранён как /tmp/minfin-subbud-execute-2026-07-18.html. В нём нет пагинатора, поэтому 8–12 архивных карточек выбрать нельзя: раздел фактически отдал три актуальные карточки, по одной каждого типа. Не дополняйте этот список предполагаемыми архивными URL.

Заголовок карточкиОпубликовано / измененоМетка каталогаПрямая ссылка на вложениеРазмер
Краткая ежемесячная информация…09.07.2026 / 09.07.2026Документ; «Бюджеты субъектов РФ», «Статистика»Prilozhenie_6_dannye_112-114_—_mes.xlsxxlsx, 98.5 kb в каталоге; скачано 100 864 байта
Краткая ежеквартальная информация…18.05.2026 / 18.05.2026Документ; «Бюджеты субъектов РФ», «Статистика»6_dannye_112-114_—_Kvartal.xlsxxlsx, 42.31 kb в каталоге; скачано 43 324 байта
Краткая ежегодная информация…05.05.2026 / 05.05.2026Документ; «Бюджеты субъектов РФ», «Статистика»Prilozhenie_6_dannye_112-114_—_god.xlsxxlsx, 22.21 kb в каталоге; скачано 22 748 байт

Реальный блок карточек — #ajax-pagination-content-10818-57; число 57 используется и в параметре карточки id_57. В снимке не найдено ни .ajax-pagination-div, ни параметра page_…: парсер не подставляет page_65 из другого раздела, а извлекает параметр только если он появится в HTML.

{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "Запись HTML-каталога Minfin subbud/execute",
"type": "object",
"additionalProperties": false,
"required": ["title", "catalog_item_url", "attachments"],
"properties": {
"title": {"type": "string"},
"catalog_document_type": {"type": ["string", "null"]},
"published_date": {"type": ["string", "null"], "format": "date"},
"modified_date": {"type": ["string", "null"], "format": "date"},
"catalog_item_url": {"type": "string", "format": "uri"},
"attachments": {
"type": "array", "minItems": 1,
"items": {
"type": "object", "additionalProperties": false,
"required": ["label", "url", "format_size"],
"properties": {
"label": {"type": "string"},
"url": {"type": "string", "format": "uri"},
"format_size": {"type": "string", "examples": ["xlsx, 98.5 kb"]}
}
}
}
}
}
curl -L --fail --silent --show-error --compressed \
-A "Mozilla/5.0 (compatible; minfin-subbud-catalog-parser/1.0)" \
-H "Accept-Language: ru-RU,ru;q=0.9" \
"https://minfin.gov.ru/ru/statistics/subbud/execute/" \
-o minfin-subbud-execute.html
from __future__ import annotations

from datetime import datetime
from urllib.parse import parse_qs, urlencode, urljoin, urlparse, urlunparse
import json
import re
import requests
from bs4 import BeautifulSoup

CATALOG_URL = "https://minfin.gov.ru/ru/statistics/subbud/execute/"
CATALOG_SELECTOR = "#ajax-pagination-content-10818-57 .document_card"
HEADERS = {"User-Agent": "Mozilla/5.0 (compatible; minfin-subbud-catalog-parser/1.0)", "Accept-Language": "ru-RU,ru;q=0.9"}

def parse_date(value: str | None) -> str | None:
if not value:
return None
value = re.sub(r"^(Опубликовано|Изменено):\s*", "", value.strip())
try:
return datetime.strptime(value, "%d.%m.%Y").date().isoformat()
except ValueError:
return None

def get_soup(session: requests.Session, url: str) -> BeautifulSoup:
response = session.get(url, timeout=30)
response.raise_for_status()
return BeautifulSoup(response.content, "html.parser")

def parse_card(card) -> dict:
title = card.select_one("a.document_title")
doc_type = card.select_one("a.document_type")
dates = {"published_date": None, "modified_date": None}
for node in card.select(".document_info .date"):
text = node.get_text(" ", strip=True)
if text.startswith("Опубликовано:"):
dates["published_date"] = parse_date(text)
elif text.startswith("Изменено:"):
dates["modified_date"] = parse_date(text)
attachments = [
{"label": link.select_one(".file_title").get_text(" ", strip=True),
"url": urljoin(CATALOG_URL, link["href"]),
"format_size": link.select_one(".file_info").get_text(" ", strip=True)}
for link in card.select(".files_list a.file_item")
]
return {"title": title.get("title", title.get_text(" ", strip=True)),
"catalog_document_type": doc_type.get_text(" ", strip=True) if doc_type else None,
"catalog_item_url": urljoin(CATALOG_URL, title["href"]), **dates, "attachments": attachments}

def page_urls(first: BeautifulSoup) -> list[str]:
# 18.07.2026 список пуст: каталог состоит из первой страницы.
urls = [urljoin(CATALOG_URL, a["href"]) for a in first.select("a[href*='page_']")]
pages = [(key, int(value[0])) for url in urls for key, value in parse_qs(urlparse(url).query).items()
if key.startswith("page_") and value and value[0].isdigit()]
if not pages:
return [CATALOG_URL]
key, maximum = pages[0][0], max(page for _, page in pages)
parsed = urlparse(CATALOG_URL)
return [urlunparse(parsed._replace(query=urlencode({key: page}))) for page in range(1, maximum + 1)]

def collect_catalog() -> list[dict]:
with requests.Session() as session:
session.headers.update(HEADERS)
first = get_soup(session, CATALOG_URL)
soups = [first] + [get_soup(session, url) for url in page_urls(first)[1:]]
records, seen = [], set()
for soup in soups:
for card in soup.select(CATALOG_SELECTOR):
record = parse_card(card)
if record["catalog_item_url"] not in seen:
seen.add(record["catalog_item_url"])
records.append(record)
if not records or any(not item["attachments"] for item in records):
raise RuntimeError("Не найдены карточки или ссылки «Скачать»; проверьте HTML-каталог.")
return records

print(json.dumps(collect_catalog(), ensure_ascii=False, indent=2))

Репрезентативные XLSX​

ФайлКарточка и размерМетаданные / листСтруктура и преобладающий контент
месячный XLSXопубликован и изменён 09.07.2026; xlsx, 98.5 kb100 864 байта; 1 лист месяц; 42 × 188A3:B3 — «№ п/п», «Показатель»; C3:GF3 — месяцы 2011–июнь 2026. Весь лист уже агрегирован по РФ; субъектов и кодов нет.
квартальный XLSXопубликован и изменён 18.05.2026; xlsx, 42.31 kb43 324 байта; 1 лист квартал; 42 × 63C3:BK3 — от 1 кв.2011 до 1 кв.2026. Шаблон показателей тот же; нет пары дат и строк субъектов.
годовой XLSXопубликован и изменён 05.05.2026; xlsx, 22.21 kb22 748 байт; 1 лист год; 48 × 22C3:V3 — годы 2006–2025; есть четыре раздела и сноска об изменении функциональной классификации для ранних лет.

Объединены только служебные ячейки заголовка (A1:B1, A2:B2) и сноски; числовая часть читается как обычные ячейки. Предупреждение openpyxl об неизвестном расширении не меняет результат чтения, но исходный файл этой библиотекой перезаписывать не следует.

Чтение XLSX и нормализация​

Код отражает реальную структуру: один лист, заголовок в строке 3, показатели в B, значения по периодам. Он не создаёт субъектов и не ищет несуществующую вторую дату. Установите зависимость: python -m pip install openpyxl.

from __future__ import annotations

from datetime import date, datetime
from pathlib import Path
from typing import Any
import re
from openpyxl import load_workbook
from openpyxl.utils import get_column_letter

MONTHS = {"янв": 1, "фев": 2, "мар": 3, "апр": 4, "май": 5, "июн": 6, "июл": 7, "авг": 8, "сен": 9, "окт": 10, "ноя": 11, "дек": 12}
QUARTER_RE = re.compile(r"(?P<q>[1-4])\s*кв\.?\s*(?P<year>20\d{2})", re.I)
MONTH_RE = re.compile(r"(?P<month>[а-яё]+)\.?\s*(?P<year>\d{2})", re.I)
SLUGS = {
"Доходы, всего": ("revenue_total", "revenue"),
"Безвозмездные поступления от других бюджетов бюджетной системы Российской Федерации": ("interbudgetary_receipts", "revenue"),
"Собственные доходы (стр.(1) - стр.(1.1.))": ("own_revenue", "revenue"),
"Налог на прибыль": ("corporate_income_tax", "revenue"),
"Налог на доходы физических лиц": ("personal_income_tax", "revenue"),
"Расходы, всего": ("expenditure_total", "expenditure"),
"Дефицит (-)/Профицит (+)": ("budget_balance", "balance"),
"Источники финансирования дефицита": ("deficit_financing", "financing"),
}
SECTION_LABELS = {"РАЗДЕЛ I", "РАЗДЕЛ II", "РАЗДЕЛ III", "РАЗДЕЛ IV", "в т.ч."}

def period_from_header(value: object) -> date:
if isinstance(value, datetime):
return value.date()
if isinstance(value, int) and 2000 <= value <= 2100:
return date(value, 12, 31)
text = str(value).strip().lower()
if match := QUARTER_RE.search(text):
q = int(match.group("q"))
return date(int(match.group("year")), q * 3, (31, 30, 30, 31)[q - 1])
if match := MONTH_RE.search(text):
number = next((n for prefix, n in MONTHS.items() if match.group("month").startswith(prefix)), None)
if number:
return date(2000 + int(match.group("year")), number, 1)
raise ValueError(f"Нераспознанный заголовок периода: {value!r}")

def parse_subbud_xlsx(path: str | Path) -> list[dict[str, Any]]:
path = Path(path)
workbook = load_workbook(path, data_only=True, read_only=False)
if len(workbook.sheetnames) != 1:
raise ValueError(f"Ожидался один лист, получено: {workbook.sheetnames}")
sheet = workbook.active
kinds = {"месяц": "year_to_date", "квартал": "year_to_date", "год": "financial_year"}
if sheet.title not in kinds or "консолидированных бюджетов субъектов" not in str(sheet["A2"].value).lower():
raise ValueError("Не подтверждены лист или заголовок A2; требуется manual_review.")
records = []
for column in range(3, sheet.max_column + 1):
header = sheet.cell(3, column).value
for row in range(4, sheet.max_row + 1):
label, value = sheet.cell(row, 2).value, sheet.cell(row, column).value
if not isinstance(label, str) or label.strip() in SECTION_LABELS or not isinstance(value, (int, float)):
continue
slug, group = SLUGS.get(label.strip(), ("unmapped_metric", "other"))
records.append({
"source_file": path.name, "reporting_date": period_from_header(header).isoformat(),
"comparison_date": None, "period_kind": kinds[sheet.title],
"geography_level": "russia", "geography_name": "Российская Федерация",
"budget_level": "consolidated_subject", "subject_code": None, "oktmo": None,
"okato": None, "inn": None, "metric_name_ru": label.strip(),
"metric_slug": slug, "metric_group": group, "value": float(value),
"comparison_value": None, "growth_percent": None, "share_percent": None,
"unit": "rub_billions", "source_sheet": sheet.title,
"source_header": str(header), "source_cell": f"{get_column_letter(column)}{row}",
"extraction_status": "native_xlsx_cell",
})
if not records:
raise RuntimeError("Не извлечены числовые ячейки; проверьте макет XLSX вручную.")
return records

records = parse_subbud_xlsx("Prilozhenie_6_dannye_112-114_—_mes.xlsx")
print(records[-1])

Числовая сверка на исходных ячейках подтверждает, что баланс — это доходы минус расходы. В месячном файле месяц!GF5 = 12 438.5516441863, GF13 = 12 598.8606947714, GF29 = −160.3090505850996 млрд руб.; GF5 − GF13 = GF29. В годовом: за 2024 год!U5 − U13 = U33 — 24 621.4995373921 − 24 919.30315202 = −297.80361462789733, за 2025 V5 − V13 = V33 — 25 858.756899381602 − 27 397.247380059198 = −1 538.4904806775958 млрд руб.

Ограничения при автоматизации​

  • Прямой URL, имя и размер вложения — свойства текущей HTML-карточки; каждый запуск начинает со свежего каталога. В снимке 18.07.2026 пагинации нет, но парсер не предполагает, что так будет всегда.
  • Исторические шапки содержат сноски и меняющиеся подписи (янв.23 **, июнь.26 *, 2 кв.2024 **). Сохраняйте source_header и не заменяйте его только нормализованной датой.
  • В шапке есть объединённые ячейки, в данных — строки-разделители и примечания. При новом листе, неизвестном периоде или несовпадении A2 переключайтесь на manual_review.
  • В файлах нет субъектных строк и нативных идентификаторов. Нельзя разложить сумму по РФ на 89 субъектов, связать её с ОКТМО/КБК или выдать за 0503317.
  • В подвале проверенной страницы Минфина указана лицензия Creative Commons Attribution 4.0. При повторном использовании указывайте Минфин России, исходную карточку, вложение и дату обращения.

Сводка для машинной обработки​

primary_url: "https://minfin.gov.ru/ru/statistics/subbud/execute/"
catalog_selector_hint: "#ajax-pagination-content-10818-57 .document_card; .files_list a.file_item[href$='.xlsx']; в снимке 2026-07-18 пагинация и page_* отсутствуют"
catalog_snapshot:
checked_on: "2026-07-18"
document_count: 3
coverage: "месячный 2011–июнь 2026; квартальный 2011–1 кв. 2026; годовой 2006–2025"
formats: [html, xlsx]
update_cadence: "три обновляемых временных ряда; фактическая публикация и изменение видны в карточках HTML"
reporting_slices: ["месяц", "квартал", "год"]
budget_scope: "consolidated_subject_budgets aggregated for Russia"
native_join_keys: []
non_native_identifiers: [oktmo, okato, subject_code, inn, kbk]
typical_units: [rub_billions]
parser_libs: [openpyxl, pandas, beautifulsoup4, requests]
known_caveats:
- "В проверенных XLSX нет строк субъектов: одна ячейка означает показатель × период для всей РФ."
- "Нет ОКТМО, ОКАТО, кода субъекта, ИНН, КБК, comparison_value, процентов и второго сравниваемого периода."
- "В шапках и сносках меняются подписи периодов; исходный source_header следует сохранять."
- "Прямые URL вложений не следует считать постоянными: сначала читать свежий HTML-каталог."
license: "CC BY 4.0; указывать Минфин России, исходную карточку и вложение"

Периодичность обновления​

Публикации привязаны к выходу новых редакций трёх документов: у каждой HTML-карточки указаны даты «Опубликовано» и «Изменено». На проверенную дату последний месячный файл опубликован 09.07.2026, квартальный — 18.05.2026, годовой — 05.05.2026. Стабильного API нет; перед массовой загрузкой проверяйте каталог и заголовок последней колонки XLSX.

Ограничения и особенности​

  • Материалы официального сайта Минфина распространяются на условиях Creative Commons Attribution 4.0 (блок в подвале страниц minfin.gov.ru); при переработке указывайте источник, карточку и вложение.
  • XLSX машиночитаемы, но не являются контрактным API: есть объединённые ячейки, сноски, пустые исторические ячейки и меняющаяся функциональная классификация между годами.
  • Это официальный, но частичный по детализации источник: он покрывает агрегированный результат по РФ, а не строки каждого субъекта или муниципалитета.
  • Показатели Минфина в этих XLSX не обязаны построчно совпадать с открытыми наборами Минфина, Казначейством или Росстатом — сверяйте охват, период, методику и подпись показателя.

Примеры доступа​

Сохранить HTML-страницу раздела для ручного или последующего разбора ссылок «Скачать»:

curl -L --fail --silent --show-error --compressed \
-A "Mozilla/5.0" \
-H "Accept-Language: ru-RU,ru;q=0.9" \
"https://minfin.gov.ru/ru/statistics/subbud/execute/" \
-o minfin-subbud-execute.html

Связанные страницы wiki​

Не путать с​

Частые вопросы​

В: Можно ли по этим XLSX восстановить исполнение по каждому КБК по субъекту?

О: Нет. В трёх проверенных файлах один агрегированный ряд по РФ; строк субъектов, КБК, ОКТМО, ОКАТО и ИНН нет. Для субъектного и регламентированного разреза используйте консолидированные бюджеты субъектов и форму 0503317.

В: Почему цифра в годовом файле Минфина не совпадает с суммой по строкам 0503317?

О: Различаются определение показателя, момент среза, методика свёртки и источник агрегации (Минфин публикует краткую сводку, Казначейство — регламентированную форму). Сверяйте заголовки документов и пояснения к таблицам в обоих источниках.