Работа с внешними данными в формате Excel — одна из самых частых задач для разработчика 1С. Казалось бы, штатный механизм ТабличныйДокумент.Прочитать() должен работать безупречно, однако на практике многие сталкиваются с критической ошибкой: программа просто «умирает» или бесконечно «висит» при попытке загрузить очередной файл. При этом стандартные блоки Попытка...Исключение не срабатывают, так как проблема происходит на уровне ядра системы.
В этой статье мы подробно разберем, почему возникают такие ситуации, проанализируем внутренние механизмы платформы и выясним, как обойти эти ограничения, чтобы ваша загрузка данных работала стабильно.
Для начала проанализируем ситуацию: когда мы вызываем метод Прочитать(), платформа 1С задействует внутреннюю библиотеку moxel.dll. Эта библиотека отвечает за работу с табличными документами и содержит парсер формата OpenXML (xlsx). Проблема заключается в том, что 1С пытается не просто прочитать данные из ячеек, а полностью реконструировать структуру документа со всеми его визуальными элементами.
Рассмотрим основные технические причины, по которым парсер может уйти в бесконечный цикл или вызвать ошибку доступа к памяти (Access Violation):
moxel.dll. 1С очень чувствительна к нестандартным стилям в XML-структуре файла..xlsm (с макросами), а вы просто переименовали его в .xlsx, внутренняя структура файла не изменится. В нем останутся части vbaProject.bin, на которые могут ссылаться кнопки или другие объекты. 1С пытается найти эти связи, не находит и зависает.Если зависание происходит на конкретном файле, первым делом стоит проверить его содержимое вручную. Рассмотрим, на что нужно обратить внимание:
Во-первых, проверим наличие скрытых графических объектов. В Excel перейдите на вкладку «Главная», выберите «Найти и выделить», затем «Выбор объектов». Попробуйте выделить область листа — часто там обнаруживаются невидимые «мусорные» кнопки или пустые рамки, оставшиеся от старых макросов. Удалите их.
Во-вторых, обратите внимание на примечания. Попробуйте сбросить форматирование всех примечаний к стандартному. Как показывает практика, установка черного цвета линий и стандартного шрифта часто решает проблему зависания 1С.
В-третьих, если файл содержит макросы, его нужно не переименовывать, а пересохранять через «Сохранить как» в формат «Книга Excel (.xlsx)». Это полностью пересоберет XML-структуру и удалит ссылки на VBA-проект.
Если файлов много и очищать их вручную невозможно, мы можем использовать Microsoft Excel как промежуточное звено для «лечения» файла перед тем, как его прочитает 1С. Суть метода заключается в том, чтобы открыть файл через COM и пересохранить его. Excel при сохранении сам исправит мелкие ошибки в структуре XML.
Рассмотрим пример кода для такой предварительной обработки:
Функция ПодготовитьФайлКЗагрузке(ПутьКФайлу)
Попытка
Excel = Новый COMОбъект("Excel.Application");
Исключение
Возврат ПутьКФайлу; // Если Excel не установлен, возвращаем как есть
КонецПопытки;
Excel.DisplayAlerts = Ложь;
Excel.Visible = Ложь;
Попытка
Книга = Excel.Workbooks.Open(ПутьКФайлу);
// Удаляем все фигуры и кнопки на всех листах, если они не нужны для данных
Для Каждого Лист Из Книга.Sheets Цикл
Для НомерФормы = 1 По Лист.Shapes.Count Цикл
Лист.Shapes.Item(1).Delete();
КонецЦикла;
КонецЦикла;
НовыйПуть = ПолучитьИмяВременногоФайла("xlsx");
// Параметр 51 соответствует формату xlsx без макросов
Книга.SaveAs(НовыйПуть, 51);
Книга.Close();
Возврат НовыйПуть;
Исключение
Сообщить("Ошибка при обработке файла через COM: " + ОписаниеОшибки());
Возврат ПутьКФайлу;
КонецПопытки;
Excel.Quit();
КонецФункции
После такой обработки файл становится «чистым» для парсера 1С, и метод ТабДок.Прочитать(НовыйПуть) отработает мгновенно.
Если вам нужно прочитать только данные (строки и колонки), а оформление, цвета и примечания вас не интересуют, проанализируем возможность использования технологии ADO (ActiveX Data Objects). Этот метод вообще не использует moxel.dll и ТабличныйДокумент, поэтому он неуязвим к графическим объектам внутри Excel.
Разберем пример подключения к файлу как к базе данных:
Connection = Новый COMОбъект("ADODB.Connection");
ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ПутьКФайлу + ";Extended Properties=""Excel 12.0 Xml;HDR=YES"";";
Попытка
Connection.Open(ConnectionString);
Recordset = Connection.Execute("SELECT * FROM [Лист1$]");
Пока НЕ Recordset.EOF Цикл
// Обработка данных
Значение = Recordset.Fields.Item(0).Value;
Recordset.MoveNext();
КонецЦикла;
Recordset.Close();
Connection.Close();
Исключение
Сообщить("Ошибка чтения через ADO: " + ОписаниеОшибки());
КонецПопытки;
Использование этого метода гарантирует, что 1С не зависнет из-за кнопки на листе или синего цвета примечания, так как драйвер Microsoft.ACE.OLEDB игнорирует всё, что не является данными в ячейках. При необходимости читать данные напрямую из структуры книги без использования офисного пакета и сторонних драйверов можно применить решение для чтения файлов Excel без MS Office и внешних библиотек.
Проанализируем еще несколько факторов, которые могут влиять на стабильность процесса:
moxel.dll, исправляя падения на защищенных листах.ТабДок = Неопределено; в конце каждой итерации, чтобы принудительно освобождать память.Подводя итог, можно сказать: если вы столкнулись с «мистическим» зависанием, не ищите ошибку в своем коде 1С. Скорее всего, дело в графическом мусоре внутри Excel-файла. Используйте программную очистку через COM или переходите на чтение через ADO, чтобы обеспечить бесперебойную работу ваших интеграций. Для быстрого получения данных всех страниц книги в таблицу значений без ручной настройки парсинга можно применить обработку для универсальной загрузки файлов Excel и CSV.