【发布时间】:2021-10-15 22:42:24
【问题描述】:
我有一个包含 30,000 行和 28 列数据的电子表格。我正在寻找以特定方式对数据进行编码。数据由字符串和数字的混合组成。对于每一行(第 1 到 28 列),我需要将每个单元格中的每个字符转换为一个数字。我有一本字典来进行转换。其中字符是键,值是编码。
我的代码可以运行,但是速度有点慢。完成任务需要 30 多分钟。鉴于我们正在查看的数据量,这是可以理解的。 30, 000 行 x 28 列 x N 个字符。很多。
以下代码的快速说明:
- 循环遍历 Range 中的每个单元格(30,000 行,28 列)
- 对于每一行,将所有值连接成一个字符串
- 将大字符串逐个字符传递到字典中,检索编码值(数字)。
- 将编码字符串写入工作表。每个值都有自己的单元格。
我猜瓶颈是当我在循环中将编码写入工作表时。我想知道他们是否是一种更快的方法?
Sub main()
Application.DisplayAlerts = False
Application.ScreenUpdating = False
'initialize dictionary for encoding data on another module
Globals.initialize_globals
'loop through each record
Dim wkbook As Workbook: Set wkbook = Workbooks.Application.ActiveWorkbook
Dim wksheet As Worksheet: Set wksheet = wkbook.Worksheets("Raw Data")
Dim lastRow As Integer: lastRow = wksheet.Cells(Rows.Count, 1).End(xlUp).Row
Dim stringbuilder As String
Dim encoding() As Integer
Dim char_count As Integer
Dim i, ii, e As Integer
'loop through rows, columns and encode string data
For i = 2 To lastRow
'loop through columns
For ii = 1 To 27
'concatenate each cell value as a large string
stringbuilder = stringbuilder & wksheet.Range(Cells(i, ii), Cells(i, ii)).Value
Next
encoding = EncodeString(stringbuilder)
stringbuilder = ""
For e = 1 To UBound(encoding)
'write encoding onto sheet
wksheet.Range(Cells(i, 33 + e), Cells(i, 33 + e)) = encoding(e)
Next
Next
Application.DisplayAlerts = True
Application.ScreenUpdating = True
End Sub
Function EncodeString(str As String) As Integer()
Dim encoded() As Integer
ReDim encoded(1 To Len(str))
For i = 1 To Len(str)
' build an encoded string by passing in each character as a key, and retrieve encoded value
encoded(i) = Parameters.Item(Mid(str, i, 1))
Next
EncodeString = encoded
End Function
【问题讨论】:
-
什么是“参数”?问题中提到的字典被声明为全局变量?有一些方法可以提高代码速度:单元之间的迭代比数组元素之间的迭代快得多。因此,将要处理的范围放在一个数组中。然后,在单元格中写入非常耗时。尝试声明另一个数组并使用编码值加载它,然后将数组内容一次放在代码末尾。
-
你能估计最大
N(一行的字符数)吗?至少可以确保支付必要的金额......
标签: excel vba performance