0

我有一张省份表和一张带有 ProvienceID 的城市表。在一个表单中,我想创建一个按省列表的选定值过滤的城市列表。我怎样才能做到这一点?

我可以创建两个列表,但城市列表显示所有省份的所有城市,但我只想显示我在省份列表中选择的省份的城市。

我有另一个表“Users”,其中包含“CityID”和“ProvinceID”,我的表单对其进行了编辑,我需要在其中保存省和市列表的选定值,而不仅仅是在表单中显示它。

4

1 回答 1

0

创建两个名为“Provinces”和“Cities”的示例表。

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

创建一个名为“Province of City”的查询:

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

在窗体中,根据查询“ProvinceNames”创建一个表控件。

使用表单导航器(或表单向导),为查询“Province of City”创建一个子表单。

表单导航器

右键单击子表单并选择Properties。在数据选项卡下:

  • 链接主字段“省”
  • 链接从属字段“省”

也为子窗体创建一个表格控件。现在,子窗体控件中显示的城市取决于主窗体控件中选择的省份。

结果

编辑

这是一个使用过滤表存储列表框当前值的示例。再创建两个名为“Users”和“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

现在我们需要像这样设置表单。在此示例中,我使用了两个顶级表单而不是子表单。ProvinceID 和 CityID 文本框不是必需的,但在出现问题时可能会有所帮助。

表单控件和层次结构

要开始创建此表单,请使用表单向导创建一个新表单并添加用户表中的所有字段。

现在,在表单导航器中,创建一个名为“CityForm”的表单。内容类型为 SQL 命令,内容为:

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

接下来,在 MainForm 下创建“listboxProvince”列表框。Data Field为“ProvinceID”,List内容为如下Sql。

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

最后,在 CityForm 下创建“listboxCity”列表框。Data Field为“CityID”,List内容为如下Sql。

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

宏链接在每个控件的事件选项卡下。

  • 将 MainForm 的“记录更改后”分配给 ReadProvince()。
  • 将 listboxProvince 的“已更改”分配给 ReadProvince()。
  • 将 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 查询。

于 2017-12-15T23:57:26.970 回答