При разработке механизмов загрузки данных из внешних источников программисты 1С часто сталкиваются с ситуацией, когда стандартный метод ТабличныйДокумент.Прочитать() ведет себя непредсказуемо. Одной из самых неприятных проблем является частичная потеря данных: числовые значения считываются корректно, а текстовые строки просто исчезают, оставляя пустые ячейки. Давайте подробно разберем, почему это происходит, и проанализируем все возможные способы решения этой задачи.
Прежде всего, проанализируем базовый код, который чаще всего используется для импорта. В системе 1С:Предприятие для чтения файлов Excel обычно применяется объект ТабличныйДокумент. Рассмотрим пример вызова метода:
ТабДок = Новый ТабличныйДокумент;
Попытка
ТабДок.Прочитать(ПутьКФайлу, СпособЧтенияЗначенийТабличногоДокумента.Текст);
Исключение
Сообщить("Ошибка при чтении файла: " + ОписаниеОшибки());
КонецПопытки;
Параметр СпособЧтенияЗначенийТабличногоДокумента может принимать значения Текст или Значение. Если вы столкнулись с тем, что текст не читается, первым делом попробуем изменить этот параметр. Однако, как показывает практика, если причина кроется в структуре файла или блокировках системы, смена этого флага редко помогает. Выясним более глубокие причины.
Иногда решение лежит на поверхности — в свойствах самого файла в операционной системе. Разберем два важных момента:
.xlsx файла. Рекомендуется программно или вручную снять этот атрибут перед чтением.Современный Microsoft Excel предлагает несколько вариантов сохранения формата .xlsx. Проанализируем ситуацию с форматом Strict Open XML. Этот стандарт более строго описывает структуру файла, и встроенные средства 1С (особенно на старых релизах платформы 8.3) не всегда умеют корректно извлекать из него текстовые данные, хотя числа считываются без проблем.
Как проверить и исправить: Откройте файл в оригинальном приложении Excel и выберите "Сохранить как". Убедитесь, что выбран тип файла "Книга Excel (*.xlsx)", а не версия Strict. После пересохранения в обычном формате 1С, как правило, начинает видеть текст.
Существуют подтвержденные ошибки в определенных релизах платформы 1С (например, в диапазоне 8.3.15.ххх – 8.3.17.ххх), связанные с механизмом обработки строковых констант в файлах XLSX. Если файл был создан не в Microsoft Excel, а, например, в LibreOffice или сформирован программно сторонней библиотекой на PHP или Python, 1С может не найти таблицу общих строк.
В этом случае рассмотрим обновление платформы до актуального релиза или использование альтернативных методов чтения, которые мы разберем ниже.
Если 1С использует системные драйверы (например, при чтении через ADO), возникает проблема "первых восьми строк". Драйвер анализирует первые несколько строк колонки, чтобы определить ее тип. Если там стоят числа, драйвер жестко фиксирует тип Numeric для всей колонки. Встретив текст в 10-й строке, он просто вернет NULL или пустое значение.
Хотя ТабличныйДокумент.Прочитать() работает иначе, он также может спотыкаться на ячейках, где применен специфический пользовательский формат. Проверьте, не является ли "текст" в Excel на самом деле числом, которое просто отображается как текст через маску формата.
Если стандартный ТабличныйДокумент категорически отказывается видеть строковые данные, воспользуемся наиболее надежным, хоть и более медленным способом — прямым обращением к Excel через COM. Этот метод гарантирует, что мы получим данные именно в том виде, в котором их видит сам Excel.
Разберем пример кода для чтения данных:
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Книга = Эксель.Workbooks.Open(ПутьКФайлу);
Лист = Книга.Sheets(1); // Читаем первый лист
// Определяем количество строк
ВсегоСтрок = Лист.Cells.SpecialCells(11).Row;
Для НомерСтроки = 1 По ВсегоСтрок Цикл
// Используем свойство Text, чтобы получить строковое представление
ЗначениеЯчейки = Лист.Cells(НомерСтроки, 1).Text;
Сообщить("Строка " + НомерСтроки + ": " + ЗначениеЯчейки);
КонецЦикла;
Книга.Close(Ложь);
Эксель.Quit();
Исключение
Сообщить("Ошибка вызова Excel: " + ОписаниеОшибки());
Если Эксель <> Неопределено Тогда
Эксель.Quit();
КонецЕсли;
КонецПопытки;
Важный нюанс: Обратите внимание на использование свойства .Text вместо .Value. Свойство .Text возвращает именно то, что отображается в ячейке, включая результаты форматирования, что часто решает проблему потери строковых данных.
Если на сервере не установлен Excel, или данных слишком много для медленного COM-соединения, проанализируем способ чтения через ADODB.Connection. Чтобы текст не пропадал при наличии чисел в той же колонке, в строку соединения нужно добавить параметр IMEX=1.
СтрокаСоединения = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу +
";Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1"";";
Соединение = Новый COMОбъект("ADODB.Connection");
Попытка
Соединение.Open(СтрокаСоединения);
Запись = Соединение.Execute("SELECT * FROM [Лист1$]");
Пока НЕ Запись.EOF() Цикл
// Обработка данных
Запись.MoveNext();
КонецЦикла;
Соединение.Close();
Исключение
Сообщить(ОписаниеОшибки());
КонецПопытки;
Параметр IMEX=1 (Intermixed) заставляет драйвер рассматривать колонки со смешанными данными как текстовые, что предотвращает обнуление строковых значений.
Подведем итог нашему анализу. Если 1С не видит текст в Excel-файле:
Прочитать() используется СпособЧтенияЗначенийТабличногоДокумента.Текст.Text.Рассмотренные шаги позволяют обойти ограничения встроенного парсера 1С и обеспечить корректную загрузку всех типов данных из документов Excel в информационную базу.