Как отменить проведение документа "Расчет курсовых разниц" в 1С:ERP, не распроводя все валютные операции?

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

Коллеги, мы сталкиваемся с ситуацией, когда стандартная отмена проведения документа Расчет курсовых разниц в 1С:ERP (версии 2.5.17.95 и аналогичных) вызывает значительные трудности, в отличие от предыдущих версий, таких как УПП. Система требует отменить проведение всех зависимых валютных операций, что может быть очень трудоемким и рискованным. Давайте разберемся, почему так происходит, и какие существуют подходы к решению этой проблемы.

Почему отмена проведения документа "Расчет курсовых разниц" в 1С:ERP так сложна?

Чтобы понять причины такого поведения системы, нам нужно рассмотреть архитектуру взаиморасчетов и механизм расчета курсовых разниц в 1С:ERP. Мы выясним, какие особенности конфигурации приводят к таким строгим ограничениям.

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

Какие есть подходы к решению проблемы?

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

  1. Использование обработки "Универсальный редактор реквизитов" для очистки движений.

    Этот метод предполагает использование мощной, но требующей крайне осторожного обращения, штатной обработки Универсальный редактор реквизитов. Мы можем использовать ее для выборочной очистки движений, сформированных документом Расчет курсовых разниц или связанным с ним Регистратором расчетов, в регистрах оперативного учета, например, в РегистрНакопления.РасчетыСПоставщикамиПоСрокам и РегистрНакопления.РасчетыСКлиентамиПоСрокам, для чего может пригодиться заполнение Корректировки регистров на основании движений.

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

    Общие шаги по применению обработки:

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

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

    Этот метод часто реализуется через разработку специализированных служебных обработок с повышенными привилегиями. Такие обработки позволяют программно очищать наборы записей движений, которые система не дает удалить типовыми средствами. Приведем концептуальный пример кода, демонстрирующий логику такой обработки. Важно: Это псевдокод, который требует адаптации и тщательной проверки в реальной базе данных.

    
    // Пример псевдокода для служебной обработки (не для прямого использования без доработки)
    // Процедура может быть вызвана из внешней обработки, ей передается ссылка на документ "Расчет курсовых разниц"
    Процедура ПринудительноОчиститьДвиженияКурсовыхРазниц(ДокументСсылкаРасчетКурсовых)
    
        Если ТипЗнч(ДокументСсылкаРасчетКурсовых) <> Тип("ДокументСсылка.РасчетКурсовыхРазниц") Тогда
            Сообщить("Передана неверная ссылка на документ.");
            Возврат;
        КонецЕсли;
    
        НачатьТранзакцию();
        Попытка
            // 1. Очищаем движения, созданные самим документом "Расчет курсовых разниц"
            Сообщить("Очистка движений, созданных документом Расчет курсовых разниц: " + ДокументСсылкаРасчетКурсовых);
    
            // Очищаем движения в регистрах накопления, которые напрямую двигает этот документ
            // (если таковые есть помимо регистраторов расчетов)
            НаборЗаписей = РегистрыНакопления.РасчетыСПоставщикамиПоСрокам.СоздатьНаборЗаписей();
            НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылкаРасчетКурсовых);
            НаборЗаписей.Очистить();
            НаборЗаписей.Записать();
            Сообщить("   - Очищены движения в РегистреНакопления.РасчетыСПоставщикамиПоСрокам.");
    
            НаборЗаписей = РегистрыНакопления.РасчетыСКлиентамиПоСрокам.СоздатьНаборЗаписей();
            НаборЗаписей.Отбор.Регистратор.Установить(ДокументСсылкаРасчетКурсовых);
            НаборЗаписей.Очистить();
            НаборЗаписей.Записать();
            Сообщить("   - Очищены движения в РегистреНакопления.РасчетыСКлиентамиПоСрокам.");
                    
            // Добавьте другие регистры, если документ их двигает напрямую (например, Рег.Бухгалтерии)
            // НаборЗаписейБух = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
            // НаборЗаписейБух.Отбор.Регистратор.Установить(ДокументСсылкаРасчетКурсовых);
            // НаборЗаписейБух.Очистить();
            // НаборЗаписейБух.Записать();
            // Сообщить("   - Очищены движения в РегистреБухгалтерии.Хозрасчетный.");
    
    
            // 2. Находим и обрабатываем связанные документы "Регистратор расчетов"
            Сообщить("Поиск и обработка связанных Регистраторов расчетов.");
    
            Запрос = Новый Запрос;
            Запрос.Текст = 
            "ВЫБРАТЬ
            |    РегистраторРасчетов.Ссылка КАК Ссылка
            |ИЗ
            |    Документ.РегистраторРасчетов КАК РегистраторРасчетов
            |ГДЕ
            |    РегистраторРасчетов.ДокументРегистратор = &ДокументСсылкаРасчетКурсовых
            |    И РегистраторРасчетов.ХозяйственнаяОперация = ЗНАЧЕНИЕ(Перечисление.ХозяйственныеОперацииВзаиморасчетов.КурсовыеРазницы)";
            Запрос.УстановитьПараметр("ДокументСсылкаРасчетКурсовых", ДокументСсылкаРасчетКурсовых);
                    
            Выборка = Запрос.Выполнить().Выбрать();
            Пока Выборка.Следующий() Цикл
                СсылкаРегистраторРасчетов = Выборка.Ссылка;
                Сообщить("   - Найден связанный Регистратор расчетов: " + СсылкаРегистраторРасчетов);
    
                // Очистка движений, созданных этим РегистраторомРасчетов
                НаборЗаписейРР = РегистрыНакопления.РасчетыСПоставщикамиПоСрокам.СоздатьНаборЗаписей();
                НаборЗаписейРР.Отбор.Регистратор.Установить(СсылкаРегистраторРасчетов);
                НаборЗаписейРР.Очистить();
                НаборЗаписейРР.Записать();
                Сообщить("      - Очищены движения в РегистреНакопления.РасчетыСПоставщикамиПоСрокам для РР.");
    
                НаборЗаписейРР = РегистрыНакопления.РасчетыСКлиентамиПоСрокам.СоздатьНаборЗаписей();
                НаборЗаписейРР.Отбор.Регистратор.Установить(СсылкаРегистраторРасчетов);
                НаборЗаписейРР.Очистить();
                НаборЗаписейРР.Записать();
                Сообщить("      - Очищены движения в РегистреНакопления.РасчетыСКлиентамиПоСрокам для РР.");
    
                // Очистка движений в Регистре Бухгалтерии, если РегистраторРасчетов их двигает
                // НаборЗаписейБухРР = РегистрыБухгалтерии.Хозрасчетный.СоздатьНаборЗаписей();
                // НаборЗаписейБухРР.Отбор.Регистратор.Установить(СсылкаРегистраторРасчетов);
                // НаборЗаписейБухРР.Очистить();
                // НаборЗаписейБухРР.Записать();
                // Сообщить("      - Очищены движения в РегистреБухгалтерии.Хозрасчетный для РР.");
    
                // Удаляем сам документ "Регистратор расчетов"
                ДокументОбъектРегистраторРасчетов = СсылкаРегистраторРасчетов.ПолучитьОбъект();
                Если ДокументОбъектРегистраторРасчетов <> Неопределено Тогда
                    ДокументОбъектРегистраторРасчетов.Удалить();
                    Сообщить("      - Документ Регистратор расчетов удален: " + СсылкаРегистраторРасчетов);
                КонецЕсли;
            КонецЦикла;
    
            // 3. После очистки всех связанных движений и служебных регистраторов
            // можно попробовать распровести сам документ "Расчет курсовых разниц"
            Сообщить("Попытка отменить проведение основного документа.");
            ДокументОбъект = ДокументСсылкаРасчетКурсовых.ПолучитьОбъект();
            Если ДокументОбъект <> Неопределено И ДокументОбъект.Проведен Тогда
                ДокументОбъект.Записать(РежимЗаписиДокумента.ОтменаПроведения);
                Сообщить("Документ Расчет курсовых разниц успешно распроведен.");
            Иначе
                Сообщить("Документ Расчет курсовых разниц либо не найден, либо уже не проведен.");
            КонецЕсли;
    
            ЗафиксироватьТранзакцию();
            Сообщить("Операция успешно завершена.");
        Исключение
            ОтменитьТранзакцию();
            Сообщить("Произошла ошибка при выполнении операции: " + ОписаниеОшибки());
        КонецПопытки;
    КонецПроцедуры
    

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

  3. Использование внешних обработок принудительной отмены проведения.

    На рынке существуют готовые или полуготовые внешние обработки, разработанные сторонними специалистами, предназначенные для принудительной отмены проведения документов в 1С:ERP, КА, УТ и других конфигурациях. Такие обработки часто обходят типовые ограничения логики прикладного решения, позволяя "протащить" отмену проведения даже в сложных случаях, когда невозможно снять с проведения документы из-за ошибочных ссылок на регистры или других проблем.

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

