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

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

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

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

Q&A

解決済

2回答

7688閲覧

C#でExcelファイルの保存ができない。

Yuki_S

総合スコア356

C#

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

0グッド

0クリップ

投稿2016/06/27 03:19

###前提・実現したいこと
C#を用いて、Excelのファイルを指定容量以下になるように分割したいです。そこで以下のフローでプログラムを構築しました。

1.Excel内にあるすべてのシートを1シートずつに分割し一時保存します。
2.一時保存した各ファイルのファイル容量を取得します。
3.分割したファイルを任意で指定しておいたファイル容量以下に収まるようにシートを結合して保存しなおします。

ここで、1.2.として一度シートを個別にしたのは、分割をせずに各シート毎のファイル容量を取得するすべがなさそうだったのでこの方法を採用しました。

###発生している問題・エラーメッセージ
実装が完了し、デバッグも概ね完了したため社内でテスト版のリリースをしたのですが、いくつかのExcelファイルでのみ以下のエラーが発生しました。この原因と解決策が見いだせず困っています。

ファイルを保存できませんでした。 エラーコード:-2146827284

###該当のソースコード
以下のコードの前に、tempフォルダを作成しておき一枚ずつに分割して保存するコードが実装されています。コード内のDictionaryはファイル名と各容量がペアになって格納されています。エラーはSaveAsの所で発生します。

C#

