Как правильно заполнить субконто при вводе начальных остатков в 1С:Бухгалтерии 3.0?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

Исходная проблема, с которой мы столкнулись, заключалась в попытке программно присвоить значения субконто в табличной части документа ввода начальных остатков. Пользователь изначально пробовал использовать синтаксис вида НовСтрока.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Контрагенты] = Справочники.Контрагенты.НайтиПоНаименованию(стр.Контрагент);, но обнаружил, что этот подход не приводит к ожидаемому результату, получая в переменной НовСтрока.СубконтоКт нечто неожиданное. Затем была предпринята попытка использовать общую процедуру БухгалтерскийУчет.УстановитьСубконто, которая, однако, привела к ошибке "Поле объекта не обнаружено (СчетРегистрБухгалтерииСубконто.ЖурналПроводокЕПСБУ)". Давайте проанализируем эти ситуации и выясним, как правильно действовать.

Почему возникают ошибки при заполнении субконто?

Основная причина недопонимания кроется в различии между тем, как субконто хранятся и обрабатываются в табличных частях документов, и как они записываются в регистры бухгалтерии. Методы и подходы, применимые для прямого формирования движений регистра бухгалтерии, не всегда подходят для непосредственного заполнения реквизитов табличных частей документов.

  1. Неправильное использование коллекции субконто в табличной части документа: Синтаксис НовСтрока.СубконтоКт[ПланыВидовХарактеристик.ВидыСубконто.Контрагенты] предполагает работу с коллекцией субконто, которая характерна для записей регистра бухгалтерии, но не для обычных реквизитов табличной части документа. Табличные части документов обычно имеют отдельные реквизиты для каждого субконто: Субконто1, Субконто2, Субконто3.
  2. Некорректное применение процедуры БухгалтерскийУчет.УстановитьСубконто: Процедура БухгалтерскийУчет.УстановитьСубконто предназначена для работы с объектами типа "Запись регистра бухгалтерии" (например, РегистрыБухгалтерии.Хозрасчетный.Запись) при формировании проводок. Она ожидает, что в качестве одного из параметров будет передан объект, имеющий внутреннюю структуру для хранения субконто как коллекции. Когда в эту процедуру передается объект табличной части документа или его поля, которые не соответствуют ожидаемой структуре, возникает ошибка "Поле объекта не обнаружено", как мы видели с параметром ДтКт = "СчетРегистрБухгалтерииСубконто.ЖурналПроводокЕПСБУ". Это означает, что процедура пыталась получить свойство из объекта, который не имел такого свойства в своей структуре, и пыталась обратиться к несуществующему полю Проводка["Счет"+ДтКт], где ДтКт было некорректным значением.

Решение 1: Прямое присвоение значений субконто в табличной части документа "Ввод начальных остатков"

Для большинства документов ввода начальных остатков, таких как "Ввод начальных остатков" в 1С:Бухгалтерии 3.0, субконто заполняются путем прямого присвоения значений соответствующим реквизитам табличной части. Эти реквизиты обычно называются Субконто1, Субконто2, Субконто3 и соответствуют видам субконто, настроенным для конкретного счета в Плане счетов.

Разберем по шагам, как это сделать, используя пример из обсуждаемой темы, касающийся табличной части "РасходыБудущихПериодов" для счета 97.21:

  1. Определяем табличную часть документа: Сначала нам нужно получить доступ к нужной табличной части документа. В нашем случае это Об.РасходыБудущихПериодов. Объект Об в данном контексте представляет собой объект текущего документа, в котором происходит заполнение.
  2. Создаем новую строку и заполняем основные реквизиты: Добавляем новую строку в табличную часть с помощью метода ТЧ.Добавить() и присваиваем основные реквизиты, такие как СчетУчета, Сумма и другие.
  3. Получаем объект субконто: Для каждого субконто нам потребуется найти или создать соответствующий элемент справочника или другого объекта конфигурации, который является видом данного субконто. Например, если первым субконто является "Расходы будущих периодов", мы можем использовать вспомогательную функцию ПолучитьРБП(Стр) для получения ссылки на нужный элемент справочника. Эта функция должна быть реализована отдельно и содержать логику поиска или создания элемента справочника по данным из входной строки Стр.
  4. Присваиваем значение субконто напрямую: Самый важный шаг — это прямое присвоение найденного объекта соответствующему реквизиту табличной части, например, СтрТЧ.Субконто1 = Субконто1;. Тип значения, которое мы присваиваем, должен соответствовать типу вида субконто, настроенного для данного счета. Например, если первое субконто – это контрагент, то Субконто1 должно быть ссылкой на элемент справочника "Контрагенты".

