我需要将excel工作表中的数据提取到将在使用VBScript作为脚本语言(Quick Test Professional)的应用程序中使用的数组。我们可以使用以下代码:
' ws must be an object of type Worksheet
Public Function GetArrayFromWorksheet(byref ws)
GetArrayFromWorksheet = ws.UsedRange.Value
End Function
myArray = GetArrayFromWorksheet(myWorksheet)
MsgBox "The value of cell C2 = " & myArray(2, 3)
一切都很好,但不幸的是,返回的数组不仅包含文字文本字符串,还包含date,integer,double等类型的原语。它发生了多次,数据被转换。
[edit] 示例:在单元格中输入=NOW()
并将单元格格式设置为hh:mm
时,显示的值 17:45 ,上述方法返回类型为double
的变量和类似 41194.7400990741
以下解决方案效果更好:我可以使用.Text
属性从单元格中获取文字文本,但它们只能在一个单元格上工作,而不能在一系列单元格上工作。我不能像.Value
属性那样立即对数组执行此操作,因此我必须一次填充数组一个单元格:
Public Function GetArrayFromWorksheet_2(byref ws)
Dim range, myArr(), row, col
Set range = ws.UsedRange
' build a new array with the row / column count as upperbound
ReDim myArr(range.rows.count, range.columns.count)
For row = 1 to range.rows.count
For col = 1 to range.columns.count
myArr(row, col) = range.cells(row, col).text
Next
Next
GetArrayFromWorksheet_2 = myArr
End Function
但是哎呀......一个嵌套的for loop
。是的,在大型工作表上有明显的性能下降
有人知道更好的方法吗?
答案 0 :(得分:2)
正如我们在评论中所述,为了避免这个问题,您需要在某个时刻遍历数组。但是,我发布此信息是因为 可能 会根据工作表中的数据类型显着提高速度。由于200个单元格是数字的一半,因此速度提高约38%。使用相同比例的600个细胞,改善率为41%。
通过循环遍历数组本身,并且只检索解释为双精度(数字)的值的.Text
,如果存在大量非双精度数据,则可以看到速度提高。这不会检查.Text
是否包含带文本的单元格,日期格式为日期或空白单元格。
Public Function GetArrayFromWorksheet_3(ByRef ws)
Dim range, myArr, row, col
Set range = ws.UsedRange
'Copy the values of the range to temporary array
myArr = range
'Confirm that an array was returned.
'Value will not be an array if the used range is only 1 cells
If IsArray(myArr) Then
For row = 1 To range.Rows.Count
For col = 1 To range.Columns.Count
'Make sure array value is not empty and is numeric
If Not IsEmpty(myArr(row, col)) And _
IsNumeric(myArr(row, col)) Then
'Replace numeric value with a string of the text.
myArr(row, col) = range.Cells(row, col).Text
End If
Next
Next
Else
'Change myArr into an array so you still return an array.
Dim tempArr(1 To 1, 1 To 1)
tempArr(1, 1) = myArr
myArr = tempArr
End If
GetArrayFromWorksheet_3 = myArr
End Function
答案 1 :(得分:0)
答案 2 :(得分:0)
如果不循环使用工作表,您无法快速轻松地完成此操作。 如果您使用上面的技术使用2行代码,那么它必须是变体类型数组。
我已经在我的代码中包含了一个真实的例子,它在6行中完成,因为我喜欢A)使用工作表对象和B)保持变量方便原始的最后一行。
Dim wsKeyword As Worksheet
Set wsKeyword = Sheets("Keywords")
Dim iLastKeywordRow As Long
iLastKeywordRow = wsKeyword.Range("A" & wsKeyword.Rows.Count).End(xlUp).Row
Dim strKeywordsArray As Variant
strKeywordsArray = wsKeyword.Range("A1:N" & iLastKeywordRow).Value
请注意,您的数组必须是一种可以这种方式使用的变体。
Variants这样工作的原因是,当您创建变体数组时,数组中的每个“单元格”都设置为变体类型。然后每个单元格获得它的变体类型设置为分配给它的任何类型的值。因此,为字符串分配的变量将设置为variant.string,现在只能用作字符串。在您的原始示例中,您看起来有时间值,它们存储为variant.time而不是variant.string。
有两种方法可以解决原始问题 1)循环并使用更多控件执行该过程,如双嵌套for循环。在另一个答案中解释,它给你完全控制 2)按原样存储数组中的所有数据,然后将其重新格式化为第二个数组,或者在使用时将其格式化为所需的文本(两者都应该更快)