Как создать виджет в 1С:Документооборот для отображения количества прочитанных и непрочитанных документов по конкретной папке?

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

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

Постановка задачи и выбор объектов метаданных

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

Для реализации нашего виджета мы будем использовать:

Работа с правами доступа: ВЫБРАТЬ РАЗРЕШЕННЫЕ

Рассмотрим важный аспект безопасности. В 1С:Документооборот используется сложная система дескрипторов доступа. Чтобы пользователь видел в виджете только те цифры, которые соответствуют доступным ему документам, в тексте запроса необходимо обязательно использовать конструкцию ВЫБРАТЬ РАЗРЕШЕННЫЕ. Без этого ключевого слова запрос может либо вернуть ошибку прав доступа, либо выдать общее количество документов в системе, к которым у пользователя нет доступа, что является нарушением безопасности.

Важный совет: При тестировании виджета обязательно используйте учетную запись обычного пользователя, а не администратора. У администратора (полные права) механизмы RLS (ограничение доступа на уровне записей) отключены, и запрос всегда будет возвращать все документы системы.

Разбор логики группового показателя

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

Проанализируем структуру запроса. Нам необходимо выполнить ЛЕВОЕ СОЕДИНЕНИЕ справочника документов с регистром прочтения. Условие соединения должно включать не только ссылку на документ, но и ссылку на текущего пользователя.


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

    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ РАЗРЕШЕННЫЕ
        |	СУММА(ВЫБОР
        |			КОГДА СведенияОПрочтении.Пользователь ЕСТЬ NULL
        |				ТОГДА 0
        |			ИНАЧЕ 1
        |		КОНЕЦ) КАК Прочтен,
        |	СУММА(ВЫБОР
        |			КОГДА СведенияОПрочтении.Пользователь ЕСТЬ NULL
        |				ТОГДА 1
        |			ИНАЧЕ 0
        |		КОНЕЦ) КАК НеПрочтен,
        |	КОЛИЧЕСТВО(ВнутренниеДокументы.Ссылка) КАК Всего
        |ИЗ
        |	Справочник.ВнутренниеДокументы КАК ВнутренниеДокументы
        |		ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОПрочтении КАК СведенияОПрочтении
        |		ПО ВнутренниеДокументы.Ссылка = СведенияОПрочтении.Объект
        |			И (СведенияОПрочтении.Пользователь = &ТекущийПользователь)
        |ГДЕ
        |	ВнутренниеДокументы.Папка В ИЕРАРХИИ(&Папка)
        |	И НЕ ВнутренниеДокументы.ПометкаУдаления";

    Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
    Запрос.УстановитьПараметр("Папка", СсылкаНаПапку);

    Выборка = Запрос.Выполнить().Выбрать();

    Если Выборка.Следующий() Тогда
        РезультатСтруктура.Всего = ?(Выборка.Всего = NULL, 0, Выборка.Всего);
        РезультатСтруктура.Прочтен = ?(Выборка.Прочтен = NULL, 0, Выборка.Прочтен);
        РезультатСтруктура.НеПрочтен = ?(Выборка.НеПрочтен = NULL, 0, Выборка.НеПрочтен);
    КонецЕсли;

    Возврат РезультатСтруктура;

КонецФункции

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

Рассмотрим, почему мы использовали именно такие конструкции в запросе:

  1. ЛЕВОЕ СОЕДИНЕНИЕ: Это позволяет нам взять все документы из папки "Приказы", даже если для них еще нет записи в регистре прочтения. Если записи нет, поля таблицы СведенияОПрочтении примут значение NULL.
  2. В ИЕРАРХИИ: Мы используем это условие вместо простого равенства, так как внутри папки "Приказы" могут быть подпапки (например, по годам или типам приказов). Конструкция В ИЕРАРХИИ корректно соберет документы со всех вложенных уровней.
  3. Фильтр по текущему пользователю в условии соединения: Это критически важно. Если мы просто соединим таблицы, а потом наложим фильтр ГДЕ Пользователь = &ТекущийПользователь в конце запроса, мы потеряем все непрочитанные документы, так как для них пользователя в регистре просто нет (строка отсеется фильтром ГДЕ). Указывая пользователя в условии ПО, мы оставляем все документы справочника в выборке.
  4. Агрегатные функции: Использование СУММА(ВЫБОР...) позволяет нам за один проход базы данных получить сразу три нужных числа, что положительно сказывается на производительности виджета.

Типичные ошибки при создании виджетов

Выясним причины, по которым виджет может работать некорректно или возвращать пустые значения:

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

← На главную