Estoy trabajando en una UDF (función definida por el usuario) para un usuario de Excel, la tarea parece fácil con la ayuda de ExcelDNA. Pero mientras lo pruebo en una celda de Excel con las siguientes dos fórmulas, ambas muestran # ¡VALOR !. Necesito ayuda para solucionar este problema, gracias.

=mySetCellFormula("Test", "")
=mySetCellFormula("Test", "A1")

Imports System.Net
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.Office.Core
Imports Excel = Microsoft.Office.Interop.Excel
Imports ExcelDna.Integration
Imports ExcelDna.Integration.XlCall

Public Module MyFunctions
    Public Function mySetCellFormula(ByVal sFormuaR1C1 As String, ByVal cellAddress As String) As String
        ' Get the correct application instance
        Dim xlApp As Excel.Application
        Dim xlSheet As Excel.Worksheet
        Dim xlCell As Excel.Range
        xlApp = CType(ExcelDnaUtil.Application, Excel.Application)
        xlSheet = CType(xlApp.ActiveSheet(), Excel.Worksheet)
        If cellAddress = "" Then
            xlCell = xlApp.ActiveCell()
        Else
            xlCell = xlSheet.Range(cellAddress)
        End If
        'xlCell.FormulaR1C1 = "=" & Chr(34) & sFormuaR1C1 & Chr(34)
        xlCell.FormulaR1C1 = "=" & sFormuaR1C1
        mySetCellFormula = ""
    End Function
End Module
0
Wayne 27 ene. 2016 a las 05:18

2 respuestas

La mejor respuesta

Gracias a Govert por iluminarme sobre el concepto de Modelo de cálculo de Excel y Macro , finalmente resuelvo una solución de la siguiente manera:

Imports System.Net
Imports System.Drawing
Imports System.Windows.Forms
Imports Microsoft.Office.Core
Imports Excel = Microsoft.Office.Interop.Excel
Imports ExcelDna.Integration
Imports ExcelDna.Integration.XlCall

Public Module MyFunctions
    Public Function mySetCellFormula(ByVal sFormuaR1C1 As String, ByVal cellAddress As String) As String
        ' Get the correct application instance
        Dim xlApp As Excel.Application
        Dim xlSheet As Excel.Worksheet
        Dim xlCell As Excel.Range
        xlApp = CType(ExcelDnaUtil.Application, Excel.Application)
        xlSheet = CType(xlApp.ActiveSheet(), Excel.Worksheet)
        If cellAddress = "" Then
            xlCell = xlApp.ActiveCell()
        Else
            xlCell = xlSheet.Range(cellAddress)
        End If

        ExcelAsyncUtil.QueueAsMacro( _
            Sub()
                xlCell.FormulaR1C1 = "=" & sFormuaR1C1
            End Sub)

        mySetCellFormula = ""
    End Function
End Module
1
Wayne 31 ene. 2016 a las 00:48

Gracias a Govert y Wayne; Necesitaba la misma implementación pero en C #: terminé con lo siguiente que funciona para mí:

public static void SetCellFormula(string cellAddress, string sFormua)
{
  try
  {
    Excel.Range xlCell;
    var xlApp = (Excel.Application)ExcelDnaUtil.Application;
    var activeSheet = xlApp.ActiveSheet;
    var xlSheet = (Excel.Worksheet)activeSheet;
    if ( string.IsNullOrEmpty(cellAddress))
    {
      xlCell = xlApp.ActiveCell;
    }
    else
    {
      xlCell = xlSheet.get_Range(cellAddress);
    }

    ExcelAsyncUtil.QueueAsMacro(
      () =>
        {
          xlCell.Formula = $"={sFormua}";
        });
  }
  catch (Exception ex)
  {
    Debug.WriteLine(ex);
  }
}

Junto con;

 public static void SetCellValue(string cellAddress, object cellValue)
{
  try
  {
    Excel.Range xlCell;
    var xlApp = (Excel.Application)ExcelDnaUtil.Application;
    var activeSheet = xlApp.ActiveSheet;
    var xlSheet = (Excel.Worksheet)activeSheet;
    if (string.IsNullOrEmpty(cellAddress))
    {
      xlCell = xlApp.ActiveCell;
    }
    else
    {
      xlCell = xlSheet.get_Range(cellAddress);
    }

    ExcelAsyncUtil.QueueAsMacro(
      () =>
        {
          xlCell.Value2 = cellValue;
        });
  }
  catch (Exception exc)
  {
    Debug.WriteLine(exc);
  }
}

Se puede verificar con:

  [ExcelFunction(Name = "TestFormula", Description = "Test Set Formula on Cell")]
public static string TestFormula()
{
  SetMyCellValue("A1", 1);

  SetMyCellValue("A2", 2);
  SetMyCellValue("A3", 4);
  SetMyCellValue("A4", 8);

  SetMyCellValue("B1", -1);
  SetMyCellValue("C1", 3);
  SetMyCellValue("D1", 5);

  SetCellFormula("B2", "$A$1*B$1-$A2");

  return "=TestFormula";
}
0
Iron Mask 24 mar. 2019 a las 14:22