OpenXML SDK: Excel 재계산 공식 만들기
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();
}
이 스니펫이 컴파일되지 않는다는 사실 외에도 두 가지 제한 사항이 있습니다.
- 다른 시트에 종속 공식이 포함될 수 있지만 단일 시트만 무효화됩니다.
- 종속성은 고려하지 않습니다.
저는 효율적이고(특히 특정 셀의 값에 의존하는 셀만 무효화) 모든 시트를 고려한 방법을 찾고 있습니다.
업데이트:
그동안 코드를 컴파일하고 실행할 수 있었고 워크북의 모든 시트에서 캐시된 값을 제거할 수 있었습니다. (답변 참조)여전히 저는 더 나은/대체 솔루션, 특히 업데이트된 셀에 실제로 의존하는 셀의 캐시된 값만 삭제하는 방법에 관심이 있습니다.
spreadSheet.WorkbookPart.Workbook.CalculationProperties.ForceFullCalculation = true;
spreadSheet.WorkbookPart.Workbook.CalculationProperties.FullCalculationOnLoad = true;
나한테 효과가 있어요!
내 문제를 부분적으로 해결해주고 아직까지는 더 나은 해결책이 없는 것 같으니, 그 코드 블록을 질문에서 답변으로 옮겼습니다.새 코드는 다음과 같습니다.
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();
}
}
}
사용합니다.
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();
}
}
worksheetPart.Worksheet.Save();
}
또는 공식을 변경하여 간접 연산자를 사용할 수 있습니다.SAX + 템플릿 파일 접근 방식을 사용하는 경우 특히 유용합니다.이 솔루션은 코드를 변경할 필요가 없으므로 템플릿 엑셀 파일만 사용합니다.여기에서 내 솔루션을 참조하십시오 - 열려 있는 공식을 다시 계산하도록 xlsx 설정
재계산에 문제가 있는 것으로 보이는 또 다른 문제에 주목하고 싶습니다.저는 맹목적으로 세포를 채우기 위해 코드를 따랐고 그것은 공유된 문자열을 보여주었습니다.오랜 시간이 지난 후, 저는 제가 사용할 필요가 있다는 것을 발견했습니다.CellValues.Number에 대한 가치DataType일단 제가 그렇게 하면, 세포들은 열었을 때 다시 계산됩니다.
언급URL : https://stackoverflow.com/questions/2668643/openxml-sdk-make-excel-recalculate-formula
'programing' 카테고리의 다른 글
| float 리터럴을 사용한 float 비교의 이상한 출력 (0) | 2023.08.12 |
|---|---|
| 최대 절전 모드 매핑의 EntityNotFoundException이 있지만 데이터가 있음 (0) | 2023.08.12 |
| npm 스크립트 실행 시 출력을 억제하는 방법 (0) | 2023.08.12 |
| node.js를 Windows 서비스로 설치하는 방법은 무엇입니까? (0) | 2023.08.12 |
| Oracle에서 키워드 뒤에 테이블 변경 (0) | 2023.08.12 |