Работа с планом счетов через встроенный язык 1С:Предприятие — одна из самых востребованных задач среди разработчиков бухгалтерских конфигураций. Без умения программно получать счета, проверять их свойства или создавать новые записи невозможно автоматизировать учетные процессы, строить сложные отчеты или интегрировать 1С с внешними системами. Однако многие программисты сталкиваются с проблемами: то Метод не обнаружен вылетает, то счет не находится по коду, то свойства не обновляются.

В этой статье мы разберем 7 проверенных способов обращения к плану счетов — от простейшего получения справочника до динамического создания счетов с заданными реквизитами. Особое внимание уделим типичным ошибкам (например, почему ПланСчетов.НайтиПоКоду() иногда возвращает Неопределено) и оптимизации кода для работы с большими планами счетов (10 000+ записей). Все примеры актуальны для платформ 1С:Предприятие 8.3 и 8.2, но с учетом особенностей управляемых форм.

Если вы только начинаете осваивать программирование в 1С, начните с первых двух разделов — там базовые методы, которые работают в 90% случаев. Опытным разработчикам будет полезен раздел про динамическое создание счетов и работу с реквизитами, где мы разбираем нюансы, о которых не пишут в документации.

1. Базовые методы получения плана счетов

Начнем с самого простого: как получить ссылку на план счетов в коде. В 1С план счетов — это объект конфигурации, и к нему можно обращаться напрямую через менеджер метаданных или глобальные переменные.

Самый универсальный способ — использовать Метод() глобального контекста:

ПланСчетов = Метод("ПланСчетов.Хозрасчетный"); // Для бухгалтерии 3.0

// Или для других конфигураций:

ПланСчетов = Метод("ПланСчетов.Основной");

Если вы работаете в управляемом приложении, лучше использовать МетодыГлобальногоКонтекста:

ПланСчетов = МетодыГлобальногоКонтекста.ПланСчетовХозрасчетный();
  • 🔹 Преимущество: работает во всех конфигурациях, не зависит от имени плана счетов.
  • 🔹 Недостаток: если план счетов переименован в конфигураторе, код перестанет работать.
  • 🔹 Альтернатива: можно получить план через Метод("Справочники.ПланыСчетов"), но это менее надежно.

Для обычных форм (8.2) подойдет прямой вызов:

ПланСчетов = ПланыСчетов.Хозрасчетный;
⚠️ Внимание: Если вы получаете ошибку "Объект не найден (ПланыСчетов)", проверьте, что в модуле объявлена переменная ПланыСчетов или используйте полный путь: Справочники.ПланыСчетов.Хозрасчетный.
📊 Какой версии 1С вы пользуетесь?
8.2 (обычные формы)
8.3 (управляемые формы)
Обе версии
Не знаю

2. Поиск счета по коду или наименованию

Чаще всего требуется найти конкретный счет по его коду (например, "60.01") или наименованию ("Расчеты с поставщиками"). Для этого используются методы НайтиПоКоду() и НайтиПоНаименованию().

Пример поиска по коду:

Счет = ПланСчетов.НайтиПоКоду("60.01");

Если Счет = Неопределено Тогда

Сообщить("Счет не найден!");

Иначе

Сообщить("Найден счет: " + Счет.Наименование);

КонецЕсли;

Важные нюансы:

  • 🔍 Код счета должен быть точным (включая точки и подсчета). Если передать "60", метод вернет Неопределено.
  • 🔍 Для поиска по частичному совпадению используйте ПланСчетов.Выбрать() с фильтром.
  • 🔍 В некоторых конфигурациях (например, Бухгалтерия 2.0) метод может возвращать Неопределено, если счет помечен на удаление.

Поиск по наименованию менее надежен, так как названия могут дублироваться или изменяться:

Счет = ПланСчетов.НайтиПоНаименованию("Расчеты с поставщиками");

Если Счет = Неопределено Тогда

// Попробуем найти по частичному совпадению

Выборка = ПланСчетов.Выбрать();

Пока Выборка.Следующий() Цикл

Если Найти(Строка(Выборка.Наименование), "поставщик") > 0 Тогда

Счет = Выборка.Ссылка;

Прервать;

КонецЕсли;

КонецЦикла;

КонецЕсли;

⚠️ Внимание: Метод НайтиПоНаименованию() чувствителен к регистру и пробелам. Если не уверены в точном наименовании, используйте выборку с фильтром по Представление или ПолноеНаименование.

Убедиться, что план счетов получен корректно|Проверить регистр и формат кода счета|Учесть возможность пометки на удаление|Обработать случай, если счет не найден-->

3. Работа с реквизитами счета: валютность, субконто, забалансовость

Каждый счет в плане счетов имеет набор реквизитов, которые определяют его поведение: является ли он валютным, требует ли указания субконто, относится ли к забалансовым. Эти свойства можно читать и иногда модифицировать программно.

