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

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

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

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

Q&A

解決済

2回答

5601閲覧

C# Excel出力するシートを参照する別シートのセルの値が変わらない

seastar

総合スコア62

C#

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

0グッド

0クリップ

投稿2021/05/17 05:09

C#でエクセル出力をしています。

シートに"sample"という名前を付けたシートに、
値をまとめたデータを上書きする処理を作成しました。

sampleシートは、同じExcelの別シート"read_sample"シートから参照しています。
例えば、sampleシートのA5セルを、read_sampleシートのセルB2で参照している。

ただ、上記のプログラム自体は動作していますが実行後にExcelを確認すると
read_sampleシートのB2セルがプログラム実行前の値になっており、更新されません。

read_sampleシートのB2セルをダブルクリックしてEnterを押すと値が更新されます。

Excelの計算方法は自動になっているのですが、
プログラムで実行し、上書きしたデータは自動更新されないのでしょうか?

また、Excelを上書きした後、全てのシートをアップデートする方法を調べましたが見つけることができず、
ご存じの方いましたらご教示お願いいたします。

参考:抜粋しているため、不足があるかもしれませんがよろしくお願いいたします

C#

1book = NPOI.SS.UserModel.WorkbookFactory.Create(file_name); 2 3ISheet sheet = book.GetSheet("sample"); 4 5using (var save_fs = new System.IO.FileStream(save_file_name, System.IO.FileMode.Create)) 6{ 7  writeCellString(sheet, 0, 0, "data"); 8  writeCellString(sheet, 0, 1, "data"); 9  writeCellString(sheet, 0, 2, "data"); 10  writeCellString(sheet, 1, 1, "data"); 11  writeCellString(sheet, 1, 2, "data"); 12 13 book.Write(save_fs); 14} 15 16・・・ 17 18

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

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

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

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

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

rtazaki

2021/05/17 09:36

writeCellStringの中身が無かったのですが、セルに代入するだけの処理だと考えました。(回答欄)
guest

回答2

0

NPOI で Excel の再計算をしたいのであればいくつかの方法があります。

  • 方法1: NPOI に再計算させる。ただしネット情報によるとサポートしていない関数もあるらしい。VBAで定義した関数もNG(NotImplementedException が発生する)。

C#

1book.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll()
  • 方法2: 次回Excelで開いた時にExcelに再計算させるようにフラグを立てる。ただし再計算されるタイミングは Excel で開いた時なので、その前にプログラム等から読むと再計算されてない。またExcel終了時に(再計算されて内容が更新されるので)保存確認される。

C#

1var sheet2 = book.GetSheet( "read_sample" ); 2sheet2.ForceFormulaRecalculation = true;

投稿2021/05/17 10:04

draq

総合スコア2577

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

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

0

ベストアンサー

目的がこれで達成できたか分かりませんが、やってみました。

ポイントは、ForceFormulaRecalculation = trueで、
これによって、保存したファイルをExcelで開き直すと参照先(read_sample)の値が
反映されたのですが、NPOIでファイルを開いただけでは値が変わってはいませんでした。

「npoi 再計算」でググってみたのですが、ほかに良い方法が見つかりませんでした。

c#

1using System; 2using System.Linq; 3 4namespace test 5{ 6 class Program 7 { 8 static void Main(string[] args) 9 { 10 var file_name = "testbook.xlsx"; 11 var book = NPOI.SS.UserModel.WorkbookFactory.Create(file_name); 12 // read_sample: Range("C6:G6") = R[5]C[2..5] = sample!B2..6への参照 13 var sheet_rs = book.GetSheet("read_sample"); 14 // read_sampleの現在のセルの値を出力 15 foreach (var c in Enumerable.Range(2, 5)) 16 { 17 var row = sheet_rs.GetRow(5) ?? sheet_rs.CreateRow(5); 18 var cell = row.GetCell(c) ?? row.CreateCell(c); 19 Console.WriteLine(cell.StringCellValue); 20 // data1 data2 data3 data4 data5 21 } 22 23 var sheet = book.GetSheet("sample"); 24 var save_file_name = "savebook.xlsx"; 25 using (var save_fs = new System.IO.FileStream( 26 save_file_name, System.IO.FileMode.Create)) 27 { 28 foreach (var r in Enumerable.Range(1, 5)) 29 { 30 var row = sheet.GetRow(r) ?? sheet.CreateRow(r); 31 var cell = row.GetCell(1) ?? row.CreateCell(1); 32 // data6..10 33 cell.SetCellValue($"data{r + 5}"); 34 // ---- 35 // ForceFormulaRecalculationによって、 36 // 「次回読み込み時に」「Excelによって」再計算が強制される模様。 37 // ---- 38 // sheet.ForceFormulaRecalculation = true; 39 } 40 41 // NPOIに再計算させる。 42 book.GetCreationHelper().CreateFormulaEvaluator().EvaluateAll(); 43 44 // read_sampleが保存前に更新されたか確認する。 45 // 期待: data6..10になって欲しいが、そのままでもよい。 46 // 結果: data6..10 47 foreach (var c in Enumerable.Range(2, 5)) 48 { 49 var row = sheet_rs.GetRow(5) ?? sheet_rs.CreateRow(5); 50 var cell = row.GetCell(c) ?? row.CreateCell(c); 51 Console.WriteLine(cell.StringCellValue); 52 // data6 data7 data8 data9 data10 53 } 54 book.Write(save_fs); 55 } 56 var book2 = NPOI.SS.UserModel.WorkbookFactory.Create(save_file_name); 57 var sheet_srs = book2.GetSheet("read_sample"); 58 59 // 保存されたread_sampleの現在のセルの値を出力 60 // 期待: data6..10になって欲しい。 61 // 結果: data6..10 62 foreach (var c in Enumerable.Range(2, 5)) 63 { 64 var row = sheet_srs.GetRow(5) ?? sheet_srs.CreateRow(5); 65 var cell = row.GetCell(c) ?? row.CreateCell(c); 66 Console.WriteLine(cell.StringCellValue); 67 // data6 data7 data8 data9 data10 68 } 69 } 70 } 71} 72

投稿2021/05/17 09:42

編集2021/05/17 10:27
rtazaki

総合スコア69

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

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

seastar

2021/05/31 13:28

せっかく迅速に答えて頂いたにもかかわらず、返事が遅れ大変申し訳ありません。 ForceFormulaRecalculation = true npoi 再計算などキーワードを元にベストな方法を再考させて頂きます。 C#側で苦労するなら、エクセル側でファイルオープン時に更新する細工をするなど、利用者にとっていい方法を模索しようと思います。 NPOIは、回答にある通り、エクセル側の参照を更新させることができない、もしくは難しいため、エクセル側で対応することになると思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問