Вставил картинку в Excel с помощью C ++ / CLI и получил 100-кратное предупреждение C4691

0

Мне была назначена задача сделать небольшую модификацию существующего приложения C++/CLI (с автоматизацией Excel) (целевая среда:.NET4.0, IDE: VS2010). Задача: вставить пару изображений (*.jpg) в рабочий лист Excel. Я был рад найти здесь в stackoverflow поток, в котором именно эта задача была рассмотрена на С#. Вот ссылка: пожалуйста, посмотрите на конец этого вопроса

В приведенном выше потоке я следил за инструкциями, приведенными в ответе от пользователя JMK. Код компилируется без ошибок и работает! Действительно, код успешно помещает изображение на рабочий лист. К сожалению, я также получаю сотни предупреждений компилятора C4691.

Мой код:

    //attributes - used by several different methods
private:
    Excel::Application^ xlApp;
    Excel::_Workbook^ xlBook;
    Excel::Workbooks^ xlBooks;
    Excel::Sheets^ xlSheets;
    Excel::_Worksheet^ xlSheet;
    Excel::Range^ range;
    String^ templateFilename;
    String^ picFilename;

private: System::Void buttonRunExcel_Click(System::Object^  sender, System::EventArgs^  e)
{
//create the Excel Application
xlApp = gcnew Excel::Application();//55 C4691 compiler warnings for this line of code
xlBooks = xlApp->Workbooks;//no compiler warnings here

//open the Excel template - 30 C4691 compiler warnings for the next line of code
xlBook = xlApp->Workbooks->Open(templateFilename, Type::Missing, false, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing, Type::Missing);

xlSheets = xlBook->Worksheets;//no compiler warnings here

//set the active worksheet to sheet 3
xlSheet = (Excel::_Worksheet^)xlSheets->Item[3];//no compiler warnings here

//insert the picture - 15 C4691 compiler warnings for the next line of code
xlSheet->Shapes->AddPicture(picFilename, Core::MsoTriState::msoFalse, Core::MsoTriState::msoCTrue, 100, 200, 640, 480);

}

Мои ссылки:

    using namespace System::Reflection;
using namespace System::Runtime::InteropServices;
using namespace Microsoft::Office::Core;
using namespace Microsoft::Office::Interop::Excel;

Пример запроса компилятора:

предупреждение C4691: "Microsoft :: Office :: Core :: Assistant": тип ссылочных ожиданий ожидался в unreferenced assembly "office", тип, определенный в используемой системе перевода. Этот диагноз произошел при импорте типа "Microsoft: Office: Interop: Excel: ApplicationClass" из сборки "Microsoft.Office.Interop.Excel, Version = 12.0.0.0, culture = neutral, PublicKeyToken = 71e9bce111e9429c".

Описание MSDN этого предупреждения компилятора не было особенно полезно (для меня). Я не хочу просто игнорировать предупреждения (глупо) и не хочу "отключать" предупреждения, используя предупреждение pragma (sloppy).

Как я могу исключить предупреждение C4691? Все советы, комментарии, даже (конструктивная) критика с благодарностью оценены. благодаря

Теги:
excel

1 ответ

1
    xlApp = gcnew Excel::Application();

Здесь довольно много автоматов, которые не работают так хорошо в IDE C++. В отличие от VB.NET и С# IDE, языки, обычно используемые для написания кода взаимодействия с Интернетом.

Excel :: Приложение - это интерфейс, а не класс. И, конечно, никогда невозможно создать экземпляр интерфейса, это абстрактный тип. Компилятор C++/CLI, конечно, знает, что это невозможно и идет на охоту за классом, который реализует интерфейс. Он находит это, ища атрибут [CoClassAttribute] в типе интерфейса, он указывает на Excel :: ApplicationClass, синтетический класс.NET, сгенерированный импортером библиотеки типов. Примечательно, что анализатор IntelliSense не знает об этом трюке и ставит красные squiggles под утверждение. Вы избавитесь от него, сделав замену самостоятельно:

    xlApp = gcnew Excel::ApplicationClass();

Перейти к предупреждениям C4691. Библиотека типов Excel использует другую библиотеку типов, которая содержит общие объявления типа Office. Вы, очевидно, уже поняли это и правильно добавили ссылку на MSO.DLL, получив типы в пространстве имен Microsoft :: Office :: Core. Но имя сопоставленного имени пространства имен, имя библиотеки типов на самом деле является "Office", а не "Microsoft.Office.Core".

Поэтому компилятор C++/CLI замечает расхождение, ApplicationClass ссылается на интерфейс с именем Assistant в библиотеке типов Office, поэтому он ожидает, что будет доступна сборка с именем "Office". Обычно это имя библиотеки типов сопоставляется с именем сборки. Другими словами, он не знает, что имя пространства имен было отображено. И он не знал, что не сделал этого картографирования. Это было сделано с помощью ключа реестра.

Это предупреждение, а не ошибка, потому что в конце концов оно действительно получается правильно, оно правильно отображает его на одну из доступных ссылок на сборку. Тот, который вы ожидаете использовать, Microsoft.Office.Core. То, что это произошло правильно, является небольшим количеством азартных игр, технически было бы возможно забыть добавить ссылку на MSO.DLL и иметь другой тип взаимодействия с именем "Помощник". Boomshakalaka, если вы проигнорируете предупреждение и используете интерфейс.

Итак, продолжайте и установите лазер на оглушение:

    #pragma warning(disable:4691)
    using namespace Microsoft::Office;
    using namespace Microsoft::Office::Interop;

Я изменил операторы using, те, которые вы указали, были неправильными и не разрешили использовать "Excel :: Приложение" и "Core :: MsoTriState", еще один полезный источник ошибок компиляции.

  • 0
    ХОРОШО. Ради целесообразности я включил лазер. C4691 ушел. Кстати, я забыл включить следующие строки кода в оригинальный вопрос:

Ещё вопросы

Сообщество Overcoder
Наверх
Меню