Как реализовать автоматическое заполнение текстового поля в 1С, не затирая данные пользователя?

Программист 1С v8.3 (Обычные формы)
← На главную

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

В этой статье мы подробно разберем несколько стратегий решения этой задачи, ориентируясь на Обычные формы (платформа 8.3), проанализируем типичные ошибки и выработаем наиболее надежный алгоритм.

Метод 1. Простое условие в событии ПриИзменении

Рассмотрим самый очевидный подход, с которого начинают многие разработчики. Мы используем событие ПриИзменении для реквизита, который служит триггером (в нашем случае это ВидРемонта).

Проанализируем базовый код:


Процедура ВидРемонтаПриИзменении(Элемент)
    Если ВидРемонта.Код = "ТО" Тогда
        Рекомендация = "Проверенные в рамках ТО параметры: ...";
    КонецЕсли;
КонецПроцедуры

В чем здесь кроется проблема? Если пользователь сначала ввел свой уникальный текст в поле Рекомендация, а затем решил изменить ВидРемонта на «ТО», его авторский текст будет безвозвратно удален и заменен шаблоном. Чтобы этого избежать, добавим проверку на пустоту строки.


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

Этот вариант лучше, но он не решает ситуацию, когда пользователь ошибочно выбрал «ТО», текст заполнился автоматически, а затем пользователь передумал и выбрал другой вид ремонта. Шаблон «ТО» останется в поле Рекомендация.

Метод 2. Использование интерактивного диалога (Вопрос пользователю)

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

Разберем логику по шагам:

  1. Проверяем, соответствует ли выбранный ВидРемонта нашему условию.
  2. Если поле Рекомендация уже содержит какой-то текст, спрашиваем пользователя, нужно ли его заменить.
  3. Если поле пустое — заполняем без лишних вопросов.

Процедура ВидРемонтаПриИзменении(Элемент)
    Если ВидРемонта.Код = "ТО" Тогда
        ТекстШаблона = "Проверенные в рамках ТО параметры: ...";
        
        Если НЕ ПустаяСтрока(Рекомендация) И Рекомендация <> ТекстШаблона Тогда
            Ответ = Вопрос("Поле 'Рекомендация' уже заполнено. Перезаполнить его стандартным текстом ТО?", РежимДиалогаВопрос.ДаНет);
            Если Ответ = КодВозвратаДиалога.Нет Тогда
                Возврат;
            КонецЕсли;
        КонецЕсли;
        
        Рекомендация = ТекстШаблона;
    КонецЕсли;
КонецПроцедуры

Метод 3. Хранение истории в переменной модуля формы

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

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


Перем СтараяРекомендация;

Процедура ПриОткрытии()
    СтараяРекомендация = Рекомендация;
КонецПроцедуры

Процедура ВидРемонтаПриИзменении(Элемент)
    Если ВидРемонта.Код = "ТО" Тогда
        // Сохраняем текущее состояние перед автозаполнением
        Если Рекомендация <> "Текст для ТО..." Тогда
             СтараяРекомендация = Рекомендация;
        КонецЕсли;
        Рекомендация = "Текст для ТО...";
    Иначе
        // Если вид ремонта сменили с ТО на другой, возвращаем то, что было
        Рекомендация = СтараяРекомендация;
    КонецЕсли;
КонецПроцедуры

Метод 4. Использование шаблонов из справочников (Профессиональный подход)

Хардкодинг (прописывание текста прямо в программном коде) — это плохая практика. Проанализируем ситуацию: сегодня текст ТО один, завтра он изменится. Если он зашит в код, вам придется обновлять конфигурацию. Правильнее хранить шаблоны в справочнике ВидыРемонтов.

Рассмотрим, как это реализовать:

  1. Добавим в справочник ВидыРемонтов реквизит ТекстРекомендации (тип Строка).
  2. В коде документа будем обращаться к этому реквизиту.

Процедура ВидРемонтаПриИзменении(Элемент)
    Если ЗначениеЗаполнено(ВидРемонта) И ЗначениеЗаполнено(ВидРемонта.ТекстРекомендации) Тогда
        // Проверяем, не заполнено ли уже поле чем-то другим
        Если ПустаяСтрока(Рекомендация) ИЛИ Рекомендация = "ПредыдущийШаблон" Тогда 
             Рекомендация = ВидРемонта.ТекстРекомендации;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Метод 5. Анализ «Автозаполнения» через поиск подстроки

Если мы хотим дополнять текст пользователя, а не заменять его, можно использовать функцию Найти(). Это позволит системе понять, содержится ли уже шаблон в поле, чтобы не дублировать его при многократном изменении реквизита.


Процедура ВидРемонтаПриИзменении(Элемент)
    ШаблонТО = "Параметры проверены.";
    Если ВидРемонта.Код = "ТО" Тогда
        Если Найти(Рекомендация, ШаблонТО) = 0 Тогда
            // Добавляем шаблон к существующему тексту
            Рекомендация = Рекомендация + ?(ПустаяСтрока(Рекомендация), "", Символы.ПС) + ШаблонТО;
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

Важные рекомендации по работе с событиями

При реализации подобных механизмов важно учитывать контекст выполнения кода:

Резюме

Для надежной работы системы автоматического заполнения лучше всего комбинировать хранение шаблонов в справочнике и диалоговое окно подтверждения. Это защитит данные пользователя от случайной потери и сделает поведение программы предсказуемым. Если же задача требует полной автоматизации без участия пользователя, используйте метод с переменными модуля для временного хранения предыдущих значений текста, чтобы иметь возможность «отката» при смене условий.

← На главную