OLEによる関数呼出し時の引数の調べ方について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
hage

OLEによる関数呼出し時の引数の調べ方について

#1

投稿記事 by hage » 1年前

OLEでのプログラム間通信で任意のEXCELシートを指定したプリンターへ出力するプログラムを作成していますがうまくいきません。
対象となるメソッドはEXCELの"PrintOut"メソッドだとは思うのですが、Invokeで実行する際引数のActivePrinterにプリンタ名を引き渡しているのですがエラーとなり実行されません。
MFC等使わずに直接IDispatchを取得し、GetIDsOfNamesで関数を取得、Invokeで実行してます。
単体でPrintOutを呼び出すと成功するのですが、これだと通常使うプリンターへ出力されてしまう為プリンターを任意に指定することが出来ません。

なんとかPrintOutへ出力したいプリンターを渡したいのですが、どのように調べるのが正しいのでしょうか?

アバター
へにっくす
記事: 628
登録日時: 6年前
住所: 東京都

Re: OLEによる関数呼出し時の引数の調べ方について

#2

投稿記事 by へにっくす » 1年前

ソースがない。こちらで確認できないのであてずっぽうですが。

以下のページは参考になりますか? プリンター指定するとき、単に名前を指定するだけではダメとか。・・・
OLEでExcelのActivePrinterを変更する
written by へにっくす

hage

Re: OLEによる関数呼出し時の引数の調べ方について

#3

投稿記事 by hage » 1年前

返信有難う御座います

ソースについてですが、
HRESULT OLEMethod(int nType, VARIANT *pvResult,
IDispatch *pDisp,LPOLESTR ptName, int cArgs...)
{
if(!pDisp) return E_FAIL;

va_list marker;
va_start(marker, cArgs);

DISPPARAMS dp = { NULL, NULL, 0, 0 };
DISPID dispidNamed = DISPID_PROPERTYPUT;
DISPID dispID;
char szName[200];

// Convert down to ANSI
WideCharToMultiByte(CP_ACP, 0, ptName, -1, szName, 256, NULL, NULL);

// Get DISPID for name passed...
HRESULT hr= pDisp->GetIDsOfNames(IID_NULL, &ptName, 1,
LOCALE_USER_DEFAULT, &dispID);
if(FAILED(hr)) {
return hr;
}
// Allocate memory for arguments...
VARIANT *pArgs = new VARIANT[cArgs+1];
// Extract arguments...
for(int i=0; i<cArgs; i++) {
pArgs = va_arg(marker, VARIANT);
}

// Build DISPPARAMS
dp.cArgs = cArgs;
dp.rgvarg = pArgs;

// Handle special-case for property-puts!
if(nType & DISPATCH_PROPERTYPUT) {
dp.cNamedArgs = 1;
dp.rgdispidNamedArgs = &dispidNamed;
}

// Make the call!
hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
nType, &dp, pvResult, NULL, NULL);
if(FAILED(hr)) {
return hr;
}

// End variable-argument section...
va_end(marker);
delete [] pArgs;
return hr;
}
Invokeに関する部分はCodeProjectにある上記コードを少し修正(例外処理の追加のみです)して使っています。

EXCELのPrintOutメソッドですが、以下のような引数ではないのかと想定しています。
https://msdn.microsoft.com/ja-jp/librar ... ntout.aspx
セルの書式を設定したり、シートを名前を付けて保存等のメソッドは上手くいくのですが、何故かPrintOutメソッドのみエラーになります。

そこでもしや引き数が異なるのではないのかと思い、OLEメソッドの関数の調べ方と引数について質問させて頂きました。
現状はPrintOutメソッド呼び出し前にGetDefaultPrinterとSetDefaultPrinterのAPIを利用してとりあえずはプリンタを切り替えていますが、なんか気持ちが悪い気がしています。

教えて頂いたサイトを参考に、ActivePrinterメソッド→PrintOutメソッドとしてみようと思います。

Bull
記事: 119
登録日時: 4年前

Re: OLEによる関数呼出し時の引数の調べ方について

#4

