EPPlus — невозможно получить значения функций NPV и IRR из Excel

У меня есть модель в excel, и я пытаюсь передать входные данные через ASP.NET в excel и возвращаю обратно результаты модели по сетке в интерфейсе. Я использую пакет EPPlus в ASP.NET, так как для него не требуется установка MS Office.

У меня возникли проблемы с получением значения ячейки, в которой использовались функции NPV [Чистая приведенная стоимость] и IRR [Внутренняя норма прибыли]. Он всегда возвращает #VALUE или #NAME. В качестве обходного пути я смог рассчитать NPV вручную, но у меня проблемы с IRR.

Есть ли способ в EPPlus вставить все ячейки в качестве значений на листе? Или есть другая альтернатива?

Помогите пожалуйста и заранее спасибо

Обновление: у меня есть EPPlus 4.5.3.1 и Visual Studio 2013.

string strfilepath = Server.MapPath(destPath);
FileInfo fileInfo = new FileInfo(strfilepath);
ExcelPackage p = new ExcelPackage(fileInfo);
ExcelWorksheet myWorksheet = p.Workbook.Worksheets["Financial"];
GridView1.Rows[0].Cells[2].Text = float.Parse(myWorksheet1.Cells["f57"].Value.ToString()).ToString("N2");

person Chendur    schedule 17.06.2019    source источник
comment
Кажется, у меня все хорошо. Какую версию EPPlus вы используете? Опубликуйте код, чтобы другие могли попробовать.   -  person Ernie S    schedule 19.06.2019
comment
Вы не разместили код, создающий лист Excel, не говоря уже о формуле, использующей NPV или IRR. Куда вы загружаете данные и где используете NPV или IRR? При попытке загрузить уже существующий лист Excel возвращается #VALUE, поскольку исходная формула содержит ошибку. Epplus не может исправить плохую формулу. Или вы ожидали, что Epplus пересчитает значения?   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
Здравствуйте @PanagiotisKanavos, спасибо за ваш ответ. Это уже существующий Excel, и рабочий лист вычисляет IRR из ячеек на другом листе с помощью встроенной функции IRR(). Я могу видеть рассчитанное значение в Excel, и это неплохая формула. Я получаю результат #VALUE только тогда, когда пытаюсь получить результат из excel в сетку.   -  person Chendur    schedule 19.06.2019
comment
@Chendur, что означает, что #VALUE хранится на этом листе Excel для начала. Epplus не будет пересчитывать формулы, если вы не попросите об этом с помощью .Workbook.Calculate(). Даже в этом случае он может дать сбой, потому что он не пытается на 100% эмулировать механизм вычислений Excel. это не его работа   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
У меня есть строка {p.Workbook.Calculate();}, так что вычисляется каждая формула во всей книге. Я что-то упускаю?   -  person Chendur    schedule 19.06.2019
comment
Этих функций нет в списке поддерживаемых функций. Однако можно добавить собственную реализацию   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
Черт, спасибо. Кроме того, есть ли способ вставить весь лист в качестве значений?   -  person Chendur    schedule 19.06.2019
comment
Что это хотя бы значит? На веб-сервере нет рабочего стола. Excel не работает, Eppluss — это библиотека   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
С другой стороны, вы должны использовать myWorksheet1.Cells["f57"].Value только для получения значения, а не двойное преобразование в строку, затем в плавающую, а затем в строку   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
Да, я понимаю, что MS Excel не работает. Мне просто интересно, может ли EPPlus скопировать и вставить ячейку в качестве значения, поскольку он может делать так много всего. Спасибо за ваше время в любом случае.   -  person Chendur    schedule 19.06.2019
comment
if EPPlus could copy and paste the cell as values это ничего не значит. И значения уже там. Если ячейка F57 содержит число, myWorksheet1.Cells["f57"].Value вернет его в виде object. Вы можете разыграть его, чтобы получить float. Нет нет причин преобразовывать это в строку, затем в плавающую, а затем обратно в строку.   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
Отладьте свой код и проверьте, что содержит .Value, например, наведя на него курсор или в контрольной переменной. Вы, наверное, уже видите, что это double или decimal   -  person Panagiotis Kanavos    schedule 19.06.2019
comment
Под копированием и вставкой значений я имею в виду, что в настоящее время ячейка представляет собой формулу, и EPPlus не может ее поддерживать. Если ячейка после вычисления формулы отображается как значение [а не результат формулы], я смогу получить значение. Когда я навожу указатель мыши на .Value, он показывает мне значение как {#NAME?}   -  person Chendur    schedule 19.06.2019


Ответы (1)


Я перепробовал все возможные способы в EPPlus, но не смог рассчитать IRR. Я придумал решение в SQL, и оно дает результат, близкий к функции IRR excel.

CREATE FUNCTION [dbo].[Ufn_irr1] (@strIDs1 VARCHAR(10), 
                                  @strIDs2 VARCHAR(10), 
                                  @guess   DECIMAL(30, 10)) 
returns DECIMAL(30, 10) 
AS 
  BEGIN 
      DECLARE @t_IDs TABLE 
        ( a
           id    INT IDENTITY(0, 1), 
           value DECIMAL(30, 10) 
        ) 
      DECLARE @strIDs VARCHAR(max) 

      SET @strIDs = @strIDs1 + ',' + @strIDs2 

      DECLARE @strID  VARCHAR(12), 
              @sepPos INT, 
              @NPV    DECIMAL(30, 10) 

      SET @strIDs = COALESCE(@strIDs + ',', '') 
      SET @sepPos = Charindex(',', @strIDs) 

      WHILE @sepPos > 0 
        BEGIN 
            SET @strID = LEFT(@strIDs, @sepPos - 1) 

            INSERT INTO @t_IDs 
                        (value) 
            SELECT ( Cast(@strID AS DECIMAL(20, 10)) ) 
            WHERE  Isnumeric(@strID) = 1 

            SET @strIDs = RIGHT(@strIDs, Datalength(@strIDs) - @sepPos) 
            SET @sepPos = Charindex(',', @strIDs) 
        END 

      SET @guess = CASE 
                     WHEN Isnull(@guess, 0) <= 0 THEN 0.00001 
                     ELSE @guess 
                   END 

      SELECT @NPV = Sum(value / Power(1 + @guess, id)) 
      FROM   @t_IDs 

      WHILE @NPV > 0 
        BEGIN 
            SET @guess = @guess + 0.00001 

            SELECT @NPV = Sum(value / Power(1 + @guess, id)) 
            FROM   @t_IDs 
        END 

      RETURN @guess 
  END 
person Chendur    schedule 09.01.2020