Добавление словаря vbscript в цикле, приводящее к существующей ключевой ошибке - PullRequest
1 голос
/ 19 июля 2011

Я просто пытаюсь создать словарь идентификаторов продуктов

dim viewableProductIDs : set viewableProductIDs = CreateObject("Scripting.Dictionary")
    do while not rsEntry.EOF
        viewableProductIDs.Add rsEntry("ProductID"), true
        rsEntry.MoveNext
    loop

rsEntry - это набор записей ADODB, и благодаря исчерпывающей печати отладки я убедился, что мой запрос действительно возвращает уникальные идентификаторы productID и что в наборе записей нет дубликатов. Тем не менее, каким-то образом VBScript настаивает на том, чтобы думать, что есть дубликаты. Это добавит первый штраф, но после этого он выдаст ошибки всем остальным. Я попытался окружить его проверкой существующего ключа, и он каким-то образом думал, что они все, но первый, существовал. Затем, в конце концов, у меня остается словарь, в котором есть только одна запись.

Кто-нибудь знает, почему он это делает?

1 Ответ

5 голосов
/ 19 июля 2011

Попробуйте добавить .Value:

viewableProductIDs.Add rsEntry("ProductID").Value, true

Объяснение:

VBScript имеет концепцию, называемую свойствами по умолчанию.Например, строка

someString = rsEntry("ProductID")

действительно является сокращением для

someString = rsEntry.Fields.Item("ProductID").Value

, где Fields, Item и Value - все свойства по умолчанию соответствующих объектов.Основная проблема здесь заключается в последнем шаге цепочки: разница между rsEntry("ProductID") и rsEntry("ProductID").Value.В приведенном выше примере, поскольку я не использовал ключевое слово Set, ссылка на объект была бы недопустимой для правой части присваивания.Поскольку rsEntry("ProductID") соответствует ссылке на объект Field, интерпретатор делает следующий шаг и раскрывает свойство по умолчанию для объекта Field, Value.Если бы я сделал

Set someObj = rsEntry("ProductID")

, интерпретатор установил бы someObj ссылку на объект Field.

Теперь вот забавная часть: объект Dictionary может использовать любой типзначения в качестве его ключей.Чаще всего используются простые значения, такие как строки или числа, но вполне допустимо использовать массивы или ссылки на объекты.Поскольку ссылка на объект допустима для первого аргумента метода Dictionary.Add, интерпретатор не заботится о расширении свойства по умолчанию и просто использует ссылку на объект Field в качестве ключа.Поскольку ссылка на объект Field не меняется от записи к записи, вы пытаетесь добавлять один и тот же ключ снова и снова.Добавление .Value четко дает понять интерпретатору, что вы хотите получить значение, а не объект.

...