使用 JACOB SafeArray getDoubles() 方法
我正在尝试从 Excel 工作簿中提取双值向量。 Excel 看起来不会返回一维数组,而是一个多维数组(维数为 2)。
我从 Excel 获得的数据是 SafeArray 格式(我也可以有 Variant,但基本上是同样的问题)。
我正在寻找一种将双精度数组提取到 Java 对象中的快速方法,而不需要循环 SafeArray 中的所有值。
查看 SafeArray 中的方法,有这样一个: getDoubles(int sa_idx, int nelems, double[] ja, int ja_start)
显然文档为空,我无法确定这个方法的作用,因为尝试使用它没有给我任何结果。
谢谢。
I'm trying to extract from an Excel Workbook a vector of double values.
Excel looks like does not return a unidimensional array, but a multidimensional one (number of dimensions is 2).
The data I have from Excel is in SafeArray format (I can have Variant too, but it's basically the same problem).
I'm looking for a fast way to extract the doubles array into a Java object, without needing to loop all the values in the SafeArray.
Looking at the methods in SafeArray there is this one:
getDoubles(int sa_idx, int nelems, double[] ja, int ja_start)
Obviously documentation is null, and I can't make up my mind of what this method does, since trying to use it gave me no results.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我假设您的数据来自电子表格(Range 对象),而不是 VBA 代码。
在这种情况下,Excel 将为您提供一个 Variants 的 SafeArray(VBA 术语中的
Variant()
),而不是双精度数的 SafeArray (Double()
),无论细胞的内容物恰好是。并且您是正确的,数组将始终是二维的(或者如果范围大小恰好为 1x1,它将返回单个 Variant)。我不熟悉 JACOB,是的,文档看起来相当缺乏。难道
getDoubles()
仅当 SafeArray 是 Double 的 SafeArray 时才起作用?您是否尝试过使用getVariants()
?如果你得到一些回报,我们就会知道我们走在正确的轨道上。请记住,从性能角度来看,您会陷入困境。某人(你或图书馆)将不得不编写该循环。变体不会神奇地变成双打;有人必须循环遍历数组,调用 Win32
VariantChangeType()
或等效方法,从 Variant 中提取双精度字段(显然在 JACOB 中,您调用changeType()
然后getDouble()
),最后将结果放入 Java double 数组中。我不知道雅各布会为你做这件事还是你必须自己做。不熟悉雅各布,我不确定我是否有道理,但我希望这会有所帮助。祝你好运。
[PS:]
我觉得我需要澄清有关调用
VariantChangeType()
的评论。这在技术上是可选的,但我发现通过VariantChangeType()
或等效方法将变体显式转换为我感兴趣的数据类型通常是健康的。将数字存储为字符串或其他内容太容易了,特别是当源是像 Excel 这样自由格式的东西时。当您使用像CDbl()
这样的函数时,该 API 调用正是 VB/VBA 所调用的。请注意,只要有一点错误的格式,您就会得到 DATE 而不是 Double。如果您绝对肯定所有单元格都将包含数字(双精度数)并且 Excel 永远不会向您返回任何其他内容,那么请务必直接调用 JACOB 的
getDouble()
并跳过转换步骤。I'm assuming here your data comes from a spreadsheet (Range object), not VBA code.
In that case, Excel will hand you a SafeArray of Variants (
Variant()
in VBA terminology), not a SafeArray of doubles (Double()
), no matter what the contents of the cells happen to be. And you are correct that the array will always be two-dimensional (or it will return a single Variant if the range size is exactly 1x1).I'm not familiar with JACOB, and yes, the documentation looks rather lacking. Could it be that
getDoubles()
only works when the SafeArray is a SafeArray of Doubles? Did you try to usegetVariants()
? If you get something back we'll know we're on the right track.Keep in mind that performance-wise, you are stuck. somebody (you or the library) is going to have to write that loop. The Variants won't magically become doubles; someone will have to loop through the array, call Win32
VariantChangeType()
or an equivalent method, extract the double field from the Variant (apparently in JACOB you callchangeType()
thengetDouble()
), and finally put the results in a Java double array. Whether JACOB will do this for you or you have to do it yourself, I have no idea.Not being familiar with JACOB I'm not sure I I'm making sense, but I hope this helps. Good luck.
[PS:]
I feel I need to clarify that comment on calling
VariantChangeType()
. This is technically optional, but I find it generally healthy to explicitly convert variants to the data type I'm interested in viaVariantChangeType()
or an equivalent method. It's too easy for numbers to be stored as strings or something else, particularly when the source is something as free-form as Excel. This API call is exactly what VB/VBA calls when you use a function likeCDbl()
. Be aware that a bit of errant formatting is all it takes for you to be provided with a DATE instead of a Double.If you are absolutely, positive beyond sure that all the cells will contain numbers (doubles) and Excel will never return to you anything else, then by all means call JACOB's
getDouble()
directly and skip the conversion step.