在Excel中添加优化数据库调用

时间:2012-11-29 15:06:57

标签: c# excel dll excel-vba formula vba

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

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

有没有办法可以为数据库中的每个公式进行一次调用?任何实施想法?

感谢。

编辑:

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

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

此插件的作用类似于报表设计器(没有任何向导,只有基于公式),用户可以在Excel中设计自己的报表,按照自己的方式格式化,并将会计软件中的值从任何单元格中提取出来想。

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

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

2 个答案:

答案 0 :(得分:0)

在不知道您尝试接收哪些数据的情况下,您可以在代码中返回数据集,并将数据集映射到公式,而不是每次都运行回数据库。因此,如果您说要抓取股票报价或其他东西,您可以获取所有“WHERE”项目,并在查询数据库时将它们放入IN子句中。获得相关更新的数据集后,您可以从数据集而不是数据库发送数据集。 Recalcs会再次通过一次调用再次运行到数据库。

您可以扩展单元格以获取更新标记,并仅从这些标记刷新。

暂停公式计算,只在必要时刷新。

只是大声思考..或者无论输入的等价物是什么。

编辑: 我深入到脑中的机制,我意识到自己不在我的元素中。抱歉。我从来没有用VS创建过.DLL或Addin,所以在此之后的一切都是纯粹的猜测和猜测,可能会或可能不会造成弊大于利。

我认为UDF的执行需要重新路由,直到执行执行计划为止。

你需要一些物品。

  1. ExecutionPlan - 此对象将管理您的查询列表。批量交易或单笔交易。您需要一个方法将请求转换为sql。然后在一次调用中将sql传递给数据库。
  2. DataCache - 这是所有返回数据的记录集。我用一面旗帜或其他东西来封装它,如果它是否被取出。

公式将类似于(伪代码)

 if(dataCache.executed)
      formula.returnValue = dataCache.value(valueYouWantToReturn)
 else
      executePlan.add(valueYouWantToGet);
      formula.returnValue = "queued";

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

你的sql转换器实际上将通过字符串构建构建巨大的IN子句或一堆chaned OR。因此,您有一个Ledger值的子句,当调用ExecutionPlan.Add方法时,会向Ledger的select语句添加您要检索的值。

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

我将其解释为死亡,但我认为它会起作用?我想......

答案 1 :(得分:0)

您可能需要考虑在Excel中使用CUBEVALUE和其他CUBE函数。 CUBEVALUE函数已经执行了您的DLL要执行的操作 - 从每个函数的外部数据库中提取单个值。问题是源数据需要采用OLAP格式并响应MDX而不是SQL。

然而,这并非难以设置,尽管这超出了本回复的范围。幸运的是,会计往往适合OLAP多维数据集 - 您可以设置日期,部门,帐户等的维度。或者对于库存,您可以在项目,位置,状态(订单,发货,库存)上设置尺寸等

值得研究,至少。