質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

4170閲覧

visual studioにおいてexcelのマクロを実行したい

muton

総合スコア31

VBA

VBAはオブジェクト指向プログラミング言語のひとつで、マクロを作成によりExcelなどのOffice業務を自動化することができます。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/01/22 11:21

編集2019/01/24 05:21

Visualstudio2017でexcelのマクロを実行したいしたいと考えています.
言語はVC++です
検索しても資料があまりなく,とっかかりが掴めない状況です.
なにかアドバイスを頂けると大変嬉しいです.
宜しくお願い致します.

開発環境
Windows8.1 Pro (64bit)
Excel 2016 (64bit)
Visual Studio 2017

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

iwanote

2019/01/22 11:51

マクロを実行とは既に作成済みのマクロの事ですか?C++でマクロと同等の事を行う事ですか?
muton

2019/01/22 12:04

質問ありがとうございます。 作成済みのマクロをc++において、実行したいという意味です。 分かりにくい説明で申し訳ございません。 よろしくお願い致します。
guest

回答3

0

ベストアンサー

マネージドなプログラムからのエクセルの操作はすでに回答があるので、アンマネージドなプログラムからエクセルを操作する方法です。

大雑把に言って三つほどあるようです。

  1. #import を使用してタイプライブラリーを読み込む方法。
  2. MFC のウィザードでヘッダーを作成する方法。
  3. #import も MFC も使用しない方法。

私自身は、主に 1 の方法でプログラムを作成しています。2 の方法もたまに使用しますが、3 はサンプルプログラムぐらいしか動かした事がありません。
以下のプログラムは 1 の方法で作ってあります。
"Book2.xlsm" に "Test" というマクロが定義されています。
引数が二つあり、それぞれをセルに書き込むだけです。
引数は 0 ~ 30 まで指定できるようです。

開発環境
Windows7 Pro (32bit)
Excel 2013 (32bit)
Visual Studio 2015

C++

1#define WIN32_LEAN_AND_MEAN 2#include <windows.h> 3#include <iostream> 4#include <comutil.h> 5 6//Excelを操作するためのタイプライブラリを読みこむ (Excel2013(32bit)) 7#import "C:\Program Files\Microsoft Office 15\root\vfs\ProgramFilesCommonX86\Microsoft Shared\OFFICE15\MSO.DLL" no_auto_exclude auto_rename 8#import "C:\Program Files\Microsoft Office 15\root\vfs\ProgramFilesCommonX86\Microsoft Shared\VBA\VBA6\Vbe6ext.olb" 9#import "C:\Program Files\Microsoft Office 15\root\office15\EXCEL.EXE" no_auto_exclude auto_search auto_rename dual_interfaces 10using namespace Excel; //名前空間の定義 11 12struct StartOle { 13 StartOle() { CoInitialize(NULL); } //COMを初期化 14 ~StartOle() { CoUninitialize(); } //COMを閉じる 15} _inst_StartOle; 16 17int main(void) 18{ 19 _ApplicationPtr pXL; 20 21 //--------------------------------------------------------- 22 //Excelの起動 23 pXL.CreateInstance(L"Excel.Application"); 24 pXL->Visible[0] = TRUE; // ウィンドウを表示 25 pXL->DisplayAlerts[0] = FALSE; //アラームを出さないように 26 27 //--------------------------------------------------------- 28 //WorkBookを開く 29 WorkbooksPtr pBooks = pXL->Workbooks; 30 _WorkbookPtr pBook = pBooks->Open("Book2.xlsm"); //マクロを含むブックを開く 31 32 //--------------------------------------------------------- 33 //マクロ名と引数を格納 34 variant_t macro = (_bstr_t)"Book2.xlsm!Test"; //実行マクロ名 35 variant_t arg1 = (_bstr_t)"テストです"; //引数1 36 variant_t arg2 = (_bstr_t)"二つ目の引数"; //引数2 37 38 //マクロを実行 39 pXL->Run(macro, arg1, arg2); 40 ::Sleep(5 * 1000); // 動作確認の為一時停止 41 42 //ウィンドウを最小化 43 pXL->WindowState[0] = xlMinimized; 44 45 std::cout << "マクロの実行を確認するために一時停止:"; 46 char buff[256]; 47 std::cin.getline(buff, sizeof buff); 48 49 //--------------------------------------------------------- 50 //ワークブックを閉じる 51 pBook->Close(); 52 pBook.Release(); // COMオブジェクトを解放 53 pBooks.Release(); // COMオブジェクトを解放 54 55 //Excelを終了する 56 pXL->Quit(); 57 pXL.Release(); // COMオブジェクトを解放 58}

それほど詳しいわけではありませんが、質問があれば答えられる範囲で回答いたします。

投稿2019/01/23 01:42

Bull

総合スコア986

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

muton

2019/01/23 11:59 編集

