2014-12-12 4 views
1

У меня есть форма Access 2007, которая дает мне головную боль.Me.Dirty перемещает выбранную в данный момент запись

У меня есть список записей, которые начинаются как поле со списком, чтобы выбрать компанию, а затем ряд флажков, чтобы указать роль компании.

Screenshot

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

Private Sub chkOperationsAndMaintenance_AfterUpdate() 
    'DoCmd.RunCommand acCmdSaveRecord' 
    If Me.Dirty Then Me.Dirty = False 
    If chkOperationsAndMaintenance.Value = True Then 
     DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog 
     Me.Requery 
    End If 
End Sub 

Этот код будет сохранять запись на столе CompanyProject создать строку. Затем он вытаскивает CompanyProjectID (ПК из таблицы CompanyProject), чтобы он знал, какой идентификатор подает всплывающее окно.

Проблема, с которой я сталкиваюсь, заключается в том, что на линии Me.Dirty (а также выше вычисленной acCmdSaveRecord) вся форма сохраняет и обновляет, перемещая выбранную строку в первую запись (в этом случае " Gamesa ") вместо новой записи. Таким образом, появившееся всплывающее окно кормится CompanyProjectID первой записи, а не вновь введенной записью, а также считывает «проверенное» состояние флажка из первой записи, а не того, на котором работает пользователь.

Я лечил код, чтобы выглядеть следующим образом:

Private Sub chkOperationsAndMaintenance_AfterUpdate() 
    Dim CPID As Long 
    Dim CID As Long 
    Dim rs As Recordset 
    Set rs = Me.RecordsetClone 
    CID = Me.CompanyID 
    'DoCmd.RunCommand acCmdSaveRecord' 
    If Me.Dirty Then Me.Dirty = False 
    CPID = DLookup("MAX(CompanyProjectID)", "CompanyProject", "cpProjectID = " & Me.cpProjectID & _ 
     " AND CompanyID = " & CID) 
    rs.Find "[CompanyProjectID] = " & CPID 
    Me.Bookmark = rs.Bookmark 
    If chkOperationsAndMaintenance.Value = True Then 
     DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog 
     Me.Requery 
    End If 
End Sub 

Идея этих изменений является то, что мы получим FK из родительской формы («cpProjectID») и CompanyID отбора из combobox, затем сохраните запись. После сохранения записи у нас уже сохранен PropertyProjectID, поэтому строки rs.Find и Me.Bookmark затем выберут запись, соответствующую этому CompanyProjectID.

Это иногда работает, а иногда и нет. Как правило, нет. В этом случае я обновил родительскую форму и текущую форму и попытался добавить новую компанию, а затем установите флажок «Владелец» (который использует тот же код, что и выше, только другой идентификатор флажка), чтобы увидеть закладку не по адресу ряд:

Screenshot2

на данный момент, я не знаю, что делать. Если я не сохраняю запись (через acCmdSaveRecord или Me.Dirty = False), то у меня нет объекта CompanyProjectID для отправки в качестве входного параметра для последующего всплывающего окна, но если я сохраню запись, форма изменит запись и неправильный параметр отправляются, и считывается неверное состояние флажка. Я не могу просто использовать произвольный индекс для работы (например, acNewRec), так как пользователю может потребоваться изменить существующую строку вместо добавления новой.

Я пробовал метод в этом сообщении уже: MS Access how to Update current row, move to next record, not first, но поиск/закладка не всегда работает.

EDIT (12/15/2014)

Я в конечном итоге происходит с помощью следующего кода VBA:

Private Sub chkOperationsAndMaintenance_AfterUpdate() 
    Dim CPID As Long 
    Dim CID As Long 
    Dim rs As Recordset 
    Set rs = Me.RecordsetClone 
    CID = Me.CompanyID 
    If Me.Dirty Then Me.Dirty = False 
    CPID = DLookup("MAX(CompanyProjectID)", "CompanyProject", "cpProjectID = " & Me.cpProjectID & _ 
     " AND CompanyID = " & CID) 
    Do While Me.CompanyProjectID <> CPID 
     If Me.CurrentRecord < Me.Recordset.RecordCount Then 
      DoCmd.GoToRecord , , acNext 
     Else 
      DoCmd.GoToRecord , , acFirst 
     End If 
    Loop 
    If chkOperationsAndMaintenance.Value = True Then 
     DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog 
     Me.Requery 
    End If 
End Sub 

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

+0

'Me.Requery' - это код, который встряхивает вещи. Он перестраивает набор записей с нуля, делает недействительными любые закладки и переходит к форме в первую запись. – pteranodon

+1

Это не сработает в случае с Rockie «пользователю может потребоваться отредактировать существующую строку вместо добавления новой» –

+0

Точно @Tom, спасибо за ответ. Запрос не влияет на выбор записи, поскольку проблемы возникают до DoCmd.OpenForm, а запрос - только для того, чтобы завершить домены пользователя в этой записи. Спасибо! – RockiesMagicNumber

ответ

1

Вы считали сохранение текущей позиции - как Me.CurrentRecord, а затем после сохранения сохраняете нужную запись. Например, вы можете добавить «Before» или «After» Insert, чтобы сохранить позицию, а затем переместить. Смотрите следующее:

Option Compare Database 
Option Explicit 

Dim lCurRec As Long 

Private Sub Form_AfterInsert() 
    lCurRec = Me.CurrentRecord 
    Debug.Print "After Insert, Current: " & Me.CurrentRecord 
End Sub 

<<< YOUR SUB>>> 
DoCmd.GoToRecord acDataForm, Me.Name, acGoTo, lCurRec 
1

Этот код будет работать при добавлении новой записи, а также при редактировании существующей записи:

Private Sub chkOperationsAndMaintenance_AfterUpdate() 
    Dim c As Long 
    Me.Dirty = False   
    If chkOperationsAndMaintenance Then 
     DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog 
     c = Me.CurrentRecord     
     Me.Requery       
     DoCmd.GoToRecord , , acGoTo, c  
    End If 
    End Sub 

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

Private Sub chkOperationsAndMaintenance_AfterUpdate() 
    Me.Dirty = False 
    If chkOperationsAndMaintenance Then 
     DoCmd.OpenForm "OmPopupForm", , , "CompanyProjectId = " & Me.CompanyProjectID, , acDialog 
    End If 
    End Sub 
+0

Лемме посмотрим, смогу ли я заставить это работать, слегка подправленный. Проблема в том, что Me.Dirty или acCmdSaveRecord обновляет форму и выбирает первую запись в этой форме, поэтому, если я пытаюсь работать над третьей записью, когда она сохраняет запись, она выделяет первое и отправляет идентификатор от первого до формы. Мне нужен номер записи, сохраненный до того, как форма сохранит и выделит первую запись. Однако, спасибо! – RockiesMagicNumber

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