none
VS2010 C++MFCで Word文書を作成する方法 RRS feed

  • 質問

  • VisualStudio2010 C++MFCで開発しております。

    この度急に、DBの中の文字をWordファイルに書き出して保存するプログラムを作る事になりました。

    Net上にもあまり情報がないので、基本的な使い方やサンプルなど入手できるサイトがないかのご質問です。

    使い方例や サンプルプログラムがありましたら是非教えてください。

    よろしくお願い申し上げます。

    2016年11月22日 13:18

回答

  • Word の VBA での書き方を知る、あるいは他言語での書き方を知ってそれを C++ の COM の使い方としてどのように書くかを探ることになりそうです。
    ただ、VBA で触ることを前提に設計されていることもあり、オプション引数があるメソッドは C++ からは非常に呼びづらいなど、不遇な状況にあるかもしれません。(引数を省略できなくて十数個指定がいるなど)

    Word の VBA や他の言語のコンテンツを含めて探してみて、移植が大変な部分に絞って質問されると、回答を得やすいかと思います。

    中身は見ていませんが、タイトルからはそれらしいものも参考までに貼っておきます。
    https://code.msdn.microsoft.com/office/CppAutomateWord-28938be1

    • 回答としてマーク AppKey 2016年11月24日 2:16
    2016年11月23日 10:40
    モデレータ
  • このサンプルだと、

    Word::_ApplicationPtr、CComPtr<T>、COleVariant の3種類のCOMサポートライブラリを利用しています。

    最初のものは、 #import <Word.tlb>などで取り込んだインターフェースを使って VC の コンパイラ COM サポート の _com_ptr_t を使っていると思います。

    2番目の、CComPtr<T> は、ATL のCOMスマートポインタです。

    Word::_ApplicationPtr を使うのなら、ほかのCOMオブジェクトも VCのCOMスマートポインタ を利用することをお勧めします。

    そうすれば、Documentsのところも Word::DocumentsPtr になり、妙なエラーなどに悩まされることもなくなると思います。

    3つ目の、COleVariant は、MFCのCOMサポートクラスです。この場合は、_com_ptr_t で統一したほうが効率がいいので、_variant_t を使うと

    _variant_t variant( L"サンプル.docx" );
    wordDoc->Save( variant );
    

    のように、すっきりと書けます。

    サンプルコードだと、Detach した variant オブジェクトが解放されず、メモリリークした状態になります。

    このあたりは、どれを使うにせよ、COMスマートポインタを統一利用することでローデータを直接扱うことなく操作できるようになります。

    それと、MFC のCOMサポートクラスを利用する場合、CoInitialize() ではなく、AfxOleInit() を使わないとMFCの内部初期化が正しく行われない場合があり、よくわからない不具合(発生頻度や条件などがやるたびに異なる)が発生することがあります。

    また、MFCでもオートメーション(Wordの外部操作などが該当)は利用可能ですが、実装が古めかしいという部分もありますが、リファレンスがかなり乏しい状況になりつつあるのでお勧めしません。

    オートメーションやカスタムCOMの利用は、コンパイラCOMサポートかATLのどちらかの利用をお勧めします。

    MFCの場合これらは原則直接インターフェースを操作する形になり、解放し忘れなどが発生しやすいのでお勧めしません。


    とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx

    • 回答としてマーク AppKey 2016年11月24日 2:16
    2016年11月24日 2:12

