При настройке стандартной подсистемы рассылки отчетов в конфигурациях на базе 1С:Предприятие 8.3 (например, «Поликлиника 2.1», «Управление торговлей 11» ранних версий и др.) пользователи могут столкнуться с тем, что тестовые письма уходят успешно, но при попытке сформировать реальный отчет по расписанию возникает критическая ошибка. В журнале регистрации или в окне сообщений фиксируется текст: «Отчет не сформирован: Поле объекта недоступно для записи (СообщенияПользователю)».
В этой статье мы подробно разберем, почему возникает эта ошибка, как она связана с работой фоновых заданий и как исправить её программным путем, изменив всего несколько строк кода в общем модуле.
Рассмотрим природу возникновения проблемы. Рассылка отчетов выполняется в контексте фонового задания на стороне сервера. В современных версиях платформы 1С:Предприятие (начиная с 8.3.8) ужесточены правила именования локальных переменных. Ошибка «Поле объекта недоступно для записи» применительно к СообщенияПользователю чаще всего вызвана тем, что программа пытается присвоить значение переменной, чье имя совпадает с именем системной функции или свойства глобального контекста.
В определенных режимах исполнения (особенно в серверных вызовах и фоновых заданиях) идентификатор СообщенияПользователю интерпретируется платформой как обращение к встроенным механизмам работы с сообщениями, которые в данном контексте могут быть доступны только для чтения. Когда код стандартной подсистемы пытается записать в эту «переменную» результат функции ПолучитьСообщенияПользователю(), происходит конфликт имен, и выполнение прерывается.
Проанализируем ситуацию с помощью отладчика. Ошибка обычно локализуется в общем модуле ВариантыОтчетов в функции СформироватьОтчет. Проблема проявляется при включенной проверке заполнения параметров отчета. Посмотрим на фрагмент кода, который вызывает сбой:
Функция СформироватьОтчет(Знач Параметры, Знач ПроверятьЗаполнение, Знач ПолучатьФлажокПустой) Экспорт
// ... часть кода ...
Если ПроверятьЗаполнение Тогда
ИсходныеСообщенияПользователю = ПолучитьСообщенияПользователю(Истина);
ПроверкаПройдена = ОтчетОбъект.ПроверитьЗаполнение();
// Ошибка происходит на следующей строке:
СообщенияПользователю = ПолучитьСообщенияПользователю(Истина);
КонецЕсли;
// ... продолжение кода ...
КонецФункции
В данном случае СообщенияПользователю выступает как локальная переменная, но платформа блокирует запись в неё, считая это обращением к системному объекту.
Самый эффективный и быстрый способ решить проблему — изменить имя локальной переменной на уникальное, которое гарантированно не будет конфликтовать с глобальным контекстом. Нам необходимо внести изменения в общий модуль ВариантыОтчетов. Разберем по шагам, что нужно сделать:
ВариантыОтчетов (или аналогичный модуль, отвечающий за формирование отчетов в вашей версии БСП).СформироватьОтчет.СообщенияПользователю на СообщенияПользователюПослеЗаполнения во всем блоке проверки заполнения.Рассмотрим исправленный вариант кода:
Если ПроверятьЗаполнение Тогда
ИсходныеСообщенияПользователю = ПолучитьСообщенияПользователю(Истина);
ПроверкаПройдена = ОтчетОбъект.ПроверитьЗаполнение();
// Используем новое уникальное имя переменной
СообщенияПользователюПослеЗаполнения = ПолучитьСообщенияПользователю(Истина);
Для Каждого Сообщение Из ИсходныеСообщенияПользователю Цикл
Сообщение.Сообщить();
КонецЦикла;
Если Не ПроверкаПройдена Тогда
Результат.ТекстОшибки = НСтр("ru = 'Отчет не прошел проверку заполнения:'");
// Применяем новое имя переменной и в цикле вывода ошибок
Для Каждого Сообщение Из СообщенияПользователюПослеЗаполнения Цикл
Результат.ТекстОшибки = Результат.ТекстОшибки + Символы.ПС + Сообщение.Текст;
КонецЦикла;
Возврат Результат;
КонецЕсли;
КонецЕсли;
После такого переименования конфликт имен исчезает, так как СообщенияПользователюПослеЗаполнения не является зарезервированным словом платформы. Это позволяет регламентному заданию успешно собирать сообщения об ошибках заполнения и продолжать работу.
Помимо прямого исправления кода, существуют и другие подходы к решению проблемы:
Если ПроверятьЗаполнение Тогда, и ошибка не возникнет. Однако это лишь временная мера, так как отчет может сформироваться с некорректными данными.Подводя итог, отметим, что при работе с фоновыми заданиями следует быть особенно внимательными к именованию переменных. Избегайте имен, совпадающих с именами методов глобального контекста, таких как СообщенияПользователю, ПараметрыСеанса или Справочники, чтобы обеспечить стабильную работу кода в любых режимах исполнения.