OpenXML SDK:Excelを再計算式を作成します
-
28-09-2019 - |
質問
Microsoft Office OpenXML SDK 2.0を通じて、Excelスプレッドシートのセルをいくつか更新します。値を変更すると、変化したセルに依存する式を含むすべてのセルが無効になります。ただし、キャッシュされた値のため、Excelは、ユーザーが「今すぐ計算」をクリックしていても、定式を再計算しません。
SDKを介してワークブック全体のすべての従属セルを無効にする最良の方法は何ですか?これまでのところ、次のコードスニペットを見つけました http://cdonner.com/introduction-to-microsofts-open-xml-format-sdk-20-with-a-focus-on-excel-documents.htm:
public static void ClearAllValuesInSheet
(SpreadsheetDocument spreadSheet, string sheetName)
{
WorksheetPart worksheetPart =
GetWorksheetPartByName(spreadSheet, sheetName);
foreach (Row row in
worksheetPart.Worksheet.
GetFirstChild().Elements())
{
foreach (Cell cell in row.Elements())
{
if (cell.CellFormula != null &&
cell.CellValue != null)
{
cell.CellValue.Remove();
}
}
}
worksheetPart.Worksheet.Save();
}
このスニペットが私のためにコンパイルされないという事実に加えて、2つの制限があります。
- 他のシートには依存式が含まれている可能性がありますが、単一のシートを無効にします。
- 依存関係は考慮されていません。
私は効率的な方法を探しています(特に、特定のセルの値に依存するセルのみを無効にし、すべてのシートを考慮に入れます。
アップデート:
それまでの間、私はコードをコンパイルして実行し、ワークブックのすべてのシートでキャッシュされた値を削除することができました。 (回答を参照してください。)それでも、私はより良い/代替ソリューションに興味があります。特に、実際に更新されたセルに依存するセルのキャッシュ値のみを削除する方法のみに興味があります。
解決
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
私のために働く!
他のヒント
私はこれを使用します
static void FlushCachedValues(SpreadsheetDocument doc)
{
doc.WorkbookPart.WorksheetParts
.SelectMany(part => part.Worksheet.Elements<SheetData>())
.SelectMany(data => data.Elements<Row>())
.SelectMany(row => row.Elements<Cell>())
.Where(cell => cell.CellFormula != null)
.Where(cell => cell.CellValue != null)
.ToList()
.ForEach(cell => cell.CellValue.Remove())
;
}
これにより、キャッシュされた値がフラッシュされます
挨拶
それは私の問題を部分的に解決し、これまでより良い解決策はないように思われるので、そのコードブロックを質問から答えに移動しました...これは新しいコードのように見える方法です:
foreach (WorksheetPart worksheetPart in spreadSheet.WorkbookPart.WorksheetParts)
{
foreach (Row row in
worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements())
{
foreach (Cell cell in row.Elements())
{
if (cell.CellFormula != null && cell.CellValue != null)
cell.CellValue.Remove();
}
}
}
最後にワークシートを保存する必要があります。これは私のために機能しました。
foreach (WorksheetPart worksheetPart in spreadSheet.WorkbookPart.WorksheetParts) {
foreach (Row row in
worksheetPart.Worksheet.GetFirstChild<SheetData>().Elements()) {
foreach (Cell cell in row.Elements()) {
if (cell.CellFormula != null && cell.CellValue != null)
cell.CellValue.Remove();
}
}
worksheetPart.Worksheet.Save();
}
アルゴリズム:
- ラジアンの角度:( math.pi / 180) *角度
- 距離:Math.Pow(Velocity、2) / Gravity * Math.Sin(2 * AngleInRadians)
- 重力は9.8に等しい
例:45度と56 m/sで、ボールは320メートル移動する必要があります。