Посмотрим на конкретный пример кода, который демонстрирует прямое присвоение субконто в табличной части документа:


// Предположим, что Об - это объект документа "ВводНачальныхОстатков" (например, в модуле объекта или форме)
// ТЗ - это некоторая таблица значений (или запрос), содержащая данные для ввода остатков
// СчетУчета - это предопределенный элемент Плана счетов, например, Счет 97.21 (полученный заранее)

// Получаем ссылку на табличную часть документа
ТЧ = Об.РасходыБудущихПериодов;
ТЧ.Очистить(); // Рекомендуется очистить табличную часть перед заполнением, если это полный перезалив данных

Для Каждого Стр Из ТЗ Цикл
    // Добавляем новую строку в табличную часть
    СтрТЧ = ТЧ.Добавить();
    
    // Заполняем счет учета для текущей строки
    СтрТЧ.СчетУчета = СчетУчета;

    // Получаем значение для первого субконто (например, элемент справочника "Расходы будущих периодов").
    // Функция ПолучитьРБП(Стр) должна быть реализована вами и возвращать ссылку
    // на элемент справочника, соответствующий виду первого субконто для СчетУчета.
    Субконто1 = ПолучитьРБП(Стр); 
    
    // Присваиваем полученное значение напрямую реквизиту Субконто1 строки табличной части.
    // Если для счета настроено несколько субконто, будут использоваться Субконто2, Субконто3.
    СтрТЧ.Субконто1 = Субконто1; 

    // Заполняем остальные реквизиты строки табличной части согласно данным из ТЗ
    СтрТЧ.Сумма = Стр.СуммаОстаток;
    СтрТЧ.СуммаНУ = Стр.СуммаНУОстаток; // Сумма для налогового учета
    СтрТЧ.СуммаПР = Стр.СуммаПРОстаток; // Сумма постоянных разниц
    СтрТЧ.СуммаВР = Стр.СуммаВРОстаток; // Сумма временных разниц
КонецЦикла;

В этом примере Субконто1 (и аналогично Субконто2, Субконто3, если они есть для данного счета) являются стандартными реквизитами строк табличных частей документов, предназначенных для ввода остатков. Важно, чтобы тип присваиваемого значения совпадал с типом вида субконто, настроенного для данного счета. Если для счета настроено, например, только одно субконто, то мы заполняем только Субконто1. Если два, то Субконто1 и Субконто2, и так далее. Если вы попытаетесь заполнить Субконто2, а для счета настроено только одно субконто, то это поле будет проигнорировано или вызовет ошибку при записи. При отсутствии соответствующего реквизита в табличной части (например, если нет Субконто2) попытка обращения к нему вызовет ошибку "Поле объекта не обнаружено".

Решение 2: Использование процедуры БухгалтерскийУчет.УстановитьСубконто для записей регистра бухгалтерии

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

