Ячейка формата ClosedXML, содержащая формулу

Я надеюсь, что кто-то может помочь мне с ClosedXML, поскольку я новичок в экспорте Excel, и судя по тому, что я видел в ClosedXML, документация в определенных областях довольно ограничена.

На данный момент я помещаю данные в Datatable, форматирую строки до их правильного типа и экспортирую с правильным макетом.

Проблема возникает, когда я пытаюсь экспортировать одну строку, содержащую повторяющуюся формулу в каждой ячейке.

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

На данный момент у меня есть (закомментировано, как я использовал XLFormula, пытался передать XLFormula формулу в виде строки и установить как общую ставку за единицу):

dt.Columns.Add("Qty", typeof(int));
dt.Columns.Add("Bid Per Unit GBP", typeof(double));
dt.Columns.Add("Total Bid GBP"); //typeof(XLFormula)
foreach (DataRow dr in dt.Rows)
{
    //XLFormula totalBidFormula = new XLFormula();

    dr["Qty"] = 1;
    dr["Bid Per Unit GBP"] = 0.00;
    dr["Total Bid GBP"] = "=[@Qty]*[@[Bid Per Unit GBP]]";

Любая помощь будет принята с благодарностью. Если то, что я пытаюсь сделать с ClosedXML, невозможно, дайте мне знать, и если бы вы могли предложить альтернативный экспортер XML (даже если он платный), который поможет!


person Verno    schedule 20.08.2015    source источник


Ответы (3)


На всякий случай, если кто-то наткнется на это, кто находится в том же положении, что и я, формулы в closedXML довольно просты.

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

Я использовал простой цикл for, чтобы получить текущую ячейку по мере обработки листа, так как мне нужен был целый столбец для хранения формулы.

//get all rows in my datatable 
int totalRows = dt.Rows.Count;

//set the first that will be filled with data
int currentRow = 1;

//loop through each row.
for(int i = 0; i < totalRows; i++){

//the current cell will be whatever column you wish to format + the current row
string currentCell = "F" + currentRow;

//create your formula
string AdjustedPriceFormula = "=C" + currentRow + "*" + "D" + currentRow;

//apply your formula to the cell.
theSheet.Cells(currentCell).FormulaA1 = AdjustedPriceFormula;

//increment your counters to apply the same data to the following row
currentRow++

С тех пор это сработало для меня несколько раз, и я добавил несколько формул в несколько столбцов / ячеек.

Надеюсь, это кому-то поможет!

person Verno    schedule 05.10.2015
comment
Просто потратил час на поиски этого, поэтому я помещу это здесь на случай, если кто-то еще столкнется с этим: если вы используете функции в excell, вы должны использовать; символ как разделитель параметров функции (пример: IF (condition; trueval; falseva)). Вставка формулы в этом формате приведет к повреждению файла xlsx. Исправление: используйте вместо; при настройке формул с помощью ClosedXML! - person Davy; 05.02.2016
comment
@davy ты спасатель. - person WiseStrawberry; 10.01.2019

Я наткнулся на этот пост с отладкой той же проблемы, что и у вас. Просмотрел некоторые комментарии к системе отслеживания проблем ClosedXML Github и наткнулся на комментарий к этой теме :

Ссылки на столбцы таблицы пока не поддерживаются. Используйте обычные ссылки в стиле A1.

Вы также можете использовать старые ссылки стиля «R1C1», если хотите, но для достижения желаемого вы должны использовать что-то вроде:

dr["Total Bid GBP"].FormulaR1C1 = "=RC[-2]*RC[-1]";

person Lovethenakedgun    schedule 24.09.2018

Дополнительный комментарий к цитате, на которую ссылается @Lovethenakedgun:

Ссылки на столбцы таблицы пока не поддерживаются. Используйте обычные ссылки в стиле A1.

. Насколько я понимаю, это все еще верно, но есть обходной путь. Если вы посмотрите в файл sheet.xml, содержащий таблицу, вы увидите, что ссылки в стиле таблицы переводятся примерно так:

"Table1[[#This Row],[testedName]]"

Теперь вы можете использовать это в коде для свойства FormulaA1, как я это сделал ниже (в F # tb - это просто объект таблицы ...):

tb.Name <- "Table1"
tb.Field(0).Name <- "testedName"
tb.Row(2).Cell(2).FormulaA1 <- "Table1[[#This Row],[testedName]]"
tb.Row(3).Cell(2).FormulaA1 <- "Table1[[#This Row],[testedName]]"
tb.Row(4).Cell(2).FormulaA1 <- "Table1[[#This Row],[testedName]]"

Это переводится в [@testedName] в книге. Вы должны делать это в каждой строке отдельно, как и я.

person mkrp    schedule 05.08.2020