C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[2]: EXCELのシートコピーとシート名の変更方法教えてください。


(過去ログ 115 を表示中)

[トピック内 6 記事 (1 - 6 表示)]  << 0 >>

■67743 / inTopicNo.1)  EXCELのシートコピーとシート名の変更方法教えてください。
  
□投稿者/ 裕猫 (64回)-(2013/08/30(Fri) 11:44:19)

分類:[C#] 

開発環境 Windows7Pro VisualStudio2008 C#
実機windowsXP SP3 EXCEL2000

 遅延バインディングを使って2013TEST.xlsを開きsheet1をコピーしてsheet名を”X1"としたいのですが、コピーの仕方と名前の変更方法がどうしてもできません。
新規シートの追加
        public static void EX_AddSheet()
        {
            sheets = book.GetType().InvokeMember("sheets", BindingFlags.GetProperty, null, book, null);
            parameters = new object[4];
            for (int CT1 = 0; CT1 < 4; CT1++) { parameters[CT1] = Type.Missing; }
            sheet = sheets.GetType().InvokeMember("Add", BindingFlags.GetProperty, null, sheets, parameters);
        }
を元に
        public static void EX_CopySheet()
        {
            sheets = book.GetType().InvokeMember("sheets", BindingFlags.GetProperty, null, book, null);
            parameters = new object[4];
            for (int CT1 = 0; CT1 < 4; CT1++) { parameters[CT1] = Type.Missing; }
            sheet = sheets.GetType().InvokeMember("Copy", BindingFlags.GetProperty, null, sheets, parameters);
        }
とやってみましたが parameters の設定が悪いのでしょうか sheet = sheets.GetType().InvokeMember("Copy", BindingFlags.GetProperty, null, sheets, parameters); で
TargetInvocationExeptionはハンドルされませんでした。 呼び出しのターゲットが例外をスローしました。
というエラーで止まってしまいます。調べたのですが、どういうパラメータを渡せばいいのかを書いてある所にたどりつけませんでした。どう書いたらよいのか教えてください。

もう一点
// シート名を取得する
	object sheetName = sheet.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, sheet, null);
でシート名は取得できるのですがシート名を設定する方法がわかりません。
                parameters = new object[1];
                parameters[0] = sheet名;
	sheet.GetType().InvokeMember( "Value", BindingFlags.SetProperty, null, sheet, Parameters );
かな?とやってみましたが
COMExceptionはハンドルされませんでした。
名前が不明です。(HRESULTからの例外:0X80020006(DISP_E_UNKNOWNNAME))
というエラーになってしまいます。以上2点どのようにしたらよいか教えてください。よろしくお願いいたします。

引用返信 編集キー/
■67744 / inTopicNo.2)  Re[1]: EXCELのシートコピーとシート名の変更方法教えてください。
□投稿者/ 魔界の仮面弁士 (318回)-(2013/08/30(Fri) 12:17:53)
2013/08/30(Fri) 12:39:55 編集(投稿者)

No67743 (裕猫 さん) に返信
> 開発環境 Windows7Pro VisualStudio2008 C#
> 実機windowsXP SP3 EXCEL2000
2010 以降だと、遅延バインディングも楽になるのですけれどね…。

それはさておき、開発環境の Excel バージョンは何でしょう。
Excel 未導入環境での開発でしょうか?


> parameters = new object[4];
> for (int CT1 = 0; CT1 < 4; CT1++) { parameters[CT1] = Type.Missing; }
> sheet = sheets.GetType().InvokeMember("Copy", BindingFlags.GetProperty, null, sheets, parameters);
Copy のパラメータ数は 2 個です。
そこに 4 個の引数を渡そうとしているためにエラーになっています。
また、Sheets.Copy メソッド(≠プロパティ)は戻り値を返しませんで、
sheet 変数で受け取るべきではありません。

一応、受け取っても動作はしますが、値にあまり意味はありませんし
それを sheet という変数名で受け取るのは、誤解を招きます。
(戻り値は多分、bool か Void か null のいずれかになると思います)


> どういうパラメータを渡せばいいのかを書いてある所にたどりつけませんでした。
(1) Excel を起動して、[ALT]+[F11]キーで VBA エディタを起動します。
(2) [F2]キーで、オブジェクトブラウザを起動します。
(3) ライブラリ名「Excel」を選択し、検索ボックスに「Copy」と入力して双眼鏡アイコンを押します。
(4) 結果一覧から、Sheets クラスの Copy メソッドを調べます。

このようにすると、Sheets.Copy メソッドの定義が
 Sub Copy([Before], [After])
であることが分かるかと思います。

ちなみに、Sheets.Add メソッドの定義は
 Function Add([Before], [After], [Count], [Type]) As Object
です。


> sheets = book.GetType().InvokeMember("sheets", BindingFlags.GetProperty, null, book, null);
本来のプロパティ名は "Sheets" です。"sheets" では無く。