Рассмотрим сценарий, когда мы создаем записи в регистре бухгалтерии РегистрыБухгалтерии.Хозрасчетный, как это делается для счетов 08.08 (Вложения во внеоборотные активы) или 97.24 (Расходы будущих периодов):

  1. Создаем набор записей регистра: Начинаем с создания нового набора записей для регистра бухгалтерии Хозрасчетный. Это делается с помощью Хозрасчетный = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();. Мы работаем с набором записей, чтобы эффективно записывать несколько движений, связанных с одним регистратором.
  2. Устанавливаем отбор по регистратору: Для набора записей регистра критически важно установить отбор по регистратору, чтобы все добавляемые записи были связаны с текущим документом и не повредили движения других документов. Например, Хозрасчетный.Отбор.Регистратор.Значение = Документ;, где Документ – это ссылка на объект-регистратор.
  3. Добавляем новую запись: В набор записей добавляем новую запись: Запись = Хозрасчетный.Добавить();. Каждая такая запись будет соответствовать одной проводке.
  4. Заполняем основные поля записи регистра: Присваиваем значения таким полям, как Регистратор, Организация, Период, Содержание, СчетДт (счет дебета), СчетКт (счет кредита), Сумма и другие необходимые аналитики (например, ПодразделениеДт, СуммаНУДт и т.д.). Эти поля напрямую отражают данные бухгалтерской проводки.
  5. Определяем значения субконто: Аналогично предыдущему случаю, нам нужно получить ссылки на нужные объекты для каждого субконто, которое требуется для данного счета (например, "НематериальныйАктив" для счета 08.08, "РасходыБудущихПериодов" для счета 97.24, "СтатьяЗатрат" для другого субконто). Здесь также могут использоваться вспомогательные функции, такие как ПолучитьНематериальныйАктив(Стр) или ПолучитьСтатьюЗатрат(Стр), которые возвращают ссылки на соответствующие объекты справочников.
  6. Используем БухгалтерскийУчет.УстановитьСубконто: Теперь, когда у нас есть объект записи регистра (Запись) и готовые значения субконто, мы можем использовать процедуру БухгалтерскийУчет.УстановитьСубконто. Ее синтаксис таков: БухгалтерскийУчет.УстановитьСубконто(Счет, НаборСубконто, ИндексИлиИмяВидаСубконто, ЗначениеСубконто).
    • Счет: Здесь мы передаем сам счет дебета или кредита, для которого устанавливается субконто, например, Запись.СчетДт или Запись.СчетКт.
    • НаборСубконто: Этот параметр должен быть коллекцией субконто для данного счета. Это либо Запись.СубконтоДт, либо Запись.СубконтоКт. Важно понимать, что это коллекция субконто, ассоциированная с конкретным счетом проводки, а не отдельный реквизит записи.
    • ИндексИлиИмяВидаСубконто: Здесь мы указываем, к какому по счету субконто мы хотим присвоить значение (1, 2, 3) или его имя (например, "Контрагенты", "Договоры"). Рекомендуется использовать числовой индекс (1, 2, 3), так как он более стабилен при изменениях названий видов субконто.
    • ЗначениеСубконто: Собственно, ссылка на объект субконто, которое мы хотим установить (например, результат работы Справочники.Контрагенты.НайтиПоНаименованию("...") или нашей вспомогательной функции).
  7. Запись набора записей: После того как все записи добавлены в набор, мы должны вызвать Хозрасчетный.Записать(); для сохранения движений в базе данных.

Давайте рассмотрим код, демонстрирующий правильное использование БухгалтерскийУчет.УстановитьСубконто для формирования движений регистра:


// Предположим, что Документ - это объект текущего документа, который является регистратором,
// Организация - ссылка на элемент справочника "Организации",
// Об - объект документа, из которого вызывается код (например, документ "ОперацияБух"),
// ТЗ - таблица значений с данными для формирования проводок.
// СчетУчета и СчетКт - предопределенные элементы Плана счетов.

Хозрасчетный = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
// Критически важно установить отбор по регистратору для правильной работы с набором записей
Хозрасчетный.Отбор.Регистратор.Значение = Документ; 

Перем СуммаОперации; // Переменная для подсчета общей суммы операций
СуммаОперации = 0;

Для Каждого Стр Из ТЗ Цикл
    // Добавляем новую запись (проводку) в набор
    Запись = Хозрасчетный.Добавить();
    Запись.Регистратор = Документ;
    Запись.Организация = Организация;
    Запись.Период = Об.Дата; // Используем дату документа
    Запись.Содержание = "Ввод остатков"; // Описание проводки
    Запись.СчетДт = СчетУчета; // Счет дебета, например, Счет 08.08 или 97.24
    Запись.СчетКт = СчетКт; // Счет кредита (например, Счет 000 для ввода остатков)
    Запись.Сумма = Стр.СуммаОстаток;
    Запись.СуммаНУДт = Стр.СуммаНУОстаток;
    Запись.СуммаПРДт = Стр.СуммаПРОстаток;
    Запись.СуммаВРДт = Стр.СуммаВРОстаток;

    // Получаем значение для подразделения, если оно предусмотрено аналитикой
    Подразделение = ПолучитьПодразделение(Стр);
    Запись.ПодразделениеДт = Подразделение;

    // Определяем, какое субконто нужно получить в зависимости от счета
    Перем Субконто1;
    Перем КодСчетаБП; // Предполагается, что эта переменная содержит код счета
    Если КодСчетаБП = "08.08" Тогда 
        Субконто1 = ПолучитьНематериальныйАктив(Стр);
    ИначеЕсли КодСчетаБП = "97.24" Тогда 
        Субконто1 = ПолучитьРБП(Стр);
    КонецЕсли;

    // Устанавливаем первое субконто для дебета, если значение получено
    Если Субконто1 <> Неопределено Тогда
        БухгалтерскийУчет.УстановитьСубконто(Запись.СчетДт, Запись.СубконтоДт, 1, Субконто1);
    КонецЕсли;

    // Получаем значение для второго субконто (например, статью затрат)
    Перем Субконто2;
    Субконто2 = ПолучитьСтатьюЗатрат(Стр);

    // Устанавливаем второе субконто для дебета, если значение получено
    Если Субконто2 <> Неопределено Тогда
        БухгалтерскийУчет.УстановитьСубконто(Запись.СчетДт, Запись.СубконтоДт, 2, Субконто2);
    КонецЕсли;

    СуммаОперации = СуммаОперации + Запись.Сумма;
