В практике разработки на платформе 1С часто возникает ситуация, когда при передаче данных между процедурами или при сохранении во временные таблицы ссылка на объект (например, на документ «Счет на оплату») внезапно превращается в обычную строку. Попытка вызвать метод ПолучитьОбъект() у такой «строковой ссылки» закономерно приводит к ошибке, так как у типа данных Строка нет подобных методов. В этой статье мы подробно разберем, почему так происходит и какими способами можно восстановить полноценную ссылку из строковых данных.
Проанализируем типичную ситуацию: программист делает запрос к базе данных, получает поле Ссылка, но при попытке использовать её в дальнейшем обнаруживает, что тип данных изменился на Строка. Выясним причину этого явления. Чаще всего это происходит из-за того, что переменная или реквизит формы, в который записывается результат запроса, имеет тип Строка. В 1С при присваивании ссылочного типа строковому полю происходит автоматическое (неявное) преобразование ссылки в её текстовое представление (например, "Счет на оплату №18 от 28.09.2023").
Важно: текстовое представление — это просто информационная надпись. Оно не содержит в себе системного адреса объекта в базе данных, поэтому из него невозможно напрямую «вытащить» ссылку без дополнительных манипуляций.
Если вы столкнулись с тем, что ссылка стала строкой в форме списка или обработки, первым делом проверим метаданные. Рассмотрим шаги по исправлению:
Строка, заменим его на соответствующий ссылочный тип (например, ДокументСсылка.СчетНаОплату).После этого ссылка будет сохраняться в своем первозданном виде, и вы сможете легко получить объект кодом:
// Ссылка теперь имеет правильный тип
ДокументОбъект = ВашаПеременнаяСсылка.ПолучитьОбъект();
ДокументОбъект.Комментарий = "Изменено программно";
ДокументОбъект.Записать();
Иногда нам действительно необходимо передать ссылку в виде текста (например, через текстовый файл или внешнюю базу DBF). В этом случае лучше передавать не «красивое» представление, а уникальный идентификатор (GUID). Рассмотрим, как получить ссылку, если у нас есть строка GUID.
Для начала получим строковый идентификатор на стороне отправителя:
СтрокаУИД = Строка(СсылкаНаОбъект.УникальныйИдентификатор());
Теперь разберем, как восстановить ссылку из этой строки на стороне получателя:
// Допустим, мы работаем со справочником Номенклатура
УИД = Новый УникальныйИдентификатор(СтрокаУИД);
СсылкаНаОбъект = Справочники.Номенклатура.ПолучитьСсылку(УИД);
// Проверим, существует ли такой объект на самом деле
Если СсылкаНаОбъект.ПолучитьОбъект() = Неопределено Тогда
Сообщить("Объект с таким идентификатором не найден!");
Иначе
Объект = СсылкаНаОбъект.ПолучитьОбъект();
// Дальнейшая работа с объектом
КонецЕсли;
Если у вас на руках оказалась только строка вида "Счет на оплату 000000018 от 28.09.2023 10:16:12", ситуация усложняется. Нам придется «разобрать» эту строку, чтобы выделить номер и дату документа для последующего поиска. Рассмотрим, как это сделать с помощью встроенных функций работы со строками.
Проанализируем алгоритм: нам нужно найти номер (в данном примере "000000018") и преобразовать фрагмент с датой в тип Дата. Посмотрим на пример кода:
ИсходнаяСтрока = "Счет на оплату 000000018 от 28.09.2023 10:16:12";
// В реальных задачах используйте СтрРазделить или поиск подстрок
// Для примера найдем по номеру и дате:
НайденныйНомер = "000000018";
НайденнаяДата = Дата(2023, 09, 28, 10, 16, 12);
Ссылка = Документы.СчетНаОплату.НайтиПоНомеру(НайденныйНомер, НайденнаяДата);
Если Не Ссылка.Пустая() Тогда
Объект = Ссылка.ПолучитьОбъект();
// Обработка объекта
КонецЕсли;
Важно: Поиск по номеру и дате эффективен, но требует точного совпадения. Если номер в строке представлен без префиксов или дата обрезана, метод НайтиПоНомеру может не сработать.
Современный стандарт платформы 1С предлагает использовать механизм навигационных ссылок. Это специальные строки, которые понимает платформа. Рассмотрим, как это упрощает жизнь программисту.
Превратим ссылку в навигационную строку:
ТекстоваяСсылка = ПолучитьНавигационнуюСсылку(СсылкаНаДокумент);
// Результат будет выглядеть примерно так: e1cib/data/Документ.СчетНаОплату?ref=8291005056c0010811e389e0bc7f7514
Восстановим ссылку из этой строки:
СсылкаИзТекста = ПолучитьСсылкуИзНавигационной ссылки(ТекстоваяСсылка);
Если СсылкаИзТекста <> Неопределено Тогда
Объект = СсылкаИзТекста.ПолучитьОбъект();
КонецЕсли;
Преимущество этого метода в том, что в строке уже зашита информация о типе объекта (например, что это именно "Счет на оплату", а не "Поступление товаров"), и нам не нужно заранее знать менеджер объекта для поиска.
Если вам нужно гарантированно сохранить объект в строковую переменную так, чтобы потом его можно было восстановить на 100%, используйте системную функцию ЗначениеВСтрокуВнутр. Рассмотрим этот метод:
// Сериализация ссылки в системную строку
СтрокаХранения = ЗначениеВСтрокуВнутр(СсылкаНаСчет);
// ... где-то в другом месте программы ...
// Десериализация обратно в ссылку
СсылкаВосстановленная = ЗначениеИзСтрокиВнутр(СтрокаХранения);
Этот метод часто используется при обмене данными через промежуточные файлы, так как он сохраняет все системные метаданные ссылки.
Подведем итог. Преобразование строки обратно в ссылку — это всегда следствие того, что на каком-то этапе тип данных был утерян. Чтобы избежать подобных сложностей в будущем, рекомендуем придерживаться следующих правил:
Строка.Соблюдение этих принципов сделает ваш код более надежным и избавит от необходимости «гадать», какой именно объект скрывается за текстовой строкой.