Почему движения в регистре бухгалтерии не записываются и как отладить процедуру проведения в 1С:БГУ 2.0?

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

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

Для успешной записи движений в регистр бухгалтерии в 1С, особенно в конфигурации БГУ 2.0, нам важно учитывать несколько ключевых аспектов, которые могут дополнить и разъяснить обсуждаемые вопросы.

1. Проверка настроек документа: Включены ли движения по регистру?

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

Что нам нужно проверить:

  1. Откройте конфигуратор и найдите ваш документ в дереве метаданных.
  2. Перейдите на вкладку "Движения".
  3. Убедитесь, что для регистра бухгалтерии, в который вы пытаетесь записать движения (например, ЖурналПроводокЕПСБУ для БГУ 2.0 или Журнал проводок (бухгалтерский и налоговый учет)), установлен флажок.
  4. Если флажок не установлен, установите его и обновите конфигурацию базы данных.

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

2. Корректное формирование движений и вызов метода "Записать()"

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

  1. Инициализация набора записей: Для работы с движениями регистра бухгалтерии необходимо сначала получить набор записей регистра. Мы делаем это, обращаясь к коллекции движений документа по имени регистра:

    
    ДвижениеХоз = Движения.ЖурналПроводокЕПСБУ;
    // или универсально, если имя регистра известно
    // ДвижениеХоз = Движения[ИмяРегистраБухгалтерии];
    

    Обратите внимание, что мы используем объект Движения, который является коллекцией наборов записей всех регистров, по которым документ может формировать движения. В БГУ 2.0 регистр бухгалтерии часто называется ЖурналПроводокЕПСБУ.

  2. Добавление новой проводки: Каждая отдельная проводка добавляется в полученный набор записей с помощью метода .Добавить(). Этот метод создает новую строку движения, которую мы затем заполняем:

    НоваяПроводка = ДвижениеХоз.Добавить();
  3. Заполнение полей проводки: Это критически важный шаг. После добавления проводки необходимо заполнить все ее обязательные реквизиты. К ним относятся:

    • СчетДт (счет дебета)
    • СчетКт (счет кредита)
    • Сумма (сумма проводки)
    • СубконтоДт (измерения субконто для счета дебета)
    • СубконтоКт (измерения субконто для счета кредита)
    • А также Дата, Валюта, Организация и другие специфичные для вашей конфигурации поля.

    Особое внимание уделите субконто! Неправильное или неполное заполнение субконто является очень частой причиной ошибок, из-за которых проводки могут не записываться или записываться некорректно. Для каждого счета могут требоваться свои виды субконто, и их типы должны строго соответствовать.

  4. Важность Записать(): После того как все проводки сформированы и добавлены в набор записей, мы должны вызвать метод Записать() для всего набора. Без этого метода изменения, внесенные в набор записей, не будут сохранены в базе данных. В общем случае это делается так:

    ДвижениеХоз.Записать();

    Если нам требуется выполнить запись с предварительной очисткой существующих движений по данному документу (это стандартное поведение при перепроведении), мы используем параметр Истина:

    ДвижениеХоз.Записать(Истина);
  5. Где вызывать Записать(): Метод Записать() для набора движений регистра бухгалтерии обычно вызывается в конце процедуры ОбработкаПроведения документа. В некоторых типовых конфигурациях (как в УТ 11.4, приведенной в сообщении 21) используется специальная общая процедура, например, ПодготовитьНаборыЗаписейКРегистрацииДвижений. В ней мы устанавливаем флаг Записывать = Истина для нужных регистров, а окончательная запись всех движений происходит уже через общий вызов Движения.Записать(); в конце основной процедуры проведения.

    Вот пример из типовой конфигурации (сообщение 21) для иллюстрации этой механики:

    
    Процедура ОбработкаПроведения(Отказ, РежимПроведения)
        ...
        ПодготовитьНаборыЗаписейКРегистрацииДвижений(Отказ);
        ...
    КонецПроцедуры
    
    Процедура ПодготовитьНаборыЗаписейКРегистрацииДвижений(Отказ)
        ...
        // Записываем наборы записей, в которых есть движения
        Для Каждого ИмяРегистра Из МассивИменРегистров Цикл
            Движения[ИмяРегистра].Записывать = Истина;
        КонецЦикла;
        Движения.Записать;
    КонецПроцедуры
    

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

3. Отладка и почему точка останова может быть серой

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

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

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

  3. Ошибка компиляции в другом месте: Хотя платформа обычно выдает ошибки компиляции, если код не компилируется, иногда могут быть неочевидные проблемы, которые препятствуют выполнению всей процедуры. Проверьте весь модуль объекта на наличие синтаксических ошибок.

  4. Неправильная версия или база данных: Убедитесь, что отладка происходит именно в той базе и на той версии конфигурации, где находится измененный код. Возможно, вы внесли изменения в одну базу, а отлаживаетесь в копии или старой версии.

  5. Клиент-серверный режим и тонкий клиент: Это очень важный момент. Если ваша база работает в клиент-серверном режиме, а вы отлаживаетесь через тонкий клиент, то серверный код (который выполняется при проведении документа) не будет остановлен точкой останова, поставленной на клиенте. Для отладки серверного кода в клиент-серверном режиме нам необходимо:

    • Настроить отладку на сервере 1С:Предприятия (через менеджер кластера или в конфигураторе).
    • Или запускать базу в толстом клиенте, который в некоторых случаях может выполнять серверный код в рамках того же процесса, что и клиент, что упрощает отладку.

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

  6. Антивирусное программное обеспечение: Иногда антивирусы могут вмешиваться в работу процессов 1С, блокируя или замедляя работу отладчика. Временное отключение антивируса может помочь в диагностике, но не является постоянным решением.

