При разработке функционала отправки писем, загрузки логов или обработки внешних данных часто возникает задача: предоставить пользователю возможность выбрать файл на диске и отобразить его содержимое в текстовом поле на форме для дальнейшего просмотра или редактирования. Разберем типичные ошибки при реализации этой задачи и рассмотрим правильные варианты решения.
Выясним причину возникновения исключения. Ошибка появляется при попытке вызвать метод Прочитать() напрямую у строкового реквизита формы или элемента управления:
// Ошибочный вызов:
ТекстПисьма.Прочитать(ПутьКТФайлу);
В платформе 1С реквизит формы строкового типа или элемент управления «Поле ввода» не являются объектами для работы с файловой системой. У обычной строки или элемента формы нет встроенного метода Прочитать(). Чтение данных с диска выполняется специализированными объектами платформы — ТекстовыйДокумент или ЧтениеТекста, после чего полученное строковое значение присваивается реквизиту формы.
Рассмотрим классический способ с использованием объекта ТекстовыйДокумент. Этот объект позволяет полностью прочитать файл с диска и сразу извлечь весь текст одной строкой через метод ПолучитьТекст() без необходимости построчного обхода в цикле.
Разберем по шагам правильную реализацию процедуры выбора и чтения файла:
ДиалогВыбораФайла и настраиваем фильтр.Если ДТФ.Выбрать() Тогда, чтобы избежать ошибок при нажатии пользователем кнопки «Отмена».Новый ТекстовыйДокумент, вызываем метод Прочитать() и передаем результат в реквизит формы.Посмотрим на пример готового кода:
Процедура ЗагрузитьТекстИзФайла()
ДТФ = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДТФ.Заголовок = "Выберите текстовый файл";
ДТФ.Фильтр = "Текстовые файлы (*.txt)|*.txt|Все файлы (*.*)|*.*";
ДТФ.ПредварительныйПросмотр = Ложь;
ДТФ.ПроверятьСуществованиеФайла = Истина;
Если ДТФ.Выбрать() Тогда
ПутьКТфайлу = ДТФ.ПолноеИмяФайла;
Попытка
Текст = Новый ТекстовыйДокумент;
// Указываем путь к файлу и при необходимости кодировку
Текст.Прочитать(ПутьКТфайлу, КодировкаТекста.UTF8);
// Заполняем реквизит формы, связанный с полем ввода
ТекстПисьма = Текст.ПолучитьТекст();
Исключение
Сообщить("Не удалось прочитать файл: " + ОписаниеОшибки(), СтатусСообщения.ОченьВажное);
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Проанализируем альтернативный и более легковесный способ чтения текстовых данных. Объект ЧтениеТекста предназначен непосредственно для потокового или полного считывания текста без создания промежуточного документа в памяти.
Посмотрим на пример с использованием объекта ЧтениеТекста:
Процедура ЗагрузитьЧерезЧтениеТекста()
ДТФ = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
ДТФ.Фильтр = "Текстовые файлы (*.txt)|*.txt";
Если ДТФ.Выбрать() Тогда
ФайлЧтения = Новый ЧтениеТекста;
Попытка
// Открываем файл с явным указанием кодировки
ФайлЧтения.Открыть(ДТФ.ПолноеИмяФайла, КодировкаТекста.UTF8);
// Метод Прочитать() без параметров считывает весь файл целиком в строку
ТекстПисьма = ФайлЧтения.Прочитать();
// Обязательно закрываем файл после чтения
ФайлЧтения.Закрыть();
Исключение
ФайлЧтения.Закрыть();
Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки(), СтатусСообщения.Важное);
КонецПопытки;
КонецЕсли;
КонецПроцедуры
Чтобы прочитанный многострочный текст корректно отображался на форме и пользователь мог редактировать его с переносами строк, необходимо проверить свойства элемента формы:
Истина, чтобы активировать отображение нескольких строк и обработку клавиши Enter.Истина, чтобы длинные строки автоматически переносились по ширине элемента.Рассмотрим подробнее важные детали, которые предотвратят ошибки в рабочей конфигурации:
КодировкаТекста.UTF8, КодировкаТекста.ANSI или "windows-1251").ТекстовыйДокумент и ЧтениеТекста предназначены только для текстовых форматов (.txt, .csv, .html, .json, .xml). Бинарные файлы Microsoft Word (.doc, .docx) или разметка .rtf при таком чтении отобразятся в виде служебного кода или нечитаемых символов.ДТФ.Выбрать() возвращает Ложь. Всегда проверяйте результат выполнения диалога, чтобы не передавать пустую строку в метод открытия файла.ВыбратьАсинх() или Показать() с объектом ОписаниеОповещения).