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

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

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

8023閲覧

C#のExcel操作で、ブック間のシートのコピーがしたい

airu_chat

総合スコア8

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2018/06/25 10:52

編集2018/06/25 11:17

前提・実現したいこと

C#のExcel操作で、ブック間のシートのコピーがしたいです。
例えば、「ブックA」のsheet1を「ブックB」にコピーしたいです。

発生している問題・エラーメッセージ

System.Runtime.InteropServices.COMException: HRESULT からの例外です

該当のソースコード

ExcelTest excel1 = new ExcelTest("excel1ファイルのパス");
ExcelTest excel2 = new ExcelTest("excel2ファイルのパス");

//コピー元とコピー先のエクセルを開く
excel1.Open();
excel2.Open();

var sheet1 = excel1.Sheets("コピーしたいシート")
var sheet2 = excel2.Sheets("コピー先")

sheet1.Copy(Type.Missing, sheet2); //ここでエラー

補足情報

コピー先を同ブックに指定するとエラーは出ません。
そもそもWorkBookクラスのCopyメソッドではブック間ではCopyできないのでしょうか。

もし方法がありましたらご教授願います。

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

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

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

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

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

imihito

2018/06/25 11:00

書き方、エラーメッセージからExcelをCOM操作していると思われますが、`excel1`、`excel2`は具体的には何型ですか?
airu_chat

2018/06/25 11:22

はい、COM操作で苦戦しております。excel1とexcel2の型は、自作のExcelWorkクラスの型になります。
imihito

2018/06/25 11:25

自作クラス間でExcelのインスタンスは共有していますか?それぞれ新規にインスタンスしていますか?
airu_chat

2018/06/25 11:37

共有はしておりません。それぞれ新規にインスタンスを生成しております。
guest

回答3

0

ベストアンサー

Excelはマルチインスタンス可能なアプリケーションとなります。

参考:Office のプロセス インスタンス制御について – Japan Office Developer Support Blog

そして、オブジェクトを引数とするメソッドに別のExcelインスタンス由来のオブジェクトを渡すと原則失敗します(私の経験上)。

今回の場合、sheet1sheet2で属しているExcelのインスタンスが異なるのが原因となります(前回の質問も原因は同じです)。

対処としては、自作クラスの処理を変更して、自作クラス間でインスタンスを共有するように変更するのが正攻法となります。

その場しのぎで良ければ以下のコードでコピーできるはずです。

cs

1// using Excel = Microsoft.Office.Interop.Excel; 2 3ExcelTest excel2 = new ExcelTest("excel2ファイルのパス"); 4 5excel2.Open(); 6var sheet2 = excel2.Sheets("コピー先") 7 8Excel.Workbook copyFromBook = sheet2.Application.Workbooks.Open("excel1ファイルのパス"); 9// 他の種類のシートなら型を変更 10Excel.Worksheet sheet1 = (Excel.Worksheet)copyFromBook.Worksheets.Item("コピーしたいシート"); 11 12sheet1.Copy(Type.Missing, sheet2);

投稿2018/06/25 11:48

imihito

総合スコア2166

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

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

airu_chat

2018/06/26 11:44

ご回答ありがとうございます。 教えていただいたコードでコピーができました。 また、自作クラスを改修することでコピーすることも可能となりました。 ご教授ありがとうございました。
guest

0

こういう質問については、Spire.XLSってライブラリを使ってごらん。

ブック間のシートのコピーはできますし、簡単です。

サンプルコードをご覧になってください

Workbook workbook1 = new Workbook(); workbook1.LoadFromFile("Vendor.xlsx"); //一つ目Worksheetを取得します。 Worksheet sheet1 = workbook1.Worksheets[0]; //二つ目のExcelをロードします。 Workbook workbook2 = new Workbook(); workbook2.LoadFromFile("Report.xlsx"); //一つ目のExcelから一つ目のシートを二つめのExcelにコピします。 Worksheet sheet2 = workbook2.Worksheets.AddCopy(sheet1); sheet2.Name = "Copy"; //保存します workbook2.SaveToFile("Report.xlsx");

どうですか?

投稿2020/10/28 03:23

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

0

ネットで拾ったVBAですが、この例だとBook1のSheet1がBook2のSheet1の後に
Sheet1(2)というシート名でコピーされるようです。

上記のコードでもいけそうですがCopy _
After:=の使い方ができていないように見受けられます。

補足ですが、このコードはファイルをOpenしていないので事前にブックを開いておくそうです。

Sub macro9()
Workbooks("Book1.xlsx").Sheets("Sheet1").Copy _
After:=Workbooks("Book2.xlsx").Sheets("Sheet1")
End Sub

上記はVBAでC#ではありませんでした。すみません。
C#もExcelも持っていませんが、次のコードでどうでしょう?

ExcelTest excel1 = new ExcelTest("excel1ファイルのパス");
ExcelTest excel2 = new ExcelTest("excel2ファイルのパス");

//コピー元とコピー先のエクセルを開く
excel1.Open();
excel2.Open();

Worksheet sheet1 = excel1.Sheets[1];
Worksheet sheet2 = excel2.Sheets[1];

sheet1.Copy(Type.Missing, sheet2);

投稿2018/06/25 11:33

編集2018/06/25 11:50
casaganai

総合スコア144

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問