В платформе 1С:Предприятие 7.7 работа с текстовыми полями на формах сильно ограничена. Стандартный элемент управления "Текст" или "Поле ввода" с признаком Многострочный не предоставляет штатных методов для определения текущей позиции курсора (номера строки и колонки). Это создает сложности, если нам требуется реализовать функционал «умной» вставки текста, автозамены или верстки документа непосредственно внутри формы. Рассмотрим несколько подходов к решению этой задачи: от использования внешних компонентов и ActiveX до имитации действий пользователя.
Одним из наиболее эффективных способов получить контроль над курсором является замена стандартного поля ввода 1С на ActiveX-объект, например, Microsoft Forms 2.0 TextBox. В отличие от штатного поля 1С, этот объект обладает свойствами SelStart и SelLength, которые позволяют точно узнать, где находится фокус ввода.
Проанализируем алгоритм реализации этого метода:
ActiveX (класс Forms.TextBox.1).MultiLine = -1 и EnterKeyBehavior = -1.SelStart. Оно возвращает порядковый номер символа от начала текста.Рассмотрим пример кода, который позволяет программно вставить заготовленный текст в то место, где находится курсор пользователя:
// Предположим, что ЭлементТекст — это наш ActiveX объект на форме
ТекстДляВставки = " [Тут наш спецсимвол] ";
ПозицияКурсора = Форма.ЭлементТекст.SelStart;
ТекущийТекст = Форма.ЭлементТекст.Value;
// Разбиваем текст на две части и вставляем новую строку
ЛеваяЧасть = Лев(ТекущийТекст, ПозицияКурсора);
ПраваяЧасть = Сред(ТекущийТекст, ПозицияКурсора + 1);
Форма.ЭлементТекст.Value = ЛеваяЧасть + ТекстДляВставки + ПраваяЧасть;
// Возвращаем курсор в позицию после вставленного текста
Форма.ЭлементТекст.SelStart = ПозицияКурсора + СтрДлина(ТекстДляВставки);
Важное примечание: При использовании этого метода на современных версиях Windows (10 и 11) может потребоваться регистрация библиотеки FM20.DLL. Также стоит учитывать, что события клавиатуры могут перехватываться самой оболочкой 1С, поэтому иногда требуется создавать объект не просто на форме, а внутри контейнера, поддерживающего события.
Если задача заключается не просто во вставке текста, а в полноценной верстке (выделение жирным, таблицы, спецсимволы), рационально использовать механизм Internet Explorer внутри формы 1С, загрузив в него редактор TinyMCE. Это решение позволяет работать с текстом как с объектом DOM.
Для корректной передачи данных между 1С и HTML-редактором нам потребуются функции очистки и подготовки строк. Проанализируем набор вспомогательных функций для работы с HTML-содержимым:
// Функция проверки, является ли строка HTML-текстом
Функция IsHTML(стр) Экспорт
Если Найти(стр, "<br />") > 0 Тогда
Возврат 1;
ИначеЕсли Найти(стр, "<table") > 0 Тогда
Возврат 1;
КонецЕсли;
Возврат 0;
КонецФункции
// Преобразование обычных разрывов строк 1С в теги HTML
Функция HTML_LineBreaks(стр) Экспорт
Возврат СтрЗаменить(стр, РазделительСтрок, "<br />");
КонецФункции
// Обратное преобразование HTML в простой текст
Функция ToPlainText(Знач стр) Экспорт
стр = СтрЗаменить(стр, "<br />", РазделительСтрок);
стр = СтрЗаменить(стр, " ", " ");
стр = СтрЗаменить(стр, "<p>", "");
стр = СтрЗаменить(стр, "</p>", РазделительСтрок);
Возврат стр;
КонецФункции
Для экранирования спецсимволов при передаче данных в JavaScript-движок редактора можно использовать MSScriptControl.ScriptControl. Это поможет избежать ошибок синтаксиса при наличии кавычек в тексте. Рассмотрим реализацию:
Функция стрЭкранироватьСпецСимволы(стр) Экспорт
ScrptCtrl = СоздатьОбъект("MSScriptControl.ScriptControl");
ScrptCtrl.Language = "jscript";
ScrptCtrl.AddCode(
"function quote(str)
|{
| str = str.replace(/\r\n/g, '<br>');
| str = str.replace(/\n\r/g, '<br>');
| str = str.replace('\r', '<br>');
| str = str.replace('\n', '<br>');
| str = str.replace('\'', '\\\'');
| str = str.replace('\"', '\\\"');
| return str;
|}
|");
Возврат ScrptCtrl.CodeObject.quote(стр);
КонецФункции
Если использование внешних компонентов невозможно, разберем более примитивный, но рабочий способ. Мы можем временно изменить текст и проанализировать изменения. Выясним алгоритм действий:
Этот метод не всегда стабилен, так как программно «нажать» клавишу в 1С 7.7 без внешних библиотек сложно, но его можно реализовать через WScript.Shell.
Наиболее профессиональный подход для платформы 7.7 заключается в использовании внешней компоненты FormEx, которая позволяет получить HWND (идентификатор окна) элемента управления формы. Имея HWND, мы можем отправить окну стандартное сообщение Windows EM_GETSEL.
Разберем, как это работает на низком уровне:
EM_GETSEL возвращает начальную и конечную позиции выделения текста. Если текст не выделен, обе позиции совпадают с текущим положением курсора.EM_LINEFROMCHAR позволяет пересчитать абсолютный индекс символа в номер строки.EM_LINEINDEX помогает найти индекс первого символа текущей строки, чтобы вычислить номер колонки.Посмотрим на пример логики (требуется наличие FormEx):
// Примерный алгоритм получения позиции через WinAPI
Расширение = СоздатьОбъект("РасширениеФормы");
ХендлПоля = Расширение.ПолучитьHWND("ИмяВашегоРеквизита");
// Здесь вызывается SendMessage из внешней DLL
// Результат даст нам позицию курсора в байтах/символах
Позиция = WinAPI_SendMessage(ХендлПоля, 176, 0, 0); // 176 - это константа EM_GETSEL
Если нам не нужно знать точные координаты (строку/символ), а нужно просто вставить текст «здесь и сейчас», можно воспользоваться объектом WScript.Shell. Рассмотрим этот простой метод:
htmlfile).SendKeys для имитации нажатия Ctrl+V.Проанализируем код:
// Вставляем текст в буфер обмена
ОбъектШелл = СоздатьОбъект("WScript.Shell");
// Код для записи в Clipboard (можно использовать стороннюю компоненту)
// ...
// Имитируем вставку
ОбъектШелл.SendKeys("^{v}");
Этот способ является самым быстрым в реализации, но требует осторожности, так как он зависит от текущей раскладки клавиатуры и фокуса окна.
Мы рассмотрели несколько подходов к определению позиции курсора в 1С 7.7. Для простых задач идеально подойдет имитация нажатия клавиш или использование буфера обмена. Если же вы разрабатываете сложный интерфейс для редактирования текстов, стоит посмотреть в сторону ActiveX MS Forms 2.0 или интеграции TinyMCE через HTML-поле. Для максимально глубокой интеграции в ОС Windows оптимальным выбором будет использование WinAPI совместно с компонентой FormEx.