Работа с внешними приложениями через технологию COM является классическим способом интеграции 1С с Microsoft Excel. Однако при написании кода часто возникают логические ловушки, из-за которых данные обрабатываются некорректно — например, во все строки записывается одно и то же значение из последней итерации цикла. Рассмотрим подробнее, как правильно организовать алгоритм разбора строк и записи результатов, а также разберем сопутствующие технические нюансы.
Проанализируем ситуацию, представленную в исходном коде. Основная ошибка заключается в разделении процесса обработки данных на несколько независимых циклов. В первом цикле автор пытается найти вхождение подстроки, во втором — выделить характеристики, а в третьем — записать результат в ячейки.
Разберем, что происходит в памяти компьютера: когда завершается второй цикл, переменные ШКХарактеристика и ШКМодель хранят значения, полученные на последней итерации (для последней строки файла). Затем запускается третий цикл по переменной k, который просто копирует эти зафиксированные значения во все строки подряд. В итоге весь результирующий файл заполняется дублями последней строки.
Для решения этой проблемы необходимо объединить чтение, обработку и запись в рамках одного прохода по строкам. Посмотрим, как должен выглядеть правильный алгоритм работы.
Вместо того чтобы плодить три разных цикла, мы будем обрабатывать каждую строку индивидуально. Прочитали строку — разобрали ее на части — сразу записали в нужные колонки этой же строки. Это не только исправит логическую ошибку, но и значительно ускорит работу скрипта.
&НаКлиенте
Процедура ОбработатьФайлExcel(Команда)
// Подготовка объекта Excel
Попытка
Эксель = Новый COMОбъект("Excel.Application");
Исключение
Сообщить("Excel не установлен на данном компьютере!");
Возврат;
КонецПопытки;
// Указывать прямые пути к файлам важно для стабильности
ПутьКФайлу = "C:\Temp\art_.xls";
ИтоговыйФайл = "C:\Temp\art_2.xls";
Книга = Эксель.WorkBooks.Open(ПутьКФайлу);
Лист = Книга.WorkSheets(1);
// Отключаем обновление экрана для ускорения процесса
Эксель.ScreenUpdating = 0;
Эксель.Calculation = -4135; // xlCalculationManual
КолВоСтрок = Лист.UsedRange.Rows.Count;
Для i = 1 По КолВоСтрок Цикл
// Получаем исходное значение из второй колонки
ИсходныйТекст = СокрЛП(Лист.Cells(i, 2).Value);
Если ПустаяСтрока(ИсходныйТекст) Тогда
Продолжить;
КонецЕсли;
// 1. Поиск ключевого слова "Модель"
ПозицияМодель = Найти(ИсходныйТекст, "Модель");
Если ПозицияМодель > 0 Тогда
// Извлекаем часть строки после слова "Модель"
ОбработаннаяСтрока = Сред(ИсходныйТекст, ПозицияМодель);
// 2. Разбор на Модель и Характеристику по первому пробелу
ПоискПробела = Найти(ОбработаннаяСтрока, " ");
Если ПоискПробела > 0 Тогда
ТекШКМодель = Лев(ОбработаннаяСтрока, ПоискПробела - 1);
ТекШКХарактеристика = Сред(ОбработаннаяСтрока, ПоискПробела + 1);
Иначе
ТекШКМодель = ОбработаннаяСтрока;
ТекШКХарактеристика = "";
КонецЕсли;
// 3. Запись результатов в нужные колонки сразу
Лист.Cells(i, 3).Value = ТекШКМодель;
Лист.Cells(i, 4).Value = ТекШКХарактеристика;
// Установка текстового формата для штрихкодов, чтобы Excel не обрезал нули
Лист.Cells(i, 1).NumberFormat = "@";
КонецЕсли;
КонецЦикла;
// Удаление ненужной теперь колонки B
Лист.Columns("B:B").Delete();
// Сохранение и закрытие
Эксель.DisplayAlerts = 0;
Книга.SaveAs(ИтоговыйФайл);
Книга.Close();
Эксель.Quit();
// Обязательная очистка переменной для выгрузки процесса из памяти
Эксель = Неопределено;
Сообщить("Обработка завершена успешно!");
КонецПроцедуры
Выясним причину, по которой код может выдавать ошибку на этапе открытия файла. В исходном примере автор использовал путь %USERPROFILE%\Desktop\art_.xls. Важно понимать, что 1С не умеет автоматически распознавать переменные окружения Windows (такие как %USERPROFILE% или %APPDATA%) в строковых переменных.
Для того чтобы получить реальный путь к рабочему столу текущего пользователя, необходимо воспользоваться объектом WScript.Shell. Проанализируем пример получения корректного пути:
Шелл = Новый COMОбъект("WScript.Shell");
ПутьКРабочемуСтолу = Шелл.SpecialFolders("Desktop");
ПолныйПуть = ПутьКРабочемуСтолу + "\art_.xls";
Также обратим внимание на опечатку в исходном сообщении: Desktop]art_2.xls. Использование закрывающей квадратной скобки вместо обратного слэша гарантированно приведет к ошибке доступа к файлу.
При записи данных в Excel из 1С программисты часто сталкиваются с тем, что длинные числовые коды (артикулы или штрихкоды) преобразуются в экспоненциальный вид (например, 4,6E+12). Чтобы этого избежать, рассмотрим несколько правил:
@ (текстовый) ДО записи данных в ячейку. Это делается командой Лист.Columns(НомерКолонки).NumberFormat = "@".NumberFormat = "0".Quit(). Нужно обязательно присвоить переменной значение Неопределено, иначе процесс EXCEL.EXE останется висеть в диспетчере задач, блокируя файл для других пользователей.Посмотрим на ситуацию шире. Если ваша задача сводится к простому преобразованию данных и сохранению их в формат Excel, использование COM-объекта может быть избыточным и медленным. В 1С есть встроенный мощный инструмент — ТабличныйДокумент.
Мы можем программно заполнить таблицу в 1С, используя метод Область(), а затем вызвать встроенный метод Записать() с типом файла ТипФайлаТабличногоДокумента.XLSX. Этот метод работает в десятки раз быстрее, не требует наличия установленного Microsoft Office на сервере или компьютере пользователя и работает стабильнее в фоновых заданиях.
Таким образом, для решения задачи автора достаточно было объединить циклы обработки в один, корректно определить пути к файлам и не забыть про очистку COM-соединения в конце процедуры. Это обеспечит корректную запись различных данных в каждую строку и стабильную работу системы.