При разработке под платформу 1С:Предприятие 7.7 программисты часто сталкиваются с вопросом: обязательно ли вызывать метод Записать() перед тем, как вызвать Провести()? В документации ИТС можно встретить прямое указание на то, что это необходимо делать, так как Провести() якобы не выполняет автоматическую запись. Однако на практике многие замечают, что изменения сохраняются и без этого вызова. Давайте разберем, как устроены эти механизмы и как писать код максимально надежно.
Провести() записывает данные?Разберемся в логике работы платформы. Когда вы вызываете метод Провести(), платформа 1С 7.7 переходит в режим транзакции, чтобы обеспечить целостность данных. В рамках этой транзакции, перед формированием движений по регистрам, системе необходимо зафиксировать актуальные значения реквизитов документа в базе данных. Таким образом, де-факто метод Провести() включает в себя процедуру записи.
Однако полагаться только на это поведение в крупных проектах бывает рискованно. Почему же тогда официальные источники рекомендуют связку методов? Давайте проанализируем преимущества явного вызова Записать().
Записать()Рассмотрим подробнее, почему использование конструкции Записать() перед Провести() является профессиональным стандартом:
Провести() произойдет программная ошибка или исключение, выполнение кода будет прервано. Если вы не вызывали Записать(), все изменения реквизитов, которые вы вносили перед проведением, могут остаться «в подвешенном состоянии» и не будут записаны в базу. Явный вызов Записать() гарантирует, что данные будут сохранены в БД еще до начала процесса формирования движений.Записать() вы четко разделяете процесс подготовки объекта и процесс формирования движений. Это позволяет легче отлаживать код и понимать, в какой момент произошел сбой.СделатьНеПроведенным(). Если вы все равно собираетесь перезаписать и перепровести документ, лишнее удаление движений только замедляет работу базы.Рассмотрим, как можно оптимизировать типичный код для изменения реквизитов документа. Предположим, у нас есть задача изменить реквизит УчетПоНормативу и провести документ. Вместо того чтобы «распроводить» документ, можно просто изменить значение и записать его.
Рассмотрим вариант кода, который считается избыточным:
// Избыточный подход
Если Док.Проведен() = 1 Тогда
Док.СделатьНеПроведенным(); // Лишнее обращение к БД
Док.УчетПоНормативу = Перечисление.Булево.Нет;
КонецЕсли;
Док.Провести();
А теперь посмотрим на рекомендуемый подход, который обеспечивает надежность и экономит ресурсы сервера:
// Рекомендуемый подход
Док.УчетПоНормативу = Перечисление.Булево.Нет;
Док.Записать(); // Явное сохранение изменений
Док.Провести(); // Выполнение движений
Проанализировав ситуацию, мы пришли к следующим выводам:
Записать().Записать() не будет ошибкой, а напротив — защитит ваши данные от потери при непредвиденных сбоях.СделатьНеПроведенным(), если ваша задача — просто изменить реквизиты и провести документ заново. Система автоматически пересчитает движения при выполнении Провести().Всегда старайтесь писать код так, чтобы он был предсказуемым. Явные вызовы методов записи и проведения позволяют другим разработчикам быстрее понять логику вашей программы и делают систему более устойчивой к ошибкам в нестандартных ситуациях.