我有一个从MS SQL数据库获取数据的Excel工作簿。其中一张表用于根据需求检查数据并突出显示故障。为了做到这一点,我得到了一个要求表,其中要求在命名范围内;更新数据后,我将表头的条件格式复制到所有数据行。到目前为止,这非常有效。当我有多套要求时,问题出现了:
一个(非常愚蠢的)例子可能是赛车,其中可能存在驾驶员执照和最小/最大马力的要求。在查看示例时,请想象目前有几千行和71列......
+-----+--------+----------------+------------+---------+
| Car | Race | RequirementSet | Horsepower | License |
+-----+--------+----------------+------------+---------+
| 1 | Monaco | 2 | 200 | A |
+-----+--------+----------------+------------+---------+
| 2 | Monaco | 2 | 400 | B |
+-----+--------+----------------+------------+---------+
| 3 | Japan | 3 | 200 | C |
+-----+--------+----------------+------------+---------+
| 4 | Japan | 3 | 300 | A |
+-----+--------+----------------+------------+---------+
| 5 | Japan | 3 | 350 | B |
+-----+--------+----------------+------------+---------+
| 6 | Mexico | 1 | 200 | A |
+-----+--------+----------------+------------+---------+
现在需要根据另一张表中设置的要求检查单个数据:
+-------------+---------------+---------------+---------+
| Requirement | MinHorsepower | MaxHorsepower | License |
+-------------+---------------+---------------+---------+
| 1 | 200 | 250 | A |
+-------------+---------------+---------------+---------+
| 2 | 250 | 500 | B |
+-------------+---------------+---------------+---------+
| 3 | 250 | 400 | A |
+-------------+---------------+---------------+---------+
为了回顾我目前的情况,我只关注摩纳哥,日本或墨西哥的比赛,而且在要求表中只有1条记录,例如, Cell B2始终是MinHorsepower,C2中的值始终是MaxHorsepower。因此,这些单元格是我可以在数据表中访问的命名范围。
现在我想立刻获得所有比赛,并将条件格式公式引用到特定要求。
专注于"马力"在摩纳哥(要求集2),我现在可以发现最小马力是250并且最大值是500 - 所以我将为汽车1的那个列着色为红色,对于汽车2为绿色。
公式是从标题行以编程方式复制的(第一个条件格式规则是if row(D1) = 1 then do nothing
)
我无法确定解决问题的最佳方法是什么。理想情况下,公式是可读的,例如`AND(D2> = MinHorsepower; D2< = MaxHorsepower) - 如果我不得不使用Vlookup与Indirect和Match结合使用以匹配需求中的列标题,我无法想象它是可维护的对于那个特殊的要求 - 特别是当涉及到HP例子中的标准与上面的min和max相结合时。
我想知道我是否应该将需求表读入字典或VBA中的某些内容,然后使用像
这样的函数public function check(requirementId as int, requirement$)
然后在Excel中我可以使用=D2 >= check(c2, "MinHorsepower")
稍微玩一下它似乎相当慢,而以前的系统我只能有一个要求。如果你能帮助我解决这个问题,那将是非常棒的。随着我的进展,我会更新这个问题;我不确定我是否能够很好地说明这个例子,但实际的数据对你来说并不意味着什么。 无论如何,谢谢你们一直待在这里!
编辑2016年10月29日
I have found a solution作为我的基础。使用以下代码,我可以将整个需求表添加到字典中,并访问需求。
使用clsRangeToDictionary类(基于Tim Williams clsMatrix)
Option Explicit
Private m_array As Variant
Private dictRows As Object
Private dictColumns As Object
Public Sub Init(vArray As Variant)
Dim i As Long
Set dictRows = CreateObject("Scripting.Dictionary")
Set dictColumns = CreateObject("Scripting.Dictionary")
'add the row keys and positions. Skip the first row as it contains the column key
For i = LBound(vArray, 1) + 1 To UBound(vArray, 1)
dictRows.Add vArray(i, 1), i
Next i
'add the column keys and positions, skipping the first column
For i = LBound(vArray, 2) + 1 To UBound(vArray, 2)
dictColumns.Add vArray(1, i), i
Next i
' store the array for future use
m_array = vArray
End Sub
Public Function GetValue(rowKey, colKey) As Variant
If dictRows.Exists(rowKey) And dictColumns.Exists(colKey) Then
GetValue = m_array(dictRows(rowKey), dictColumns(colKey))
Else
Err.Raise 1000, "clsRangeToDictionary:GetValue", "The requested row key " & CStr(rowKey) & " or column Key " & CStr(colKey) & " does not exist"
End If
End Function
' return a zero-based array of RowKeys
Public Function RowKeys() As Variant
RowKeys = dictRows.Keys
End Function
' return a zero-based array of ColumnKeys
Public Function ColumnKeys() As Variant
ColumnKeys = dictColumns.Keys
End Function
我现在可以将整个RequirementSet表读入字典并编写一个帮助程序来大致获取特定需求:
myDictionaryObject.GetValue(table1's RequirementSet, "MinHorsePower")
如果有人可以帮我弄清楚如何把这个放到答案中,因为蒂姆·威廉姆斯会给你带来的好处。