我正在处理来自大型机的字母数字数据。由于访问点的性质,GetString 方法在网络浏览器界面中用于从大型机中提取数据。我正在重构我的代码以及旧代码以使用数据结构而不仅仅是范围对象,因为范围对象代码在大型数据集上花费的时间要长得多。
作为一般优化实践的一部分,我运行所有大型数据集宏Application.ScreenUpdating = False
并Application.Calculation = xlCalculationManual
激活。为了计时,在将 Counter 与状态栏结合使用后,我将QueryPerformanceCounter与 DoEvents 一起使用,以便它为我提供完成特定宏所需的时间。QueryPerformanceCounter 位于类模块中,在执行我的代码的域逻辑/业务逻辑中没有直接作用。
例如,我最近重构了从大型机屏幕中提取大约 10,000 个字符串并通过循环将它们放入工作表的代码。当重构为数据结构循环时,代码在将字符串放入数组时大约需要 70 秒。代码也更便携,因为这些字符串可以很容易地转移/放置到字典中进行排序或集合中进行解析。因此,我将所有 VBA 代码从基于范围的代码切换到数据结构,这是我的问题的引入/背景。
我在一个分析项目中遇到了一些旧代码,这些代码有一些有趣的逻辑来从大型机中提取内容。本质上,代码以这种布局形式从服务器拉取内容:
然后使用 Worksheet/Cell 逻辑作为框架将内容解析为 Excel 表单中的此表单:
没有登录/访问逻辑以及没有子程序声明的代码如下:
Sub AcquireData()
CurrentServerRow = 13
WhileLoopHolder = 1
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)) <> "" Then
NewWorksheetLine_Sub
End If
Do While WhileLoopHolder = 1
If CurrentSession.Screen.Getstring(CurrentServerRow, 9, 1) = "-" Then
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow + 1, 15, 1)) <> "" Then
NewWorksheetLine_Sub
End If
ElseIf Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)) = "" Then
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14)) <> "" Then
Cells(WorksheetRow, ValueSets) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14))
ValueSets = ValueSets + 1
End If
Else
If CurrentSession.Screen.Getstring(CurrentServerRow, 5, 1) = "" Then
Cells(WorksheetRow, WorksheetColumn) = "X"
Else
Cells(WorksheetRow, WorksheetColumn) = CurrentSession.Screen.Getstring(CurrentServerRow, 5, 1)
End If
Cells(WorksheetRow, WorksheetColumn + 1) = CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)
Cells(WorksheetRow, WorksheetColumn + 2) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 17, 39))
Cells(WorksheetRow, ValueSets) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14))
WorksheetColumn = WorksheetColumn + 3
ValueSets = ValueSets + 1
End If
CurrentServerRow = CurrentServerRow + 1
If CurrentServerRow > 41 Then
WhileLoopHolder = 0
End If
Loop
End Sub
Sub NewWorksheetLine_Sub()
WorksheetRow = WorksheetRow + 1
WorksheetColumn = 1
ValueSets = 10
End Sub
这段代码嵌套在另一个程序的循环中,从而拉出数千行并整齐地组织它们。它还需要数小时并浪费宝贵的时间,这些时间可用于分析从服务器获取的数据。我设法将基本代码重构为数据结构,并利用我的学习重构其他代码。不幸的是,我错误地重构了这段代码,因为我无法正确地模仿业务逻辑。我的片段如下:
Sub AcquireData()
'This code refactors the data into a datastructure from a range object, but does not really capture the logic.
'Also, There is an error in attempting to insert a variant array into a collection/dictionary data structure.
CurrentServerRow = 13
ReDim SourceDataArray(10)
WhileLoopHolder = 1
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)) <> "" Then
NewWorksheetLine_Sub
End If
Do While WhileLoopHolder = 1
If CurrentSession.Screen.Getstring(CurrentServerRow, 9, 1) = "-" Then
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow + 1, 15, 1)) <> "" Then
NewWorksheetLine_Sub
End If
ElseIf Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)) = "" Then
If Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14)) <> "" Then
ReDim Preserve SourceDataArray(ValueSets)
SourceDataArray(ValueSets) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14))
ValueSets = ValueSets + 1
ReDim Preserve SourceDataArray(ValueSets)
End If
Else
If CurrentSession.Screen.Getstring(CurrentServerRow, 5, 1) = "" Then
ReDim Preserve SourceDataArray(WorkSheetColumn)
SourceDataArray(WorkSheetColumn) = "X"
Else
SourceDataArray(WorkSheetColumn) = CurrentSession.Screen.Getstring(CurrentServerRow, 5, 1)
End If
SourceDataArray(WorkSheetColumn + 1) = CurrentSession.Screen.Getstring(CurrentServerRow, 9, 7)
SourceDataArray(WorkSheetColumn + 2) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 17, 39))
SourceDataArray(ValueSets) = Trim(CurrentSession.Screen.Getstring(CurrentServerRow, 58, 14))
WorkSheetColumn = WorkSheetColumn + 3
ValueSets = ValueSets + 1
ReDim Preserve SourceDataArray(ValueSets)
End If
CurrentServerRow = CurrentServerRow + 1
If CurrentServerRow > 41 Then
WhileLoopHolder = 0
End If
Loop
End Sub
Sub NewWorksheetLine_Sub()
SourceIndexAsString = SourceCollectionIndex
SourceDataCollection.Add SourceDataArray(), SourceIndexAsString
SourceCollectionIndex = SourceCollectionIndex + 1
WorkSheetColumn = 1
ValueSets = 10
End Sub
我考虑过,为了使用相同类型的“单元”逻辑,我可能想使用嵌套在数组中的数组,然后将其转置到工作表中。然而,在过去的几周里,我迄今未能成功实施任何此类解决方案。此外,可能存在将逻辑重构为数据结构形式的更好方法。但是,我一直无法确定如何成功地做到这一点。
总而言之,我的问题如下:我可以通过什么方式将基于“单元”的逻辑转换为数据结构逻辑?这样做的最佳数据结构是什么?在这种特殊情况下,如何使用此业务逻辑实现数据结构逻辑的使用?