Как проверить наличие движений в отладчике:

После того как вы добьетесь срабатывания точки останова, установите ее перед выходом из процедуры проведения. В отладчике мы можем просмотреть содержимое объекта Движения.ЖурналПроводокЕПСБУ. Разверните его, чтобы увидеть, добавлены ли в него строки движений и правильно ли заполнены все поля, включая счета, суммы и субконто. Это поможет нам убедиться, что код формирования движений работает корректно, и проблема кроется именно в записи, а не в формировании.

4. Типичные ошибки в коде формирования движений

Даже если все настройки верны и отладка работает, ошибки в самом коде могут препятствовать записи движений. Давайте проанализируем распространенные ошибки, которые упоминались на форуме, и как их исправить.

  1. Неверное использование переменных: Как справедливо заметил участник форума в сообщении 11, частая ошибка – это создание новой строки движения в одну переменную, а попытка заполнения совершенно другой:

    
    // Неправильно:
    Проводка = ДвижениеХоз.Добавить; // Создали объект в переменной Проводка
    // ...
    // Движение.СчетДт = ПланыСчетов.ЕПСБУ.Счет101; // Попытка заполнить мифическое "Движение"
    // ...
    

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

    
    // Правильно:
    НоваяПроводка = ДвижениеХоз.Добавить(); // Создали объект в переменной НоваяПроводка
    НоваяПроводка.СчетДт = ПланыСчетов.ЕПСБУ.Счет101;
    НоваяПроводка.Сумма = 100;
    // ... и так далее для всех полей НоваяПроводка
    
  2. Синтаксические ошибки в циклах: Сообщение 15 указывает на синтаксическую ошибку в цикле Для каждого к = 4 Из КоличествоСубконтоДт Цикл. Такой цикл не скомпилируется. При работе с циклами в 1С мы должны использовать корректный синтаксис. Если вы хотите перебрать элементы коллекции или диапазон чисел, это делается так:

    
    // Перебор элементов коллекции
    Для Каждого ТекСтрокаИзТабличнойЧасти Документа.Услуги Цикл
        // ... ваш код
    КонецЦикла;
    
    // Перебор чисел от 1 до N
    Для Индекс = 1 По КоличествоСубконтоДт Цикл
        // ... ваш код
    КонецЦикла;
    
  3. Неполное или некорректное заполнение субконто: Этот момент мы уже затрагивали, но подчеркнем его снова. Каждый счет имеет определенное количество видов субконто (от 0 до 3), и при заполнении проводки мы обязаны указать правильные объекты для каждого из них. Например, если счет 101 имеет субконто "Основные средства", мы должны присвоить этому полю ссылку на элемент справочника "Основные средства".

    
    НоваяПроводка.СубконтоДт[ПланыВидовХарактеристик.ВидыСубконтоБухгалтерскогоУчета.ОсновныеСредства] = МойОбъектОсновныхСредств;
    

    Если субконто не заполнить, а оно является обязательным для счета, проводка не будет записана или будет записана некорректно, что приведет к ошибкам в учете.

  4. Отсутствие вызова Записать(): Как было указано в сообщении 19, если после всех манипуляций с добавлением проводок вы не вызвали ДвижениеХоз.Записать(), то никаких данных в базу не попадет.

Пример исправленного кода формирования движений (на основе сообщений 10 и 11):

Предположим, у нас есть табличная часть "Услуги" и мы хотим сформировать проводки по каждой ее строке.


Процедура ОбработкаПроведения(Отказ, РежимПроведения)

    // ... ваш код до формирования движений ...

    // Получаем набор записей регистра бухгалтерии
    Движения.ЖурналПроводокЕПСБУ.Очистить(); // Очищаем существующие движения документа перед формированием новых
    Движения.ЖурналПроводокЕПСБУ.Записывать = Истина; // Указываем, что набор должен быть записан

    // Перебираем строки табличной части "Услуги"
    Для Каждого ТекСтрокаУслуги Из Услуги Цикл

        // Создаем новую проводку
        НоваяПроводка = Движения.ЖурналПроводокЕПСБУ.Добавить();

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

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

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

        // Также могут потребоваться дополнительные реквизиты проводки, специфичные для БГУ 2.0
        // Например: КПС, КФО, ИсточникСредств, ВидРасхода, и т.д.
        // НоваяПроводка.КФО = ТекСтрокаУслуги.КФО;
        // НоваяПроводка.КПС = ТекСтрокаУслуги.КПС;

    КонецЦикла;

    // Окончательная запись всех сформированных движений.
    // Если Записывать = Истина было установлено ранее, этот вызов сохранит изменения.
    Движения.Записать();

    // ... ваш код после формирования движений ...

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

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

5. Режим проведения документа

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

Например, в оперативном режиме некоторые документы могут формировать движения по оперативным регистрам, а в неоперативном – по бухгалтерским. Убедитесь, что ваш код не пропускает создание проводок из-за неподходящего режима.

Мы видим, что проблема с незаписью движений в регистр бухгалтерии в 1С:БГУ 2.0 может быть вызвана множеством факторов – от простой невнимательности при настройке метаданных до сложных синтаксических или логических ошибок в коде. Системный подход к проверке настроек, тщательная отладка и внимание к деталям в коде формирования движений помогут нам успешно решить эту задачу и обеспечить корректное ведение бухгалтерского учета.

← На главную