Пользовательский источник строки для поля со списком в непрерывной форме в Access - PullRequest
12 голосов
/ 17 сентября 2008

Я искал вокруг, и кажется, что это ограничение в MS Access, поэтому мне интересно, какие творческие решения другие нашли для этой головоломки.

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

Следующим шагом, который мы все пытаемся, конечно же, является использование события onCurrent для запроса поля со списком, которое фактически ограничивает параметры данной строкой. Однако в этот момент Access сходит с ума и запрашивает все полей со списком для каждой строки, и в результате часто происходит исчезновение и повторное появление параметров в других строках в зависимости от того, выбрали ли они опция, действительная для источника строки текущей записи.

Единственное решение, которое я нашел, это просто перечислить все доступные варианты, все время. Есть какие-нибудь креативные ответы?

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

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

Ответы [ 13 ]

15 голосов
/ 18 сентября 2008

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

Вот что я хотел бы сделать, столкнувшись с такой ситуацией (и ранее я применял аналогичные обходные пути):

Поместите UNBOUND комбобокс на форму. Затем поместите BOUND textBox для поля, которое вы хотите редактировать.

Убедитесь, что поле со списком скрыто позади (НЕ невидимо, просто скрыто) за текстом.

В событии OnCurrent заполните listBox необходимыми данными. Идите вперед и «Ограничить список» это тоже.

В событии OnEnter или OnClick элемента textBox укажите фокус поля со списком. Это выведет комбобокс на первый план. Когда фокус покидает поле со списком, он снова прячется.

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

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

3 голосов
/ 18 сентября 2008

используйте непрерывные формы .. определенно. Фактически вы можете создавать целые приложения с отличным и интуитивно понятным пользовательским интерфейсом, построенным на непрерывных формах. Не слушай тост!

Ваше решение перечисления всех доступных вариантов является правильным. На самом деле нет другого чистого решения. Но вы ошибаетесь, когда говорите, что Acccess сходит с ума. В непрерывной форме вы можете видеть каждую строку как экземпляр подробного раздела, где поле со списком является свойством, общим для всех экземпляров подробного раздела. Вы можете обновить это свойство для всех экземпляров, но не можете установить его для одного конкретного экземпляра. Вот почему Access ДОЛЖЕН отображать одни и те же данные в выпадающем списке для всех записей!

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

Нельзя установить для свойства limitToList значение «Нет», если связанные данные (хранящиеся в элементе управления) скрыты. Это логично: как машина может принять ввод новой строки данных, когда связанное поле (не видно) остается пустым?

1 голос
/ 13 февраля 2012

Это, кажется, работает хорошо. CBOsfrmTouchpoint8 - это комбинированный список, укороченный до выпадающего квадрата. CBOsfrmTouchpoint14 - это текстовое поле, которое занимает оставшееся пространство. Никогда не говори никогда:

  Private Sub CBOsfrmTouchpoint8_Enter()  

  If Me.CBOsfrmTouchpoint8.Tag = "Yes" Then  
  CBOsfrmTouchpoint14.SetFocus  
  Me.CBOsfrmTouchpoint8.Tag = "No"  
  Exit Sub  
  End If  

  Me.CBOsfrmTouchpoint8.Tag = "No"  
  Me.CBOsfrmTouchpoint8.RowSource = "XXX"  
  Me.CBOsfrmTouchpoint8.Requery  
  Me.CBOsfrmTouchpoint8.SetFocus  
  End Sub 

  Private Sub CBOsfrmTouchpoint8_GotFocus()  
  Me.CBOsfrmTouchpoint14.Width = 0  
  Me.CBOsfrmTouchpoint8.Width = 3420  
  Me.CBOsfrmTouchpoint8.Left = 8580  
  Me.CBOsfrmTouchpoint8.Dropdown  
  End Sub

  Private Sub CBOsfrmTouchpoint8_LostFocus()  
  Me.CBOsfrmTouchpoint8.RowSource = "XXX"  
  Me.CBOsfrmTouchpoint8.Requery  
  End Sub 

  Private Sub CBOsfrmTouchpoint8_Exit(Cancel As Integer)  
  Me.CBOsfrmTouchpoint14.Width = 3180  
  Me.CBOsfrmTouchpoint8.Width = 240  
  Me.CBOsfrmTouchpoint8.Left = 11760  
  Me.CBOsfrmTouchpoint8.Tag = "Yes"  
  End Sub
1 голос
/ 27 ноября 2008

