Files
Desktop_WT_DMS/WT-DMS/form_Query.vb
2025-12-11 11:43:00 +08:00

607 lines
21 KiB
VB.net
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
Public Class form_Query
Dim SectionNameList As New ArrayList
Dim TableNameList As New ArrayList
Dim m_ComboDataType(COLS.max - 1) As COMBO_DATA_TYPE '存储下拉列表的类型
Dim m_ConditionCount As Integer = 0
Dim m_EditCol As Integer
Dim m_EditRow As Integer
Dim QueryTable As New DataTable
Public Class SECTION_UNIT
Public name As String
Public check As Boolean
End Class
Enum COMBO_DATA_TYPE
table
section
End Enum
Enum COLS
序号
关联
字段
运算
字段_值
max
End Enum
Enum SECTION_TYPE
无效
字段
End Enum
'获取W&T Database数据库中所有的表
Private Function GetTableList() As Boolean
Dim rTable As New Data.DataTable
Dim result As Boolean = True
TableNameList.Clear()
rTable.Columns.Clear()
rTable.Rows.Clear()
rTable.Clear()
If SQL_Query(CAccountManage.COL_RIGHTS.登录, "show tables", rTable) = True Then
If rTable.Rows.Count > 0 Then
Try
For i As Integer = 0 To rTable.Rows.Count - 1
Dim pSectionUnit As New SECTION_UNIT
pSectionUnit.name = rTable.Rows.Item(i).Item(0)
pSectionUnit.check = False
TableNameList.Add(pSectionUnit)
Next
Catch ex As Exception
End Try
End If
Else
result = False
End If
Return result
End Function
'获取所有表对应的字段名称列表
Private Function GetSectionNameList() As Boolean
Dim rTable As New Data.DataTable
Dim result As Boolean = True
SectionNameList.Clear()
Dim TableName As String
For Each pTableInfo As SECTION_UNIT In TableNameList
TableName = pTableInfo.name
Dim pItemList As New ArrayList
rTable.Columns.Clear()
rTable.Rows.Clear()
rTable.Clear()
If SQL_Query("SELECT * FROM `" & TableName & "` WHERE 0", rTable) = True Then
For i As Integer = 0 To rTable.Columns.Count - 1
Dim pSectionUnit As New SECTION_UNIT
pSectionUnit.name = rTable.Columns.Item(i).ColumnName
pSectionUnit.check = False
pItemList.Add(pSectionUnit)
Next
SectionNameList.Add(pItemList)
Else
result = False
End If
Next
Return result
End Function
Private Sub form_Query_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
If GetTableList() = False Then
MsgBox("载入数据表错误")
Me.Close()
Return
End If
If GetSectionNameList() = False Then
MsgBox("载入数据表字段错误")
Me.Close()
Return
End If
'填充查询表
Fill_TableList()
'初始化Conditions列表
Init_ConditionTable()
End Sub
Private Sub Init_ConditionTable()
Grid_Conditions.Cols = COLS.max
Grid_Conditions.Rows = 2
'填充列名
Grid_Conditions.Cell(0, 0).Text = "序号"
Grid_Conditions.Cell(0, 1).Text = "关联"
Grid_Conditions.Cell(0, 2).Text = "字段"
Grid_Conditions.Cell(0, 3).Text = "运算"
Grid_Conditions.Cell(0, 4).Text = "字段/值"
Grid_Conditions.Cell(1, 0).Text = m_ConditionCount + 1
Grid_Conditions.Cell(COLS.关联, 1).Locked = True
'填入“关联”字段列表值
Grid_Conditions.Column(COLS.关联).CellType = FlexCell.CellTypeEnum.ComboBox
Dim i As Integer
With Grid_Conditions.ComboBox(COLS.关联)
.Locked = True
.AutoComplete = True
For i = 0 To mdl_SQLConst.rel_Conditions.Length / 2 - 1
.Items.Add(mdl_SQLConst.rel_Conditions(i, 0))
Next
End With
'填入“运算”字段列表值
Grid_Conditions.Column(COLS.运算).CellType = FlexCell.CellTypeEnum.ComboBox
With Grid_Conditions.ComboBox(COLS.运算)
.Locked = True
.AutoComplete = True
For i = 0 To mdl_SQLConst.rel_Operator.Length / 2 - 1
.Items.Add(mdl_SQLConst.rel_Operator(i, 0))
Next
End With
'填入“字段”
Grid_Conditions.Column(COLS.字段).Width = 80
Grid_Conditions.Column(COLS.字段).CellType = FlexCell.CellTypeEnum.ComboBox
Fill_ComboList(Grid_Conditions.ComboBox(COLS.字段), "", 0, COMBO_DATA_TYPE.table)
'填入"字段/值"
Grid_Conditions.Column(COLS.字段_值).Width = 80
Grid_Conditions.Column(COLS.字段_值).CellType = FlexCell.CellTypeEnum.ComboBox
Fill_ComboList(Grid_Conditions.ComboBox(COLS.字段_值), "", 0, COMBO_DATA_TYPE.table)
End Sub
Private Sub Fill_TableList()
clb_Table.Items.Clear()
For Each pItem As SECTION_UNIT In TableNameList
clb_Table.Items.Add(pItem.name)
Next
End Sub
Private Function Fill_SectionList(ByVal index As Integer) As Boolean
If index > SectionNameList.Count Then Return False
Dim pItem As ArrayList = SectionNameList.Item(index)
clb_Section.Items.Clear()
Dim sec_idx As Integer
For Each pSec As SECTION_UNIT In pItem
sec_idx = clb_Section.Items.Add(pSec.name)
clb_Section.SetItemChecked(sec_idx, pSec.check)
Next
Return True
End Function
Private Sub chklb_Table_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles clb_Table.SelectedIndexChanged
If clb_Table.SelectedIndex >= 0 Then
Fill_SectionList(clb_Table.SelectedIndex)
End If
End Sub
Private Function GetAnySectionChecked(ByVal currIndex As Integer) As Boolean
Dim checked As Boolean = False
For i As Integer = 0 To clb_Section.Items.Count - 1
If i <> currIndex Then
If clb_Section.GetItemChecked(i) = True Then
checked = True
Exit For
End If
End If
Next
Return checked
End Function
Private Sub clb_Table_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb_Table.ItemCheck
Dim pTable As SECTION_UNIT = TableNameList.Item(e.Index)
pTable.check = e.NewValue
SQLGenerateFromCondition()
End Sub
Private Sub clb_Section_ItemCheck(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ItemCheckEventArgs) Handles clb_Section.ItemCheck
If clb_Table.SelectedIndex >= 0 AndAlso e.Index >= 0 Then
Dim pTable As ArrayList = SectionNameList(clb_Table.SelectedIndex)
Dim pSec As SECTION_UNIT = pTable(e.Index)
pSec.check = e.NewValue
If e.NewValue OrElse GetAnySectionChecked(e.Index) = True Then
clb_Table.SetItemChecked(clb_Table.SelectedIndex, True)
Else
clb_Table.SetItemChecked(clb_Table.SelectedIndex, False)
End If
SQLGenerateFromCondition()
End If
End Sub
Private Sub Grid_Conditions_LeaveCell(ByVal Sender As System.Object, ByVal e As FlexCell.Grid.LeaveCellEventArgs) Handles Grid_Conditions.LeaveCell
SQLGenerateFromCondition()
End Sub
'填充dgview_Condition中的“字段”下拉框列表
Private Function Fill_ComboList(ByRef pCombo As FlexCell.ComboBox, ByVal PreTableName As String, ByVal index As Integer, ByVal type As COMBO_DATA_TYPE) As Boolean
Dim pSection As SECTION_UNIT
pCombo.Items.Clear()
pCombo.DropDownWidth = 200
If type = COMBO_DATA_TYPE.table Then
For i As Integer = 0 To TableNameList.Count - 1
pSection = TableNameList(i)
If pSection.check = True Then
pCombo.Items.Add(pSection.name)
End If
Next
Else
If index > SectionNameList.Count Then Return False
Dim pTable As ArrayList = SectionNameList.Item(index)
For Each pSec As SECTION_UNIT In pTable
pCombo.Items.Add(PreTableName & "." & pSec.name)
Next
End If
Return True
End Function
Private Sub UpdateComboBoxList(ByVal row As Integer, ByVal col As Integer)
'Dim col As Integer = e.Col
'Dim row As Integer = e.Row
If col < 1 OrElse row < 1 Then Return
If col = COLS.字段 OrElse col = COLS.字段_值 Then
Try
Dim pCombo As FlexCell.ComboBox = Grid_Conditions.ComboBox(col)
Dim strContent As String = Grid_Conditions.Cell(row, col).Text
Dim dotPos As Integer = Strings.InStr(strContent, ".")
If dotPos > 0 Then
Dim tablename As String = Strings.Left(strContent, dotPos - 1)
Dim index As Integer = GetTableIndex(tablename)
If index >= 0 Then
If pCombo.Items.Count = 0 OrElse m_ComboDataType(col) <> COMBO_DATA_TYPE.section Then
Fill_ComboList(pCombo, tablename, index, COMBO_DATA_TYPE.section)
m_ComboDataType(col) = COMBO_DATA_TYPE.section
End If
End If
Else
If pCombo.Items.Count = 0 OrElse m_ComboDataType(col) <> COMBO_DATA_TYPE.table Then
Fill_ComboList(pCombo, "", 0, COMBO_DATA_TYPE.table)
m_ComboDataType(col) = COMBO_DATA_TYPE.table
End If
End If
pCombo.DropDown()
Catch ex As Exception
End Try
End If
End Sub
'Private Sub Grid_Conditions_ComboClick(ByVal Sender As System.Object, ByVal e As FlexCell.Grid.ComboClickEventArgs) Handles Grid_Conditions.ComboClick
' '更新下拉列表
' UpdateComboBoxList(m_EditRow, m_EditCol)
'End Sub
Private Sub Grid_Conditions_CellChanging(ByVal Sender As System.Object, ByVal e As FlexCell.Grid.CellChangingEventArgs) Handles Grid_Conditions.CellChanging
'更新下拉列表
UpdateComboBoxList(e.Row, e.Col)
'自动添加"序号"
If Grid_Conditions.Cell(e.Row, 0).Text <> e.Row.ToString Then
Grid_Conditions.Cell(e.Row, 0).Text = e.Row
End If
'自动增加一行
If Grid_Conditions.Rows = (e.Row + 1) Then
Grid_Conditions.Rows += 1
End If
End Sub
Private Function dgview_Condition() As Object
Throw New NotImplementedException
End Function
'Private Sub Grid_Conditions_EditRow(ByVal Sender As System.Object, ByVal e As FlexCell.Grid.EditRowEventArgs) Handles Grid_Conditions.EditRow
' If Grid_Conditions.Cell(e.Row, 0).Text <> e.Row.ToString Then
' Grid_Conditions.Cell(e.Row, 0).Text = e.Row
' End If
'End Sub
Private Sub Grid_Conditions_RowColChange(ByVal Sender As System.Object, ByVal e As FlexCell.Grid.RowColChangeEventArgs) Handles Grid_Conditions.RowColChange
If e.Col = COLS.字段 OrElse e.Col = COLS.字段_值 Then
bt_FillIn.Enabled = True
Else
bt_FillIn.Enabled = False
End If
m_EditCol = e.Col
m_EditRow = e.Row
'更新下拉列表
UpdateComboBoxList(m_EditRow, m_EditCol)
End Sub
Private Sub bt_FillIn_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_FillIn.Click
Dim table_idx As Integer = clb_Table.SelectedIndex
Dim section_idx As Integer = clb_Section.SelectedIndex
If table_idx >= 0 AndAlso section_idx >= 0 Then
Grid_Conditions.Cell(m_EditRow, m_EditCol).Text = clb_Table.Items(table_idx) & "." & clb_Section.Items(section_idx)
End If
End Sub
'在TableNameList中查找tblName并返回序号
'如果未找到则返回-1
Private Function GetTableIndex(ByVal tblName As String) As Integer
Dim index As Integer = 0
For Each pTable As SECTION_UNIT In TableNameList
If pTable.name.ToUpper = tblName.ToUpper Then
Return index
End If
index += 1
Next
Return -1
End Function
'在SectionNameList中查找secName并返回序号
'如果未找到则返回-1
Private Function GetSectionIndex(ByVal tblIndex As Integer, ByVal secName As String) As Integer
Dim pTable As ArrayList = SectionNameList.Item(tblIndex)
Dim index As Integer = 0
For Each pSec As SECTION_UNIT In pTable
If pSec.name.ToUpper = secName.ToUpper Then
Return index
End If
index += 1
Next
Return -1
End Function
'检查指定的行是否为空
Private Function CheckConditionTableLineEmpty(ByVal row As Integer) As Boolean
Dim line_not_empty As Boolean = False
Dim cell_text As String
For col = 1 To Grid_Conditions.Cols - 1
If Not (col = COLS.关联 And row = 1) Then '忽略行1的关联单元
Try
cell_text = Grid_Conditions.Cell(row, col).Text
If cell_text.Length > 0 Then
line_not_empty = True
Exit For
End If
Catch ex As Exception
End Try
End If
Next
Return line_not_empty
End Function
'检查指定字符串是否为有效的字段名
Private Function CheckTextIsValidSectionName(ByVal text As String) As SECTION_TYPE
If text.Length = 0 Then Return SECTION_TYPE.无效
Dim m_section_type As SECTION_TYPE = SECTION_TYPE.无效
Dim cell_split() As String = Split(text, ".")
If cell_split.Length >= 2 Then '如果包含点,则检查是否为有效的字段名
'查找当前表名是否存在
Dim tbl_index As Integer = GetTableIndex(cell_split(0))
If tbl_index >= 0 Then
If GetSectionIndex(tbl_index, cell_split(1)) >= 0 Then
m_section_type = SECTION_TYPE.字段
End If
End If
Else
'否则为其它值,非字段名
m_section_type = SECTION_TYPE.
End If
Return m_section_type
End Function
'对Grid_Conditions列表进行错误检查
'并将错误的单元标记为红色
'返回 True -- 无错误
' False -- 错误
Private Function ConditionCheck() As Boolean
Dim col As Integer
Dim row As Integer
Dim col_count As Integer = Grid_Conditions.Cols
Dim row_count As Integer = Grid_Conditions.Rows
Dim cell_text As String
Dim valid As Boolean = True
Dim line_not_empty As Boolean
Dim line_valid As Boolean
Dim cell_valid As Boolean
For row = 1 To row_count - 1
line_valid = True
'检查当前行是否为空行
line_not_empty = CheckConditionTableLineEmpty(row)
'如果当前行不为空
If line_not_empty = True Then
'检测每个行中的值是否有效
For col = 0 To col_count - 1
cell_valid = True
If Not (col = COLS.关联 And row = 1) Then '忽略行1的关联单元
cell_text = Grid_Conditions.Cell(row, col).Text
'当前单元不能为空
If cell_text.Length > 0 Then
'字段列中的表与字段需要有效
If col = COLS.字段 OrElse col = COLS.字段_值 Then
If CheckTextIsValidSectionName(cell_text) = SECTION_TYPE.无效 Then
cell_valid = False
End If
End If
Else
cell_valid = False
End If
End If
If cell_valid = False Then
Grid_Conditions.Cell(row, col).BackColor = Color.Red
line_valid = False
Else
Grid_Conditions.Cell(row, col).BackColor = Color.White
End If
Next
End If
If line_valid = False Then
Grid_Conditions.Cell(row, 0).BackColor = Color.Red
valid = False
Else
Grid_Conditions.Cell(row, 0).BackColor = Grid_Conditions.Cell(0, 0).BackColor
End If
Next
Return valid
End Function
'依据条件设置生成对应的SQL语句
Private Sub SQLGenerateFromCondition()
Dim strSQL_all As String = ""
Dim strSQL_Sections As String = ""
Dim strSQL_Tables As String = ""
Dim strSQL_Conditions As String = ""
Dim pTable As SECTION_UNIT
Dim pSecList As ArrayList
Dim pSec As SECTION_UNIT
Dim tbl_idx As Integer
Dim sec_idx As Integer
'查询字段与表
For tbl_idx = 0 To TableNameList.Count - 1
pTable = TableNameList.Item(tbl_idx)
'如果表被选中
If pTable.check = True Then
If strSQL_Tables.Length > 0 Then
strSQL_Tables &= ","
End If
strSQL_Tables &= "`" & pTable.name & "`"
pSecList = SectionNameList.Item(tbl_idx)
For sec_idx = 0 To pSecList.Count - 1
pSec = pSecList.Item(sec_idx)
If pSec.check = True Then
If strSQL_Sections.Length > 0 Then
strSQL_Sections &= ","
End If
strSQL_Sections &= "`" & pTable.name & "`.`" & pSec.name & "`"
End If
Next
End If
Next
'查询条件
'Dim col As Integer
Dim row As Integer
Dim col_count As Integer = Grid_Conditions.Cols
Dim row_count As Integer = Grid_Conditions.Rows
Dim cell_text As String
Dim valid As Boolean = True
Dim line_not_empty As Boolean
Dim line_valid As Boolean
For row = 1 To row_count - 1
line_valid = True
'检查当前行是否为空行
line_not_empty = CheckConditionTableLineEmpty(row)
If line_not_empty = True Then
If strSQL_Conditions.Length > 0 Then
strSQL_Conditions &= " "
End If
'关联
cell_text = Grid_Conditions.Cell(row, COLS.关联).Text
If cell_text.Length > 0 Then
strSQL_Conditions &= GetRelConditionSQL(cell_text) & " "
End If
'字段
cell_text = Grid_Conditions.Cell(row, COLS.字段).Text
strSQL_Conditions &= cell_text
'运算符
cell_text = Grid_Conditions.Cell(row, COLS.运算).Text
strSQL_Conditions &= " " & GetRelOperatorSQL(cell_text) & " "
'字段/值
cell_text = Grid_Conditions.Cell(row, COLS.字段_值).Text
If CheckTextIsValidSectionName(cell_text) = SECTION_TYPE.字段 Then
strSQL_Conditions &= " " & cell_text & " "
Else
strSQL_Conditions &= "'" & cell_text & "' "
End If
End If
Next
'合并各个字段
strSQL_all = "SELECT " & strSQL_Sections & " FROM " & strSQL_Tables
If strSQL_Conditions.Length > 0 Then
strSQL_all &= " WHERE " & strSQL_Conditions
End If
txt_SQL.Text = strSQL_all
End Sub
'通过“关联”名称获取对应的SQL表示符
Private Function GetRelConditionSQL(ByVal disname As String) As String
For i As Integer = 0 To rel_Conditions.Length / 2 - 1
If rel_Conditions(i, 0) = disname Then
Return rel_Conditions(i, 1)
End If
Next
Return ""
End Function
'通过"运算符"民初获取对应的SQL表示符
Private Function GetRelOperatorSQL(ByVal disname As String) As String
For i As Integer = 0 To rel_Operator.Length / 2 - 1
If rel_Operator(i, 0) = disname Then
Return rel_Operator(i, 1)
End If
Next
Return ""
End Function
Private Sub bt_Query_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_Query.Click
If ConditionCheck() = False Then
MsgBox("条件列表存在错误!")
Else
QueryTable.Columns.Clear()
QueryTable.Rows.Clear()
QueryTable.Clear()
If SQL_Query(txt_SQL.Text, QueryTable) = True Then
grid_Result.SetDataBinding(QueryTable)
End If
grid_Result.Locked = True
lblItemCount.Text = "" & QueryTable.Rows.Count & ""
End If
End Sub
End Class