1 try 2 { 3 for (int i = 0; i < FC; i++) 4 { 5 if (一つ後ろのファイルのサイズを足したときに上限を超えているかチェック) 6 { 7 continue; 8 } 9 else 10 { 11 if (i == N) 12 { 13 //一枚で指定容量に達する場合、コピーを行うコード 14 } 15 else 16 { 17 Workbook FromBook = ExcelApp.Workbooks.Open(@FileNames[N].Key.ToString()); 18 Worksheet Outputsheet = FromBook.Worksheets[1]; 19 try 20 { 21 for (int j = N + 1; j < i + 1; j++) 22 { 23 if (j != N + 1) 24 { 25 System.Runtime.InteropServices.Marshal.ReleaseComObject(Outputsheet); 26 Outputsheet = FromBook.Sheets[copynum]; 27 } 28 //コピー元ブックを開く 29 try 30 { 31 Workbook ForBook = ExcelApp.Workbooks.Open(@FileNames[j].Key.ToString()); 32 33 //コピーするシートを開く 34 try 35 { 36 Worksheet Fromsheet = ForBook.Sheets[1]; 37 38 //シート1の後ろにコピーする 39 try 40 { 41 Fromsheet.Copy(Type.Missing, Outputsheet); 42 } 43 catch (Exception ex) 44 { 45 MessageBox.Show(ex.Message); 46 } 47 finally 48 { 49 //解放 50 if (Outputsheet != null) 51 { 52 System.Runtime.InteropServices.Marshal.ReleaseComObject(Outputsheet); 53 } 54 55 if (Fromsheet != null) 56 { 57 System.Runtime.InteropServices.Marshal.ReleaseComObject(Fromsheet); 58 } 59 } 60 } 61 catch (Exception ex) 62 { 63 MessageBox.Show(ex.Message); 64 } 65 finally 66 { 67 //解放 68 if (ForBook != null) 69 { 70 try 71 { 72 ForBook.Close(false); 73 } 74 finally 75 { 76 System.Runtime.InteropServices.Marshal.ReleaseComObject(ForBook); 77 } 78 } 79 } 80 } 81 catch (Exception ex) 82 { 83 MessageBox.Show(ex.Message); 84 } 85 copynum++; 86 } 87 } 88 catch (Exception ex) 89 { 90 MessageBox.Show(ex.Message); 91 } 92 finally 93 { 94 var name = FromBook.Sheets[1].Name; 95 96 if (FromBook.Sheets.Count > 1) 97 { 98 var name2 = FromBook.Sheets[FromBook.Sheets.Count].Name; 99 name += "-" + name2; 100 } 101 102 var savestr = System.IO.Path.Combine(dirname, name + ".xlsx"); 103 104 var fi = new System.IO.FileInfo(savestr); 105 106 try 107 { 108 if (fi.Exists) 109 { 110 fi.Delete(); 111 FromBook.SaveAs(savestr); 112 } 113 else 114 { 115 //ブックの保存 116 FromBook.SaveAs(savestr); 117 } 118 } 119 catch (Exception ex) 120 { 121 MessageBox.Show(ex.Message); 122 } 123 124 if (FromBook != null) 125 { 126 try 127 { 128 FromBook.Close(); 129 } 130 finally 131 { 132 System.Runtime.InteropServices.Marshal.ReleaseComObject(FromBook); 133 } 134 } 135 } 136 } 137 N = i + 1; 138 } 139 } 140 } 141 finally 142 { 143 if (ExcelApp != null) 144 { 145 try 146 { 147 ExcelApp.Quit(); 148 } 149 finally 150 { 151 System.Runtime.InteropServices.Marshal.ReleaseComObject(ExcelApp); 152 } 153 } 154 } 155

###試したこと
別のファイルでは問題なく処理が完了することを確認。
Excelのシートごとにマクロが入っている場合に発生しやすい。Excelのバージョンが古い場合に発生しやすい。ということを確認。
エラーの発生したExcelファイルでコピーされてきたシートをExcel上で全て削除すると保存ができるようになる。

分かり辛いところもあるかと思いますが、思いついたことがありましたらコメントいただけると幸いです。

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

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

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

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

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

guest

回答2

0

自己解決

2の工程までで一度はコピーシートの保存ができているのにもかかわらず、
1,2で作成されたExcelを使ってコピーを行うと保存ができなくなることが問題でした。

よって、回避策として
1,2で作成したものは容量の確認の為だけに用いて
3の工程でのコピーでは使用せずに1と同様に大元のファイルから行うことで保存をおこなうようプログラムを修正しました。

投稿2016/07/05 08:15

Yuki_S

総合スコア356

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

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

Yuki_S

2016/07/12 01:14

現状、原因などの特定には至っていないのでもしご存知の場合追記していただけると非常に助かります。
guest

0

ウィルス検査ソフトによってブロックされている可能性があります。
同じファイルで再現するなら、常時監視を一時切ってやってみてもらえますか?

投稿2016/06/27 03:34

Zuishin

総合スコア28656

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

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

Yuki_S

2016/06/27 03:44

回答ありがとうございます。さっそくウイルスソフトの監視を切ってやってみましたが、効果はありませんでした。。。ウイルス監視はいつも失念してしまうのでご指摘いただけたのは非常に助かります。 補足情報ですが、 ・マクロが入っていても問題なく処理が終わることもあります。 ・1.の部分で一度分割してtempに保存するときはどのExcelでも問題なく保存が完了しており、結合してから保存する際にのみエラーが発生しています。
Yuki_S

2016/06/27 06:13

ご指摘いただいて、私もそれだ!セキュリティだ!と喜び勇んでチェックしたんですが・・・ダメでしたfT_T こんなこともあるんですねチェックしてみます。貴重な情報ありがとうございます!
coco_bauer

2016/06/27 07:08

サイズ(幅か高さ)が0の画像ファイルが含まれていると保存できない場合があると、Microsoftのページ"https://support.microsoft.com/ja-jp/kb/2660122"に書いてあります。回避策も書かれているので、試してみてはどうでしょうか。
Yuki_S

2016/07/05 08:11

coco様 回答ありがとうございます。 こちら確認してみましたが、解決しませんでした。 なお、質問では不明瞭かもしれませんので補足すると 2の工程で一度はコピーで保存ができているのにもかかわらず、 2で作成したExcelを使ってコピーを行うと保存ができなくなります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問