КонецЦикла;

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

Обратите внимание, что в данном случае мы работаем с коллекцией Запись.СубконтоДт (или Запись.СубконтоКт), которая является частью объекта записи регистра, а не с отдельными реквизитами. Процедура БухгалтерскийУчет.УстановитьСубконто правильно заполняет эту коллекцию на основе переданных параметров, учитывая виды субконто, настроенные для данного счета.

Определение видов субконто для счета

Прежде чем программно заполнять субконто, мы всегда должны убедиться, какие виды субконто настроены для конкретного счета в Плане счетов. Для каждого счета может быть до трех видов субконто. Вы можете посмотреть эту информацию в конфигураторе (раздел "Планы счетов" -> "Хозрасчетный" -> закладка "Виды субконто") или непосредственно в режиме 1С:Предприятие (раздел "Справочники" -> "Планы счетов" -> "Хозрасчетный" -> кнопка "Настройка видов субконто").

Важно помнить, что порядок и типы видов субконто жестко заданы для каждого счета. Если для счета настроено, например, два вида субконто, а вы пытаетесь заполнить третье (например, используя СтрТЧ.Субконто3 или передавая 3 в БухгалтерскийУчет.УстановитьСубконто), то это будет проигнорировано или может вызвать ошибку в зависимости от контекста и проверки, которая выполняется в системе. Всегда согласуйте программный код с фактической настройкой Плана счетов.

Советы по отладке и диагностике ошибок

Когда вы сталкиваетесь с ошибками при работе с субконто, пошаговая отладка является вашим лучшим инструментом. Вот что мы рекомендуем для эффективной диагностики:

  1. Установите точки останова: Разместите точки останова непосредственно перед строкой, где происходит присвоение субконто или вызов процедуры БухгалтерскийУчет.УстановитьСубконто. Это позволит нам "заморозить" выполнение кода в нужный момент.
  2. Проверьте значения переменных: Во время отладки внимательно изучите значения всех переменных, которые передаются в проблемную строку.
    • Убедитесь, что объект субконто (например, Субконто1 или Контрагент) содержит корректную ссылку на элемент справочника или другой объект нужного типа, а не Неопределено, пустую ссылку или некорректный тип. Несоответствие типов — очень частая причина ошибок.
    • При использовании БухгалтерскийУчет.УстановитьСубконто проверьте значения всех четырех параметров: Счет (должен быть ссылкой на элемент Плана счетов), НаборСубконто (должен быть коллекцией субконто записи регистра, т.е. Запись.СубконтоДт или Запись.СубконтоКт), ИндексИлиИмяВидаСубконто (число 1, 2, 3 или строка с именем вида субконто), и ЗначениеСубконто (ссылка на объект, соответствующий виду субконто). В нашем случае, ошибка "Поле объекта не обнаружено (СчетРегистрБухгалтерииСубконто.ЖурналПроводокЕПСБУ)" возникла из-за того, что в процедуру был передан некорректный параметр, который должен был быть либо "Дт", либо "Кт" для правильного обращения к полю Проводка["Счет"+ДтКт] внутри общей процедуры. Это указывает на то, что объект, переданный в процедуру, имел не ту структуру, которую она ожидала.
  3. Анализируйте трассировку стека вызовов: Трассировка покажет вам полный путь выполнения кода до момента возникновения ошибки, что поможет понять, из какого модуля и с какими параметрами был вызван проблемный участок. Это неоценимо для понимания контекста ошибки, особенно при работе с общими модулями.
  4. Используйте функции для поиска: При поиске элементов справочников по наименованию или коду, всегда проверяйте результат. Например, Справочники.Контрагенты.НайтиПоНаименованию("...") может вернуть Неопределено, если элемент не найден, что затем приведет к ошибкам при попытке использования этого значения как ссылки.

Заключение

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

← На главную