Как правильно поменять значения поля между двумя наборами записей, которые также были запрошены этими значениями в VBA Access - PullRequest
0 голосов
/ 11 ноября 2018

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

  1. Сохраните все записи, где PhaseID равен X, в набор записей A
  2. Сохраните все записи, где PhaseID равен Y, вНабор записей B
  3. Установите для всех записей в наборе записей A значение PhaseID, равное Y
  4. Установите для всех записей в наборе записей B значение PhaseID, равное X

Вот мойФактический код:

Private Sub swapReferences(firstRec() As Variant, secondRec() As Variant)
      ...
      Set rstFirst = CurrentDb.OpenRecordset("Select * From Scenarios Where PhaseID = " & firstRec(0))
      Set rstSecond = CurrentDb.OpenRecordset("Select * From Scenarios Where PhaseID = " & secondRec(0))

      updateRecords rstFirst, "PhaseID", secondRec(0)
      updateRecords rstSecond, "PhaseID", firstRec(0)
End Sub

Private Sub updateRecords(rst As Recordset, fieldName As String, newVal As Variant)
     While Not rst.EOF
        rst.Edit
        rst(fieldName) = newVal
        rst.update
        rst.MoveNext
     Wend
End Sub

Странно то, что этот код может работать с первого раза (в этом случае значения на самом деле меняются местами).Но во второй раз это почти гарантированно провалится.В результате вместо обмена строками один из наборов записей получает все записи, а другой - ни одной.Как будто rstSecond динамически увеличивается, когда rstFirst обновляет свои записи, чтобы получить значения, с которыми запросил rstSecond.

Еще более странным является то, что мне показалось, что я нашел исправление, которое не имеет никакого смысла.Я изменил первую функцию, как показано:

Private Sub swapReferences(firstRec() As Variant, secondRec() As Variant)
    Set rstFirst = CurrentDb.OpenRecordset("Select * From Scenarios Where PhaseID = " & firstRec(0))
    Set rstSecond = CurrentDb.OpenRecordset("Select * From Scenarios Where PhaseID = " & secondRec(0))

    'Debug
    If Not rstSecond.EOF Then
       'For whatever reason .RecordCount isn't accurate unless the last record has been accessed
       rstSecond.MoveLast
       Debug.Print rstSecond.RecordCount
       rstSecond.MoveFirst
    End If

    updateRecords rstFirst, "PhaseID", secondRec(0)

    'Debug
    If Not rstSecond.EOF Then
       rstSecond.MoveLast
       Debug.Print rstSecond.RecordCount
       rstSecond.MoveFirst
    End If

    updateRecords rstSecond, "PhaseID", firstRec(0)
End Sub

Те, если блоки использовались, чтобы увидеть, магически ли rstSecond изменял свой размер после того, как rstFirst обновил свои записи.Когда я запустил код с этими блоками отладки, я обнаружил, что не только константа rstSecond осталась неизменной, но и мой код работал должным образом.

Итак, мой вопрос двоякий: почему добавление этих блоков отладки исправило мой код?И есть ли более подходящий способ сделать то, что я хочу сделать, чтобы мой код не казался настолько бессмысленным?

...