База libreoffice создает список, отфильтрованный по значению другого списка

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

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

У меня есть другая таблица «Пользователи» с «CityID» и «ProvinceID», которую редактирует моя форма, и мне нужно сохранить в ней выбранные значения списков провинций и городов, а не только показать их в форме.


person ahmad    schedule 15.12.2017    source источник


Ответы (1)


Создайте две примерные таблицы с именами «Провинции» и «Города».

ProvinceID  Name    
~~~~~~~~~~  ~~~~
0           South   
1           North   
2           Large Midwest   
3           Southeast   
4           West    

CityID  Name              ProvinceID
~~~~~~  ~~~~              ~~~~~~~~~~
0       Big City          2
1       Very Big City     2
2       Rural Village     1
3       Mountain Heights  0
4       Coastal Plains    4
5       Metropolis        2

Создайте запрос под названием «ProvinceNames»:

SELECT "Name" AS "Province"
FROM "Provinces"
ORDER BY "Province" ASC

Создайте запрос под названием «Провинция города»:

SELECT "Provinces"."Name" AS "Province", "Cities"."Name" AS "City"
FROM "Cities", "Provinces" WHERE "Cities"."ProvinceID" = "Provinces"."ProvinceID"
ORDER BY "Province" ASC, "City" ASC

В форме создайте табличный элемент управления на основе запроса «ProvinceNames».

С помощью навигатора форм (или мастера форм) создайте подчиненную форму для запроса «Провинция города».

Навигатор форм

Щелкните правой кнопкой мыши подчиненную форму и выберите Свойства. На вкладке Данные:

  • Связать мастер-поля "Провинция"
  • Связать подчиненные поля "Провинция"

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

Результат

ИЗМЕНИТЬ:

Вот пример использования таблицы фильтров для хранения текущего значения списка. Создайте еще две таблицы с именами «Пользователи» и «FilterCriteria».

UserID  Name     ProvinceID  CityID
~~~~~~  ~~~~~~~  ~~~~~~~~~~  ~~~~~~
0       Person1  1           2
1       Person2  2           0

RecordID  ProvinceID  CityID
~~~~~~~~  ~~~~~~~~~~  ~~~~~~
the only  0           0

Нам также понадобятся два базовых макроса, которые можно сохранить в документе или в папке «Мои макросы». Перейдите в раздел Инструменты -> Макросы -> Упорядочить макросы -> LibreOffice Basic.

Sub ReadProvince (oEvent as Object)
    forms = ThisComponent.getDrawPage().getForms()
    mainForm = forms.getByName("MainForm")
    cityForm = forms.getByName("CityForm")
    listboxProvince = mainForm.getByName("listboxProvince")
    listboxCity = cityForm.getByName("listboxCity")
    selectedItemID = listboxProvince.SelectedValue
    If IsEmpty(selectedItemID) Then
        selectedItemID = 0
    End If
    conn = mainForm.ActiveConnection
    stmt = conn.createStatement()
    strSQL = "UPDATE ""FilterCriteria"" SET ""ProvinceID"" = " & selectedItemID & _
             "WHERE ""RecordID"" = 'the only'"
    stmt.executeUpdate(strSQL)
    listboxCity.refresh()
    lCityCol = mainForm.findColumn("CityID")
    currentCityID = mainForm.getInt(lCityCol) 
    cityForm.updateInt(cityForm.findColumn("CityID"), currentCityID)
    listboxCity.refresh()
End Sub

Sub CityChanged (oEvent as Object)
    listboxCity = oEvent.Source.Model
    cityForm = listboxCity.getParent()
    mainForm = cityForm.getParent().getByName("MainForm")
    lCityCol = mainForm.findColumn("CityID")
    selectedItemID = listboxCity.SelectedValue
    If IsEmpty(selectedItemID) Then
        selectedItemID = 0
    End If
    mainForm.updateInt(lCityCol, selectedItemID)
End Sub

Теперь нам нужно настроить такую ​​форму. В этом примере я использовал две формы верхнего уровня вместо подчиненной формы. Текстовые поля «идентификатор провинции» и «идентификатор города» не обязательны, но могут быть полезны, если что-то пойдет не так.

элементы управления формами и иерархия

Чтобы приступить к созданию этой формы, используйте мастер форм, чтобы создать новую форму и добавить все поля из таблицы «Пользователи».

Теперь в Навигаторе форм создайте форму под названием «CityForm». Тип содержимого — команда SQL, а содержимое — это:

SELECT "RecordID", "ProvinceID", "CityID" FROM "FilterCriteria"
WHERE "RecordID" = 'the only'

Затем создайте список listboxProvince в MainForm. Поле данных — «ProvinceID», а содержимое списка — следующий код Sql.

SELECT "Name", "ProvinceID" FROM "Provinces" ORDER BY "Name" ASC

Наконец, создайте список listboxCity в CityForm. Поле данных — «CityID», а содержимое списка — следующий код Sql.

SELECT "Name", "CityID" FROM "Cities" WHERE "ProvinceID" = (
    SELECT "ProvinceID" FROM "FilterCriteria"
    WHERE "RecordID" = 'the only')

Макросы связаны на вкладке «События» каждого элемента управления.

  • Назначьте «После изменения записи» MainForm для ReadProvince().
  • Назначьте «Изменено» из listboxProvince в ReadProvince().
  • Назначьте «Changed» элемента управления listboxCity функции CityChanged().

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

результат

Есть еще один подход, который может быть лучше, но у меня не было времени изучить его. Вместо таблицы «FilterCriteria» примените фильтр к списку «Города». Соответствующий код в ReadProvince() будет выглядеть примерно так.

cityForm.Filter = "ProvinceID=" & selectedItemID
cityForm.ApplyFilter = True
cityForm.reload()
cityForm.absolute(0)

Какой бы подход ни был выбран, полное решение требует сложного программирования макросов. Чтобы упростить задачу, вы можете решить использовать более простое решение, но не такое мощное. Для получения дополнительной информации см. руководство по адресу https://forum.openoffice.org/en/forum/viewtopic.php?t=46470.

ИЗМЕНИТЬ 2

Решение, требующее меньшего количества запросов, находится по адресу https://ask.libreoffice.org/en/question/143186/how-to-use-user-selected-value-from-combobox1-in-combobox2-select.-statement/?answer=143231#post-id-143231. Второй список основан на списке значений, а не на SQL-запросе.

person Jim K    schedule 15.12.2017
comment
Оно работает. но я хочу это в списке, а не в таблице. Мне нужно сохранить выбранное значение списков провинций и городов в другой таблице Users. - person ahmad; 16.12.2017
comment
@ahmad, в разделе «Пользователи», я думаю, вы хотите использовать список для поиска города. Другими словами, одним из ваших полей в Users является CityID. Это становится указателем на конкретный город в таблице City. Поскольку город уже связан с провинцией (через редактор Джим К. показал вам, как это сделать выше), это хорошее решение. - person Elliptical view; 16.12.2017
comment
@ahmad: похоже, что способ сделать то, что вы просите, - это связать главный Users.CityID с подчиненным Cities.CityID, а затем использовать макрос для фильтрации списка городов по ProvinceID из текущей выбранной записи пользователей. Дайте мне знать, если вам нужен пример использования макроса. - person Jim K; 22.12.2017
comment
@jim-k: да, я не знаком с макросами, и мне нужен пример. и какие элементы должны быть в подчиненной форме? - person ahmad; 22.12.2017
comment
@ahmad: Хорошо, наконец-то у меня есть полное рабочее решение. Смотрите отредактированный ответ. - person Jim K; 24.12.2017