2009-09-01 2 views
1

Я рассматриваю использование элемента управления вкладками в родительской форме, для которой я хотел бы иметь около 20 вкладок. На каждой вкладке я рассматриваю использование одной или двух отдельных подформ. Каждая подформата будет иметь сложную сложность в кодированной логике. Приняв такой подход, я уменьшу производительность своего приложения? В настоящее время я использую это в MS Access 2003. Я ожидаю в среднем 15 пользователей в любой момент времени в разных формах.Разлагает ли производительность производительность на использование подформ в MS Access?

Мысли?

ответ

4

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

Как только у вас есть подчиненная работа, удовлетворяющая вашим требованиям, либо сохраните источник записи в качестве запроса, либо дайте ему имя или сохраните строку запроса SQL. Затем либо вставьте имя запроса, либо строку SQL запроса в код VBA в событии изменения управления вкладкой.

Private Sub TabCtl_Change() 
    On Error GoTo TabCtl_Change_Error 

    Select Case Me.TabCtl.Value 
    Case Me.pagPartsConsumed.PageIndex 
     If Me.PartsConsumedsbf.Form.RecordSource <> "Equipment - Parts Consumed sbf" Then _ 
      Me.PartsConsumedsbf.Form.RecordSource = "Equipment - Parts Consumed sbf" 
.... 

Теперь просто чтобы убедиться, что я не случайно оставить некоторые субформы recordsources заполнены замедляя приложение при запуске проверить, чтобы увидеть, если файл код выполняется является MDB (вместо МРЗ. функция ниже), тогда отобразите сообщение, сообщающее мне, что мне нужно удалить источник записей.

If Not tt_IsThisAnMDE Then 
     If Me.PartsConsumedsbf.Form.RecordSource <> "" Then _ 
      MsgBox "Record source of Equipment - Parts Consumed sbf not empty" 
     ... 
    End If 

Public Function tt_IsThisAnMDE() 
On Error GoTo tagError 

    Dim dbs As Database 
    Set dbs = CurrentDb 
    Dim strMDE As String 
    On Error Resume Next 
    strMDE = dbs.Properties("MDE") 
    If Err = 0 And strMDE = "T" Then 
    ' This is an MDE database. 
    tt_IsThisAnMDE = True 
    Else 
    tt_IsThisAnMDE = False 
    End If 

    Exit Function 

tagError: 
    Call LogError(Application.CurrentObjectName, "") 
    Exit Function 

End Function 

Также в форме выгрузки я также очищаю источник Recourd.

Private Sub Form_Unload(Cancel As Integer) 

    On Error GoTo Form_Unload_Error 

    Me.PartsConsumedsbf.Form.RecordSource = "" 
    .... 

BTW Я почти всегда ставил каждую подформу на отдельную вкладку. Кроме того, многие записи вкладок выглядят ужасно громоздкими. Когда у меня был аналогичный вопрос, мои коллеги Access MVP предложили использовать список слева, чтобы контролировать, какая подформация просматривается.

Также каждое поле со списком и поле списка также слегка ухудшают производительность. Так что, если у вас есть те, на подформе, то рассмотрите аналогичную логику.

+0

Спасибо, это очень полезно. Я попытаюсь обойти и посмотреть, что работает лучше всего.+1 –

+0

Просто комментарий о вашем событии OnChange: если вы используете имя закладки и получаете .PageIndex, почему бы просто не сделать ваш SELECT CASE на основе Me! CtlTab.Pages (Me! CtlTab) .Name, а затем каждый случай будет «pagPartsConsumed». Очевидно, вы хотите избежать выбора индекса страницы, поскольку это может измениться при добавлении/перемещении страниц в элементе управления вкладкой. Но мне кажется, что поиск значения строки однажды будет проще, чем поиск .PageIndex для каждого CASE вашего SELECT CASE. Наверное, не имеет никакого значения для производительности, но для меня это имеет более логичный смысл. –

+0

Дэвид, ваш синтаксис выглядит уродливее, чем просто использование Me.pagPartsConsumed.PageIndex, поэтому я, вероятно, не понимаю ваш комментарий. –

2

В дополнение к добавлению наборов записей во время выполнения я обычно использовал только одну или две вкладки и несколько элементов управления для загрузки различных подчиненных элементов в элемент управления подчиненными элементами.

Текст для замкового события On контроля может быть:

=WhichPage([Form],"lblLocations") 

Где WhichPage функция со следующими линиями, среди прочего:

Function WhichPage(frm, Optional LabelName = "") 
    <..> 

    Select Case LabelName 

    Case "lblLocations" 
     frm("sfrmAll").SourceObject = "sfrmLocations" 

<...> 

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

Me.sfrmAll.LinkChildFields = "LocationKey" 
Me.sfrmAll.LinkMasterFields = "txtLocationKey" 
+0

Вот что я собирался предложить. Используйте управление ОНО одним подформатом и динамически загружайте подформы, как вы предлагаете. Поймите, что для этого подхода требуется, чтобы подформа не была встроена ни на одну вкладку, а просто наложила элемент управления вкладкой. Идея Тони является лучшей, если все вкладки должны использовать одну и ту же подформу с разными данными. Но в тех ситуациях, когда фактическая подформация может меняться, я бы использовал этот подход. Seth –

+0

Я не накладываю элемент управления подформы, он находится на вкладке. У меня может быть несколько вкладок, обычно не более трех, в зависимости от того, что я делаю. – Fionnuala

+0

Очень прямой подход. Благодаря! –

2

Чтобы развернуть ответ Рему ... вот что я написал, что динамически загружает форму в элемент управления подчиненной формы. Вы передаете имя формы в вызове и загрузите ее в подчиненную форму Основной формы. Аргументы сопоставляются аргументам метода доступа Docmd.OpenForm. Если основная форма, на которой размещается элемент управления подчиненной формы, не открыта ... она просто выполняет регулярное открытие формы. В противном случае он загружает его в элемент управления подформы. Если предложение where было передано, оно используется для фильтрации подформы.

Public Sub MyOpenForm(FormName As String, _ 
          Optional View As AcFormView = acNormal, _ 
          Optional FilterName As String = vbNullString, _ 
          Optional WhereCondition As String = vbNullString, _ 
          Optional DataMode As AcFormOpenDataMode, _ 
          Optional WindowMode As AcWindowMode, _ 
          Optional OpenArgs As String) 

On Error GoTo PROC_ERR 

Dim frm As Form 
Dim strNewForm As String 
Dim strCurrentForm As String 
Dim strNewTable As String 
Dim fDoNotFilter As Boolean 
Dim strActionText As String 
Dim strID As String 

If Not IsLoaded("frmMain") Then 
    DoCmd.OpenForm FormName:=FormName, View:=View, FilterName:=FilterName, WhereCondition:=WhereCondition, DataMode:=DataMode, WindowMode:=WindowMode, OpenArgs:=OpenArgs 
Else 
    strCurrentForm = Forms![frmMain]![sfrMyForm].SourceObject 
    If strCurrentForm <> FormName Then 
     Forms![frmMain]![sfrMyForm].SourceObject = vbNullString 
     Forms![frmMain]![sfrMyForm].SourceObject = FormName 
    End If 
    If WhereCondition <> vbNullString Then 
     Forms![frmMain]![sfrMyForm].Form.Filter = WhereCondition 
     Forms![frmMain]![sfrMyForm].Form.FilterOn = True 
    End If 
End If 


PROC_EXIT: 
    Exit Sub 

PROC_ERR: 
    MsgBox Err.Description 
    Resume PROC_EXIT 

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