投稿記事 by Bull » 1年前

普段 VC で#importを使用するプログラムしか作ってないので、状況が違うのですが、
メソッドのパラメーターはVBAのヘルプやVCが#importするときに作ったヘッダーを参考にしています。
VBAは微妙に違うものがあるし、ヘッダーは説明がないので、名前から連想して最終的には、
試行錯誤でプログラミングしてます。
もし、VCをお使いならば、一度#importを使用したプログラムをコンパイルして、
ヘッダーファイルだけでも作っておくといいかもしれません。

PrintOutのパラメーターは全部で、9個みたいです。そのうち5番目がプリンター名です。
パラメーターの省略はできないようなので、すべて指定する必要があります。


以前 Microsoft のサイトにあったソースに適当に追加してみたら、
こちらではうまくいっているようです。

コード:

	// PrintOut
	{
		VARIANT printer;
		printer.vt = VT_BSTR;
		printer.bstrVal = ::SysAllocString(L"プリンター名");

		AutoWrap(DISPATCH_METHOD, NULL, pXlSheet, L"PrintOut", 9, vtMissing, vtMissing, vtMissing, vtMissing, printer, vtMissing, vtMissing, vtMissing, vtMissing);

		VariantClear(&printer);
	}

hage

Re: OLEによる関数呼出し時の引数の調べ方について

#5

投稿記事 by hage » 1年前

Bull様、返信ありがとうございます。

やはり試行錯誤していくしかないのですね・・・。
OLEに関しては日本語のドキュメントがWEB上にも(自分の探し方が悪いのもありますが)殆ど無くて途方に暮れることが多いです。

タイプライブラリを利用していしまうと環境依存が発生してしまう為、利用はしないルールになっています(泣。
ですが、ヘッダー作成用にTLIBをimportしたプロジェクトを1つ作ってみようと思います、ありがとうございます。

最後に記述頂いたソースで少し質問しても宜しいでしょうか。
AutoWrap(DISPATCH_METHOD, NULL, pXlSheet, L"PrintOut", 9, vtMissing, vtMissing, vtMissing, vtMissing, printer, vtMissing, vtMissing, vtMissing, vtMissing);
上記コードですが、
1)pXlSheetは"Worksheets"オブジェクトで宜しいでしょうか?(Worksheets、sheets、sheetとEXCELはやたらにオブジェクトがありますので・・・)
2)vtMissingはVariantInitにより初期化したVARIANT型変数という認識で宜しいでしょうか?

よろしくお願いします。

Bull
記事: 119
登録日時: 4年前

Re: OLEによる関数呼出し時の引数の調べ方について

#6

投稿記事 by Bull » 1年前

hage さんが書きました:最後に記述頂いたソースで少し質問しても宜しいでしょうか。
AutoWrap(DISPATCH_METHOD, NULL, pXlSheet, L"PrintOut", 9, vtMissing, vtMissing, vtMissing, vtMissing, printer, vtMissing, vtMissing, vtMissing, vtMissing);
上記コードですが、
1)pXlSheetは"Worksheets"オブジェクトで宜しいでしょうか?(Worksheets、sheets、sheetとEXCELはやたらにオブジェクトがありますので・・・)
2)vtMissingはVariantInitにより初期化したVARIANT型変数という認識で宜しいでしょうか?
1) 正確にはよくわかりませんが、WorksheetsではなくWorksheetだと思います。
 サンプルプログラムでは "AcriveSheet" を取得して使っています。
2) vtMissingは

コード:

		VARIANT missing;
		missing.vt = VT_ERROR;
		missing.llVal = -2147352572;
 でいいと思います。

hage

Re: OLEによる関数呼出し時の引数の調べ方について

#7

投稿記事 by hage » 1年前

Bullさん

ありがとうございます。
上手くいきました。

原因ですが、自分が省略用の引数をVT_EMPTYと勘違いしてた事でした。
指示された通りにVT_ERRORにした所うまくいきました。

ありがとうございます。
大変助かりました。

返信

“C言語何でも質問掲示板” へ戻る