Что за документ лежит в переменной: определяем вид ссылки в 1С 8.3

· 10 мин

Содержание

Проверить, что за документ в 1С, проще всего сравнением типов: ТипЗнч(Значение) = Тип("ДокументСсылка.РеализацияТоваровУслуг"). Если вид заранее неизвестен, сначала убедитесь, что это вообще документ — Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)), — а затем узнайте его реальное имя через Значение.Метаданные().Имя. В запросе то же делают оператор ССЫЛКА и функция ТИПЗНАЧЕНИЯ().

Частая ошибка — сравнивать строки: Строка(Значение) или Строка(ТипЗнч(Значение)). Так вы получите представление для пользователя — номер, дату или синоним, — которое меняется при переименовании и смене языка. Тип надо сравнивать с типом, а имя брать из метаданных. Всё ниже относится к платформе 8.3 целиком и не зависит от конфигурации: БП, ЗУП и УТ работают одинаково, отличаются только имена документов.

Ссылка, объект и тип: из чего состоит документ в платформе

У каждого документа в конфигурации платформа создаёт несколько типов. Путаница между ними — главный источник ошибок при проверке.

ТипПримерЧто этоГде встречается
ДокументСсылка.<Имя>ДокументСсылка.ПоступлениеТоваровУслугУказатель на запись в базеРеквизиты, регистраторы, параметры процедур
ДокументОбъект.<Имя>ДокументОбъект.ПоступлениеТоваровУслугСам документ с данными, который можно изменить и записатьМодуль объекта, обработчики ПередЗаписью
ДокументМенеджер.<Имя>Документы.ПоступлениеТоваровУслугМенеджер: создание, поиск, печатьКод вида Документы.Имя.СоздатьДокумент()
Объект метаданныхМетаданные.Документы.ПоступлениеТоваровУслугОписание документа в конфигурации: имя, синоним, реквизитыАнализ структуры, универсальный код

Что из этого следует на практике:

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

Если в коде у вас объект, а нужна ссылка, берите Объект.Ссылка. Для нового, ещё не записанного документа ссылка пустая — об этом ниже.

Проверка типа документа в коде: пять рабочих способов

1. Конкретный вид документа

Самый частый случай: нужно понять, реализация это или нет.

Если ТипЗнч(Значение) = Тип("ДокументСсылка.РеализацияТоваровУслуг") Тогда
    // обрабатываем реализацию
КонецЕсли;

Работает на клиенте и на сервере, обращения к базе нет. Строку внутри Тип() пишите точно как имя в конфигураторе. Опечатка даст ошибку времени выполнения Тип не определен.

2. Один из нескольких видов

Когда подходит любой из списка, удобнее ОписаниеТипов, чем цепочка ИЛИ:

ДокументыДвижения = Новый ОписаниеТипов(
    "ДокументСсылка.ПоступлениеТоваровУслуг, ДокументСсылка.РеализацияТоваровУслуг, ДокументСсылка.ПеремещениеТоваров");

Если ДокументыДвижения.СодержитТип(ТипЗнч(Значение)) Тогда
    // это один из трёх документов
КонецЕсли;

Описание типов можно создать один раз в начале процедуры и проверять им строки таблицы в цикле.

3. Любой документ, вид неважен

Если Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
    // в переменной ссылка на какой-то документ
КонецЕсли;

ТипВсеСсылки() есть и у других менеджеров: Справочники.ТипВсеСсылки(), ПланыВидовХарактеристик.ТипВсеСсылки(). Так отличают документ от справочника в поле составного типа.

4. Реальное имя и синоним из метаданных

Когда вид заранее неизвестен и его надо узнать, спросите метаданные:

МД = Значение.Метаданные();
ИмяДокумента   = МД.Имя;         // например, "РеализацияТоваровУслуг"
ПолноеИмя      = МД.ПолноеИмя(); // "Документ.РеализацияТоваровУслуг"
ДляПользователя = МД.Синоним;    // название, которое видно в программе
ЭтоДокумент    = Метаданные.Документы.Содержит(МД);

Есть и вариант без вызова метода у ссылки — Метаданные.НайтиПоТипу(ТипЗнч(Значение)). Для примитивных типов (строка, число, Неопределено) он вернёт Неопределено, и это тоже удобно как проверка.

Вызывать .Метаданные() у значения Неопределено нельзя: получите Метод объекта не обнаружен (Метаданные). Сначала проверка типа, потом обращение к метаданным.

5. Функции БСП в типовых конфигурациях

В БП 3.0, ЗУП 3.1, УТ 11 и других конфигурациях на Библиотеке стандартных подсистем есть готовые функции общего модуля ОбщегоНазначения:

  • ✅ ОбщегоНазначения.ЭтоДокумент(ОбъектМетаданных) — принимает объект метаданных, а не ссылку: ОбщегоНазначения.ЭтоДокумент(Значение.Метаданные()).
  • ✅ ОбщегоНазначения.ЭтоСсылка(Тип) — проверяет, что тип вообще ссылочный.

В собственной обработке или в конфигурации без БСП их нет — пользуйтесь способами 1–4.

