Добавить данные в ADODB Recordset динамически - PullRequest
2 голосов
/ 24 сентября 2019

Интересно, возможно ли добавить данные в набор записей ADODB, используя список именованных диапазонов без указания имен в отдельных строках.

Я попытался оценить имя, но набор записей воспринимает мою переменную какимя, ставшее целью его оценки.Это приводит к ошибке, поскольку в базе данных нет имени с моим именем переменной.

Set rst = New ADODB.Recordset

SqlStr = "SELECT * From " & table & ";"
rst.Open SqlStr, conn, adOpenDynamic, adLockOptimistic 'adLockPessimistic

If rst.EOF Then
    rst.AddNew
End If

namedCells = Array("orgNr", "name")

With rst
    For i = LBound(namedCells) To UBound(namedCells)
        MsgBox (namedCells(i) & " = " & Range(namedCells(i)))
        !orgNr = Range(namedCells(i)) 'works fine
        !namedCells(i) = "!orgNr" 'gives error du to "namedCells(i)" is not present in database
    Next i
End With

Ответы [ 2 ]

3 голосов
/ 24 сентября 2019

Оператор ! bang - это просто сокращенная запись неявного вызова члена по умолчанию.

Когда вы делаете это:

Debug.Print rs!SomeField

В действительности происходит следующее:

Debug.Print rs.[Default].[Default]("SomeField").[Default]

Три неявных вызова члена по умолчанию - первый для объекта Recordset - это свойство Recordset.Fields, которое дает ссылку на объект Fields, которая сама имеет элемент по умолчанию Item, который принимает String аргумент - оператор ! bang передает идентификатор, следующий за ним, в качестве значения для этого строкового аргумента (поэтому вам нужно заключить его в квадратные скобки, если это не допустимое имя идентификатора VBA) - этот Item член возвращаетField объект, который также имеет элемент по умолчанию Value.Таким образом, полностью прописанная запись оператора взрыва становится следующей:

Debug.Print rs.Fields.Item("FieldName").Value

Теперь вызовы по умолчанию для членов, которые являются параметризованными (/ проиндексированными), обычно считаются хорошими, так что это тоже нормально:

Debug.Print rs.Fields("FieldName").Value

Все остальное включает неявные вызовы членов по умолчанию и заставляет ваш код говорить одно ... и фактически делать другое.

Обратите внимание, что эти неквалифицированные вызовы Range, которые вы имеете в этомФрагмент, неявно ссылается на то, что ActiveSheet равно , и это очень распространенный источник ошибок.

См. Современные рекомендации VBA: члены по умолчанию длябольше информации о членах по умолчанию и лучших практиках вокруг них (я написал эту статью).

3 голосов
/ 24 сентября 2019

Вы можете попробовать с .fields:

For i = LBound(namedCells) To UBound(namedCells)
    MsgBox (namedCells(i) & " = " & Range(namedCells(i)))
    rst!orgNr = Range(namedCells(i)) 'works fine
    rst.fields(namedCells(i)) = Range(namedCells(i))
Next i
...