回答ありがとうございます. 頂いたコードを参考にまず,abc.xlsmというブックを開くことを目的にコードを少し変更しました. するとビルドは通るのですが, .exeファイルを実行すると動作が停止してしまいます. 何か原因は考えられますでしょうか,宜しくお願い致します. ``` #define WIN64_LEAN_AND_MEAN #include <windows.h> #include <iostream> #include <comutil.h> //Excelを操作するためのタイプライブラリを読みこむ (Excel2016(64bit)) #import "C:\Program Files\Common Files\microsoft shared\OFFICE16\MSO.DLL" no_auto_exclude auto_rename #import "C:\Program Files (x86)\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB" #import "C:\Program Files\Microsoft Office\office16\EXCEL.EXE" no_auto_exclude auto_search auto_rename dual_interfaces using namespace Excel; //名前空間の定義 struct StartOle { StartOle() { CoInitialize(NULL); } //COMを初期化 ~StartOle() { CoUninitialize(); } //COMを閉じる } _inst_StartOle; int main(void) { _ApplicationPtr pXL; //--------------------------------------------------------- //Excelの起動 pXL.CreateInstance(L"Excel.Application"); pXL->Visible[0] = TRUE; // ウィンドウを表示 pXL->DisplayAlerts[0] = FALSE; //アラームを出さないように //--------------------------------------------------------- //WorkBookを開く WorkbooksPtr pBooks = pXL->Workbooks; _WorkbookPtr pBook = pBooks->Open("abc.xlsm"); //マクロを含むブックを開く } ```
Bull

2019/01/23 11:52

エクセルの Open でブック(ワークシート)を開くときファイル名を相対パスで指定した場合、基準となるフォルダーはエクセルの(バージョンにより名称は違うかもしれませんが)“規定のローカル ファイルの保存場所”になります。C++ プログラムのカレントフォルダーではありません。 ファイル名は絶対パスの方が無難かもしれません。
muton

2019/01/23 12:08 編集

何度も申し訳ございません.回答ありがとうございます. ``` _WorkbookPtr pBook = pBooks->Open("C:\Users\owner\source\repos\Project10\x64\Release\abc.xlsm"); //マクロを含むブックを開く ``` コードを上記の様に絶対パスで指定しましたが,同様に.exe実行時に動作が停止してしまいます.
Bull

2019/01/23 13:02

エクセルは起動できているのですよね? ブックのオープンでエラーになるのは余り考えられないですが。 これはソースから直接コピーしましたか? パスの区切りは '\' (円マーク・バックスラッシュ)が二つです。 もう一度、確認してみて下さい。 もし、ファイルを確認してもエラーになるようでしたら。 try-catch でエラーを確認することができます。 こんな感じです。 try { WorkbooksPtr pBooks = pXL->Workbooks; _WorkbookPtr pBook = pBooks->Open("xxxxxx.xlsm"); } catch (_com_error &e) { std::cerr << "\tCode = " << std::setw(8) << std::hex << e.Error() << '\n'; std::cerr << "\tCode meaning = " << e.ErrorMessage() << '\n'; _bstr_t bstrSource(e.Source()); _bstr_t bstrDescription(e.Description()); LPCSTR source = (LPCSTR)bstrSource; std::cerr << "\tSource = " << (source ? source : "(NULL)") << "\n"; LPCSTR descript = (LPCSTR)bstrDescription; std::cerr << "\tDescription = " << (descript ? descript : "(NULL)") << "\n"; } これを追加して、プログラムを実行してみて下さい。
muton

2019/01/24 05:30

回答ありがとうございます. エクセルの起動時に”.exeは動作を停止しました”と出てしまいます. ソースから直接コピーしていたので, パスの区切りを¥から'¥'に変更しましたが, 変化は見られませんでした. また,ビルドは通っているのですが,以下のエラーが500件ほど生じています.このことが停止の要因になっていると考えられますでしょうか. エラー E0102 列挙型の事前宣言は非標準です try-chatchの件ありがとうございます. 確認してみます.
Bull

2019/01/24 06:55