Пример чтения свойств счета:

Счет = ПланСчетов.НайтиПоКоду("50.01");

Если Счет <> Неопределено Тогда

Сообщить("Счет: " + Счет.Наименование);

Сообщить("Валютный: " + ?(Счет.Валютный, "Да", "Нет"));

Сообщить("Забалансовый: " + ?(Счет.Забалансовый, "Да", "Нет"));

Сообщить("Количество уровней субконто: " + Счет.КоличествоУровнейСубконто());

КонецЕсли;

Некоторые реквизиты доступны только для чтения (например, Забалансовый), а другие можно изменять динамически. Например, можно добавить субконто к счету (если это разрешено конфигурацией):

Счет = ПланСчетов.НайтиПоКоду("10.01");

Если Счет.КоличествоУровнейСубконто() < 3 Тогда

Счет.ДобавитьВидСубконто(ПланыВидовХарактеристик.Субконто1);

ПланСчетов.Записать();

КонецЕсли;

Реквизит Тип данных Доступен для записи? Пример использования
Валютный Булево Нет Проверка перед проводкой в валюте
Забалансовый Булево Нет Фильтрация счетов в отчетах
КоличествоУровнейСубконто() Число Нет Определение структуры аналитики
ВидСубконто() Массив Да (с ограничениями) Динамическое добавление аналитики

Обратите внимание, что изменение реквизитов счета может потребовать перезаписи плана счетов (ПланСчетов.Записать()), а в некоторых случаях — даже обновления конфигурации.

💡

Если вам нужно часто проверять свойства счетов (например, в цикле по проводкам), кэшируйте результаты в Соответствие или Массив, чтобы избежать повторных обращений к плану счетов. Это ускорит работу в 3-5 раз.

4. Создание нового счета программно

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

Пример создания простого счета:

НовыйСчет = ПланСчетов.СоздатьСчет();

НовыйСчет.Код = "10.10";

НовыйСчет.Наименование = "Новые материалы (спецучет)";

НовыйСчет.Родитель = ПланСчетов.НайтиПоКоду("10"); // Указываем родительский счет

НовыйСчет.Валютный = Ложь;

НовыйСчет.Забалансовый = Ложь;

НовыйСчет.Записать();

Важные моменты при создании счетов:

  • 📌 Код счета должен быть уникальным и соответствовать формату плана счетов (например, "XX.XX" для бухгалтерии 3.0).
  • 📌 Родительский счет обязателен, если создается субсчет (например, "10.10" должен иметь родителя "10").
  • 📌 Не все свойства можно задать при создании — некоторые (например, ВидСубконто) требуют дополнительной настройки.

Если нужно создать счет с аналитикой (субконто), используйте следующий подход:

НовыйСчет = ПланСчетов.СоздатьСчет();

НовыйСчет.Код = "20.05";

НовыйСчет.Наименование = "Спецзаказы (с аналитикой)";

НовыйСчет.Родитель = ПланСчетов.НайтиПоКоду("20");

НовыйСчет.ДобавитьВидСубконто(ПланыВидовХарактеристик.Номенклатура);

НовыйСчет.ДобавитьВидСубконто(ПланыВидовХарактеристик.Подразделения);

НовыйСчет.Записать();

⚠️ Внимание: Создание счетов программно может нарушить структуру плана счетов, если не соблюдать иерархию. Всегда проверяйте, что родительский счет существует и не является забалансовым (если новый счет тоже не забалансовый).
Что будет, если создать счет с дублирующимся кодом?

При попытке создать счет с кодом, который уже существует в плане счетов, метод Записать() вызовет исключение с текстом "Нарушение уникальности кода". Чтобы избежать этого, всегда проверяйте наличие счета по коду перед созданием:

Если ПланСчетов.НайтиПоКоду("10.10") = Неопределено Тогда

// Создаем новый счет

Иначе

Сообщить("Счет с таким кодом уже существует!");

КонецЕсли;

5. Массовая обработка счетов: выборки и фильтры

Когда нужно обработать все счета или их группу (например, все валютные или забалансовые), удобно использовать Выборку с фильтрами. Это значительно быстрее, чем перебор в цикле.

Пример выборки всех валютных счетов:

Выборка = ПланСчетов.Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Валютный Тогда

Сообщить(Выборка.Код + " - " + Выборка.Наименование);

КонецЕсли;

КонецЦикла;

Для ускорения работы можно использовать отбор:

Отбор = Новый Структура();

Отбор.Вставить("Валютный", Истина);

Выборка = ПланСчетов.Выбрать(,, Отбор);

Если нужно получить счета определенного раздела (например, все счета раздела "Денежные средства"), используйте свойство Родитель:

