Разработка и Конфигурация · 12 мин
Как заменить текст в табличном документе 1С
Способы замены текста в табличном документе 1С: методы НайтиТекст и ЗаменитьТекст, перебор областей, работа с параметрами макета. Примеры кода и типичные ошибки.
Табличный документ в 1С — универсальный объект: в нём формируются печатные формы, отчёты и макеты для вывода на экран или принтер. Задача замены текста в таком документе возникает постоянно: нужно подставить актуальные данные в шаблон, исправить значение после формирования отчёта или массово обновить надписи в уже готовом табличном документе. Способ решения зависит от того, где возникает замена — при заполнении макета параметрами или в уже сформированном документе.
Встроенный язык 1С предоставляет для этого несколько инструментов: методы НайтиТекст() и ЗаменитьТекст() объекта «ТабличныйДокумент», прямое обращение к ячейкам и областям, а также механизм параметров макета. У каждого подхода есть ограничения: например, ЗаменитьТекст() работает только с ячейками, содержащими текст, и не затрагивает значения других типов, а параметры макета подставляются только до вывода области.
Ниже разобраны рабочие сценарии с примерами кода, условиями выбора метода, проверкой результата и типичными ошибками, которые приводят к тому, что замена «молча» не срабатывает.
Как устроен табличный документ и где в нём хранится текст
Табличный документ состоит из ячеек, объединённых в области. У каждой ячейки есть свойство Текст, а также возможность содержать значение определённого типа — число, дату, булево. Это принципиально важно: методы поиска и замены работают со строковым представлением, и если в ячейке лежит число или дата как значение (а не как текст), простая текстовая замена может её не затронуть или привести к неожиданному результату.
Кроме обычных ячеек текст может находиться в параметрах макета, в расшифровке, в примечаниях и в именах областей. Замена через ЗаменитьТекст() касается только содержимого ячеек. Если нужно поменять текст в шаблоне макета до формирования документа — это другая задача, решаемая редактированием макета в конфигураторе или подстановкой параметров.
Быстрая замена всех вхождений методом ЗаменитьТекст
Самый простой способ — метод ЗаменитьТекст(). Он принимает искомую строку и строку замены и обрабатывает весь документ целиком:
ТабДок = Новый ТабличныйДокумент;
// ... формирование документа ...
ТабДок.ЗаменитьТекст("ООО «Старое название»", "ООО «Новое название»");
Метод заменяет все найденные вхождения подстроки в текстовых ячейках. Поиск выполняется по подстроке, поэтому замена короткого фрагмента может затронуть и более длинные строки, где этот фрагмент встречается. Например, замена «Иванов» на «Петров» изменит и «Иванова», и «Иванович», если такие строки есть в документе. Для точной замены целого содержимого ячейки надёжнее использовать поиск области с проверкой полного совпадения.
Учитывайте регистр: поведение зависит от настроек, и безопаснее приводить обе строки к одному регистру при самостоятельном поиске по областям. Метод не возвращает количество замен, поэтому для контроля результата стоит предварительно выполнить поиск и убедиться, что искомый текст вообще присутствует.
ТабДок.ЗаменитьТекст("#Организация#", "ООО Ромашка");Поиск текста перед заменой: метод НайтиТекст
Метод НайтиТекст() возвращает область ячейки, в которой найден искомый текст, или Неопределено, если совпадений нет. С его помощью можно реализовать выборочную замену — не всех вхождений, а конкретных, с проверкой контекста:
Область = ТабДок.НайтиТекст("Итого:");
Пока Область <> Неопределено Цикл
Если Область.Текст = "Итого:" Тогда
Область.Текст = "Всего:";
КонецЕсли;
Область = ТабДок.НайтиТекст("Итого:", Область);
КонецЦикла;
Второй параметр НайтиТекст() задаёт область, с которой продолжается поиск, — это позволяет пройти по всем вхождениям в цикле. Дополнительные параметры метода управляют направлением поиска, учётом регистра и поиском по целому слову. Поиск по целому слову особенно полезен, чтобы не задеть части других слов.
Такой подход медленнее одиночного вызова ЗаменитьТекст() на больших документах, но даёт полный контроль: можно проверить соседние ячейки, тип значения, оформление и заменить только нужные вхождения.
- 1Сформируйте или откройте табличный документ
- 2Вызовите НайтиТекст с искомой строкой и получите первую область
- 3В цикле проверяйте условия (полное совпадение, тип, контекст) и меняйте Область.Текст
- 4Передавайте найденную область как начало следующего поиска
- 5После цикла проверьте, что лишних вхождений не осталось
Замена через параметры макета при формировании документа
Если документ ещё не сформирован, замена текста «после факта» — не лучший путь. Правильная практика — шаблоны с параметрами в макете. В конфигураторе в ячейке макета указывается шаблон вида [Организация] или параметр <Организация>, а при выводе значение подставляется через коллекцию параметров области:
Макет = ПолучитьМакет("МакетСчета");
ОбластьШапка = Макет.ПолучитьОбласть("Шапка");
ОбластьШапка.Параметры.Организация = "ООО Ромашка";
ТабДок.Вывести(ОбластьШапка);
Преимущество подхода в том, что подстановка происходит до вывода, значения могут быть любого типа (число отформатируется по заданному формату), а логика не зависит от хрупкого текстового поиска. Если шаблон изменится — например, рядом с параметром добавят слово — код замены не сломается, в отличие от сценария с ЗаменитьТекст().
Типичная ситуация, когда разработчики всё же используют замену текста после вывода, — доработка типовой печатной формы без изменения макета, например через внешнюю печатную форму или расширение. Это допустимо как временное решение, но при обновлении конфигурации такой код требует проверки.
Сравнение вариантов замены
Быстро для готового документа, заменяет все вхождения. Не контролирует контекст, не сообщает число замен, риск задеть части слов.
Полный контроль над каждой заменой, можно проверять условия. Медленнее на больших документах, больше кода.
Самый надёжный способ при формировании. Требует доступа к макету и работает только до вывода области.
Точечная замена по известному адресу (Область(\"R5C3\")). Хрупко при изменении структуры документа.
Точечная замена через обращение к области
Когда известно точное положение ячейки, можно обратиться к ней напрямую по имени области или координатам:
ОбластьЯчейки = ТабДок.Область("R10C2");
ОбластьЯчейки.Текст = "Новый текст";
Для именованных областей макета адресация ещё проще — по имени области. Способ уместен, когда структура документа фиксирована и вы сами её формируете. В чужих или типовых документах жёсткая привязка к координатам опасна: достаточно добавить одну строку в макет, и замена попадёт не в ту ячейку без какого-либо сообщения об ошибке.
Присваивая значение свойству Текст, помните, что вы заменяете всё содержимое ячейки, а не часть строки. Если нужно изменить фрагмент, сначала прочитайте текущее значение, выполните строковую замену функцией СтрЗаменить() и запишите результат обратно.
Ограничения, риски и типичные ошибки
Главный риск текстовой замены — её «молчаливость». Если искомая строка не найдена, ни ЗаменитьТекст(), ни НайтиТекст() не вызовут ошибку: программа просто продолжит работу с незаменённым документом. Поэтому в ответственных местах (печатные формы с юридически значимыми реквизитами) добавляйте проверку: выполните поиск и убедитесь, что вхождение найдено, либо зафиксируйте предупреждение в журнале регистрации.
Вторая группа проблем связана с типами данных. Числа, выведенные с форматной строкой (разделители разрядов, пробелы), в текстовом виде могут не совпадать с искомой строкой из кода. Например, сумма «1 250,50» содержит неразрывный пробел или иной разделитель в зависимости от региональных настроек, и поиск «1 250,50» с обычным пробелом её не найдёт.
Третья группа — контекст выполнения. Табличный документ и его методы недоступны в некоторых режимах (например, ограничения на сервере в отдельных конфигурациях, различия тонкого и толстого клиента при интерактивной работе). Перед выводом заменённого документа пользователю проверяйте, что код выполняется в допустимом контексте.
Проверка результата замены
После замены убедитесь, что документ содержит ожидаемый текст и не содержит остатков исходного. Минимальная проверка — повторный вызов НайтиТекст() со старой строкой: результат Неопределено означает, что вхождений не осталось. Для контроля корректности нового значения выполните поиск строки замены и сверьте содержимое найденной области.
При пакетной обработке нескольких документов полезно считать количество замен в цикле с НайтиТекст() и выводить его в протокол. Это позволяет быстро найти документы, где шаблон не совпал, вместо ручного просмотра каждого.
Как проверить результат
НайтиТекст возвращает Неопределено
Область найдена — остались незаменённые вхождения
Текст полностью совпадает с ожидаемым значением
Заменён только фрагмент или затронуто соседнее слово
Числа и даты остались значениями со своим форматом
Ячейка стала текстовой, итоги перестали считаться
Предпросмотр показывает корректные данные
Текст обрезан, съехала верстка, видны служебные метки шаблона
Часто задаваемые вопросы
ЗаменитьТекст не находит строку, хотя она видна в документе. Почему?
Чаще всего дело в невидимых различиях: неразрывный пробел вместо обычного, другой регистр букв, лишние пробелы в конце строки или часть текста вынесена в параметр макета, который подставился при выводе. Скопируйте строку непосредственно из свойства Текст найденной области и сравните посимвольно с искомой.
Можно ли заменить текст только в определённой строке или колонке табличного документа?
Метод ЗаменитьТекст работает по всему документу и не принимает диапазон. Для ограничения области используйте цикл с НайтиТекст и проверяйте координаты найденной ячейки (свойства Верх, Лево области), либо перебирайте ячейки нужного диапазона напрямую через Область с координатами.
Как заменить текст в макете, а не в сформированном документе?
Макет редактируется в конфигураторе: откройте макет, найдите ячейку и измените текст или шаблон. Программно макет тоже можно получить как табличный документ через ПолучитьМакет, изменить и использовать для вывода, но сохранить его обратно в конфигурацию из кода нельзя — для постоянного изменения правьте макет в конфигураторе или расширении.
Замена работает, но числа в документе «сломались» и перестали суммироваться. Что произошло?
Присвоение строки свойству Текст превращает ячейку в текстовую. Если замена затронула ячейки с числами, они потеряли тип значения. Заменяйте только текстовые ячейки, а для чисел либо не трогайте их, либо записывайте значение с сохранением типа, работая с макетом и параметрами до вывода.
Есть ли способ заменить текст с учётом регистра или без него?
У метода НайтиТекст есть параметр, управляющий игнорированием регистра при поиске — используйте его для регистронезависимого поиска. Для ЗаменитьТекст такой настройки нет в явном виде, поэтому при строгих требованиях к регистру реализуйте замену через цикл поиска с нужными параметрами и присвоение Область.Текст.
Что быстрее на больших документах: ЗаменитьТекст или перебор ячеек?
Одиночный вызов ЗаменитьТекст обычно быстрее ручного перебора всех ячеек в цикле встроенного языка. Цикл с НайтиТекст оправдан, когда нужна выборочная замена с проверками. Если документ очень большой и замен много, рассмотрите перенос логики на этап формирования через параметры макета — это устраняет постобработку полностью.
Что важно запомнить
Для готового документа используйте ЗаменитьТекст или цикл с НайтиТекст, для формируемого — параметры макета. Всегда проверяйте, что искомый текст найден, не заменяйте числовые ячейки строками и избегайте жёсткой привязки к координатам.