6 мифов об автоматизации бюджетирования в 1С

Введение: почему финансисты не доверяют 1С
Каждый второй финансовый директор, с которым приходится работать консультантам по автоматизации, произносит примерно одну и ту же фразу: «Мы пробовали перейти на бюджетирование в 1С, но в итоге всё равно вернулись к Excel». Эта ситуация настолько типична, что давно стала отраслевым анекдотом. Только вот смеяться над ней не получается, за каждым таким «возвратом» стоят потраченные деньги, нервы сотрудников и упущенное время.
Парадокс в том, что платформа 1С 8.3 технически вполне способна закрыть задачи бюджетирования: вести БДДС (Бюджет движения денежных средств), БДР (Бюджет доходов и расходов), строить cashflow-отчёты, контролировать лимиты и согласовывать заявки. Тем не менее Excel с его сводными таблицами, формулами и макросами продолжает царить в финансовых отделах компаний с оборотом от 100 млн до нескольких миллиардов рублей.
В этой статье мы разберём 6 устойчивых мифов, которые мешают компаниям выстроить нормальное бюджетирование в 1С. Для каждого мифа, реальная причина его возникновения, техническое объяснение и практические пути решения, включая примеры кода.
Миф 1: «В 1С нет нормального инструмента для бюджетирования»
Это самый распространённый миф, и он же, самый далёкий от истины. В экосистеме 1С существует несколько специализированных решений именно для бюджетирования:
- 1С:ERP Управление предприятием, содержит полноценную подсистему бюджетирования с моделями, сценариями, статьями бюджета и маршрутами согласования. Подробнее о возможностях системы можно узнать в разделе задачи по 1С:ERP.
- 1С:Управление холдингом, решение корпоративного уровня с консолидацией бюджетов нескольких юридических лиц.
- 1С:Управление нашей фирмой (УНФ), облегчённая версия для малого бизнеса.
- Расширения и отраслевые решения, десятки конфигураций от партнёров 1С.
Откуда тогда берётся миф? Проблема не в отсутствии инструмента, а в несоответствии ожиданий и реальности внедрения. Финансист привык к Excel, где он сам рисует структуру таблицы под свою логику. В 1С он сталкивается с тем, что сначала нужно описать модель бюджета: статьи, аналитики, периоды, сценарии. Это требует методологической работы, которую большинство компаний пропускают.
Результат предсказуем: система настроена «как попало», отчёты не совпадают с тем, что финансист привык видеть, и он возвращается к привычному инструменту. Виновата не 1С, виновато отсутствие методологии.
Миф 2: «1С не умеет строить cashflow косвенным методом»
Это технически спорное утверждение, которое часто звучит от людей, работавших только с типовыми отчётами. Действительно, в типовых конфигурациях отчёт о движении денежных средств косвенным методом (то есть через корректировку чистой прибыли на неденежные статьи) не реализован «из коробки» в том виде, к которому привыкли финансисты МСФО.
Однако это решаемая задача. Косвенный cashflow строится через запрос к регистрам бухгалтерии и специальным регистрам накопления. Рассмотрим упрощённый пример построения движений по операционной деятельности:
// Функция получения данных для косвенного cashflow
// Возвращает таблицу значений с корректировками к чистой прибыли
Функция ПолучитьДанныеКосвенногоCashflow(НачалоПериода, КонецПериода, Организация) Экспорт
// Формируем запрос к регистру бухгалтерии
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| РБ.СчетДт.Код КАК СчетДт,
| РБ.СчетКт.Код КАК СчетКт,
| РБ.Сумма КАК Сумма,
| РБ.Период КАК Период
|ИЗ
| РегистрБухгалтерии.Хозрасчетный.ДвиженияССубконто КАК РБ
|ГДЕ
| РБ.Период МЕЖДУ &НачалоПериода И &КонецПериода
| И РБ.Организация = &Организация
| И РБ.СчетДт.Код ПОДОБНО &МаскаСчета
|УПОРЯДОЧИТЬ ПО
| РБ.Период";
Запрос.УстановитьПараметр("НачалоПериода", НачалоПериода);
Запрос.УстановитьПараметр("КонецПериода", КонецПериода);
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("МаскаСчета", "90%");
РезультатЗапроса = Запрос.Выполнить();
// Создаём таблицу для накопления результата
ТаблицаРезультата = Новый ТаблицаЗначений;
ТаблицаРезультата.Колонки.Добавить("Статья", Новый ОписаниеТипов("Строка", Новый КвалификаторыСтроки(100)));
ТаблицаРезультата.Колонки.Добавить("Сумма", Новый ОписаниеТипов("Число", Новый КвалификаторыЧисла(15, 2)));
Выборка = РезультатЗапроса.Выбрать();
Пока Выборка.Следующий() Цикл
// Определяем тип корректировки по корреспонденции счетов
НоваяСтрока = ТаблицаРезультата.Добавить();
Если Выборка.СчетДт = "90" И Выборка.СчетКт = "68" Тогда
НоваяСтрока.Статья = "Налог на прибыль (корректировка)";
НоваяСтрока.Сумма = -Выборка.Сумма;
ИначеЕсли Выборка.СчетДт = "90" И Выборка.СчетКт = "02" Тогда
НоваяСтрока.Статья = "Амортизация (добавляется обратно)";
НоваяСтрока.Сумма = Выборка.Сумма;
КонецЕсли;
КонецЦикла;
Возврат ТаблицаРезультата;
КонецФункции
Реальная проблема здесь не техническая, а методологическая: чтобы косвенный cashflow строился автоматически, необходима корректная аналитика в проводках, статьи движения денежных средств должны проставляться в каждом документе. В большинстве компаний этого нет, потому что бухгалтеры не обучены или не мотивированы заполнять эту аналитику.
Миф 3: «Согласование заявок на оплату в 1С, это сложно и долго»
Этот миф питается реальным опытом: во многих внедрениях маршруты согласования настраивают так, что проще позвонить директору и получить устное «ок», чем проводить заявку через систему. Но это не проблема платформы, это проблема проектирования бизнес-процесса.
В 1С:ERP и в 1С:Документооборот механизм бизнес-процессов позволяет реализовать любую схему согласования. Рассмотрим пример программного старта процесса согласования заявки на расходование денежных средств:
// Процедура запуска бизнес-процесса согласования заявки
// Вызывается из формы документа "ЗаявкаНаРасходованиеДенежныхСредств"
Процедура ЗапуститьСогласованиеЗаявки(ДокументСсылка) Экспорт
// Проверяем, не запущен ли уже процесс для этого документа
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| БП.Ссылка КАК БизнесПроцесс
|ИЗ
| БизнесПроцесс.СогласованиеЗаявкиНаОплату КАК БП
|ГДЕ
| БП.ПредметСогласования = &Документ
| И БП.Завершён = ЛОЖЬ";
Запрос.УстановитьПараметр("Документ", ДокументСсылка);
Результат = Запрос.Выполнить();
Если НЕ Результат.Пустой() Тогда
Сообщить("Процесс согласования уже запущен для данной заявки.");
Возврат;
КонецЕсли;
// Создаём новый экземпляр бизнес-процесса
НовыйПроцесс = БизнесПроцессы.СогласованиеЗаявкиНаОплату.СоздатьБизнесПроцесс();
НовыйПроцесс.ПредметСогласования = ДокументСсылка;
НовыйПроцесс.ДатаНачала = ТекущаяДата();
// Определяем маршрут в зависимости от суммы заявки
ОбъектДокумента = ДокументСсылка.ПолучитьОбъект();
Если ОбъектДокумента.СуммаДокумента > 500000 Тогда
// Крупные суммы, двухуровневое согласование
НовыйПроцесс.МаршрутСогласования = Перечисления.МаршрутыСогласования.ДвухУровневый;
НовыйПроцесс.ФинансовыйДиректор = ПолучитьФинансовогоДиректора(ОбъектДокумента.Организация);
НовыйПроцесс.Руководитель = ПолучитьРуководителяЦФО(ОбъектДокумента.ЦФО);
Иначе
// Небольшие суммы, одноуровневое согласование
НовыйПроцесс.МаршрутСогласования = Перечисления.МаршрутыСогласования.ОдноУровневый;
НовыйПроцесс.Руководитель = ПолучитьРуководителяЦФО(ОбъектДокумента.ЦФО);
КонецЕсли;
// Записываем и стартуем процесс
НовыйПроцесс.Записать();
НовыйПроцесс.Старт();
Сообщить("Процесс согласования запущен. Ответственные уведомлены.");
КонецПроцедуры
Ключевой момент: согласование в 1С работает хорошо тогда, когда маршруты спроектированы совместно с бизнесом, а не навязаны IT-отделом. Если финансовый директор не участвовал в проектировании схемы согласования, он найдёт способ её обойти.
Миф 4: «Контроль лимитов по статьям БДДС в 1С работает некорректно»
Вот здесь миф уже имеет реальное основание. В ряде типовых конфигураций контроль лимитов действительно реализован слабо: он либо работает только в момент проведения документа (и не учитывает незакрытые заявки), либо не учитывает аналитику в разрезе ЦФО и проектов.
Правильный контроль лимита должен учитывать три составляющих:
- Утверждённый бюджет, плановая сумма по статье на период.
- Акцептованные заявки, суммы уже согласованных, но ещё не оплаченных заявок.
- Фактические платежи, суммы реально проведённых платёжных документов.
Доступный остаток = Утверждённый бюджет − Акцептованные заявки − Фактические платежи.
Пример запроса для получения доступного остатка по статье бюджета:
// Функция проверки доступного лимита по статье БДДС
// Возвращает сумму доступного остатка (может быть отрицательной)
Функция ПолучитьДоступныйЛимит(СтатьяДДС, ЦФО, Период, Организация) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ЕСТЬNULL(Бюджет.СуммаПлан, 0) КАК СуммаПлан,
| ЕСТЬNULL(Заявки.СуммаАкцептовано, 0) КАК СуммаАкцептовано,
| ЕСТЬNULL(Факт.СуммаФакт, 0) КАК СуммаФакт
|ИЗ
| (
| ВЫБРАТЬ
| СУММА(РегБюджет.СуммаОборот) КАК СуммаПлан
| ИЗ
| РегистрНакопления.БюджетДвиженияДенежныхСредств.Обороты(
| &НачалоПериода,
| &КонецПериода,
| Месяц,
| СтатьяДДС = &СтатьяДДС
| И ЦФО = &ЦФО
| И Организация = &Организация
| ) КАК РегБюджет
| ) КАК Бюджет,
| (
| ВЫБРАТЬ
| СУММА(Заявка.СуммаДокумента) КАК СуммаАкцептовано
| ИЗ
| Документ.ЗаявкаНаРасходованиеДенежныхСредств КАК Заявка
| ГДЕ
| Заявка.Проведён = ИСТИНА
| И Заявка.СтатусСогласования = ЗНАЧЕНИЕ(Перечисление.СтатусыСогласования.Согласовано)
| И Заявка.СтатьяДДС = &СтатьяДДС
| И Заявка.ЦФО = &ЦФО
| И Заявка.Организация = &Организация
| И Заявка.ДатаПланируемойОплаты МЕЖДУ &НачалоПериода И &КонецПериода
| И Заявка.Оплачено = ЛОЖЬ
| ) КАК Заявки,
| (
| ВЫБРАТЬ
| СУММА(РегФакт.СуммаОборот) КАК СуммаФакт
| ИЗ
| РегистрНакопления.ДвиженияДенежныхСредств.Обороты(
| &НачалоПериода,
| &КонецПериода,
| Месяц,
| СтатьяДДС = &СтатьяДДС
| И ЦФО = &ЦФО
| И Организация = &Организация
| ) КАК РегФакт
| ) КАК Факт";
Запрос.УстановитьПараметр("СтатьяДДС", СтатьяДДС);
Запрос.УстановитьПараметр("ЦФО", ЦФО);
Запрос.УстановитьПараметр("Организация", Организация);
Запрос.УстановитьПараметр("НачалоПериода", НачалоМесяца(Период));
Запрос.УстановитьПараметр("КонецПериода", КонецМесяца(Период));
Выборка = Запрос.Выполнить().Выбрать();
Выборка.Следующий();
// Возвращаем доступный остаток
Возврат Выборка.СуммаПлан - Выборка.СуммаАкцептовано - Выборка.СуммаФакт;
КонецФункции
Если такая функция вызывается при записи заявки, контроль лимитов работает корректно. Проблема в том, что в большинстве внедрений этот контроль либо не настраивают вовсе, либо настраивают только на уровне платёжного поручения, игнорируя акцептованные заявки. Отсюда и берётся миф.
Миф 5: «Интеграция 1С с Excel для бюджетирования невозможна или слишком сложна»
Многие финансисты говорят: «Нам не нужно полностью уходить от Excel, нам нужно, чтобы данные из Excel попадали в 1С и обратно». И здесь возникает миф о том, что такая интеграция либо невозможна, либо требует огромных затрат.
На практике интеграция 1С с Excel реализуется несколькими способами:
- Загрузка через табличный документ, стандартный механизм платформы.
- COM-объект Excel, прямое управление Excel из 1С.
- Загрузка через формат XLSX, с помощью сторонних библиотек или встроенных средств.
- REST API / HTTP-сервисы, для интеграции через веб.
Пример загрузки плановых данных из Excel-файла в регистр бюджетирования:
// Процедура загрузки плановых данных БДДС из файла Excel
// ПутьКФайлу, строка с полным путём к файлу.xlsx
Процедура ЗагрузитьПланБДДСИзExcel(ПутьКФайлу, Сценарий, Организация) Экспорт
// Открываем файл как табличный документ
ТабДок = Новый ТабличныйДокумент;
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Значение);
КоличествоСтрок = ТабДок.ВысотаТаблицы;
КоличествоКолонок = ТабДок.ШиринаТаблицы;
// Начинаем транзакцию для атомарной загрузки
НачатьТранзакцию();
Попытка
// Строки начинаются со 2-й (1-я, заголовки)
Для НомерСтроки = 2 По КоличествоСтрок Цикл
НаименованиеСтатьи = ТабДок.ПолучитьОбласть(НомерСтроки, 1, НомерСтроки, 1).ТекущаяОбласть.Текст;
НаименованиеЦФО = ТабДок.ПолучитьОбласть(НомерСтроки, 2, НомерСтроки, 2).ТекущаяОбласть.Текст;
ПериодСтрока = ТабДок.ПолучитьОбласть(НомерСтроки, 3, НомерСтроки, 3).ТекущаяОбласть.Текст;
СуммаСтрока = ТабДок.ПолучитьОбласть(НомерСтроки, 4, НомерСтроки, 4).ТекущаяОбласть.Текст;
// Пропускаем пустые строки
Если ПустаяСтрока(НаименованиеСтатьи) Тогда
Продолжить;
КонецЕсли;
// Ищем статью ДДС по наименованию
СтатьяДДС = Справочники.СтатьиДвиженияДенежныхСредств.НайтиПоНаименованию(НаименованиеСтатьи, Истина);
Если СтатьяДДС.Пустая() Тогда
Сообщить("Статья ДДС не найдена: " + НаименованиеСтатьи + ". Строка " + НомерСтроки + " пропущена.");
Продолжить;
КонецЕсли;
// Ищем ЦФО
ЦФО = Справочники.ЦентрыФинансовойОтветственности.НайтиПоНаименованию(НаименованиеЦФО, Истина);
// Преобразуем период и сумму
ПериодДата = Дата(ПериодСтрока);
Сумма = Число(СуммаСтрока);
// Записываем движение в регистр накопления
\
Найдите специалиста для решения этой задачи на koderion.ru