Как проверить заполненность реквизита в табличной части другого документа при вводе данных?

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

В процессе разработки часто возникает задача контроля ввода данных, когда необходимо убедиться, что сотрудник еще не был «отмечен» в других документах за выбранную дату. Рассмотрим, как реализовать такую проверку, если бизнес-логика запрещает проводить документы до конца отчетного периода.

Разбор архитектурного подхода

Когда проведение документов невозможно, единственным верным способом получения данных является прямой запрос к табличной части документов. Основная сложность заключается в необходимости оптимизации кода, чтобы не создавать 31 дублирующую процедуру для каждого дня месяца.

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

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

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


&НаСервереБезКонтекста
Процедура ПроверитьЗаполнениеДняНаСервере(ИмяРеквизита, ДатаДок, ФИО, ТекущаяСсылка)
    
    // Формируем текст запроса динамически
    ТекстЗапроса = "ВЫБРАТЬ
                   | ТабельСписок.Ссылка.Номер КАК Номер,
                   | ТабельСписок.НомерЗадания КАК НомерЗадания,
                   | ТабельСписок.Ответственный КАК Ответственный
                   |ИЗ
                   | Документ.Табель.Список КАК ТабельСписок
                   |ГДЕ
                   | ТабельСписок.ДатаДок = &ДатаДок
                   | И ТабельСписок.ФИО = &ФИО
                   | И ТабельСписок.Ссылка <> &ТекущаяСсылка
                   | И ТабельСписок.%ИмяРеквизита% > 0";
                   
    ТекстЗапроса = СтрЗаменить(ТекстЗапроса, "%ИмяРеквизита%", ИмяРеквизита);
    
    Запрос = Новый Запрос(ТекстЗапроса);
    Запрос.УстановитьПараметр("ДатаДок", ДатаДок);
    Запрос.УстановитьПараметр("ФИО", ФИО);
    Запрос.УстановитьПараметр("ТекущаяСсылка", ТекущаяСсылка);
    
    Результат = Запрос.Выполнить();
    Если НЕ Результат.Пустой() Тогда
        Выборка = Результат.Выбрать();
        Пока Выборка.Следующий() Цикл
            Сообщить("Сотрудник уже учтен в документе № " + Выборка.Номер);
        КонецЦикла;
    КонецЕсли;
    
КонецПроцедуры

Интеграция в управляемую форму

Чтобы вызывать эту процедуру из любого поля табличной части, используйте событие ПриИзменении или ОкончаниеВводаТекста. В обработчике события доступен параметр Элемент, из которого мы можем извлечь имя реквизита.

Алгоритм действий:

  1. Получаем имя элемента формы через Элемент.Имя.
  2. Выделяем из имени только часть, соответствующую реквизиту табличной части (например, отрезаем префикс).
  3. Передаем полученную строку в серверную процедуру.
  4. Обязательно учитываем условие Ссылка <> &ТекущаяСсылка, чтобы исключить проверку данных внутри самого редактируемого документа.

Рекомендации по надежности данных

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

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

← На главную