Почему 1С 7.7 не находит значение реквизита справочника и всегда возвращает ноль

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

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

Причина 1: Отсутствие позиционирования на объекте

Проанализируем типичный фрагмент кода, который часто становится источником ошибки:


Спр = СоздатьОбъект("Справочник.Номенклатура");
Если Спр.Маркер = 1 Тогда
    Сообщить("Маркер установлен");
КонецЕсли;

В данном случае команда СоздатьОбъект лишь инициализирует программную оболочку справочника в памяти. В этот момент объект является «пустым» — он не указывает ни на одну конкретную запись в базе данных. Выясним причину, по которой Спр.Маркер возвращает 0: программа просто не знает, данные какой именно строки справочника вы хотите прочитать. Для решения этой проблемы необходимо позиционировать объект на конкретном элементе.

Разберем основные способы позиционирования:

  1. Поиск по коду или наименованию: Если нам известен код товара, мы должны сначала найти его в базе.
    
    Спр = СоздатьОбъект("Справочник.Номенклатура");
    Если Спр.НайтиПоКоду("00001") = 1 Тогда
        // Теперь объект Спр позиционирован на товаре с кодом 00001
        Сообщить(Спр.Маркер); 
    КонецЕсли;
    
  2. Использование ссылки: Если у нас уже есть ссылка на элемент (например, из другого реквизита), нужно использовать метод НайтиЭлемент.
    
    Спр = СоздатьОбъект("Справочник.Номенклатура");
    Спр.НайтиЭлемент(ВыбранныйТовар);
    Сообщить(Спр.Маркер);
    

Причина 2: Контекст формы и глобальный модуль

Часто задача звучит так: «Я ввел значение в поле на форме элемента и хочу получить его в глобальном модуле». Здесь важно понимать различие между данными в базе и данными на экране. Рассмотрим ситуацию: пользователь открыл форму, ввел в поле «Маркер» значение «1», но еще не нажал кнопку «Сохранить».

Если в этот момент вы создадите новый объект через СоздатьОбъект и найдете этот же товар, метод прочитает данные напрямую из файла базы данных (DBF или SQL). А там всё еще записано старое значение (например, 0). Чтобы получить то, что пользователь только что ввел на экране, нужно обращаться к контексту текущей формы.

Для передачи данных из формы в процедуру глобального модуля используем механизм передачи контекста:

  1. В Глобальном модуле описываем процедуру с ключевым словом Экспорт:
    
    Процедура ПроверитьМаркер(Конт) Экспорт
        // Обращаемся к реквизиту через переданный контекст
        Если Конт.Маркер = 1 Тогда
            Сообщить("В форме введено значение 1");
        КонецЕсли;
    КонецПроцедуры
    
  2. В модуле формы элемента вызываем эту процедуру, передавая зарезервированное слово Контекст:
    
    Процедура ПриЗаписи()
        ПроверитьМаркер(Контекст);
    КонецПроцедуры
    

Причина 3: Обращение через коллекции и таблицы

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


ТаблицаПодбора.ВыбратьСтроки();
Пока ТаблицаПодбора.ПолучитьСтроку() = 1 Цикл
    // Прямое обращение через точку от ссылки на номенклатуру
    Если ТаблицаПодбора.Номенклатура.Маркер = 1 Тогда
        Сообщить("Товар " + ТаблицаПодбора.Номенклатура.Наименование + " помечен маркером");
    КонецЕсли;
КонецЦикла;

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


ТекНом = ТаблицаПодбора.Номенклатура;
ЗначМаркера = ТекНом.Маркер;

Специфика реквизитов формы в 1С 7.7

Проанализируем, как реквизиты добавляются на форму. В конфигураторе 7.7 есть два способа разместить поле ввода:

  1. Реквизит объекта: Вы нажимаете на панели инструментов кнопку «Добавить реквизиты» (иконка с плюсиком) и выбираете «Маркер» из списка доступных полей справочника. В этом случае поле на форме жестко связано с базой данных.
  2. Реквизит формы (Переменная): Вы просто рисуете поле ввода и в поле «Идентификатор» пишете «Маркер», не связывая его с данными справочника.

Если вы использовали второй способ, то СоздатьОбъект никогда не увидит значение этого поля, так как оно существует только «внутри» открытого окна и не сохраняется в справочнике. Проверьте в конфигураторе, является ли ваш «Маркер» реальным реквизитом справочника Номенклатура в дереве метаданных.

Типизация данных

Выясним еще одну возможную причину неудачи. 1С 7.7 чувствительна к типам данных при сравнении. Если в метаданных реквизит «Маркер» определен как Строка, то сравнение Маркер = 1 (с числом) всегда будет давать результат Ложь.

Правильные варианты сравнения в зависимости от типа:

Итоги

Подводя итог, для корректного получения значения реквизита в 1С 7.7 придерживайтесь следующих правил:

← На главную