Требовать несколько экземпляров формы независимо в VBA (доступ) - PullRequest
0 голосов
/ 11 января 2019

Я использую блестящий код Аллена Брауна (http://allenbrowne.com/ser-35.html), чтобы открыть несколько экземпляров формы при событии щелчка. Я понимаю, что новые экземпляры доступны только для чтения, и мне удалось записать данные, введенные пользователем, чтобы сохранить журнал, благодаря этому сообщению ( Access 2007 / VBA - множественные экземпляры формы, обновление элементов управления для конкретного экземпляра из модуля ).

У меня есть несколько полей со списком в каждой форме, и я хотел бы обновить / запросить то, что показано в одном, в зависимости от выбора пользователя в другом (для каждой формы, а не среди форм). Например, пользователь выбирает компонент A на cmb1, cmb2 показывает только возможные сбои компонента A.

{me.Requery} будет только и всегда запрашивать форму в классе Forms (тот, который открыт из окна базы данных / навигационной панели, если таковые имеются, а не экземпляры в коллекции clnClient ниже). Тем не менее, я могу передать информацию с помощью «Я» и получить значения для ведения журнала.

Использование слегка модифицированной версии OpenAClient от Аллена Брауна с входными данными из MajP (в этой замечательной теме https://www.tek -tips.com / viewthread.cfm? Qid = 1753790 )

Public clnClient As New Collection

Public Function OpenAClient(FormName As String, Optional inputCaption As String = "") As Form_f_myForm
    'Purpose:   Open an independent instance of form f_myForm
    On Error GoTo Err_OpenAClient

    Dim frm As Form

    'Open a new instance, show it, and set a caption.
    Set frm = New Form_f_myForm
    frm.Visible = True
    frm.Caption = inputCaption
    frm.Tag = FormName

    'Append it to our collection.
    clnClient.Add Item:=frm, Key:=FormName

    Set OpenAClient = frm
    Set frm = Nothing
    Exit Function

Err_OpenAClient:
    If Err.Number = 457 Then
        MsgBox "A Form with this name already exists."
    Else
        MsgBox Err.Number & " " & Err.Description
    End If
End Function

Я пытался

Public ActiveForm As Form_f_myform
Set activeForm = OpenAClient("ExampleForm","Example caption")

или простой

Set activeForm = clnClient.Item(2) 'just to test the second instance

, а затем использовать ActiveForm вместо «Я» и манипулировать им таким образом, но, похоже, это не работает. Любые идеи / помощь будут оценены. Или идеи по-другому. Спасибо!

Немного фона. Я очень новичок в VBA и Access, работаю над базой данных (Access Office365) для отчетов об ошибках. Все сбои были оценены заранее до доставки пользователю. Пользователь идентифицирует конкретный отказавший компонент и заполняет форму соответствующим образом (дата, тип сбоя и т. Д.). Они не изменят таблицу, содержащую предварительную оценку. Это все нормально и работает. Проблема заключается в добавлении пользователю возможности сообщать о множественных сбоях.

Ответы [ 2 ]

0 голосов
/ 12 января 2019

Большое спасибо @kismert за решение и советы !! Я уже попробовал и работает так же, как вы упоминаете. (Мне пришлось использовать .RowSource вместо .RecordSource в моей версии Access).

0 голосов
/ 12 января 2019

Во-первых, давайте разберемся с некоторыми заблуждениями:

Я понимаю, что новые экземпляры доступны только для чтения ...

Их действительно можно читать и писать. Они просто не могут быть прикреплены к одному и тому же запросу. Причина этого в том, что выражения запроса, такие как Forms!f_myform!cmb1, не работают, когда открыто более одного экземпляра f_myform. Вы должны создать собственный SQL для источника записей каждого экземпляра, чтобы получить действительно независимую операцию.

{Me.Requery} будет только и всегда запрашивать форму в классе Forms ...

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

Что касается стратегии кодирования, избавьтесь от глобального Public ActiveForm As Form_f_myform. Это только рецепт для проблем.

Сам экземпляр формы содержит все, что вам нужно, чтобы ваш код работал. Попробуйте вызвать функции с самой ссылкой на форму (как вы делали ранее). Например:

    Public Sub ShowComponentFailures(thisForm As Form_f_myform)
        Dim varCompID As Variant
        Dim strSQL As String
        ' get Component ID from given instance's cmb1
        varCompID = thisForm.cmb1.Value
        ' create SQL to retrieve possible failures for CompID 
        strSQL = GetComponentFailuresSQL(varCompID)
        ' set cmb2's record source to SQL
        thisForm.cmb2.RowSource = strSQL
    End Sub
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...