При реализации механизмов штрихкодирования в 1С:Документооборот или других конфигурациях часто возникает задача автоматической вставки изображения штрихкода в файл формата .doc или .docx. Один из самых распространенных способов — использование COM-соединения с приложением Microsoft Word. Однако при работе с графическими объектами в колонтитулах программисты нередко сталкиваются с критической ошибкой 0x80004005 при вызове метода ConvertToShape. Рассмотрим подробно, почему это происходит и как реализовать задачу максимально надежно.
Типичный алгоритм вставки, который можно встретить в примерах, заключается в следующем: мы вставляем картинку как InlineShape (встроенную в строку текста), а затем пытаемся преобразовать ее в Shape (плавающий объект), чтобы свободно позиционировать по координатам. Ошибка 0x80004005 (неопределенная ошибка выполнения) сигнализирует о том, что MS Word не может выполнить операцию преобразования в текущем контексте.
Проанализируем основные причины возникновения сбоя:
.doc открыт в новой версии Word), многие операции с графическим слоем блокируются.ConvertToShape не может корректно вычислить привязку (Anchor) для нового плавающего объекта.InlineShape, из-за чего метод конвертации вызывается для «пустого» или не полностью созданного объекта.Вместо двухступенчатой процедуры (вставка как символ и последующая конвертация) мы рекомендуем использовать прямой метод Shapes.AddPicture. Это позволяет сразу создать объект типа Shape в нужном месте, минуя проблемную стадию преобразования. Рассмотрим пример кода, который реализует этот подход:
// Инициализация приложения Word
Попытка
WordApp = Новый COMОбъект("Word.Application");
Исключение
ВызватьИсключение "Ошибка при запуске MS Word";
КонецПопытки;
// Открываем документ
Док = WordApp.Documents.Open(ПутьКФайлу);
// Получаем доступ к колонтитулу первой секции
// item(1) - нижний колонтитул (wdHeaderFooterPrimary)
Колонтитул = Док.Sections.Item(1).Footers.Item(1);
// Вместо InlineShapes сразу используем коллекцию Shapes
// Параметры: ИмяФайла, LinkToFile, SaveWithDocument, Left, Top, Width, Height
// Координаты задаются в пунктах (points)
Штрихкод = Колонтитул.Shapes.AddPicture(ПутьККартинкеШК, Ложь, Истина, -999998, -999997);
// Настройка позиционирования относительно страницы
Штрихкод.RelativeHorizontalPosition = 1; // wdRelativeHorizontalPositionPage
Штрихкод.RelativeVerticalPosition = 1; // wdRelativeVerticalPositionPage
В данном примере использование значения -999998 для координат является специфической константой Word, которая заставляет объект прижаться к границе области. Однако более надежным будет явное указание координат в пунктах. Разберем ситуацию подробнее: использование Shapes.AddPicture сразу помещает картинку в «плавающий» слой документа, что полностью исключает ошибку ConvertToShape.
Если специфика вашей задачи требует обязательного использования InlineShapes, или вы работаете со старыми шаблонами, можно попробовать устранить причины ошибки через подготовку документа. Выясним, как сделать среду выполнения более «стабильной» для Word.
Во-первых, перед началом манипуляций стоит вызвать метод Convert(), который обновит документ до последней версии формата. Во-вторых, кратковременное включение видимости приложения (Visible = Истина) часто помогает Word корректно инициализировать графические объекты в памяти.
Док = WordApp.Documents.Open(ПутьКФайлу);
// Обновляем формат документа до текущего
Попытка
Док.Convert();
Исключение
// Файл уже в актуальном формате или не требует конвертации
КонецПопытки;
// Включаем видимость (опционально, если ошибка сохраняется)
WordApp.Visible = Истина;
Колонтитул = Док.Sections.Item(1).Footers.Item(1);
Колонтитул.Range.Select(); // Выделяем область колонтитула
// Вставка картинки
Picture = Колонтитул.Range.InlineShapes.AddPicture(ПутьККартинкеШК, Ложь, Истина);
// Небольшая пауза для обработки событий Word
// (в 1С можно использовать Предупреждение или проверку состояния)
Shape = Picture.ConvertToShape();
Shape.WrapFormat.Type = 3; // wdWrapNone (перед текстом)
Проанализируем несколько технических моментов, которые критичны для стабильной работы системы:
WINWORD.EXE, что со временем приведет к отказу в обслуживании новых запросов. Используйте WordApp.Quit().RelativeHorizontalPosition и RelativeVerticalPosition. Значение 1 означает привязку к краю страницы (Page). Это самое надежное решение для штрихкодов, так как они не будут «уезжать» при изменении текста в самом колонтитуле.Попытка... КонецПопытки. Word — внешнее приложение, и его поведение может зависеть от установленных обновлений, антивирусов или открытых диалоговых окон «О программе» или «Печать» в других экземплярах приложения.Таким образом, для решения проблемы с ошибкой 0x80004005 наиболее эффективным методом является отказ от конвертации объектов в пользу прямого создания Shape через метод AddPicture коллекции Shapes колонтитула. Это делает код более лаконичным, быстрым и устойчивым к особенностям разметки различных файлов Word.