Какой способ выбрать

ЗадачаСпособОбращение к базеГде работает
Это реализация?ТипЗнч = Тип(...)НетКлиент и сервер
Один из спискаОписаниеТипов.СодержитТипНетКлиент и сервер
Это вообще документ?Документы.ТипВсеСсылки()НетСервер
Как он называется.Метаданные().Имя, СинонимНетСервер
Он реально есть в базе?Запрос по ссылкеДаСервер

Метаданные и менеджеры документов надёжнее трогать в серверной процедуре. На клиенте ограничьтесь сравнением через Тип(), остальное выносите в &НаСервереБезКонтекста.

Как узнать, что это за документ, в интерфейсе пользователя

Программировать не обязательно. Пользователю и консультанту хватает нескольких приёмов.

Заголовок формы

Откройте документ двойным щелчком. В заголовке окна стоит его представление: синоним вида, номер и дата. Это ответ «для людей», но не техническое имя.

Навигационная ссылка

В заголовке открытой формы есть значок ссылки — команда получения навигационной ссылки. Скопируйте ссылку, и вы увидите строку вида:

e1cib/data/Документ.РеализацияТоваровУслуг?ref=8f3e00155d0a1b2c11ee5d3a9b7c4e10

После Документ. идёт реальное имя вида документа из конфигурации, после ref= — уникальный идентификатор записи. Тот же вид программно вернёт функция ПолучитьНавигационнуюСсылку(Значение). Ссылку можно отправить коллеге: она откроет тот же документ через главное меню, команду перехода по ссылке.

Все функции

Если документ нужно найти по виду, включите полный список объектов: Главное меню (☰) → Сервис → Параметры, флажок «Отображать команду «Все функции»». Затем Главное меню → Все функции → Документы — там все виды документов конфигурации под их синонимами.

Отчёты и журналы

В оборотно-сальдовой ведомости, карточке счёта и отчётах по регистрам документ-основание движения показан в колонке «Регистратор» или «Документ». Двойной щелчок по нему открывает форму — дальше смотрите заголовок или навигационную ссылку. В журналах документов в одном списке лежат разные виды, и колонка с видом документа подсказывает, что перед вами.

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

Разбираем структуру документа в Конфигураторе

Когда имя известно, а нужно понять, что внутри, идите в Конфигуратор.

  1. Запустите базу в режиме «Конфигуратор» и откройте дерево: Конфигурация → Открыть конфигурацию.
  2. Разверните ветку «Документы». Начните печатать имя прямо в дереве — курсор перейдёт к совпадению. Имя берите из навигационной ссылки.
  3. Откройте окно редактирования документа. На закладках видно:
    • 📌 Основные — имя, синоним, комментарий;
    • 📌 Данные — реквизиты шапки и табличные части с типами;
    • 📌 Нумерация — длина и тип номера, периодичность;
    • 📌 Движения — проводится ли документ и в какие регистры пишет.
  4. Чтобы найти, где этот вид используется в других объектах, вызовите в контекстном меню документа команду «Поиск ссылок на объект». Список покажет реквизиты составного типа, журналы, регистры с ним в регистраторах.

Тип значения в отладчике

Если непонятно, что лежит в переменной во время выполнения, поставьте точку останова и откройте «Вычислить выражение» (Shift+F9). Введите ТипЗнч(Значение) или Значение.Метаданные().ПолноеИмя(). В табло и окне вычисления у значения есть колонка «Тип» — там сразу видно ДокументСсылка.<Имя>.

Отладку в рабочей базе включайте только с согласия администратора: пока выполнение стоит на точке останова, сеанс пользователя висит. Ничего не меняйте в конфигурации рабочей базы без резервной копии.

Неопределено, пустая ссылка и битая ссылка: в чём разница

Реквизит составного типа может хранить три «ненастоящих» значения. Их нужно различать до любых проверок вида.

СостояниеКак выглядитПроверкаЗначениеЗаполнено()
НеопределеноПоле пустое, тип не выбранЗначение = НеопределеноЛожь
Пустая ссылкаТип выбран, документ — нетЗначение.Пустая()Ложь
Битая ссылка<Объект не найден> (…)Запрос к таблице документаИстина
Нормальная ссылкаНомер и датаТип совпадает, запись найденаИстина

Ключевые моменты:

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

Универсальная функция «что это за документ»

Функция собирает все проверки вместе и возвращает понятную структуру:

&НаСервереБезКонтекста
Функция ОписаниеДокумента(Значение)

    Результат = Новый Структура("ЭтоДокумент, Имя, Синоним, Существует", Ложь, "", "", Ложь);

    Если Значение = Неопределено Тогда
        Возврат Результат;
    КонецЕсли;

    Если Не Документы.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)) Тогда
        Возврат Результат;
    КонецЕсли;

    МД = Значение.Метаданные();
    Результат.ЭтоДокумент = Истина;
    Результат.Имя = МД.Имя;
    Результат.Синоним = МД.Синоним;

    Если Не Значение.Пустая() Тогда
        Запрос = Новый Запрос;
        Запрос.Текст = "ВЫБРАТЬ ПЕРВЫЕ 1 ИСТИНА КАК Есть ИЗ " + МД.ПолноеИмя() + " ГДЕ Ссылка = &Ссылка";
        Запрос.УстановитьПараметр("Ссылка", Значение);
        Результат.Существует = Не Запрос.Выполнить().Пустой();
    КонецЕсли;

    Возврат Результат;

