Как программно изменить время проведенного документа в 1С 7.7

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

В платформе 1С:Предприятие 7.7 задача изменения времени уже записанного и проведенного документа является классической, но требует строгого соблюдения последовательности действий. В отличие от интерактивного изменения в журнале, программный метод требует работы с объектом документа, управления его состоянием (проведен/не проведен) и учета механизмов автоматической расстановки времени. Разберем подробно, как реализовать эту задачу эффективно и избежать типичных ошибок программиста.

Базовый алгоритм изменения времени

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

  1. Найти документ и создать объект типа Документ.
  2. Отменить проведение (сделать документ непроведенным), чтобы освободить ресурсы и подготовить его к перемещению на новую временную точку.
  3. Установить новое время с помощью специальных методов объекта.
  4. Записать изменения в базу данных.
  5. Провести документ заново, чтобы его движения сформировались на новую дату и время.

Рассмотрим пример кода, реализующий этот алгоритм:


Процедура ИзменитьВремяДокумента(ТекДок, Час, Мин, Сек)
    Док = СоздатьОбъект("Документ");
    Если Док.НайтиДокумент(ТекДок) = 1 Тогда
        НачатьТранзакцию();
        Попытка
            // Снимаем с проведения, если документ проведен
            Если Док.Выбран() = 1 Тогда
                Если Док.Проведен() = 1 Тогда
                    Док.СделатьНеПроведенным();
                КонецЕсли;
                
                // Устанавливаем новое время
                Док.УстановитьВремя(Час, Мин, Сек);
                Док.Записать();
                
                // Проводим документ
                Док.Провести();
                ЗафиксироватьТранзакцию();
                Сообщить("Время документа успешно изменено!");
            КонецЕсли;
        Исключение
            ОтменитьТранзакцию();
            Сообщить("Ошибка при изменении времени: " + ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

Разбор нюансов: Объект против Ссылки

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

Как отметили участники форума, использование длинных цепочек вызовов типа Док.ТекущийДокумент.УстановитьВремя(...) может привести к непредсказуемому поведению. Правильнее сначала получить объект документа, а затем работать с его методами напрямую. Если вы работаете в модуле самого документа, используйте методы текущего объекта без лишних обращений к ссылкам.

Влияние режима АвтоВремя

Важный технический нюанс, который часто упускают — это режим автоматической установки времени, заданный в метаданных. Если для конкретного вида документа включена опция «Автоматическая установка времени» (например, «В конец дня»), то ваш вызов УстановитьВремя может быть проигнорирован системой при записи. Для обхода этого ограничения необходимо программно отключить автоматическое управление временем для текущего экземпляра объекта.

Рассмотрим, как модифицировать код с учетом этого требования:


// Отключаем автоматический режим перед установкой времени
Док.АвтоВремяОтключить();
Док.УстановитьВремя(Час, Минута, Секунда);
Док.Записать();

Метод АвтоВремяОтключить() сообщает системе, что программист берет на себя ответственность за позиционирование документа. Это критически важно, если вам нужно установить строго определенное время, а не полагаться на логику конфигурации.

Альтернативный метод: УстановитьНовоеВремя

Иногда нам не требуется указывать точные часы и минуты, а нужно просто переместить документ в определенную позицию дня. Для этого в 1С 7.7 существует метод УстановитьНовоеВремя(Режим). Разберем его возможности:

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


Док.УстановитьНовоеВремя("ПослеПоследнего");
Док.Записать();

Последствия для последовательностей и учета

Проанализируем ситуацию с точки зрения целостности базы данных. Изменение времени проведенного документа — это не просто косметическая правка. В 1С 7.7 существует понятие Границы Последовательности (ГП) и Точки Актуальности (ТА). Если вы меняете время документа «задним числом» (дата раньше текущей ТА), то последовательность документов, скорее всего, будет разорвана.

Что это означает на практике? После программного перепроведения документа с новым временем, все последующие документы в этой последовательности могут начать показывать некорректные остатки или себестоимость, так как они были проведены без учета изменений в вашем документе. Поэтому после массового изменения времени документов программным способом настоятельно рекомендуется выполнить восстановление последовательностей через «Операции — Проведение документов — Последовательности».

Работа в транзакции и блокировки

При выполнении операций перепроведения крайне важно использовать конструкцию НачатьТранзакцию() ... ЗафиксироватьТранзакцию(). Это гарантирует, что если на этапе записи или проведения произойдет сбой (например, не хватит остатков на складе или объект будет заблокирован другим пользователем), документ не останется в промежуточном «разобранном» состоянии (непроведенным и со старым временем).

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


Если Док.Блокировка(1) = 1 Тогда
    // Объект успешно заблокирован, можно менять время
Иначе
    Сообщить("Документ занят другим пользователем!");
КонецЕсли;

Заключение

Мы рассмотрели комплексный подход к изменению времени документа в 1С 7.7. Главное правило успеха — использовать прямой объект документа, не забывать про отключение автоматического времени АвтоВремяОтключить() и всегда оборачивать действия в транзакцию с проверкой результата проведения. Соблюдение этих рекомендаций позволит вам корректно управлять хронологией документов без риска повреждения логической структуры базы данных.

← На главную