2013-03-08 2 views
0

Я собираюсь преобразовать проект данных доступа (ADP) в стандартный формат ACCDB с помощью связанных таблиц ODBC. В АДФЕ, я переопределен кнопка Обновить, чтобы вернуть пользователь к текущей записи, используя следующий код:«Недействительная закладка» с DAO Recordset

Public Sub RibbonCmd_RefreshScreen(ctl As IRibbonControl, ByRef cancelDefault) 
    On Error GoTo ErrHandler 

    cancelDefault = False 

    DoCmd.Echo False 

    Dim saveBookmark 
    With Screen.ActiveForm 
     saveBookmark = .Bookmark 
     .Requery 
     .Bookmark = saveBookmark 
    End With 

    'Success - cancel the default behavior 
    cancelDefault = True 

ExitHandler: 
    DoCmd.Echo True 
    Exit Sub 

ErrHandler: 
    cancelDefault = False 
    Resume ExitHandler 

End Sub 

Я понимаю, что это должно работать нормально с DAO, но я получаю ошибку 3159, Not a valid bookmark. Я также попытался заменить .Bookmark на .Recordset.Bookmark, но это дало мне тот же результат. Что-то я здесь делаю неправильно?

ответ

1

На самом деле, требование формы или запроса набора записей будет повторно устанавливать и аннулировать буквенные знаки.

Таким образом, такие книжные знаки больше не действительны после запроса.

Так что лучший подход здесь будет зависеть от обеих

а) Я просто хочу, чтобы повторно отобразить любые измененные записи (и не отъезжать текущую запись).

b) Я просто хочу повторно отобразить любые измененные записи И ТАКЖЕ отображать новые записи (новые записи являются важной частью).

Если вам просто нужно обновить, вы можете использовать соответствующее вызванное обновление команды.

Например:

Me.Refresh 

Или в вашем случае

Screen.ActiveForm.Refresh 

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

Обратите внимание, что, так как вы можете за использование кнопки формы:

Me.Refresh 

Затем LITTLE нужно обязательно вызвать общую процедуру, как вы написали.

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

Итак, для кода, требуемого для запроса, мы используем значение PK (и, надеюсь, вы использовали значение pk по умолчанию, которое по умолчанию было 20 лет). Код бы тогда:

Dim lngID   As Long 

If IsNull(Me!ID) Then Exit Sub 

lngID = Me!ID 

Me.Requery 

Me.Recordset.FindFirst "id = " & lngID 

Теперь, конечно, если PK ID не то же самое для каждой формы, то вы, безусловно, можешь передать имя значения ПК к вашей «общей» обновлению жизни. Это будет выглядеть так:

Public Sub MyRefresh(strPK As String) 

    Dim lngID   As Long 

    If IsNull(Me(strPK)) Then Exit Sub 

    lngID = Me(strPK) 

    Me.Requery 

    Me.Recordset.FindFirst strPK & " = " & lngID 

End Sub 

«Надежда» здесь вы на самом деле очень просто нужно обновить, так как было отмечено, это только одна строка кода, а еще лучше не перемещает указатель записи.

+0

Спасибо, Альберт. Кажется, это информация, которую я отсутствовал - запрос не делает недействительной закладку в ADP, и я не понимал, что в ACCDB будет иначе. Я подумал об использовании Refresh, но я боюсь, что мне нужно реквизит. Я надеялся, что есть способ сделать это, не меняя код на использование идентификаторов, но, по крайней мере, ваш ответ объясняет, почему я должен это делать. –

0

У меня возникла идея «мгновенного фильтра», где вы позиционируете курсор в поле в форме вкладок, нажмите F2, а затем фильтр применяется, чтобы вы видели только записи с выбранным значением поля.Нажмите F2 еще раз, и фильтр будет удален, и курсор вернется в место, когда вы нажмете F2 в первый раз. Boolmarks здесь не работают, как говорит Альберт выше, но я использовал формы Recordset.AbsolutePosition, и это работает нормально, например. на выходе OnKeyDown поля

Dim PrefilterPosition As Long 

Private Sub ValnSubject_KeyDown(KeyCode As Integer, Shift As Integer) 

' Not F2 - exit 
If KeyCode <> vbKeyF2 Then Exit Sub 

' Get the active control 
Dim ActiveCtl As Control 
Set ActiveCtl = Me.ActiveControl 

ActiveControlName = ActiveCtl.Name 

' Is the form's filter set? 
If Me.Filter = "" Then 

' NO: Apply the new filter 
     ' Note the current position in the recordset 
     PrefilterPosition = Me.Recordset.AbsolutePosition 

     ' Set the filter to the Active control's value 
     Me.Filter = "[" & ActiveCtl.ControlSource & "]='" & ActiveCtl.Value & "'" 
     Me.FilterOn = Me.Filter <> "" 
     Me.Requery 
Else 

' YES: Clear the filter 
     Me.Filter = "" 
     Me.FilterOn = Me.Filter <> "" 
     Me.Requery 

     ' Align the recordset on the previously stored position 
     Me.Recordset.AbsolutePosition = PrefilterPosition 

    End If 

' Restore the cursor to where it came from 
Me.Controls(ActiveControlName).SetFocus 

Ex_it: 

End Sub 
0

Я использую VB6 и Visual Data Manager в разработке. У меня была такая же проблема. Скорее всего, это произошло, когда 2 пользователя попытались обновить одну и ту же запись за одно время. Поэтому некоторые поля в таблице повреждены. Вот шаги, которые я использовал для решения проблемы: 1- Скопируйте структуру таблицы (позвоните в нее table1) в другую таблицу (позвоните на нее table2). 2- Найти записи, выполненные в соответствии с таблицей 1. 3- Перенесите данные из таблицы1 в таблицу2, за исключением поврежденных записей 4 Повторно введите исключенные записи в таблицу2. 5- Rename table1 Таблица3 6- Rename table2 table1

Это все, Folk

[email protected]

Смежные вопросы