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

В этой статье мы детально разберем технические механизмы платформы, которые позволяют различать эти состояния. Мы рассмотрим как классические подходы, так и подводные камни, с которыми сталкиваются разработчики при работе с временными таблицами и ссылками.

Понимание внутренней структуры хранения ссылок и флагов состояния объекта — ключ к написанию устойчивого и производительного кода. Давайте погрузимся в технические детали реализации этой проверки.

Концепция нового объекта на платформе 1С

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

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

Для разработчика важно осознавать разницу между объектом в форме и объектом в модуле. В форме объект может быть временно создан для подбора значений, но в модуле документа проверка на новизну часто определяет, нужно ли создавать новые движения по регистрам или обновлять существующие записи.

Некорректная трактовка состояния объекта может привести к тому, что система попытается обновить запись, которой еще не существует, что вызовет ошибку транзакции или логический сбой в последовательности проведения.

Использование свойства Новый()

Самым прямым и рекомендуемым способом проверки статуса объекта является обращение к встроенному свойству Новый (или New в английской версии платформы). Это булево значение, которое возвращает Истина, если объект был создан в текущей сессии и еще не записан в базу данных.

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

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

⚠️ Внимание: Свойство Новый возвращает Ложь для объектов, загруженных из базы, даже если вы изменили их реквизиты и еще не сохранили изменения. Оно реагирует только на факт первичного создания экземпляра.

Рассмотрим пример использования в коде модуля объекта:

Если Объект.Новый Тогда

Сообщить("Создан новый документ, номер будет присвоен при записи");

Иначе

Сообщить("Редактируется существующий документ");

КонецЕсли;

Также важно учитывать поведение этого свойства при копировании объектов. Если вы используете метод Скопировать(), новый созданный экземпляр будет иметь свойство Новый равным Истина, так как для системы это фактически новый объект, требующий новой записи с новым уникальным идентификатором.

💡

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

Проверка через пустую ссылку и UUID

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

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

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

  • 🔍 Свойство Новый — наиболее семантически верный способ проверки.
  • 🆔 Проверка UUID полезна при анализе временных таблиц, где свойство Новый недоступно.
  • ⚠️ Функция ПустаяСсылка() не подходит для определения новизны записанного, но измененного объекта.

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

📊 Какой метод проверки вы используете чаще всего?
Свойство Новый()
Проверка ПустаяСсылка()
Анализ UUID
Запрос к базе данных

Особенности работы во временных таблицах

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

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

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

Метод проверки Доступен в объекте Доступен в запросе Производительность
Свойство Новый() Да Нет Высокая
ПустаяСсылка() Да (частично) Да Высокая
Запрос к базе Да Да Низкая
Служебное поле Н/Д Да Средняя

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

⚠️ Внимание: В запросах нельзя напрямую проверить свойство Новый(). Если вам критично важно отфильтровать новые объекты в запросе, передавайте список их UUID через параметр или используйте временную таблицу с флагом.

Как передать статус новизны в запрос?

Создайте временную таблицу с полями Ссылка и ЭтоНовый. Заполните её в цикле, проверяя свойство Новый() у каждого объекта. Затем используйте эту таблицу в основном запросе для соединения.

Нюансы при проведении документов

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

Если документ новый, система должна создать новые записи в регистрах накопления. Если документ старый, часто требуется сначала удалить старые движения (методом НаборЗаписей.Очистить()), а затем записать новые. Неправильное определение приведет к задвоению итогов.

Обычно в стандартных подсистемах 1С используется свойство Новый именно для выбора стратегии обработки движений. Однако, если документ был записан, но не проведен, а затем пользователь нажал "Провести", объект уже не будет считаться новым, хотя движения в регистрах могут отсутствовать.

Поэтому в сложных сценариях рекомендуется проверять не только свойство Новый, но и наличие записей в регистрах, связанных с данным документом. Это обеспечивает"idempotency" (идемпотентность) проведения — многократное выполнение операции дает тот же результат, что и однократное.

💡

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

Влияние режима совместимости и версий платформы

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

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

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

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

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

☑️ Проверка логики нового объекта

Выполнено: 0 / 4

Часто задаваемые вопросы (FAQ)

В чем разница между Записать() и Провести() в контексте нового объекта?

Метод Записать() сохраняет объект в базу данных, после чего свойство Новый становится Ложь. Метод Провести() обычно вызывает Записать() внутри себя, но также формирует движения по регистрам. Объект перестает быть новым именно в момент записи, а не проведения.

Может ли свойство Новый() быть истинным для загруженного из файла объекта?

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

Как определить новый объект в запросе к базе данных?

Напрямую в языке запросов 1С это сделать нельзя, так как свойство Новый() — это свойство объекта в памяти. Необходимо выгрузить данные в таблицу значений, обработать в коде и передать список идентификаторов новых объектов обратно в запрос через параметр.

Сбрасывается ли свойство Новый() при отмене проведения?

Нет. Отмена проведения (ОбработкаОтменыПроведения) работает с уже записанным объектом. Свойство Новый будет равно Ложь, так как объект физически существует в базе данных. Отмена проведения лишь удаляет движения, но не удаляет сам документ.

Влияет ли режим управляемого приложения на проверку нового объекта?

Нет, логика свойства Новый едина для управляемого и обычного приложения. Различия могут быть только в том, на каком клиенте (толстый или тонкий) создается объект, но семантика свойства остается неизменной.