Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 优化Excel加载项中的数据库调用_C#_Dll_Excel_Formula_Vba - Fatal编程技术网

C# 优化Excel加载项中的数据库调用

C# 优化Excel加载项中的数据库调用,c#,dll,excel,formula,vba,C#,Dll,Excel,Formula,Vba,我正在.NET(C#)中编写一个DLL,它可以作为Excel中的插件加载。DLL将提供许多函数,这些函数可用作Excel中的公式,用于从外部应用程序的数据库中查找某些值 对于这些公式函数中的每一个,DLL都需要访问数据库,因此会有太多的数据库调用。例如,如果在10个单元格中使用公式1,在20个单元格中使用公式2,则将有30个对数据库的调用 是否有一种方法可以对数据库中的每个公式进行一次调用?有什么实施方案吗 谢谢 编辑: 基本上,我正在尝试编写一个通用的DLL(Excel插件),任何使用Exce

我正在.NET(C#)中编写一个DLL,它可以作为Excel中的插件加载。DLL将提供许多函数,这些函数可用作Excel中的公式,用于从外部应用程序的数据库中查找某些值

对于这些公式函数中的每一个,DLL都需要访问数据库,因此会有太多的数据库调用。例如,如果在10个单元格中使用公式1,在20个单元格中使用公式2,则将有30个对数据库的调用

是否有一种方法可以对数据库中的每个公式进行一次调用?有什么实施方案吗

谢谢

编辑:

基本上,我正在尝试编写一个通用的DLL(Excel插件),任何使用Excel和特定第三方会计软件的用户都可以使用它。用户插入Excel的每个公式将查询第三方应用程序数据库,并根据传递的参数返回特定值

例如,用户可以使用公式查询特定分类账的分类账余额,或使用其他公式查询SKU的库存余额等。我将有不同类别的公式,如基于分类账的公式、基于SKU的公式等。用户可以设计并排比较报告,在单独的列中显示第一季度和第二季度的分类账余额等

这个插件的作用就像一个报表设计器(没有任何向导,只基于公式),用户可以在Excel中设计自己的报表,按照自己想要的方式格式化报表,并将会计软件中的值拉到自己想要的任何单元格中

然而,我想首先设计一个“公式执行计划”,而不是通过每次从数据库中读取来评估每个公式,这样我就可以将对数据库的多次调用合并为对单个公式的一次调用,从而可以在Excel表中传递用户在该公式的所有实例中指定的所有参数


否则,Excel表格将花费很长的时间来评估公式,使其不切实际。我预计一份报告中平均有100个公式。

在不知道您试图接收什么数据的情况下,您可以返回代码中的数据集,并将数据集映射到公式,而不是每次都返回数据库。因此,如果您想抓取股票报价或其他内容,您可以抓取所有“WHERE”项,并在查询数据库时将它们放入IN子句中。一旦有了相关更新的数据集,就可以从数据集而不是数据库发送。Recalcs将通过一个调用再次运行到数据库

您可以扩展更新标志的单元格,并仅从这些单元格中刷新

暂停公式上的计算,仅在必要时刷新

只是大声思考..或者其他类似打字的东西

编辑: 我在脑子里开始思考它的机理,我意识到我已经失去了自我。很抱歉我从来没有用VS创建过.DLL或加载项,所以这之后的一切都是纯粹的猜测和猜测,可能会也可能不会造成弊大于利

我认为UDF的执行需要重新安排,直到执行计划执行完毕

你需要一些物品

  • ExecutionPlan-此对象将管理查询列表。批量或单笔交易。您需要一个方法将请求转换为sql。然后在一次调用中将sql传递给数据库。
  • DataCache—它将是所有返回数据的记录集。我会用一个标志或一些东西来封装它,以表明它是否被提取。 公式将类似于(psuedocode)

    然后,您需要强制重新计算(这将导致所有100个公式在dataCache进入数据库一次后进入数据存储(dataCache)以获取其值)

    sql转换器基本上是在子句中构建巨大的
    ,或通过字符串构建一组变化的
    。因此,当调用ExecutionPlan.Add方法时,您有一个用于分类账值的子句,该子句将您要检索的值添加到分类账的select语句中

    然后当调用ExecutionPlan.Execute时,它将执行sql语句,将其放入记录集中,以便在调用dataCache.getValue(value)时对其进行索引。您将搜索“value”并将其发送回函数


    我解释它是死的,但我想它会起作用的。我想…

    < p>你可以考虑在Excel中使用Cube值和其他多维数据集函数。CuBeValk函数已经完成了你的DLL想要做的事情——从每个函数的外部数据库中拉取一个单一的值。rm和响应MDX而不是SQL

    然而,这并不是很难设置,尽管它超出了本答复的范围。幸运的是,会计往往可以整齐地放入OLAP多维数据集中——您可以设置日期、部门、帐户等维度。或者,对于库存,您可以设置项目、位置、状态(订单、发货、库存)等维度


    至少值得研究一下。

    我编辑了我的问题,以提供更多关于DLL的预期用途和一些用例的详细信息。获取所有数据是不可能的,因为会计应用程序的数据库在每个表中都会有大量行。还有其他想法吗?用新内容编辑答案。嗯……但是什么会触发数据库调用?Excel只会调用我的函数来获取公式结果。如果我的DLL继续将其添加到执行计划中,我什么时候才能最终进入数据库?什么会触发ExecutionPlan.Execute?如果我以某种方式将所有公式缓存到执行计划中,然后对它们进行计算,我将如何将结果强制返回Excel工作表,因为对于Excel而言就其而言,它已经计算了公式并显示了结果!由于结果已经显示,基本上我如何强制重新计算
     if(dataCache.executed)
          formula.returnValue = dataCache.value(valueYouWantToReturn)
     else
          executePlan.add(valueYouWantToGet);
          formula.returnValue = "queued";