Разработка на платформе 1С:Предприятие 7.7 даже в современных реалиях остается актуальной для многих крупных систем, где важна скорость отклика и работа с прямыми запросами к базе данных. Однако некоторые механизмы этой платформы, такие как работа с внутренними идентификаторами и блокировками, имеют свои «подводные камни». В этой статье мы подробно разберем, как эффективно конвертировать ссылки в строковые представления и как управлять доступом к данным в многопользовательской среде.
В 1С 7.7 часто возникает задача передать ссылку на объект (документ, справочник) в виде строки, например, для логирования, передачи в стороннюю систему или использования в прямом SQL-запросе. Существует несколько методов получения такого представления, и важно понимать разницу между ними.
Метод ЗначениеВДлиннуюСтрокуБД(Объект) возвращает компактный идентификатор объекта длиной 13 символов. Однако у него есть существенный недостаток: эта строка не содержит информации о типе объекта. Если мы попытаемся выполнить обратное преобразование через ЗначениеИзДлиннойСтрокиБД(), нам обязательно придется указать тип объекта (например, "Справочник.Товары"), что крайне неудобно, если тип заранее неизвестен.
Рассмотрим ситуацию, когда нам нужно получить универсальный идентификатор, включающий информацию о типе. Проанализируем возможности метода ЗначениеВСамуюДлиннуюСтрокуБД(Объект). Эта функция возвращает строку длиной 23 символа. Преимущество этого формата заключается в том, что в первых символах строки «зашит» код типа метаданных:
Хотя в штатном наборе функций 1С 7.7 отсутствует симметричный метод «ЗначениеИзСамойДлиннойСтрокиБД», опытные разработчики используют возможности внешних компонент, таких как 1С++. Выясним, как восстановить объект из такой строки с помощью прямого запроса к SQL.
Посмотрим на пример кода, который позволяет получить ссылку на объект, зная только его «самую длинную строку»:
Функция ЗначениеИзСамойДлиннойСтрокиБД(СамыйДлинныйИД)
// Используем внешнюю компоненту 1С++ для выполнения SQL-запроса
рс = СоздатьОбъект("ODBCRecordset");
// [$Неопределенный] — это специальный типизатор в 1С++, который умеет
// распознавать 23-символьный ИД и превращать его в объект 1С
Возврат рс.ВыполнитьСкалярный("select '" + СамыйДлинныйИД + "' [$Неопределенный]");
КонецФункции
Этот метод является наиболее надежным, если в вашей системе используется SQL-версия и установлена компонента 1С++. Если же вы работаете в «чистой» конфигурации без внешних компонент, вам придется вручную анализировать первые два символа строки, определять тип и использовать стандартный метод ЗначениеИзДлиннойСтрокиБД().
Второй важный аспект — это управление блокировками. В 1С 7.7 метод Блокировка() часто вызывает недоумение у начинающих разработчиков. Основная проблема заключается в том, что этот метод нельзя вызвать напрямую у ссылки, полученной как реквизит другого объекта.
Проанализируем ситуацию: у нас есть документ «Расходная», и в нем есть реквизит ДокументОснование. Попытка вызвать ДокументОснование.Блокировка(1) приведет к ошибке выполнения. Почему так происходит? Дело в том, что 1С 7.7 строго разделяет ссылку (простое значение идентификатора в памяти) и объект (контекст с данными, загруженными из базы).
Чтобы заблокировать объект, нам необходимо сначала «материализовать» его. Разберем правильный алгоритм действий по шагам:
СоздатьОбъект().НайтиДокумент()).Блокировка(1).Посмотрим на пример корректного кода:
// Предположим, ТекущийДок — это ссылка на документ
Док = СоздатьОбъект("Документ.РасходнаяНакладная");
Если Док.НайтиДокумент(ТекущийДок) = 1 Тогда
Если Док.Блокировка(1) = 1 Тогда
// Объект успешно заблокирован для текущего пользователя
// Можно производить изменения или защищенное чтение
Иначе
Предупреждение("Объект уже заблокирован другим пользователем!");
КонецЕсли;
КонецЕсли;
Многие разработчики ищут метод, позволяющий проверить, заблокирован ли объект, не пытаясь установить блокировку самим. К сожалению, в штатном функционале платформы 1С 7.7 такого метода нет. Единственный способ узнать состояние — попытаться вызвать Блокировка(1). Если функция вернула 0, это однозначно сигнализирует о том, что объект занят другим процессом или пользователем.
Важный нюанс для SQL-версий: стоит помнить, что программная блокировка в 1С 7.7 на уровне SQL-сервера работает иначе, чем в файловых версиях. Вызов Блокировка(1) устанавливает логическую блокировку внутри сессий 1С, но реальная блокировка строки в таблице базы данных может произойти только в момент начала транзакции при записи объекта.
Если перед нами стоит задача просто сохранить объект в строку «для себя» (например, в рамках одной сессии или в текстовый файл), лучше использовать проверенный метод ЗначениеВСтрокуВнутр(Объект). Эта функция возвращает длинную, но полную структуру данных, которую 1С гарантированно распознает при обратном преобразовании ЗначениеИзСтрокиВнутр() без каких-либо дополнительных условий.
Однако если мы строим сложные системы обмена или аналитические отчеты на прямых запросах, понимание того, как устроены ЗначениеВДлиннуюСтрокуБД и ЗначениеВСамуюДлиннуюСтрокуБД, становится критически важным для обеспечения производительности и целостности данных.
Подведем итог: для работы с идентификаторами объектов в сложных задачах рекомендуем использовать связку 1С++ и 23-символьных строк, а при работе с блокировками — всегда предварительно загружать объект через СоздатьОбъект(). Такой подход минимизирует количество ошибок и сделает ваш код более надежным.