> parameters = new object[4];
> for (int CT1 = 0; CT1 < 4; CT1++) { parameters[CT1] = Type.Missing; }
「parameters = Enumerable.Repeat(Type.Missing, 4).ToArray();」という書き方もあります。
引用返信 編集キー/
■67746 / inTopicNo.3)  Re[1]: EXCELのシートコピーとシート名の変更方法教えてください。
□投稿者/ shu (373回)-(2013/08/30(Fri) 12:23:23)
2013/08/31(Sat) 10:28:09 編集(投稿者)

No67743 (裕猫 さん) に返信

シートのコピーはWorkSheetsクラスではなく
WorkSheetクラスのメソッド
Copy(Before,After)
で行います。プロパティではないので
BindingFlags.GetProperty
ではなく
BindingFlags.InvokeMethod
を使用します。


#67749 魔界の仮面弁士さんの指摘によりGetPropertyに修正
引用返信 編集キー/
■67747 / inTopicNo.4)  Re[1]: EXCELのシートコピーとシート名の変更方法教えてください。
□投稿者/ 魔界の仮面弁士 (319回)-(2013/08/30(Fri) 12:31:10)
No67743 (裕猫 さん) に返信
> object sheetName = sheet.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, sheet, null);
これは、Name プロパティの getter を呼び出しています。

> sheet.GetType().InvokeMember( "Value", BindingFlags.SetProperty, null, sheet, Parameters );
これは、Value プロパティの setter を呼び出しています。
本来呼び出すべきは、Name プロパティの setter ですよね?

> 名前が不明です。(HRESULTからの例外:0X80020006(DISP_E_UNKNOWNNAME))
Worksheet オブジェクトは、Value プロパティを持っていないからです。
引用返信 編集キー/
■67749 / inTopicNo.5)  Re[2]: EXCELのシートコピーとシート名の変更方法教えてください。
□投稿者/ 魔界の仮面弁士 (320回)-(2013/08/30(Fri) 13:21:20)
No67746 (shu さん) に返信
> シートのコピーはWorkSheetsクラスではなく
> WorkSheetクラスのメソッド
>   Copy(Before,After)
> で行います。

その通りですね。

ですが一応、Sheets/Worksheets(≠WorkSheets) の
Copy メソッドでも、複製は可能だったりします。
VBA 的にはこんな感じです。

 Set objSheets = ThisWorkbook.WorkSheets(Array("Sheet1"))
 Call objSheets.Copy(ThisWorkbook.Sheets("Sheet1"))

上記は本来、複数のシートを一度にコピーする場合などに
使う手法なので、今回のようなケースでは Sheets.Copy ではなく、
shu さんが紹介された Sheet.Copy の方が望ましいですけれどね。


> プロパティではないので
> BindingFlags.SetProperty
> ではなく
> BindingFlags.InvokeMethod
> を使用します。

裕猫さんが書かれていたのは GetProperty でしたね。SetProperty ではなく。

メソッドの呼び出しに InvokeMethod を使うべきというのはその通りなのですが、
実際には GetProperty でも呼び出せてしまったりします。
もちろん、InvokeMethod の方が適切ですけれども。


修正案。下記では、コピーした新シートを一番左側に配置しています。

public static void EX_CopySheet()
{
    sheets = book.GetType().InvokeMember("Sheets", BindingFlags.GetProperty, null, book, null);
    object target = book.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, new object[] { "sheet1" });
    object firstSheet = book.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, new object[] { 1 });
    parameters = new object[2] { firstSheet, Type.Missing };
    target.GetType().InvokeMember("Copy", BindingFlags.InvokeMethod, null, target, parameters);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(target);
    System.Runtime.InteropServices.Marshal.ReleaseComObject(firstSheet);

    sheet = book.GetType().InvokeMember("Item", BindingFlags.GetProperty, null, sheets, new object[] { 1 });
    string oldSheetName = (string)sheet.GetType().InvokeMember("Name", BindingFlags.GetProperty, null, sheet, null);
    parameters = new object[] { "X1" };
    sheet.GetType().InvokeMember("Name", BindingFlags.SetProperty, null, sheet, parameters);

    Console.WriteLine("「{0}」を「{1}」に改名", oldSheetName, "X1");
}

引用返信 編集キー/
■67750 / inTopicNo.6)  Re[2]: EXCELのシートコピーとシート名の変更方法教えてください。
□投稿者/ 裕猫 (65回)-(2013/08/30(Fri) 14:14:38)
No67747 (魔界の仮面弁士 さん) に返信
いろいろご教授いただきありがとうございました。Excelを使ってパラメータを調べればいいこと初めて知りました。みんなどうやってパラメータに入れる内容を調べてるのだろうと疑問に思ってました。ネットで調べてもこうという内容書かれてなくて困っていました。
コピーも targetについてやっていくんですね。勉強になりました。
名前変更はセルに文字を書き込むときにValue使っていたのでValueでやるのだろうと考えてました。Nameかなとも考えたんですがやっぱValueだろうという先入観念でやってしまいました。
おかげさまで無事コピーと名前変更できるようになりました。 ありがとうございました。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -