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

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

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

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

1. Использование флага "ИзменяетДанные" для отслеживания модифицированности формы

Первый и самый простой способ, который мы можем применить, позволяет отслеживать не столько каждое конкретное изменение текста, сколько факт модификации формы в целом. Это особенно полезно, когда нам нужно задать пользователю вопрос о сохранении данных при закрытии формы. Мы устанавливаем флаг ИзменяетДанные для элемента формы "Поле текстового документа".

Как это работает:

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

Преимущества:

Недостатки:

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

2. Применение Обработчика Ожидания для периодической проверки содержимого

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

Как это работает:

  1. Сохраняем начальное значение: При открытии формы или инициализации поля, мы сохраняем текущее содержимое поля текстового документа в некоторую переменную формы. Например, в реквизит формы строкового типа, скажем, СтарыйТекстПоля.
  2. Создаем Обработчик Ожидания: В модуле формы мы создаем процедуру-обработчик ожидания и устанавливаем ее с определенным интервалом. Обычно, интервал в 0.5 - 1 секунду является приемлемым компромиссом между оперативностью и нагрузкой на систему.
  3. Логика в Обработчике: Внутри процедуры ОбработчикОжидания мы будем выполнять следующие шаги:
    • Получаем текущее содержимое поля текстового документа.
    • Сравниваем его с сохраненным значением СтарыйТекстПоля.
    • Если значения отличаются, значит текст был изменен. В этом случае мы выполняем необходимую логику (например, выводим сообщение, обновляем другие поля, пересчитываем что-либо).
    • После выполнения логики, мы обновляем значение СтарыйТекстПоля текущим содержимым, чтобы подготовиться к следующей проверке.
  4. Управление Обработчиком: Важно правильно управлять обработчиком ожидания – включать его при открытии формы и отключать при ее закрытии, чтобы избежать лишней нагрузки.

Давайте посмотрим на пример кода:


// В модуле формы

// Реквизит формы для хранения старого значения текста
// Можно добавить как реквизит формы строкового типа
// Переменная СтарыйТекстПоля;

Процедура ПриОткрытии()
    // Инициализируем СтарыйТекстПоля при открытии формы
    СтарыйТекстПоля = ЭлементыФормы.ПолеТекстовогоДокумента1.ПолучитьТекст();
    
    // Устанавливаем обработчик ожидания
    // "ПроверитьИзменениеТекста" - имя процедуры-обработчика
    // 0.5 - интервал в секундах
    ПодключитьОбработчикОжидания("ПроверитьИзменениеТекста", 0.5); 
КонецПроцедуры

Процедура ПриЗакрытии()
    // Отключаем обработчик ожидания при закрытии формы
    ОтключитьОбработчикОжидания("ПроверитьИзменениеТекста");
КонецПроцедуры

Процедура ПроверитьИзменениеТекста()
    Перем ТекущийТекст;
    ТекущийТекст = ЭлементыФормы.ПолеТекстовогоДокумента1.ПолучитьТекст();
    
    Если ТекущийТекст <> СтарыйТекстПоля Тогда
        // Текст изменился!
        Сообщить("Текст в поле текстового документа был изменен!");
        
        // Здесь мы можем выполнить любую необходимую логику
        // Например, обновить другой элемент формы, пересчитать что-то
        // МодифицироватьДанныеФормы(Истина); // Если нужно отметить форму как модифицированную
        
        // Обновляем СтарыйТекстПоля для следующей проверки
        СтарыйТекстПоля = ТекущийТекст;
    КонецЕсли;
КонецПроцедуры

Преимущества:

Недостатки:

3. Использование внешних компонент (ВК)

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

Как это работает:

  1. Разработка или поиск ВК: Нам потребуется внешняя компонента, которая умеет перехватывать события клавиатуры на уровне операционной системы или конкретного элемента управления. Такие компоненты могут быть разработаны на языках, поддерживающих взаимодействие с Windows API, например, C++ или Delphi.
  2. Подключение ВК к 1С: Внешняя компонента регистрируется в системе и подключается к 1С с помощью метода ПодключитьВнешнююКомпоненту().
  3. Подписка на события: После подключения, компонента может предоставлять методы или события, которые мы можем использовать для подписки на ввод с клавиатуры в конкретном поле текстового документа.
  4. Обработка событий: В процедурах-обработчиках событий, предоставляемых ВК, мы можем анализировать введенные символы, отслеживать изменения и выполнять необходимую логику в реальном времени.

Преимущества:

Недостатки:

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

4. Рассмотрение Поля HTML-документа как альтернативы

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

Особенности Поля HTML-документа:

Применимость к задаче:

Если нам нужно редактировать простой текст, ПолеHTMLДокумента является избыточным и, возможно, неудобным выбором. Его использование может потребовать встраивания элемента <textarea> внутрь HTML-документа и затем реализации сложной логики взаимодействия через JavaScript и механизм обратных вызовов в 1С. Этот путь будет гораздо сложнее, чем использование ОбработчикаОжидания для обычного поля текстового документа.

Таким образом, для задачи отслеживания изменений в простом текстовом поле, ПолеHTMLДокумента не является оптимальным или простым решением.

5. Привязка к реквизиту формы и событие "ПриИзменении" (как контраст)

Хотя наш исходный вопрос касается поля, не связанного ни с какими данными, важно понимать, что идеальное решение для поля ввода в 1С — это привязка к реквизиту формы и использование стандартного события ПриИзменении. Давайте кратко рассмотрим этот вариант как эталон, от которого мы отталкиваемся при поиске обходных путей.

Как это работает (в идеальном случае для связанного поля):

  1. Создаем реквизит формы: В конфигураторе мы создаем реквизит формы, например, МойТекст строкового типа.
  2. Связываем элемент формы: Мы добавляем на форму элемент типа "Поле ввода" и связываем его с реквизитом МойТекст.
  3. Используем событие "ПриИзменении": Для этого элемента "Поле ввода" мы можем создать обработчик события ПриИзменении. Этот обработчик будет срабатывать каждый раз, когда пользователь изменяет текст в поле и уводит с него фокус, или нажимает Enter.

Давайте посмотрим на пример кода для связанного поля:


// В модуле формы
// Предполагаем, что есть реквизит формы МойТекст строкового типа
// И элемент формы ПолеВводаМойТекст, связанный с этим реквизитом

Процедура ПолеВводаМойТекстПриИзменении(Элемент)
    // Эта процедура будет вызвана, когда текст в поле изменится
    // и пользователь переведет фокус или нажмет Enter.
    
    Сообщить("Значение поля 'МойТекст' изменилось на: " + Элемент.Значение);
    // Здесь мы можем выполнять любую логику,
    // используя новое значение текста, доступное через Элемент.Значение
КонецПроцедуры

Почему это не применимо к нашему случаю:

Наш первоначальный запрос явно указывает на "поле текстового документа не связанное ни с какими данными". Само "Поле текстового документа" (в отличие от "Поля ввода", которое обычно используется для привязки к строковым реквизитам) не имеет такого прямого события ПриИзменении и не предназначено для непосредственной привязки к строковым реквизитам таким же образом. Оно больше ориентировано на работу с более объемными текстами, вставку изображений и форматирование.

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

6. Отслеживание изменений в управляемых формах (для сравнения)

Хотя наш вопрос сосредоточен на обычных формах, полезно провести сравнение с управляемыми формами, где для поля ввода (аналог текстового поля в некоторых аспектах) предусмотрено более продвинутое событие ИзменениеТекстаРедактирования. Это событие в управляемых формах предоставляет гораздо более гранулярный контроль.

Событие "ИзменениеТекстаРедактирования" (в управляемых формах):

Контраст с обычными формами:

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

Заключение:

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

  1. Использование флага ИзменяетДанные подходит для базового отслеживания модификации формы.
  2. Применение ОбработчикаОжидания является наиболее сбалансированным решением по сложности реализации и оперативности для большинства задач. Мы можем настроить его для периодической проверки содержимого поля, сравнивая текущий текст с ранее сохраненным значением. Это позволяет нам реагировать на изменения текста, внесенные как с клавиатуры, так и путем вставки из буфера обмена.
  3. Использование внешних компонент обеспечивает максимальный контроль и оперативность, но требует значительных усилий по разработке и поддержке.

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

← На главную