КонецФункции

Для битой ссылки функция вернёт ЭтоДокумент = Истина и Существует = Ложь. Запрос лёгкий: читается одна запись по индексу, объект целиком в память не грузится — в отличие от Значение.ПолучитьОбъект().

Что у вас в поле?

Определение вида документа в запросе

В запросах тип проверяют на стороне СУБД — это быстрее, чем выбирать всё и фильтровать в цикле.

Отбор по виду: ССЫЛКА и ТИПЗНАЧЕНИЯ

Два равнозначных условия. Пример по регистру бухгалтерии в БП 3.0 — отобрать движения только от реализаций:

ВЫБРАТЬ
    Хозрасчетный.Регистратор КАК Регистратор,
    ВЫРАЗИТЬ(Хозрасчетный.Регистратор КАК Документ.РеализацияТоваровУслуг).Контрагент КАК Контрагент
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Регистратор ССЫЛКА Документ.РеализацияТоваровУслуг
    И Хозрасчетный.Период МЕЖДУ &НачалоПериода И &КонецПериода

Вместо ССЫЛКА можно написать ТИПЗНАЧЕНИЯ(Хозрасчетный.Регистратор) = ТИП(Документ.РеализацияТоваровУслуг). Результат тот же; ССЫЛКА короче и читается проще.

ВЫРАЗИТЬ нужен, чтобы получить реквизит конкретного вида из поля составного типа. Без него платформа соединяет таблицы всех возможных регистраторов, и запрос тяжелеет.

Какие виды документов есть в выборке

Если надо узнать, какие документы вообще двигали регистр за период, сгруппируйте по типу:

ВЫБРАТЬ
    ТИПЗНАЧЕНИЯ(Хозрасчетный.Регистратор) КАК ТипДокумента,
    КОЛИЧЕСТВО(РАЗЛИЧНЫЕ Хозрасчетный.Регистратор) КАК Документов
ИЗ
    РегистрБухгалтерии.Хозрасчетный КАК Хозрасчетный
ГДЕ
    Хозрасчетный.Период МЕЖДУ &НачалоПериода И &КонецПериода
СГРУППИРОВАТЬ ПО
    ТИПЗНАЧЕНИЯ(Хозрасчетный.Регистратор)

В результате поле ТипДокумента — значение типа Тип. Человеческое название получите в коде: Метаданные.НайтиПоТипу(Выборка.ТипДокумента).Синоним.

Поиск битых ссылок запросом

Битая ссылка в запросе видна так: поле заполнено, а соединение с таблицей документа не нашло записи.

ВЫБРАТЬ
    Т.Ссылка КАК Документ,
    Т.ДокументОснование КАК Основание
ИЗ
    Документ.СчетФактураВыданный КАК Т
        ЛЕВОЕ СОЕДИНЕНИЕ Документ.РеализацияТоваровУслуг КАК Р
        ПО Т.ДокументОснование = Р.Ссылка
ГДЕ
    Т.ДокументОснование ССЫЛКА Документ.РеализацияТоваровУслуг
    И Р.Ссылка ЕСТЬ NULL
    И НЕ Т.ДокументОснование = ЗНАЧЕНИЕ(Документ.РеализацияТоваровУслуг.ПустаяСсылка)

Имена документа и реквизита замените на свои — проверьте их в Конфигураторе. Схема запроса от этого не меняется.

Где ошибаются при проверке типа и как этого избежать

Диагностика: выберите симптом

Ещё три привычки, которые экономят время на отладке:

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

Частые вопросы

Как проверить, что значение — ссылка на справочник, а не на документ?
Тем же приёмом с другим менеджером: Справочники.ТипВсеСсылки().СодержитТип(ТипЗнч(Значение)). В конфигурациях на БСП подойдёт ОбщегоНазначения.ЭтоСправочник(Значение.Метаданные()).
Можно ли узнать вид документа по уникальному идентификатору?
Нет. Идентификатор хранится без вида: по одному GUID платформа не скажет, какая это таблица. Нужна либо полная ссылка, либо навигационная ссылка, где вид указан явно.
Почему ЗначениеЗаполнено возвращает Истину для документа, которого нет?
Битая ссылка содержит идентификатор, поэтому она не пустая. Существование проверяйте запросом к таблице документа.
Чем Имя отличается от Синонима и что брать в код?
Имя — техническое, по нему пишут Тип() и запросы. Синоним — подпись для пользователя, её меняют без последствий для кода. В условиях всегда используйте Имя или сравнение типов.
Как в отладчике быстро увидеть тип переменной?
Добавьте её в табло или вычислите ТипЗнч(Переменная) через Shift+F9. Колонка «Тип» сразу покажет ДокументСсылка с именем вида.