Рекомендации и лучшие практики

При работе с такими сложными операциями, как отмена проведения документа Расчет курсовых разниц в 1С:ERP, важно соблюдать определенные правила и следовать рекомендациям.

  1. Проверяйте настройки переоценки валютных средств. Убедитесь, что параметры переоценки валютных средств настроены корректно в разделе "НСИ и администрирование – Настройка НСИ и разделов – Казначейство и взаиморасчеты – Переоценка валютных средств". Возможные варианты: "На дату оплаты и на конец месяца" или "На каждый день месяца". Изменение этой настройки может потребовать полного перерасчета курсовых разниц, и именно это может быть первопричиной, по которой вы хотите распровести документ.
  2. Строго следуйте последовательности закрытия месяца. Расчет курсовых разниц является частью сложной процедуры закрытия месяца, которая включает последовательность регламентных операций. Отмена его проведения может быть затруднена, если она нарушает строгую последовательность операций, которая обеспечивает корректность формирования финансового результата. Рекомендуется строго следовать регламенту закрытия месяца в 1С:ERP, чтобы минимизировать необходимость ручных правок.
  3. Всегда делайте резервные копии. Любые действия по принудительному изменению данных в базе, особенно те, что включают прямое удаление движений или использование универсальных редакторов, должны предваряться созданием актуальной резервной копии базы данных. Это позволит восстановить систему в случае непредвиденных проблем.
  4. Консультируйтесь со специалистами. Если вы не уверены в своих действиях или глубина проблемы превышает ваш уровень компетенции, лучше обратиться к опытным программистам или консультантам 1С, которые имеют опыт работы с подобными задачами в 1С:ERP.

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

← На главную