すべての返信

  • 途中サンプルです。

    Word::_ApplicationPtr  wordApp;
    CComPtr<Word::_Document> wordDoc;
    CComPtr<Documents> docs;
    
    
    CoInitialize(NULL);
    wordApp.CreateInstance(L"Word.Application");
    wordApp->get_Documents(&docs);
    COleVariant objVariant( "テンプレート.dotx" );
    VARIANT variant = objVariant.Detach();
    // Create Document and attach.
    wordDoc = docs->Add(&variant);
    
    
    spPara = document->Paragraphs;
    pPara = spPara->Add();
    
    いろいろ文字を書き出す
    
    
    COleVariant objVariant( "サンプル.docx" );
    VARIANT variant = objVariant.Detach();
    wordDoc->SaveAs(&variant);	
    wordDoc->Close();
    CoUninitialize();

    この手のプログラム方法や、メソッドの説明を探しています。

    この分野は初めてなのでどこを見れば良いかさっぱり判りません。

    みなさまよろしくお願い致します。

    2016年11月22日 13:51
  • Word の VBA での書き方を知る、あるいは他言語での書き方を知ってそれを C++ の COM の使い方としてどのように書くかを探ることになりそうです。
    ただ、VBA で触ることを前提に設計されていることもあり、オプション引数があるメソッドは C++ からは非常に呼びづらいなど、不遇な状況にあるかもしれません。(引数を省略できなくて十数個指定がいるなど)

    Word の VBA や他の言語のコンテンツを含めて探してみて、移植が大変な部分に絞って質問されると、回答を得やすいかと思います。

    中身は見ていませんが、タイトルからはそれらしいものも参考までに貼っておきます。
    https://code.msdn.microsoft.com/office/CppAutomateWord-28938be1

    • 回答としてマーク AppKey 2016年11月24日 2:16
    2016年11月23日 10:40
    モデレータ
  • Word の VBA での書き方を知る、あるいは他言語での書き方を知ってそれを C++ の COM の使い方としてどのように書くかを探ることになりそうです。
    ただ、VBA で触ることを前提に設計されていることもあり、オプション引数があるメソッドは C++ からは非常に呼びづらいなど、不遇な状況にあるかもしれません。(引数を省略できなくて十数個指定がいるなど)

    Word の VBA や他の言語のコンテンツを含めて探してみて、移植が大変な部分に絞って質問されると、回答を得やすいかと思います。

    中身は見ていませんが、タイトルからはそれらしいものも参考までに貼っておきます。
    https://code.msdn.microsoft.com/office/CppAutomateWord-28938be1

    ご返答ありがとうございます。

    自分はMFC C++ のグラフィックス中心のプログラマで、この手(OfficeのAPI)を触るのが初めてでしたのでドキュメントが何処にあるのかもさっぱり判らない状況でした。

    1日やって、Word文書が保存できてAPIも少しだけいじれるようになりました。
    また行き詰ったらご指導よろしくお願いします。


    2016年11月23日 15:30
  • このサンプルだと、

    Word::_ApplicationPtr、CComPtr<T>、COleVariant の3種類のCOMサポートライブラリを利用しています。

    最初のものは、 #import <Word.tlb>などで取り込んだインターフェースを使って VC の コンパイラ COM サポート の _com_ptr_t を使っていると思います。

    2番目の、CComPtr<T> は、ATL のCOMスマートポインタです。

    Word::_ApplicationPtr を使うのなら、ほかのCOMオブジェクトも VCのCOMスマートポインタ を利用することをお勧めします。

    そうすれば、Documentsのところも Word::DocumentsPtr になり、妙なエラーなどに悩まされることもなくなると思います。

    3つ目の、COleVariant は、MFCのCOMサポートクラスです。この場合は、_com_ptr_t で統一したほうが効率がいいので、_variant_t を使うと

    _variant_t variant( L"サンプル.docx" );
    wordDoc->Save( variant );
    

    のように、すっきりと書けます。

    サンプルコードだと、Detach した variant オブジェクトが解放されず、メモリリークした状態になります。

    このあたりは、どれを使うにせよ、COMスマートポインタを統一利用することでローデータを直接扱うことなく操作できるようになります。

    それと、MFC のCOMサポートクラスを利用する場合、CoInitialize() ではなく、AfxOleInit() を使わないとMFCの内部初期化が正しく行われない場合があり、よくわからない不具合(発生頻度や条件などがやるたびに異なる)が発生することがあります。

    また、MFCでもオートメーション(Wordの外部操作などが該当)は利用可能ですが、実装が古めかしいという部分もありますが、リファレンスがかなり乏しい状況になりつつあるのでお勧めしません。

    オートメーションやカスタムCOMの利用は、コンパイラCOMサポートかATLのどちらかの利用をお勧めします。

    MFCの場合これらは原則直接インターフェースを操作する形になり、解放し忘れなどが発生しやすいのでお勧めしません。


    とっちゃん@わんくま同盟, Visual Studio and Development Technologies http://blogs.wankuma.com/tocchann/default.aspx

    • 回答としてマーク AppKey 2016年11月24日 2:16
    2016年11月24日 2:12
  • とっちゃん様

    貴重な情報 たいへんありがとうございました。

    判らない言葉もありますが、一づつ調べて理解して行きたいと思います。

    2016年11月24日 2:16