将工作表转换为仅包含string的数组

我需要从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) 

所有很好很好,但不幸的是,返回的数组不仅包含文本string,而且还包括typesdate,整数,双精度的原语。它多次发生数据转换。

例如:在单元格中input=NOW()并将单元格格式设置为hh:mm使得显示的值为17:45时 ,上述方法回退一个doubletypes的variables和一个类似于41194.7400990741的值

下面的解决scheme工作得更好:我可以通过使用.Text属性从单元格中获取字面文本,但它们只能在一个单元格上工作,而不能在一定范围的单元格中工作。 我无法像数组一样一次为数组做一次,因此我必须一次在数组中填充一个单元格:

 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 。 是的,在大的工作表上,显着的性能下降是显而易见的。
有人知道更好的方法来做到这一点?

正如我们在评论中所述,为了避免这个问题,你将需要在某个点上循环访问数组。 不过,我张贴这个,因为它可能会给你一个显着的速度提升取决于您的工作表上的数据types。 有200个单元是数字的一半,大约快了38%。 用相同比例的600个细胞改善了41%。

通过循环数组本身,并且只检索被解释为双精度(数字)的值的.Text ,如果存在大量的非双精度数据,则可以看到速度的提高。 这不会检查包含文本的单元格的文本,date格式为date或空白单元格。

 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 
  • 将您的工作表复制到一个新的工作表。
  • 复制粘贴值以删除公式
  • 对每一列做一个文本到列,把每一列变成文本
  • 像你最初一样加载你的数组
  • 删除新的工作表

你无法快速,轻松地做到这一点,没有循环通过工作表。 如果使用上面的两行代码的技巧,它必须是一个变体types的数组。

我从我的代码中包含了一个真正的例子,它在6行中,因为我喜欢A)与工作表对象和B)与原来的最后一行保持一个variables。

 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像这样工作的原因是当你创build一个variables数组时,数组中的每个“单元格”被设置为一个变体types。 每个单元格然后得到它的变体types设置为分配给它的任何types的值。 所以一个被赋值为string的variables被设置为variant.string,现在只能被用作string。 在你的原始示例中,它看起来像是有时间值,它们被存储为variant.time而不是variant.string。

有两种方法可以处理原始问题1)循环,并通过更多控制来执行该过程,如双嵌套for循环。 在另一个给你完全控制的答案中进行了解释2)按原样将所有数据存储在数组中,然后将其重新格式化为第二个数组,或者在使用时将其格式化为期望的文本(两者应该更快)