Нахождение ключа, соответствующего предмету в словаре - PullRequest
2 голосов
/ 27 января 2012

Есть ли способ найти ключ, соответствующий данному элементу в словаре VBA?

http://msdn.microsoft.com/en-us/library/aa164502%28v=office.10%29.aspx MSDN предлагает использовать свойство «Ключ», но когда я пытаюсь его использовать, я получаю сообщение об ошибке («Ошибка компиляции: недопустимое использование свойства»). В прошлом я обнаружил, что приведенный здесь метод «Exists» у меня тоже не работает, поэтому я предполагаю, что они были командами в предыдущей версии Office и теперь устарели. Однако мне не удалось найти эквивалент для последней версии Office.

Я мог бы использовать для каждого цикла, чтобы создать новый словарь, где ключи в старом словаре - это элементы в новом словаре (и наоборот), а затем использовать ".Item", но мне было интересно, если есть встроенная команда, которая позволила бы мне избежать этого.

Ответы [ 4 ]

10 голосов
/ 27 января 2012

но мне было интересно, есть ли встроенная команда, которая позволила бы мне избежать этого.

Нет, встроенной команды как таковой нет. Вам придется прибегнуть к какому-то циклу. Вот один пример. Я создал небольшую функцию, чтобы получить ключ, соответствующий элементу в словаре.

Dim Dict As Dictionary

Sub Sample()
    Set Dict = New Dictionary

    With Dict
      .CompareMode = vbBinaryCompare
      For i = 1 To 10
        .Add i, "Item " & i
      Next i
    End With

    Debug.Print GetKey(Dict, "Item 3")
End Sub

Function GetKey(Dic As Dictionary, strItem As String) As String
    Dim key As Variant
    For Each key In Dic.Keys
        If Dic.Item(key) = strItem Then
            GetKey = CStr(key)
            Exit Function
        End If
    Next
End Function
2 голосов
/ 27 января 2012

Альтернативное решение (..?)

Вместо того, чтобы просматривать каждый элемент в словаре на предмет совпадения, как насчет того, чтобы поддерживать 2 объекта словаря?Второй, использующий значение в качестве ключа и ключ в качестве его значения.Когда вы добавляете элемент, вы добавляете его в оба словаря.Если у вас есть ключ, вы ищите его в первом словаре, а если у вас есть значение, вы ищите его во втором.

0 голосов
/ 14 апреля 2015

Исходя из этого, я сначала подумал, что .exists (ключ) совершенно бесполезен. Но есть простое решение.

Во-первых, позвольте мне упомянуть бесполезную попытку:

  1. убедитесь, что при первом обращении к значению для проверки вы назначаете .exists (ключ) для логической переменной.
  2. если значение этого логического значения равно FALSE, немедленно удалите словарь
    запись, случайно созданная при тестировании ключа

Хорошо, это работает, но в следующий раз вы снова будете проверять существование с помощью этого кода

itExists = a.exists(key) 

вы можете получить ошибку 424 - разработчик .exists действительно потерпел неудачу. Но следующее будет работать (или, по крайней мере, для меня это работает ... пока)

if isempty(a.item(key)) then  ' checking on value of the object
  a.remove(key)
  a.add key, value
else ' you have a key duplicate
  ' do something about dupe, like quit
end if 

Для небольшого разъяснения вы можете посмотреть следующий пример кода


Sub aDict()
Dim a As Dictionary
Dim x As Long
Set a = New Dictionary
With a
  On Error Resume Next
' first add
  .Add 1, "sumpn"
' second add
  .Add "dog", "beagle"
  x = 66
' third add
  .Add "sixty", x
  printd a, 1, "added with numerical key"
  printd a, 2, "added with string key = dog, using numeric key=2"
  Stop    ' look at count of items: we added 3, but have 4 in local vars
  printd a, "2", "searching string key '2', not retrieving 2nd added"
  printd a, 9, "should not exist, first try"
     ' but the .exists has created it!!
  printd a, 9, "should not exist, second try, *** but now created ***"
  printd a, 8, "never seen anywhere"
Stop    ' look at a in local vars!! #8 exists now as item 7
  a.Remove 8  ' so we kill it
' *************************** the great fixit *******  
Stop    ' observe that #8 (item 7) is gone again
  printd a, "dog", "added as second position (Item 2)"
' fourth add
  .Add 1, "else" ' doublette
  printd a, 1, "position 1 is taken, Err=457 is correct"
' fifth add
  .Add 3, "beagle"
  printd a, "3", "string key='3' <> numeric 3"
' 6th add
  .Add 5, "beagle"
  printd a, "beagle", "value is already there with key 'dog'"
  printd a, 5, "numeric key=5"
End With
End Sub

Sub printd(a As Dictionary, mkey, Optional msg As String)
Dim ex As Boolean
With a
  If Err.number <> 0 Then
      Debug.Print mkey, "error " & Err.number, Err.Description
  End If
Err.clear
  ex = .Exists(mkey) ' very first reference to a.Exists(mkey)
  Debug.Print "key " & mkey, "a(" & mkey & ")" & a(mkey), _
              "Exists", ex, "a.item " & .Item(mkey), msg
  If Err.number <> 0 Then
    Debug.Print mkey, "error " & Err.number, Err.Description
  End If
End With
End Sub
0 голосов
/ 27 января 2012

На самом деле, существует метод Exists, который будет делать именно то, что вы хотите. Вот как это работает:

...
Dim dict
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "utensil", "spork"
Debug.Print dict.Exists("utensil")

Выше возвращается True.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...