Гость
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / перехват события изменения изменения записи / 13 сообщений из 13, страница 1 из 1
25.04.2018, 14:58
    #39636076
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Всем доброго времени суток! Есть ли для форм способ перехвата события изменения записи, если более корректно, то событие "после_изменения_значения_любого_поля" :-) Допустим, источником данных формы рекордсет с полным доступом к данным из какой-нибудь таблицы. Я когда-то придумал туповатый способ: создаем самопальную процедурку типа:
Код: vbnet
1.
2.
3.
Sub recordChange()
    'код обработки
End Sub


Ну, и в событии Dirty каждого поля просто вызываем эту процедуру. Очень тупо, особенно, при большом количестве полей. Но, может, есть какой-то более рациональный способ?
...
Рейтинг: 0 / 0
25.04.2018, 15:16
    #39636091
POKEP
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Beliar,

Чем не устраивает стандартное событие "До обновления" формы?

Например,


Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
Private Sub Form_BeforeUpdate(Cancel As Integer)
'Перед обновлением данных в форме.

'Перехват обработки ошибок.
On Error GoTo Err_Form_BeforeUpdate


'
With Me

    '
    If Nz(.ПолеОдин.Value) <> "Нужное значение" And Not isUsrGrp("Admins") Then

        DoCmd.CancelEvent
        MsgBox "Некорректный ввод в форму... бла-бла-бла"
        .Undo
        Exit Sub

    End If

    If IsNull(.ПолеДва.Value) Then
        MsgBux "Не заполнено поле [ПолеДва] !!! Это поле обязательное!"
        Cancel = True
        Exit Sub
    End If

End With


'Нормальное завершение процедуры.
Exit_Form_BeforeUpdate:
    Exit Sub

'Обработка ошибок.
Err_Form_BeforeUpdate:
    MsgBоx Err.Description & vbCrLf & "Ошибка: " & Err.Number, vbCritical, "Форма [Имя формы] -> Sub [Form_BeforeUpdate]"
    Resume Exit_Form_BeforeUpdate

End Sub
...
Рейтинг: 0 / 0
25.04.2018, 16:23
    #39636171
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
POKEPЧем не устраивает стандартное событие "До обновления" формы?
Это событие срабатывает один раз перед апдейтом всей записи, а ТС, насколько я понимаю, нужно фиксировать все изменения в полях до того, как они полетят в базу.

Если это так, то такого события нет, нужно перехватывать события от каждого контрола. Кстати, можно не прописывать код для каждого контрола, а вызывать процедуру, указав ее непосредственно в свойстве события:
Код: vbnet
1.
=recordChange()


Просто выделяем все нужные контролы и прописываем этот код в свойство On Dirty
Только это должна быть Function, не Sub.
И еще, думаю, лучше брать не On Dirty, а After Update, но это нужно смотреть, что в конечном итоге требуется, есть нюансы в срабатывании. Dirty срабатывает после первого же изменения, а After Update - при выходе из поля и может вообще не сработать, если пользователь отменил изменения, нажав на ESC
...
Рейтинг: 0 / 0
25.04.2018, 16:25
    #39636174
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
POKEP,
BeforUpdate срабатывает только кода уходишь с записи. Не то пальто, нужно при изменении значения любого из полей записи.
...
Рейтинг: 0 / 0
25.04.2018, 17:52
    #39636274
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Данные пусть "летят в базу", главное, чтобы срабатывала процедура обработки (код из recordChange), после того как пользователь изменил значение какого-нибудь поля.
MrShinЕсли это так, то такого события нет, нужно перехватывать события от каждого контрола. Кстати, можно не прописывать код для каждого контрола, а вызывать процедуру, указав ее непосредственно в свойстве события:
Код: vbnet
1.
=recordChange()


Просто выделяем все нужные контролы и прописываем этот код в свойство On Dirty
Только это должна быть Function, не Sub.

Попробовал - весьма приемлемо! Пожалуй, остановлюсь на этом. Спасибо огромное! Хотя идея с событиями именно рекорда, а не контролов или формы, меня не отпускает. Доберусь до литературы и поищу, я помню, что где-то расписывалось по событиям для каждого элемента, может и для записей рекордсета есть. Если найду - поделюсь, вдруг еще вариант найдется.
...
Рейтинг: 0 / 0
25.04.2018, 18:10
    #39636291
alecko
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Beliar, а чем не нравится implements? создали коллекцию, интерфейсный класс, объект закинули в коллекцию, объявили свойство, прописали его один раз для всех.
Здесь есть достойные примеры
- по их мотивам.
в объявлении модуля
Код: vbnet
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
Implements ITextBoxEvents
Private COLTextBoxes As New Collection ' рекомендуется разделять объявление и создание, но если обязательно создается, то возможно и так
' закидываете поля в класс, который сохраняете в коллекции
Dim Mess$()
Mess = Array("fld16", "fld17", "fld18", "fld20", "fld21", "fld22")' поля
 For i = 0 To UBound(Mess)
            With New clsTextBox
                .Initialize sufrm.Controls(Mess(i))
                COLTextBoxes.Add .Instance
            End With
