Почему значение реквизита в коде отличается от отображаемого в списке накладных?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

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

Разберем причину: Ссылка против Данных формы

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

Когда мы пишем Док.Получен, где Док — это ссылка, система выполняет неявное обращение к базе данных. Однако, если данные в базе уже были изменены другим процессом, фоновым заданием или в другом окне, а список в текущей форме еще не обновился (не был нажат F5 или не сработал метод Обновить()), то возникнет визуальный диссонанс. Вы видите «старое» состояние в списке, но код получает «новое» состояние из базы.

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

Правильный метод получения данных из списка

Посмотрим на пример кода, который считается более надежным при работе с обычными формами. Вместо ТекущаяСтрока рекомендуется использовать ТекущиеДанные. Разберем разницу:

  1. ТекущаяСтрока — возвращает ссылку на объект в базе данных.
  2. ТекущиеДанные — возвращает структуру данных, которая в данный момент загружена в визуальную таблицу формы.

Если в вашей форме списка выведена колонка с реквизитом Получен, то обращение через ТекущиеДанные вернет именно то, что видит пользователь на экране. Рассмотрим пример реализации:


ТекущаяСтрока = ЭлементыФормы.ДокументСписок.ТекущиеДанные;

Если ТекущаяСтрока <> Неопределено Тогда
    // Обращаемся напрямую к данным, загруженным в таблицу
    Если ТекущаяСтрока.Получен Тогда 
        Предупреждение("Заявка уже создана (данные из списка)!");
        Возврат;
    КонецЕсли;
КонецЕсли;

Использование функций общего назначения для гарантии результата

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


СсылкаНаДок = ЭлементыФормы.ДокументСписок.ТекущаяСтрока;

Если ЗначениеЗаполнено(СсылкаНаДок) Тогда
    // Выполняем запрос к БД, минуя объектный кэш
    ФлагПолучен = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаДок, "Получен");
    
    Если ФлагПолучен Тогда
        Сообщить("В базе данных документ уже помечен как полученный.");
    Иначе
        Сообщить("Документ в базе еще не имеет признака получения.");
    КонецЕсли;
КонецЕсли;

Этот метод позволяет избежать проблем «грязного чтения», когда объект изменен, но форма об этом еще не знает.

Как проверить реальное состояние данных

Если вы столкнулись с «чудесами», когда код утверждает одно, а глаза видят другое, выполните следующие шаги для диагностики:

  1. Проверьте данные запросом. Создайте простую консоль запросов и выберите значение реквизита по ссылке конкретного документа. Это «истина в последней инстанции».
  2. Обновите список. Нажмите F5 в форме списка. Если галочка появилась — значит, данные в базе были изменены ранее, но форма не была синхронизирована.
  3. Изучите модуль формы. Найдите обработчик ПриВыводеСтроки или ПриПолученииДанных. Если там есть строки вида ОформлениеСтроки.Ячейки.Получен.ОтображатьФлажок = Ложь, значит, интерфейс намеренно вводит пользователя в заблуждение.

Особенности работы с несохраненными объектами

Рассмотрим еще один важный аспект: если документ еще не записан или находится в процессе редактирования в другом окне. В 1С Ссылка на документ появляется в момент первого сохранения (или при программной генерации ссылки), но данные физически записываются в таблицы БД только при вызове метода Записать(). Если вы открыли документ, программно установили галочку, но не нажали кнопку «Записать», то при чтении через ссылку из другого места вы все равно будете получать старое значение (ЛОЖЬ), так как в базе данных изменений еще нет.

Однако в случае автора темы ситуация обратная — в базе ИСТИНА, а на экране ЛОЖЬ. Это явный признак того, что либо документ был изменен фоновым процессом (например, при обмене данными или выполнении регламентного задания), либо логика формы скрывает реальное значение.

Работа с множественным выделением

Зачастую кнопки в списке накладных должны обрабатывать не одну «текущую» строку, а все строки, которые выделил пользователь. В этом случае свойство ТекущаяСтрока может подвести, так как оно указывает только на ту строку, на которой стоит фокус (пунктирная рамка). Рассмотрим правильный подход с использованием коллекции ВыделенныеСтроки:


Для Каждого СсылкаИзСписка Из ЭлементыФормы.ДокументСписок.ВыделенныеСтроки Цикл
    // Используем запрос для каждого документа для надежности
    Если ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаИзСписка, "Получен") Тогда
        Сообщить("Документ " + СсылкаИзСписка + " уже обработан.");
        Продолжить;
    КонецЕсли;
    
    // Логика создания заявки...
КонецЦикла;

Подведем итоги

Для стабильной работы в Обычных формах придерживайтесь следующих правил:

Соблюдение этих принципов позволит избежать ошибок, связанных с кэшированием данных и рассинхронизацией интерфейса с базой данных 1С.

← На главную