РодительскийСчет = ПланСчетов.НайтиПоКоду("50"); // Касса

Выборка = ПланСчетов.Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Родитель = РодительскийСчет Тогда

Сообщить("Субсчет: " + Выборка.Код);

КонецЕсли;

КонецЦикла;

Для сложных фильтров (например, счета с определенным видом субконто) удобно использовать Запрос:

Запрос = Новый Запрос();

Запрос.Текст =

"ВЫБРАТЬ

| ПланыСчетов.Ссылка КАК Счет,

| ПланыСчетов.Код КАК Код

|ИЗ

| ПланСчетов.Хозрасчетный КАК ПланыСчетов

|ГДЕ

| ПланыСчетов.Валютный = &Валютный

| И НЕ ПланыСчетов.ПометкаУдаления";

Запрос.УстановитьПараметр("Валютный", Истина);

Результат = Запрос.Выполнить();

ВыборкаРезультата = Результат.Выбрать();

Пока ВыборкаРезультата.Следующий() Цикл

Сообщить(ВыборкаРезультата.Код);

КонецЦикла;

💡

Использование запросов для выборки счетов позволяет применять сложные условия фильтрации (например, по нескольким реквизитам одновременно) и работает быстрее, чем поочередный перебор через Выбрать().

6. Проверка и валидация счетов перед использованием

Перед тем как использовать счет в проводке или отчете, необходимо проверить его корректность. Это поможет избежать ошибок типа "Счет не найден" или "Недопустимый тип счета".

Минимальный набор проверок:

Функция ПроверитьСчет(КодСчета) Экспорт

Счет = ПланСчетов.НайтиПоКоду(КодСчета);

Если Счет = Неопределено Тогда

Возврат Ложь; // Счет не существует

КонецЕсли;

Если Счет.ПометкаУдаления Тогда

Возврат Ложь; // Счет помечен на удаление

КонецЕсли;

Если Счет.Забалансовый И НЕ РазрешитьЗабалансовыеСчета Тогда

Возврат Ложь; // Забалансовые счета запрещены

КонецЕсли;

Возврат Истина;

КонецФункции;

Расширенная проверка может включать:

  • 🔎 Проверку валютности (если проводка в валюте, а счет не валютный).
  • 🔎 Проверку субконто (если счет требует аналитики, а она не указана).
  • 🔎 Проверку разрешенных операций (например, нельзя делать проводки по счету "99" вручную).

Пример проверки субконто:

Функция ПроверитьСубконтоСчета(Счет, ДанныеАналитики)

Если Счет.КоличествоУровнейСубконто() > 0 Тогда

Если ДанныеАналитики = Неопределено Или ДанныеАналитики.Количество() = 0 Тогда

Возврат Ложь; // Требуется субконто, но не указано

КонецЕсли;

// Проверяем соответствие типов субконто

Для Инд = 0 По Счет.КоличествоУровнейСубконто() - 1 Цикл

Если ДанныеАналитики[Инд].ТипЗначения() <> Счет.ВидСубконто(Инд).ТипЗначения Тогда

Возврат Ложь; // Несовпадение типов

КонецЕсли;

КонецЦикла;

КонецЕсли;

Возврат Истина;

КонецФункции;

⚠️ Внимание: В конфигурациях с включенным контролем отрицательных остатков (например, Бухгалтерия 3.0) дополнительно проверяйте, разрешены ли проводки по счету с отрицательным сальдо. Это можно сделать через свойство РазрешитьОтрицательныеОстатки.

7. Типичные ошибки и их решения

Даже опытные разработчики сталкиваются с ошибками при работе с планом счетов. Рассмотрим самые распространенные и способы их исправления.

Ошибка Причина Решение
Метод не обнаружен (НайтиПоКоду) Неправильное имя плана счетов или работа в неподходящем контексте Используйте Метод("ПланСчетов.Хозрасчетный") или проверьте имя плана в конфигураторе
Объект не является значением объекта (ПланСчетов) Попытка вызвать метод у неинициализированной переменной Проверьте, что переменная ПланСчетов получена корректно
Нарушение прав доступа Недостаточно прав у пользователя для изменения плана счетов Выполняйте код в привилегированном режиме или настройте права ролей
Недопустимый код счета Код счета не соответствует формату (например, "601" вместо "60.01") Используйте функцию форматирования кода или проверяйте формат перед созданием

Еще одна частая проблема — несоответствие версий. Например, код, работающий в 1С:Бухгалтерии 3.0, может не работать в 1С:УНФ из-за разных структур планов счетов. Всегда проверяйте:

  • 🛠 Имя плана счетов (Хозрасчетный, Основной, Бухгалтерский).
  • 🛠 Наличие обязательных реквизитов (например, ВидСчета в некоторых конфигурациях).
  • 🛠 Разрешенные символы в коде счета (в некоторых конфигурациях запрещены пробелы или специальные символы).