set clsTextBox=nothing
    Next
'---------------------
Private Sub ITextBoxEvents_change(sender As Textbox)
recordChange ' событие, ради которого все и затевалось
end sub

При закрытии коллекцию лучше уничтожить
Private Sub Class_Terminate()
 Set COLTextBoxes = Nothing
End Sub

'===================================
'Интерфейсный класс ITextBoxEvents
Option Compare Database
Option Explicit

Public Sub change(sender As Textbox)

End Sub

'================================
'это наш класс clsTextBox, в который закидываем поля 
Option Compare Database
Option Explicit
Private TextBoxEvents As ITextBoxEvents
Private WithEvents tbx As Textbox

Private Sub Class_Terminate()
    Set tbx = Nothing
End Sub

Private Sub tbx_change(Cancel As Integer)
    TextBoxEvents.change tbx
End Sub
Public Sub Initialize(tb As Textbox)
    Set tbx = tb
    With tbx
        .Onchange = "[Event Procedure]"
    End With
Set TextBoxEvents = tbx.parent' иногда может быть не так (если форма создана в модуле и имеет подчиненную форму, в которой прописываем эти события, то лучше явно указать модуль с которым работем)
' Property Set ustsvz(tmp As ClFormAnalizCommerce)
' Set TextBoxEvents = tmp
' End Property

End Sub
Public Property Get Instance() As clsTextBox
    Set Instance = Me
End Property



хорошо тем что прописываете все в том же классе в котором все и создали (поскольку наследования реализации нет-часто прописывать все переменные по новой может быть утомительно), конечно для одного события кажется кода многовато, но когда одинаковых событий наберется побольше, количество кода практически не увеличится, этот же интерфейсный класс может быть задействован и в других случаях
не говоря о том что в случае добавления/удаления новых элементов все изменения проводятся в пару кликов.
...
Рейтинг: 0 / 0
25.04.2018, 20:59
    #39636378
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
alecko,
Слишком громоздко для маленькой задачки. Но стоит запомнить. Спасибо.
...
Рейтинг: 0 / 0
26.04.2018, 08:41
    #39636535
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
MrShinЕсли это так, то такого события нет, нужно перехватывать события от каждого контрола. Кстати, можно не прописывать код для каждого контрола, а вызывать процедуру, указав ее непосредственно в свойстве события:
Код: vbnet
1.
=recordChange()


Просто выделяем все нужные контролы и прописываем этот код в свойство On Dirty
Только это должна быть Function, не Sub.

Вопрос: а как передать этой функции данные этого контрола? в данном случае это поле, нужно значение свойства text этого поля. Скажем, у функции указан стринговый аргумент t1. Как ему присвоить значение этого поля? Вызов функции я прописываю в свойстве "внесены изменения" просто в режиме конструктора формы.
...
Рейтинг: 0 / 0
26.04.2018, 08:46
    #39636540
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Впрочем сам додумался: в свойстве "внесены изменения" вызываю эту свою функцию:
Код: vbnet
1.
=recordChange([имя_контрола])

и все. Работает, проверил.
...
Рейтинг: 0 / 0
26.04.2018, 08:51
    #39636546
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
BeliarВпрочем сам додумался: в свойстве "внесены изменения" вызываю эту свою функцию:
Код: vbnet
1.
=recordChange([имя_контрола])

и все. Работает, проверил.
поправочка: функцию вызывать надо в свойстве "изменения". Если в свойстве "внесены изменения", то считывается значение до изменения, тоже может где-нибудь пригодится.
...
Рейтинг: 0 / 0
26.04.2018, 09:55
    #39636590
Панург
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
Beliarвсе. Работает, проверил.
Код: vbnet
1.
Screen.ActiveForm.ActiveControl 
...
Рейтинг: 0 / 0
26.04.2018, 10:00
    #39636594
MrShin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
BeliarВпрочем сам додумался: в свойстве "внесены изменения" вызываю эту свою функцию:
Код: vbnet
1.
=recordChange([имя_контрола])


и все. Работает, проверил.
Не надо ничего передавать, иначе придется руками редактировать каждое свойство. Просто в функции получайте ссылку на контрол, как посоветовал Панург
...
Рейтинг: 0 / 0
26.04.2018, 15:49
    #39636829
Beliar
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
перехват события изменения изменения записи
MrShin,
Я сделал проще, без всяких аргументов, просто значение из [имя_контрола].value с проверкой функцией IsNull(), тем более что значения надо брать из нескольких текст- и комбо-боксов. Весьма удобно получилось.
...
Рейтинг: 0 / 0
Форумы / Microsoft Access [игнор отключен] [закрыт для гостей] / перехват события изменения изменения записи / 13 сообщений из 13, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]