Как программно установить счет в отчете Карточка счета через расширение

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия Бухгалтерский учет
← На главную

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

Разбираем типичные ошибки: Объект против Отчета

Первая и самая важная причина, по которой код Объект.Счет = ... выдает ошибку в форме отчета, заключается в архитектуре платформы 1С. Мы привыкли, что в формах документов, справочников или задач основным реквизитом является Объект. Однако формы отчетов устроены иначе.

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

Ошибка контекста выполнения процедуры

Другой важный аспект — правильное использование директив компиляции. Рассмотрим ситуацию, когда процедура ПриОткрытии помечена директивой &НаСервере. Это грубая ошибка, так как событие ПриОткрытии является исключительно клиентским. Оно предназначено для взаимодействия с пользователем непосредственно перед тем, как форма станет доступна для ввода.

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

  1. Создать серверную функцию для получения ссылки на счет.
  2. Вызвать эту функцию из клиентской процедуры ПриОткрытии.
  3. Либо использовать серверное событие ПриСозданииНаСервере для первоначальной инициализации данных.

Элемент формы vs Данные формы

Часто начинающие разработчики пытаются присвоить значение непосредственно визуальному элементу: Элементы.Счет = ДайСчет(). Это приводит к ошибке «Поле объекта недоступно для записи». Разберем почему.

Коллекция Элементы содержит объекты типа «ПолеФормы», «КнопкаФормы» и так далее. У них есть свойства, отвечающие за внешний вид (Доступность, Видимость, ТолькоПросмотр), но они сами по себе не хранят данные. Данные хранятся в реквизитах формы. Чтобы изменить значение в поле ввода, нужно изменить значение реквизита, с которым это поле связано (свойство ПутьКДанным). В нашем случае это Отчет.Счет.

Пошаговое решение задачи в расширении

Рассмотрим правильную реализацию задачи: нам нужно при открытии отчета «Карточка счета» установить счет 70 для всех пользователей, кроме Ольги, и запретить им его редактирование.

Шаг 1. Создание серверной функции для получения счета

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


&НаСервере
Функция ПолучитьСсылкуНаСчет(КодСчета)
    Возврат ПланыСчетов.Хозрасчетный.НайтиПоКоду(КодСчета);
КонецФункции

Шаг 2. Реализация логики в обработчике ПриОткрытии

Теперь воспользуемся механизмом расширений и создадим обработчик &После("ПриОткрытии"). Обратите внимание на использование правильного пути к данным и работу с элементами формы.


&НаКлиенте
Процедура Расш1_ПриОткрытииПосле(Отказ)
    
    // Проверяем имя пользователя (приводим к верхнему регистру для надежности)
    ТекущийПользователь = ВРег(ИмяПользователя());
    
    Если СтрНайти(ТекущийПользователь, "ОЛЬГА") = 0 Тогда
        // Если это не Ольга, устанавливаем счет программно
        СчетДляУстановки = ПолучитьСсылкуНаСчет("70");
        
        // ВАЖНО: Присваиваем реквизиту Отчет.Счет, а не Элементу!
        Отчет.Счет = СчетДляУстановки;
        
        // Блокируем возможность редактирования для пользователя
        Элементы.Счет.Доступность = Ложь;
        
        Сообщить("Для вашего пользователя установлен предопределенный счет.");
    Иначе
        Сообщить("Добро пожаловать, Ольга. Поле выбора счета доступно для редактирования.");
    КонецЕсли;
    
КонецПроцедуры

Особенности работы с отчетами на СКД

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

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


&НаСервере
Процедура УстановитьСчетВКомпоновщике(ЗначениеСчета)
    // Поиск параметра "Счет" в настройках компоновщика
    Для Каждого Параметр Из Отчет.КомпоновщикНастроек.Настройки.ПараметрыДанных.Элементы Цикл
        Если Строка(Параметр.Параметр) = "Счет" Тогда
            Параметр.Значение = ЗначениеСчета;
            Параметр.Использование = Истина;
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

Использование события ПриСозданииНаСервере

Наиболее корректным способом инициализации данных в расширениях считается использование события ПриСозданииНаСервере. Это позволяет избежать лишних вызовов между клиентом и сервером. Посмотрим на итоговый пример реализации через это событие:


&НаСервере
&После("ПриСозданииНаСервере")
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    ТекущийПользователь = ВРег(ИмяПользователя());
    
    Если СтрНайти(ТекущийПользователь, "ОЛЬГА") = 0 Тогда
        // Находим счет сразу на сервере
        Счет70 = ПланыСчетов.Хозрасчетный.НайтиПоКоду("70");
        
        // Заполняем реквизит отчета
        Отчет.Счет = Счет70;
        
        // Управляем доступностью элемента формы
        Элементы.Счет.Доступность = Ложь;
    КонецЕсли;
    
КонецПроцедуры

Резюме

Для успешной работы с расширением в отчете «Карточка счета» помните следующие правила:

  1. Используйте Отчет.Счет для обращения к данным, а не Объект.Счет.
  2. Для изменения внешнего вида поля (доступность, видимость) обращайтесь к Элементы.Счет.
  3. Поиск по коду в плане счетов (ПланыСчетов.Хозрасчетный.НайтиПоКоду) выполняйте только на сервере.
  4. Если отчет использует СКД, убедитесь, что значения синхронизированы с параметрами компоновщика настроек.

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

← На главную