- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我已经使用自己的 RTD 实现创建了一个 VSTO 插件,我从 Excel 工作表中调用该插件。为了避免在单元格中使用成熟的 RTD 语法,我创建了一个 UDF,从工作表中隐藏该 API。我创建的 RTD 服务器可以通过自定义功能区组件中的按钮启用和禁用。
我想要实现的行为如下:
Disabled
.Loading
.听起来很简单。以下是非功能代码的示例:
Public Function RetrieveData(id as Long)
Dim result as String
// This returns either 'Disabled' or 'Loading'
result = Application.Worksheet.Function.RTD("SERVERNAME", "", id)
RetrieveData = result
If(result = "Disabled") Then
// Obviously, this recurses (and fails), so that's not an option
If(Not IsEmpty(Application.Caller.Value2)) Then
// So does this
RetrieveData = Application.Caller.Value2
End If
End If
End Function
该函数将在数千个单元格中被调用,因此将“原始”值存储在另一个数据结构中将是一项主要开销,我想避免它。此外,RTD 服务器不知道这些值,因为它也不保留其历史记录,或多或少出于相同的原因。
我在想可能有某种方法可以退出该函数,迫使它不改变显示的值,但到目前为止我还没有找到类似的东西。
编辑:
由于大众的需求,我想提供一些关于为什么我要做这一切的附加信息:正如我所说,该函数将在数千个单元格中被调用,并且 RTD 服务器需要检索相当多的信息。这对于网络和 CPU 来说都是相当困难的。为了让用户自己决定是否希望在自己的计算机上加载此负载,他们可以禁用服务器的更新。在这种情况下,他们仍然应该能够使用字段中当前的值来计算工作表,但不会将任何更新推送到其中。一旦需要新数据,就可以启用服务器并更新字段。
再说一次,由于我们在这里讨论相当多的数据,我宁愿不将其存储在工作表中的某个位置。另外,即使工作簿关闭并再次加载,数据也应该可用。
最佳答案
不同的策略=新答案。
我费尽心思才发现的一些东西,可能对你有用:
1.在 UDF 中,像这样返回 RTD 调用
' excel equivalent: =RTD("GeodesiX.RTD",,"status","Tokyo")
result = excel.WorksheetFunction.rtd( _
"GeodesiX.RTD", _
Nothing, _
"geocode", _
request, _
location)
的行为就好像您在单元格中插入了注释函数,而不是 RTD 返回的值。换句话说,“结果”是“RTD-函数调用”类型的对象,而不是 RTD 的答案。相反,这样做:
' excel equivalent: =RTD("GeodesiX.RTD",,"status","Tokyo")
result = excel.WorksheetFunction.rtd( _
"GeodesiX.RTD", _
Nothing, _
"geocode", _
request, _
location).ToDouble ' or ToString or whetever
返回实际值,相当于在单元格中键入“3.1418”。这是一个重要的区别;在第一种情况下,细胞继续参与 RTD 馈送,在第二种情况下,它仅获得恒定值。这可能是适合您的解决方案。
2.MS VSTO 看起来编写 Office Addin 似乎是小菜一碟……直到您真正尝试构建工业、可分发的解决方案。获得安装程序的所有特权和权限是一场噩梦,如果您有支持多个 Excel 版本的好主意,情况会变得更加糟糕。我一直在使用Addin Express已有几年了。它隐藏了所有这些 MS 的肮脏之处,让我专注于编写我的插件。他们的支持也是一流的,值得一看。 (不,我没有附属机构或类似的东西)。
3.请注意,Excel 可以随时调用 Connect/RefreshData/RTD,即使您正在处理某些事情 - 幕后正在进行一些微妙的多任务处理。您需要使用适当的同步块(synchronized block)来装饰您的代码,以保护您的数据结构。
4.当您接收数据(可能在单独的线程上异步接收)时,您绝对必须在最初(由 Excel)调用您的线程上回调 Excel。如果你不这样做,它会工作一段时间,然后你就会开始遇到神秘的、无法解决的崩溃,更糟糕的是,后台会出现孤立的 Excel。以下是执行此操作的相关代码示例:
Imports System.Threading
...
Private _Context As SynchronizationContext = Nothing
...
Sub New
_Context = SynchronizationContext.Current
If _Context Is Nothing Then
_Context = New SynchronizationContext ' try valiantly to continue
End If
...
Private Delegate Sub CallBackDelegate(ByVal GeodesicCompleted)
Private Sub GeodesicComplete(ByVal query As Query) _
Handles geodesic.Completed ' Called by asynchronous thread
Dim cbd As New CallBackDelegate(AddressOf GeodesicCompleted)
_Context.Post(Function() cbd.DynamicInvoke(query), Nothing)
End Sub
Private Sub GeodesicCompleted(ByVal query As Query)
SyncLock query
If query.Status = "OK" Then
Select Case query.Type
Case Geodesics.Query.QueryType.Directions
GeodesicCompletedTravel(query)
Case Geodesics.Query.QueryType.Geocode
GeodesicCompletedGeocode(query)
End Select
End If
' If it's not resolved, it stays "queued",
' so as never to enter the queue again in this session
query.Queued = Not query.Resolved
End SyncLock
For Each topic As AddinExpress.RTD.ADXRTDTopic In query.Topics
AddinExpress.RTD.ADXRTDServerModule.CurrentInstance.UpdateTopic(topic)
Next
End Sub
5.我做了一些显然类似于您在this addin中要求的事情。在那里,我从 Google 异步获取地理编码数据,并通过 UDF 阴影的 RTD 提供该数据。由于对 GoogleMaps 的调用非常昂贵,我尝试了 101 种方法和几个月的夜晚来将值保留在单元格中,就像您正在尝试的那样,但没有成功。我没有计时任何东西,但我的直觉是像“Application.Caller.Value”这样对 Excel 的调用比字典查找慢一个数量级。
最后,我创建了一个缓存组件,用于保存和重新加载从非常隐藏的电子表格中获取的值,该电子表格是我在 Workbook OnSave 中动态创建的。数据存储在字典(字符串,myQuery)中,其中每个 myQuery 保存所有相关信息。
它运行良好,满足离线工作的要求,甚至对于 20'000 多个公式,它看起来也是即时的。
HTH。
<小时/>编辑:出于好奇,我测试了我的预感:调用 Excel 比进行字典查找要昂贵得多。事实证明,这种预感不仅是正确的,而且是可怕的。
Public Sub TimeTest()
Dim sw As New Stopwatch
Dim row As Integer
Dim val As Object
Dim sheet As Microsoft.Office.Interop.Excel.Worksheet
Dim dict As New Dictionary(Of Integer, Integer)
Const iterations As Integer = 100000
Const elements As Integer = 10000
For i = 1 To elements + 1
dict.Add(i, i)
Next
sheet = _ExcelWorkbook.ActiveSheet
sw.Reset()
sw.Start()
For i As Integer = 1 To iterations
row = 1 + Rnd() * elements
Next
sw.Stop()
Debug.WriteLine("Empty loop " & (sw.ElapsedMilliseconds * 1000) / iterations & " uS")
sw.Reset()
sw.Start()
For i As Integer = 1 To iterations
row = 1 + Rnd() * elements
val = sheet.Cells(row, 1).value
Next
sw.Stop()
Debug.WriteLine("Get cell value " & (sw.ElapsedMilliseconds * 1000) / iterations & " uS")
sw.Reset()
sw.Start()
For i As Integer = 1 To iterations
row = 1 + Rnd() * elements
val = dict(row)
Next
sw.Stop()
Debug.WriteLine("Get dict value " & (sw.ElapsedMilliseconds * 1000) / iterations & " uS")
End Sub
结果:
Empty loop 0.07 uS
Get cell value 899.77 uS
Get dict value 0.15 uS
在 10,000 个元素的字典(整数、整数)中查找值比从 Excel 中获取单元格值快 11,000 倍以上。
Q.E.D.
关于Excel UDF 计算应返回 'original' 值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4555825/
我的问题:非常具体。我正在尝试想出解析以下文本的最简单方法: ^^domain=domain_value^^version=version_value^^account_type=account_ty
好吧,这就是我的困境: 我正在为 Reddit 子版 block 开发常见问题解答机器人。我在 bool 逻辑方面遇到了麻烦,需要一双更有经验的眼睛(这是我在 Python 中的第一次冒险)。现在,该
它首先遍历所有 y 值,然后遍历所有 x 值。我需要 X 和 y 同时改变。 For x = 3 To lr + 1 For y = 2 To lr anyl.Cells(x, 1)
假设我有一个包含 2 列的 Excel 表格:单元格 A1 到 A10 中的日期和 B1 到 B10 中的值。 我想对五月日期的所有值求和。我有3种可能性: {=SUM((MONTH(A1:A10)=
如何转换 Z-score来自 Z-distribution (standard normal distribution, Gaussian distribution)到 p-value ?我还没有找到
我正在重写一些 Javascript 代码以在 Excel VBA 中工作。由于在这个网站上搜索,我已经设法翻译了几乎所有的 Javascript 代码!但是,有些代码我无法准确理解它在做什么。这是一
我遇到过包含日期格式的时间戳日期的情况。然后我想构建一个图表,显示“点击”项目的数量“每天”, //array declaration $array1 = array("Date" => 0); $a
我是scala的新手! 我的问题是,是否有包含成员的案例类 myItem:Option[String] 当我构造类时,我需要将字符串内容包装在: Option("some string") 要么 So
我正在用 PHP 创建一个登录系统。我需要用户使用他或她的用户名或电子邮件或电话号码登录然后使用密码。因为我知道在 Java 中我们会像 email==user^ username == user 这
我在 C++ 项目上使用 sqlite,但是当我在具有文本值的列上使用 WHERE 时出现问题 我创建了一个 sqlite 数据库: CREATE TABLE User( id INTEGER
当构造函数是显式时,它不用于隐式转换。在给定的代码片段中,构造函数被标记为 explicit。那为什么在 foo obj1(10.25); 情况下它可以工作,而在 foo obj2=10.25; 情况
我知道这是一个主观问题,所以如果需要关闭它,我深表歉意,但我觉得它经常出现,让我想知道是否普遍偏爱一种形式而不是另一种形式。 显然,最好的答案是“重构代码,这样你就不需要测试是否存在错误”,但有时没有
这两个 jQuery 选择器有什么区别? 以下是来自 w3schools.com 的定义: [attribute~=value] 选择器选择带有特定属性,其值包含特定字符串。 [attribute*=
为什么我们需要CSS [attribute|=value] Selector根本当 CSS3 [attribute*=value] Selector基本上完成相同的事情,浏览器兼容性几乎相似?是否存在
我正在解决 regx 问题。我已经有一个像这样的 regx [0-9]*([.][0-9]{2})。这是 amont 格式验证。现在,通过此验证,我想包括不应提供 0 金额。比如 10 是有效的,但
我正在研究计算机科学 A 考试的样题,但无法弄清楚为什么以下问题的正确答案是正确的。 考虑以下方法。 public static void mystery(List nums) { for (
好的,我正在编写一个 Perl 程序,它有一个我收集的值的哈希值(完全在一个完全独立的程序中)并提供给这个 Perl 脚本。这个散列是 (string,string) 的散列。 我想通过 3 种方式对
我有一个表数据如下,来自不同的表。仅当第三列具有值“债务”并且第一列(日期)具有最大值时,我才想从第四列中获取最大值。最终值基于 MAX(DATE) 而不是 MAX(PRICE)。所以用简单的语言来说
我有一个奇怪的情况,只有错误状态保存到数据库中。当“状态”应该为 true 时,我的查询仍然执行 false。 我有具有此功能的 Controller public function change_a
我有一个交易表(针对所需列进行了简化): id client_id value 1 1 200 2 2 150 3 1
我是一名优秀的程序员,十分优秀!