Как исправить ошибку «Поле объекта недоступно для записи (СообщенияПользователю)» при рассылке отчетов?

Программист 1С v8.3 (Управляемые формы) Сфера услуг, туризм и социальный сектор
← На главную

При настройке стандартной подсистемы рассылки отчетов в конфигурациях на базе 1С:Предприятие 8.3 (например, «Поликлиника 2.1», «Управление торговлей 11» ранних версий и др.) пользователи могут столкнуться с тем, что тестовые письма уходят успешно, но при попытке сформировать реальный отчет по расписанию возникает критическая ошибка. В журнале регистрации или в окне сообщений фиксируется текст: «Отчет не сформирован: Поле объекта недоступно для записи (СообщенияПользователю)».

В этой статье мы подробно разберем, почему возникает эта ошибка, как она связана с работой фоновых заданий и как исправить её программным путем, изменив всего несколько строк кода в общем модуле.

Почему возникает эта ошибка?

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

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

Поиск проблемного участка кода

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


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

В данном случае СообщенияПользователю выступает как локальная переменная, но платформа блокирует запись в неё, считая это обращением к системному объекту.

Способ решения: Переименование переменной

Самый эффективный и быстрый способ решить проблему — изменить имя локальной переменной на уникальное, которое гарантированно не будет конфликтовать с глобальным контекстом. Нам необходимо внести изменения в общий модуль ВариантыОтчетов. Разберем по шагам, что нужно сделать:

  1. Откроем конфигуратор и найдем общий модуль ВариантыОтчетов (или аналогичный модуль, отвечающий за формирование отчетов в вашей версии БСП).
  2. Найдем функцию СформироватьОтчет.
  3. Заменим имя переменной СообщенияПользователю на СообщенияПользователюПослеЗаполнения во всем блоке проверки заполнения.

Рассмотрим исправленный вариант кода:


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

После такого переименования конфликт имен исчезает, так как СообщенияПользователюПослеЗаполнения не является зарезервированным словом платформы. Это позволяет регламентному заданию успешно собирать сообщения об ошибках заполнения и продолжать работу.

Альтернативные варианты и рекомендации

Помимо прямого исправления кода, существуют и другие подходы к решению проблемы:

Подводя итог, отметим, что при работе с фоновыми заданиями следует быть особенно внимательными к именованию переменных. Избегайте имен, совпадающих с именами методов глобального контекста, таких как СообщенияПользователю, ПараметрыСеанса или Справочники, чтобы обеспечить стабильную работу кода в любых режимах исполнения.

← На главную