Если вы работаете с распределенными информационными базами, учитывайте, что план счетов может отличаться в разных базах. В этом случае используйте ПланыОбмена для синхронизации.

FAQ: Ответы на частые вопросы

Как получить все счета определенного раздела (например, "Расчеты с контрагентами")?

Используйте свойство Родитель и рекурсивный обход:

Процедура ПолучитьСчетаРаздела(РодительскийСчет, МассивСчетов)

Выборка = ПланСчетов.Выбрать();

Пока Выборка.Следующий() Цикл

Если Выборка.Родитель = РодительскийСчет Тогда

МассивСчетов.Добавить(Выборка.Ссылка);

// Рекурсивно обрабатываем субсчета

ПолучитьСчетаРаздела(Выборка.Ссылка, МассивСчетов);

КонецЕсли;

КонецЦикла;

КонецПроцедуры;

Пример вызова:

Родитель = ПланСчетов.НайтиПоКоду("60");

МассивСчетов = Новый Массив();

ПолучитьСчетаРаздела(Родитель, МассивСчетов);

Можно ли изменить код или наименование счета программно?

Да, но с оговорками:

  • 📝 Код счета можно изменить, если он не используется в проводках (иначе нарушится целостность данных).
  • 📝 Наименование можно изменять свободно, но это может сломать печатные формы или отчеты, где используется старое название.

Пример изменения наименования:

Счет = ПланСчетов.НайтиПоКоду("10.01");

Счет.Наименование = "Новое название материала";

ПланСчетов.Записать();

Для изменения кода требуется дополнительная проверка:

Если НЕ Счет.ИспользуетсяВПроводках() Тогда

Счет.Код = "10.02";

ПланСчетов.Записать();

Иначе

Сообщить("Нельзя изменить код — счет используется в проводках!");

КонецЕсли;

Как экспортировать план счетов в Excel или JSON?

Для экспорта используйте Запрос и ЗаписьJSON или ТабличныйДокумент:

Пример экспорта в JSON:

Запрос = Новый Запрос();

Запрос.Текст = "ВЫБРАТЬ Код, Наименование, Валютный ИЗ ПланСчетов.Хозрасчетный";

Результат = Запрос.Выполнить();

ЗаписьJSON = Новый ЗаписьJSON;

ЗаписьJSON.УстановитьСтроку();

ЗаписьJSON.ЗаписатьНачалоОбъекта();

ЗаписьJSON.ЗаписатьКлюч("Счета");

ЗаписьJSON.ЗаписатьНачалоМассива();

Выборка = Результат.Выбрать();

Пока Выборка.Следующий() Цикл

ЗаписьJSON.ЗаписатьНачалоОбъекта();

ЗаписьJSON.ЗаписатьКлюч("Код");

ЗаписьJSON.ЗаписатьЗначение(Выборка.Код);

ЗаписьJSON.ЗаписатьКлюч("Наименование");

ЗаписьJSON.ЗаписатьЗначение(Выборка.Наименование);

ЗаписьJSON.ЗаписатьКонецОбъекта();

КонецЦикла;

ЗаписьJSON.ЗаписатьКонецМассива();

ЗаписьJSON.ЗаписатьКонецОбъекта();

JSONСтрока = ЗаписьJSON.Закрыть();

ЗаписьJSON = Неопределено;

Для экспорта в Excel используйте ТабличныйДокумент и метод Записать().

Как проверить, является ли счет забалансовым?

Используйте свойство Забалансовый:

Счет = ПланСчетов.НайтиПоКоду("001");

Если Счет.Забалансовый Тогда

Сообщить("Это забалансовый счет!");

Иначе

Сообщить("Это балансовый счет.");

КонецЕсли;

В некоторых конфигурациях (например, БГУ) забалансовые счета могут иметь специальные префиксы в коде (например, "0").

Можно ли программно создать план счетов с нуля?

Технически да, но это крайне не рекомендуется. План счетов — это объект конфигурации, и его создание требует:

  • 🔧 Права администратора в конфигураторе.
  • 🔧 Полного понимания структуры метаданных.
  • 🔧 Последующего обновления конфигурации базы данных.

Вместо этого обычно:

  • 📌 Импортируют план счетов из другой базы.
  • 📌 Используют типовой план и донастраивают его программно.
  • 📌 Создают дополнительные счета в существующем плане.

Если все же нужно создать план счетов программно, используйте объект Метод() в конфигураторе:

НовыйПланСчетов = Метод("НовыйОбъектМетаданных.ПланСчетов");

НовыйПланСчетов.Имя = "МойПланСчетов";

НовыйПланСчетов.Синоним = "Новый план счетов";

НовыйПланСчетов.КодДлины = 5;

НовыйПланСчетов.Добавить();