У меня есть более простой способ, чем Джиллиган. Кажется, много работы, но на самом деле это не так. Мое решение требует наличия моей непрерывной формы в виде таблицы данных подчиненной формы. В моей подчиненной форме у меня есть два комбинированных списка поиска, среди прочих, называемых «Оборудование» и «Производитель». Оба просто держат длинную целую клавишу в источнике данных. Производитель должен быть отфильтрован по тому, что выбрано в Оборудование. Единственный раз, когда я фильтрую Manufacturer.RowSource, находится в событии Manufacturer_GotFocus.

Private Sub Manufacturer_GotFocus ()

If Nz(Me.Equipment, 0) > 0 Then
    Me.Manufacturer.RowSource = GetMfrSQL()  '- gets filtered query based on Equipment
Else
    Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"
End If

End Sub

В Manufacturer_LostFocus я также сбрасываю Manufacturer.RowSource для всех производителей. Это необходимо сделать, поскольку при первом щелчке в подчиненной форме события GotFocus запускаются для всех элементов управления, включая «Производитель», даже если вы не обновляете никакие поля.

Private Sub Manufacturer_LostFocus ()

Me.Manufacturer.RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"

End Sub

В событии Enter производителя вы должны проверить, выбрано ли оборудование, если не установлено фокус на оборудовании.

Private Sub Manufacturer_Enter ()

If Nz(Me.EquipmentID, 0) = 0 Then
    '-- Must select Equipment first, before selecting Manufacturer
    Me.Equipment.SetFocus
End If

End Sub

Вам также необходимо запросить комбинированный список «Производитель» в событии Form_Current (т.е. Me.Manufacturer.Requery), и вам следует установить для свойства Cycle этой подчиненной формы значение «Текущая запись».

Кажется, достаточно просто, но вы еще не закончили. Вы также должны сбросить Manufacturer.RowSource для всех производителей в событии SubForm_Exit в родительской форме, если пользователь переходит к списку производителей, но не делает выбор и щелкает где-то в родительской форме. Пример кода (в родительской форме):

Private Sub sFrmEquip_Exit (Отмена как целое число)

Me.sFrmEquip.Controls("Manufacturer").RowSource = "SELECT MfgrID, MfgrName FROM tblManufacturers ORDER BY MfgrName"

End Sub

Есть еще одна часть этого, которая не чиста. Когда вы щелкаете по «Изготовителю» и имеете несколько строк в сетке таблицы данных, поле «Производитель» становится пустым в других строках (данные под полями со списками остаются без изменений), пока вы меняете «Изготовителя» в текущей строке. Как только вы удалите это поле, появится текст в других полях производителя.

1 голос
/ 18 сентября 2008

Мы также часто сталкиваемся с этим в наших приложениях. Что мы нашли, чтобы быть хорошим решением: Просто покажите все строки в выпадающих списках. Затем, как только пользователь вводит компоновщик в определенную строку, настройте источник строк (с фильтром для этой строки). Когда выпадающий список теряет фокус, вы можете переустановить источник строк, чтобы отобразить все.

1 голос
/ 18 сентября 2008

Я не думаю, что непрерывные формы Access вообще должны быть осуждены, но я определенно считаю, что их следует избегать для РЕДАКТИРОВАНИЯ ДАННЫХ. Они отлично работают для списков и предоставляют вам значительно больше возможностей форматирования, чем простое окно списка (и с ними гораздо проще работать, хотя, конечно, они не поддерживают множественный выбор).

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

Или, если вы используете непрерывную форму для отображения дочерних данных в родительской форме, вы можете связать подчиненную форму детали со ссылкой на PK в непрерывной подчиненной форме, что-то вроде:

[MySubForm].[Form]!MyID

Это будет свойство мастера ссылки, а MyID будет дочерним свойством ссылки.

1 голос
/ 17 сентября 2008

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

0 голосов
/ 08 января 2016

Я только что сделал подобное. Мое решение состояло в том, чтобы использовать фиксированный источник строки, связанный с запросом. Условия запроса WHERE ссылаются на элемент управления формы, т.е. Client=Forms!frmMain!ClientTextBox. Одно это заполнит поля со списком данными первого ряда. Хитрость заключается в том, чтобы установить событие «On Enter», которое просто выполняет повторный запрос в поле со списком, например, ComboBox1.Requery, он будет повторно запрашивать это поле со списком и перетаскивать только данные, относящиеся к этой строке записи.

Надеюсь, что это работает и для вас!

0 голосов
/ 10 марта 2010

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

0 голосов
/ 13 февраля 2010

Для меня, я думаю, лучший и самый простой способ - создать временную таблицу со всеми вашими связанными полями и дополнительным полем, представляющим собой поле yes / no.

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

Я думаю, что после этого легко сделать цикл выбора, просто маленький цикл, чтобы прочитать поле yeas / no из временной таблицы.

Надеюсь, это поможет

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...