えっと、もしかしてエクセルの起動ができていないと言うことでしょうか? サンプルでは、エクセルを表示するようにしているので、起動すればウィンドウが確認できるはずです。 では、以下のプログラムはどうでしょうか? struct StartOle { StartOle() { CoInitialize(NULL); } //COMを初期化 ~StartOle() { CoUninitialize(); } //COMを閉じる } _inst_StartOle; int main(void) { char buff[256]; _ApplicationPtr pXL; //--------------------------------------------------------- //Excelの起動 HRESULT hr = pXL.CreateInstance(L"Excel.Application"); if SUCCEEDED(hr) { //エクセルの起動を確認 pXL->Visible[0] = TRUE; //ウィンドウを表示 std::cout << "エクセルの起動を確認するために一時停止:"; std::cin.getline(buff, sizeof buff); //--------------------------------------------------------- //Excelを終了する pXL->Quit(); pXL.Release(); // COMオブジェクトを解放 } else { std::cout << "エクセルを起動できません\n"; } std::cout << "プログラム終了:"; std::cin.getline(buff, sizeof buff); } エクセルを起動するだけのものです。 「エラー E0102 列挙型の事前宣言は非標準です」 これはインテリセンスのエラーなので、あまり気にしなくてもいいと思います。気になるようでしたら、オプションの "/permissive-" をはずせばいいです。
muton

2019/01/24 07:14

回答ありがとうございます. 頂いたコードをビルドしたところ,コマンドプロンプトに エクセルの起動を確認するために一時停止:" と表示されることを確認しました. 宜しくお願い致します.
muton

2019/01/24 09:27 編集

追記 絶対パスの書き方を以下の様に変更したところabc.xlsmを開くことができました. "C:/Users/owner/source/repos/Project10/x64/Release/abc.xlsm" なお,現在以下の様にしてabc.xlsm内のassembleというマクロを実行しようとしているのですが,停止してしまいます. 何か原因など分かりますでしょうか ```C++ int main(void) { char buff[256]; _ApplicationPtr pXL; //--------------------------------------------------------- //Excelの起動 HRESULT hr = pXL.CreateInstance(L"Excel.Application"); if SUCCEEDED(hr) { //エクセルの起動を確認 pXL->Visible[0] = TRUE; //ウィンドウを表示 std::cout << "エクセルの起動を確認するために一時停止:"; WorkbooksPtr pBooks = pXL->Workbooks; _WorkbookPtr pBook = pBooks->Open("C:/Users/owner/source/repos/Project10/x64/Release/abc.xlsm"); //マクロを含むブックを開く variant_t macro = (_bstr_t)"abc.xlsm!assemble"; //実行マクロ名 pXL->Run(macro); std::cin.getline(buff, sizeof buff); //--------------------------------------------------------- //Excelを終了する pXL.Release(); // COMオブジェクトを解放 } else { std::cout << "エクセルを起動できません\n"; } std::cout << "プログラム終了:"; std::cin.getline(buff, sizeof buff); ```
Bull

2019/01/24 09:50 編集

では、先ほどのプログラムで書いた try-catch を使用して、エラーの原因を表示させてみて下さい。 それと、デバッガーでエラーになる行を特定して下さい。 もし、マクロの実行でエラーになっているのであれば、原因はマクロ名の間違いまたは、引数の間違いであろうかと思います。
guest

0

突っ込まれても答えられないのはほぼ確実なので参考程度に。

セルアクセスに関して、昔作っておいたメモ(何か抜けているかもしれません)を起こしたものですが、参考になるでしょうか。Officeのインストールで、.net開発云々のオプションが必要だったと思います。

まずは、プロジェクトの参照設定にMicrosoft.Office.Interop.Excelを追加。

C++

1using namespace Microsoft::Office::Interop; 2 3// 新しいブックを作成 4Excel::Workbook^ wbook = oXls->Workbooks->Add(Type::Missing); 5Excel::Worksheet^ wsheet = (Excel::Worksheet^)wbook->Worksheets[1]; 6 7//表見出し 8wsheet->Range["A1",Type::Missing]->Value2 = "y=2^x"; 9wsheet->Range["A2",Type::Missing]->Value2 = "x"; 10wsheet->Range["B2",Type::Missing]->Value2 = "y"; 11 12wbook->Close() 13oXls->Quit();

というわけで、C++はやる気が無い全く勉強しておらず、環境もないので確認出来ませんが、ブックを開いてマクロを実行だけなら、こんな感じで行けるんじゃないでしょうか。

C++

1Excel::Workbook^ wbook = oXls->Workbooks->Open(<実行マクロのブック>); 2wbook->Run(<マクロ名>);

投稿2019/01/22 14:55

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

muton

2019/01/24 06:50

回答ありがとうございます. VC++ではプロジェクトの参照設定において"アセンブリ"タブがなく,Microsoft.Office.Interop.Excelを追加することができないのですが, どうすれば良いでしょうか. 宜しくお願い致します.
MMashiro

2019/01/24 09:35

lazybones2000さんが提示した内容はC++/CLIという.NET基盤上で動く特殊なC++なので今回質問者様の内容とは合致しないと思います。 逆にC++/CLIでもいいなら上記の方法を取ることができます(それならC#でいいよねってなりますが…)
退会済みユーザー

退会済みユーザー

2019/01/24 12:47 編集

解決したようでよかったです。 MMashioさんにコメントいただいたように、C++/CLIでプロジェクトであれば、参照を追加できます。 もっとも、これもコメントいただいているように、作成されているコードでの目的がExcelの操作だけならば、この方法を使ってまでわざわざC++を使うメリットはないと思います。 こんなのもあるんだ、くらいに受け止めてもらった方がよいですね。 なお、たとえCLIプロジェクトであっても、先日貼付したコードは、ちょっとプログラムを齧っていればすぐ気がつくようなレベルの記載漏れがあることに気がついてしまいました。そのほかも怪しいところがあると思います。もともと(今も)C++の理解が薄いまま、こんな感じでやれるとメモしておいたものだったので、その辺お察し頂ければと思います。
guest

0

言語が、vb.netですけど、ここ参考にならないでしょうか?
リンク内容
これを、Cに置き換えて、いろいろとやってみるってのはどうでしょうか?

投稿2019/01/22 13:07

akirafudo6

総合スコア341

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問