У меня есть приложение, для которого я в настоящее время использую объект словаря (в частности, это словарь словарей словарей, поэтому каждый поиск имеет три шага, если это имеет смысл!). Я делаю большое количество поисков на этих словарях и умножаю результаты вместе.excel словарь object error
Проблема в том, что в предыдущей версии приложения я использовал функцию VLookup для выполнения этой функции, и она будет ошибочной, когда я попытаюсь найти ключ, которого не было. Теперь он возвращает «Пустое», которое Excel с удовольствием размножается тем, что у меня уже было, и возвращает ноль. Это трудно отследить, и я бы очень хотел, чтобы он возвращал ошибку, как раньше.
Есть ли что-то, что я могу изменить, чтобы вернуть его, как это было бы с VLookup, или мне нужно создать новый модуль класса для этого? Модуль класса, скорее всего, потребует от меня перезаписать большой объем кода, который я бы хотел избежать (есть сотни запросов, которые мне нужно будет обновить в коде).
Спасибо.
Вот некоторые из моего кода:
Это модуль, который я использую для загрузки во всех таблицах в словаре:
Sub LoadFactorsAndBaseRates()
Dim t As Double
t = Timer
Dim n As Name
Dim TempArray()
Dim dict1 As Dictionary
Dim dict2 As Dictionary
Dim i As Integer
Dim j As Integer
For Each n In ThisWorkbook.Names
If InStr(1, n.RefersTo, "#") <> 0 Or InStr(1, n.RefersTo, "\") Then GoTo skipname
If Not FactorLookup.Exists(n.Name) And n.RefersToRange.Parent.Name <> "Rate Matrix" And InStr(1, n.Name, "Print") = 0 And InStr(1, n.Name, "FilterDatabase") = 0 And n.Name <> "Policies" Then
Set dict1 = New Dictionary
On Error GoTo err1
TempArray = n.RefersToRange.Value
For j = 1 To n.RefersToRange.Columns.Count
On Error Resume Next
Set dict2 = New Dictionary
For i = 1 To UBound(TempArray, 1)
dict2.Add TempArray(i, 1), TempArray(i, j)
Next i
dict1.Add j, dict2
Next j
Erase TempArray
FactorLookup.Add n.Name, dict1
End If
skipname:
Next n
Exit Sub
err1:
If Err.number = 1004 Then Resume skipname
End Sub
А вот пример кода поиска:
CoverageColumn = 2
'Base Rate
Temp = FactorLookup("Base_Rates")(CoverageColumn)(State & "_" & Company & "_" & Terr)
If Vehicle <> "Snowmobile" Then
'Class 1
x = FactorLookup("Class1")(CoverageColumn)(State & "_" & Company & "_" & Class1)
Temp = xRound(Temp * x, 1)
'Class 2
x = FactorLookup("Class2")(CoverageColumn)(State & "_" & Company & "_" & Class2)
Temp = xRound(Temp * x, 1)
'Class 3
x = FactorLookup("Class3")(CoverageColumn)(State & "_" & Company & "_" & Class3)
Temp = xRound(Temp * x, 1)
'Class 4
x = FactorLookup("Class4")(CoverageColumn)(State & "_" & Company & "_" & Class4)
Temp = xRound(Temp * x, 1)
Код в основном представляет собой кучу страниц этого: посмотрите вверх, умножьте, округлите до ближайшей десятой, повторите. Иногда есть шаг, на котором мы добавляем вместо умножения.
Функция xRound добавляет 0,0000001, а затем использует функцию Round для округления до указанного числа десятичных знаков (для учета странности функции округления Excel VBA).
Можете ли вы проверить данные, чтобы увидеть, пуст ли он до умножения? Например. 'If IsEmpty (MyVariable) = False then ...' –
Прежде чем мы получим дальнейшее, мне любопытно, почему у вас есть три уровня вложенного словаря. Я предполагаю, что вы используете их для построения связей между таблицами, а затем запрашиваете эти отношения. В этом случае я бы определенно предложил перейти к системе, созданной для этих видов запросов (либо для миграции в базу данных, либо просто для непосредственного запроса Excel непосредственно, как базы данных с использованием ADO). – Mikegrann
Да, перед умножением данные пустые, но добавление операторов «if» вокруг каждого отдельного поиска было бы чрезвычайно трудоемким. Я могу это сделать, но это то, что я пытаюсь избежать, если это возможно. – whitesox130