Вставить запрос не выполняется внутри цикла - PullRequest
1 голос
/ 01 февраля 2020

У меня проблемы с выполнением нескольких запросов на вставку с помощью VBA в Access 2016.

Я загружаю соответствующие записи из tbl_Routes в DAO.Recordset, затем перебираю их с внешним l oop, затем используйте внутреннюю l oop, чтобы вставить пять записей (по одной для каждого дня недели) в tbl_Route_Times для каждой записи из tbl_Routes.

Итак, что я хочу, чтобы мой код выполнялся так (слева направо):

(1, 1) (1, 2) (1, 3) (1, 4) (1, 5)
(2, 1) (2, 2) (2, 3) (2, 4) (2, 5)
(3, 1) (3, 2) (3, 3) (3, 4) (3, 5)

... и т. Д. Для сотен записей.

Механически петли работают просто отлично. Он проходит по каждой строке так, как вы ожидаете, но на самом деле он выполняет запрос только на первой итерации внутренней l oop каждый раз, (1, 1) (2, 1) (3, 1) и т. Д.

Она будет правильно вставлять запись при первом проходе через внутреннюю l oop, но при последующих проходах через l oop она попадет в строку .Execute, ничего не делая - запись не вставлена , нет ошибки, нет ничего. Это просто поражает и продолжает идти. Как только он запускается пять раз и ломает внутренний l oop, он переходит к следующей записи в rs и делает то же самое снова, вставляя одну запись в первый проход через внутренний l oop, но не более.

Я пробовал это с помощью DoCmd.RunSQL и каждый раз вводил значения в запрос, но результат один и тот же, независимо от того, как на самом деле выполняется запрос.

Я перестроил все с просто бессмысленным тестовым целым числом, которое увеличивается и , что на самом деле работает нормально, выполняя запрос и вставляя запись в каждую итерацию внутреннего l oop. Кажется, я выделил проблему, связанную с первой загрузкой записей в rs, затем запуском запроса на вставку, но я не знаю, что еще можно попробовать на этом этапе.

В приведенном ниже фрагменте я показываю, как настроить использование различных объектов - если есть что-то, что я делаю неправильно, это блокирует четыре из пяти запросов вставки на фактический запуск, я бы с удовольствием знаете, что это такое.

Что мне здесь не хватает?

Вот сами циклы:

' For reference...
Dim db As DAO.Database
Dim rs As DAO.Recordset

Set db = CurrentDb()
Set rs = db.OpenRecordset(strSqlSelect)

... 

Do While Not rs.EOF
     Do While dayCount < 6
          With db.CreateQueryDef("", strSqlInsert)
               .Parameters!pRid = rs!routeID
               .Parameters!pDay = dayCount     
               .Parameters!pIn = rs!checkIn  
               .Parameters!pOut = rs!checkOut 
               .Execute
          End With
          dayCount = dayCount + 1
     Loop
     dayCount = 1
     rs.MoveNext
Loop

SQL рассматриваемые операторы:

/* strSqlSelect (note: G_SCHOOLYEAR returns the value 2) */
SELECT
    tbl_Routes.routeID
  , tbl_Routes.checkInTime  AS checkIn
  , tbl_Routes.checkOutTime AS checkOutFROM tbl_Routes
WHERE
    (
        (
            (
                tbl_Routes.schoolYearID
            )
            =G_SCHOOLYEAR()
        )
    )
;

/* strSqlInsert */
INSERT INTO tbl_Route_Times
    (
        routeID
      , dayID
      , checkIn
      , checkOut
    )
    VALUES
    (
        [pRoute]
      , [pDay]
      , [pIn]
      , [pOut]
    )
;

Ответы [ 2 ]

2 голосов
/ 01 февраля 2020

Используйте DAO для таких задач - намного проще и способ быстрее:

Public Function InsertDays()

    Dim db As DAO.Database
    Dim rsSource As DAO.Recordset
    Dim rsTarget As DAO.Recordset

    Dim dayCount As Integer

    Set db = CurrentDb()
    Set rsSource = db.OpenRecordset("tbl_Routes")
    Set rsTarget = db.OpenRecordset("tbl_Route_Times")

    Do While Not rsSource.EOF
        Do While dayCount < 5
            dayCount = dayCount + 1
            With rsTarget
                .AddNew
                    !Rid.Value = rsSource!routeID.Value
                    !Day.Value = dayCount
                    !In.Value = rsSource!CheckIn.Value
                    !Out.Value = rsSource!CheckOut.Value
                .Update
            End With
        Loop
        dayCount = 0
        rsSource.MoveNext
    Loop
    rsTarget.Close
    rsSource.Close

End Function
1 голос
/ 04 февраля 2020

После попытки и .Execute dbFailOnError, и метода Густава DAO он выдал ошибку времени выполнения 3022: проблемы с индексацией. После этого не потребовалось много исследований, чтобы выяснить, что вся проблема в том, что tbl_Route_Times просто имеет неправильное поле, обозначенное как первичный ключ. Каким-то образом я ошибочно установил его на routeID, который ссылается на tbl_Routes, а не routeTimeID, как предполагалось.

Итак, примерно после трех щелчков мыши я установил первичный ключ на routeTimeID, запустил все снова и все работает нормально. Спасибо всем за помощь, которая привела меня к решению, и пару маленьких кусочков VBA, которые я раньше не использовал!

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