При импорте данных из текстовых файлов (особенно формата CSV, выгруженного из сторонних систем или старых версий 1С, таких как 7.7) разработчики часто сталкиваются со следующей проблемой: строковые значения в файле обернуты в двойные кавычки. Например, строка в файле выглядит так: "Гр.","00000010","Клиенты". При обычном чтении файла и разбиении строки на подстроки кавычки остаются внутри значений, из-за чего стандартное сравнение по типу Если ТекущееЗначение = "Гр." Тогда перестает работать. В этой статье мы подробно разберем, почему возникает эта проблема, как на самом деле видит строки отладчик 1С, и рассмотрим несколько эффективных способов очистки данных от кавычек.
Прежде чем приступать к написанию кода, проанализируем поведение конфигуратора 1С. Очень часто начинающие разработчики путаются, глядя на значения переменных в табло отладчика. Если реальное строковое значение переменной содержит кавычки по краям (например, "Гр."), то в отладчике оно будет отображаться с удвоенными кавычками: ""Гр."".
Важно понимать: платформа 1С в окне отладки всегда оборачивает любые строковые значения во внешние кавычки, чтобы показать разработчику тип данных «Строка». Если внутри строки уже есть кавычки, 1С экранирует их, удваивая. Таким образом:
Гр. (без кавычек), отладчик покажет его как "Гр."."Гр.", отладчик покажет его как ""Гр."".Именно поэтому простое сравнение не дает результата. Давайте разберем по шагам, как решить эту проблему программно.
Если загружаемый файл гарантированно не содержит кавычек внутри самих данных (например, в названиях контрагентов отсутствуют конструкции вида ООО "Рога и Копыта"), мы можем применить простую замену символов ко всем строкам файла еще до момента их разбиения на колонки.
Для этого воспользуемся функцией СтрЗаменить. Посмотрим на практический пример реализации:
// Читаем файл
Текст = Новый ТекстовыйДокумент;
Текст.Прочитать(ИмяФайлаЗагрузкиКонтрагентов);
Для НомерСтроки = 1 по Текст.КоличествоСтрок() Цикл
// Читаем строку и сразу же удаляем из нее все двойные кавычки
СтрокаБезКавычек = СтрЗаменить(Текст.ПолучитьСтроку(НомерСтроки), """", "");
// Теперь строку можно безопасно делить на колонки по запятой
МассивКолонок = РазложитьСтрокуВМассивПодстрок(СтрокаБезКавычек, ",");
ТекущееЗначение = МассивКолонок[0]; // Будет содержать чистый текст "Гр." без кавычек
Если ТекущееЗначение = "Гр." Тогда
// Условие выполнится корректно!
КонецЕсли;
КонецЦикла;
Преимущества: Метод пишется в одну строку кода и работает чрезвычайно быстро.
Ограничения: Если в файле содержатся названия компаний с внутренними кавычками, этот метод сотрет их (например, "ИП "Зайцев"" превратится в ИП Зайцев). Если это критично для учета, переходите к следующим методам.
Если структура CSV-файла строго определена и каждое поле гарантированно обрамляется кавычками, мы можем обойти проблему, изменив символ разделителя. Вместо того чтобы делить строку по обычной запятой ",", мы можем разделить ее по комбинации кавычки и запятой: "","" (кавычка-запятая-кавычка).
Разберем, как это будет выглядеть на практике. Наша строка в файле имеет вид:
"Гр.","00000010","Клиенты"
Если мы укажем в качестве разделителя "","", то разделим строку ровно по границам значений. При этом нам останется лишь вручную удалить одну лишнюю кавычку в самом начале строки и одну в самом конце строки. Этот способ гораздо надежнее, так как он не повреждает кавычки внутри самих текстовых полей.
Для гарантированно корректного разбора сложных текстовых файлов с разделителями лучше всего использовать специализированную функцию. Она посимвольно обходит строку, учитывает наличие кавычек и аккуратно очищает от них только границы значений.
Рассмотрим готовую функцию, которая отлично решает эту задачу:
// Функция разбирает строку с разделителями, корректно удаляя обрамляющие кавычки.
Функция ИзСтрокиСРазделителями(Знач СтрокаТекста, Разделитель = ",", НаличиеКавычек = Истина) Экспорт
СписокДанных = Новый Массив;
ПрошлыйРазделитель = 0;
КоличествоСимволов = 0;
Для СимволИндекс = 1 По СтрДлина(СтрокаТекста) Цикл
Если Сред(СтрокаТекста, СимволИндекс, 1) = Разделитель Тогда
ВыбранноеЗначение = Сред(СтрокаТекста, (ПрошлыйРазделитель + 1), КоличествоСимволов);
// Если включен режим обработки кавычек, удаляем их по краям значения
Если НаличиеКавычек Тогда
Если Лев(ВыбранноеЗначение, 1) = """" И Прав(ВыбранноеЗначение, 1) = """" Тогда
ВыбранноеЗначение = Сред(ВыбранноеЗначение, 2, (СтрДлина(ВыбранноеЗначение) - 2));
КонецЕсли;
КонецЕсли;
СписокДанных.Добавить(ВыбранноеЗначение);
ПрошлыйРазделитель = СимволИндекс;
КоличествоСимволов = 0;
Продолжить;
КонецЕсли;
КоличествоСимволов = КоличествоСимволов + 1;
КонецЦикла;
// Обрабатываем последний элемент строки после крайнего разделителя
ВыбранноеЗначение = Сред(СтрокаТекста, (ПрошлыйРазделитель + 1));
Если НаличиеКавычек Тогда
Если Лев(ВыбранноеЗначение, 1) = """" И Прав(ВыбранноеЗначение, 1) = """" Тогда
ВыбранноеЗначение = Сред(ВыбранноеЗначение, 2, (СтрДлина(ВыбранноеЗначение) - 2));
КонецЕсли;
КонецЕсли;
СписокДанных.Добавить(ВыбранноеЗначение);
Возврат СписокДанных;
КонецФункции
Использование данной функции в вашем цикле загрузки позволит полностью исключить появление лишних кавычек на краях значений, сохранив при этом целостность текстовых данных внутри колонок.
Мало кто из разработчиков знает, что в платформе 1С встроен мощный и быстрый механизм разбора файлов CSV, который не требует написания сложных циклов парсинга строк. Объект ТабличныйДокумент умеет самостоятельно открывать и корректно разбирать текстовые файлы с разделителями по правилам Microsoft Excel. При этом платформа автоматически удаляет все обрамляющие кавычки и корректно обрабатывает кавычки и запятые внутри текстов ячеек.
Рассмотрим, как реализовать этот элегантный подход:
ТабДок = Новый ТабличныйДокумент;
// Читаем файл CSV напрямую в табличный документ
ТабДок.Прочитать(ИмяФайлаЗагрузкиКонтрагентов, СпособЧтенияЗначенийТабличногоДокумента.Текст);
// Обходим строки табличного документа
Для НомерСтроки = 1 По ТабДок.ВысотаТаблицы Цикл
// Получаем значение первой колонки. Платформа сама очистила его от кавычек!
ТекущееЗначение = ТабДок.Область(НомерСтроки, 1).Текст;
КодКонтрагента = ТабДок.Область(НомерСтроки, 2).Текст;
Если ТекущееЗначение = "Гр." Тогда
Сообщить("Успешно найдена группа контрагентов с кодом: " + КодКонтрагента);
КонецЕсли;
КонецЦикла;
Преимущества данного метода:
Используйте этот метод как основной стандарт разработки при интеграции с текстовыми файлами обмена данными.