Файл Excel не читается после добавления функции «SUMIF» на лист с C # .NET - PullRequest
0 голосов
/ 13 февраля 2012

Когда я пытаюсь добавить формулу SUMIF в файл Excel, содержащий данные, Excel говорит, что файл содержит «нечитаемый контент», и спрашивает, нужно ли пытаться восстановить содержимое файла. Если я затем нажимаю «Да», он удаляет указанную формулу и открывает файл.

Когда я пытаюсь скопировать и вставить ту же формулу SUMIF, которая была сгенерирована в файле Excel вручную, она работает. Когда я пытаюсь использовать другую формулу (например, просто «СУММА»), она работает.

Кто-нибудь знает, что может быть не так?

Я использую OpenXML SDK от Microsoft для записи в файл Excel. Опять же, этот код отлично работает для некоторых формул (например, SUM), но не для SUMIF.

/// <summary>
/// Gets or set the cell formula
/// </summary>
public string Formula
    {
        get
        {
            return _cell.CellFormula.Text;
        }
        set
        {
            if(_cell.CellFormula == null) 
                _cell.CellFormula = new CellFormula(); 

            _cell.CellFormula.Text = value;
        } 
    }

Редактировать: открыв файл Excel и проверив XML-файлы, я обнаружил, что функция SUMIF сохраняется точно так же, как и функция SUM («= SUMIF (J3: J33; L34; N3: N33)» и "= SUM (N3: N33)" соответственно, оба без кавычек), поэтому нет реальной разницы в том, как формула записывается в файл.

Заранее спасибо!

- Спойлер: решение состоит в том, чтобы использовать "," вместо ";" при работе с формулами в вашем коде.

1 Ответ

1 голос
/ 15 февраля 2012

Всякий раз, когда я получаю нечитаемые ошибки содержимого при работе с Open XML SDK, я создаю пустой лист и добавляю фрагмент, который вызывает ошибки, в этот лист.Затем я воспользуюсь Open XML SDK 2.0 Productivity Tool , чтобы посмотреть, что генерируется за кулисами, и использую его код, чтобы избавиться от нечитаемых ошибок содержимого.

Я сделал эти шагии заметил, что при добавлении формулы SUMIF было добавлено следующее.Во-первых, вам нужно добавить формулу в ячейку, используя следующий код:

    // Creates an Cell instance and adds its children.
    public Cell GenerateCell()
    {
        Cell cell1 = new Cell(){ CellReference = "A1" };
        CellFormula cellFormula1 = new CellFormula();
        cellFormula1.Text = "SUMIF(J3:J33,L34,N3:N33)";
        CellValue cellValue1 = new CellValue();
        cellValue1.Text = "0";

        cell1.Append(cellFormula1);
        cell1.Append(cellValue1);
        return cell1;
    }

Это приведет к следующему XML:

<x:c r="A1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
  <x:f>SUMIF(J3:J33,L34,N3:N33)</x:f>
  <x:v>0</x:v>
</x:c>

Текстовое значение является просто результатомсумма, которая в моем случае равна нулю, так как заданный мною диапазон был пустым.

Далее необходимо убедиться, что worksheet содержит sheetDimension, который определяется как:

Этот элемент указывает используемый диапазон листа.Он определяет границы строк и столбцов используемых ячеек на листе.Это необязательно и не обязательно.Используемые ячейки включают ячейки с формулами, текстовым содержимым и форматированием ячейки.Когда весь столбец отформатирован, считается, что используется только первая ячейка в этом столбце.

Код, сгенерированный для меня, был:

 // Creates an SheetDimension instance and adds its children.
 public SheetDimension GenerateSheetDimension()
 {
    SheetDimension sheetDimension1 = new SheetDimension(){ Reference = "A1" };
    return sheetDimension1;
 }

XML выглядит следующим образом:

<x:dimension ref="A1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />

Далее необходимо убедиться, что worksheetPart содержит calcChainPart, в котором будет элемент calcChain с дочерним элементом calculationCell.

Этот элемент представляет собой отдельную ячейку, которая должна содержать формулу, в цепочке calc.Ячейки вычисляются в том же порядке, в котором элементы c отображаются в части «Цепочка вычислений».

Это просто говорит Excel о том, на каком листе содержится формула и к какой ячейке она применяется.Вот код и XML для моего:

// Creates an CalculationCell instance and adds its children.
public CalculationCell GenerateCalculationCell()
{
   CalculationCell calculationCell1 = new CalculationCell(){ CellReference = "A1", SheetId = 1 };
   return calculationCell1;
}

<x:c r="A1" i="1" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />

Наконец, workbookPart нужен элемент calculationProperties, который определяет коллекцию свойств, которые приложение использует для записи статуса расчета и деталей.Вычисление - это процесс вычисления формул и последующего отображения результатов в виде значений в ячейках, содержащих формулы.

// Creates an CalculationProperties instance and adds its children.
public CalculationProperties GenerateCalculationProperties()
{
   CalculationProperties calculationProperties1 = new CalculationProperties(){ CalculationId = (UInt32Value)125725U };
   return calculationProperties1;
}

<x:calcPr calcId="125725" xmlns:x="http://schemas.openxmlformats.org/spreadsheetml/2006/main" />

Как видите, все эти различные элементы и части создаются для вас за кулисами.при добавлении формулы в ячейку при использовании Excel.К сожалению, вы несете ответственность за добавление необходимых элементов при добавлении формул с использованием Open XML SDK.Скорее всего, один из этих элементов отсутствует в вашем документе Excel, поэтому вы, вероятно, получаете ошибку нечитаемого содержимого при открытии документа Excel.

...