Scribling Doodle Ответов: 1

Как отфильтровать 5 различных таблиц с помощью одного datagridview и tabcontrol


У меня есть 4 таблицы, касающиеся компьютерного оборудования. Рабочий стол, Блокнот, БАРАН, ЦП и ДИСК.

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

Что я уже пробовал:

If tcStock.SelectedIndex = 0 Then

            Dim ds As New DataSet
            Dim dt As New DataTable
            ds.Tables.Add(dt)
            Dim da As New OleDbDataAdapter("SELECT * FROM CPU WHERE sold = 0", connection)
            da.Fill(dt)
            Dim coluna As DataRow
            For Each coluna In dt.Rows
                lvProdutos.Items.Add(coluna.Item(0))
                lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
            Next
        ElseIf tcStock.SelectedIndex = 1 Then
            Dim ds As New DataSet
            Dim dt As New DataTable
            ds.Tables.Add(dt)
            Dim da As New OleDbDataAdapter("SELECT * FROM RAM WHERE sold = 0", connection)
            da.Fill(dt)
            Dim coluna As DataRow
            For Each coluna In dt.Rows
                lvProdutos.Items.Add(coluna.Item(0))
                lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
            Next
        ElseIf tcStock.SelectedIndex = 2 Then
            Dim ds As New DataSet
            Dim dt As New DataTable
            ds.Tables.Add(dt)
            Dim da As New OleDbDataAdapter("SELECT * FROM DISK WHERE sold = 0", connection)
            da.Fill(dt)
            Dim coluna As DataRow
            For Each coluna In dt.Rows
                lvProdutos.Items.Add(coluna.Item(0))
                lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
            Next
        ElseIf tcStock.SelectedIndex = 3 Then
            Dim ds As New DataSet
            Dim dt As New DataTable
            ds.Tables.Add(dt)
            Dim da As New OleDbDataAdapter("SELECT * FROM NOTEBOOK WHERE sold = 0", connection)
            da.Fill(dt)
            Dim coluna As DataRow
            For Each coluna In dt.Rows
                lvProdutos.Items.Add(coluna.Item(0))
                lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
            Next
        ElseIf tcStock.SelectedIndex = 4 Then
            Dim ds As New DataSet
            Dim dt As New DataTable
            ds.Tables.Add(dt)
            Dim da As New OleDbDataAdapter("SELECT * FROM DESKTOP WHERE sold = 0", connection)
            da.Fill(dt)
            Dim coluna As DataRow
            For Each coluna In dt.Rows
                lvProdutos.Items.Add(coluna.Item(0))
                lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
            Next
        End If

Richard Deeming

"У меня есть 4 стола ..."
Так почему же вы перечислили 5 столы?

"это не совсем хорошо работает"
Это не очень хороший вопрос. Вы не сказали нам, что вы хотите, чтобы код сделал, и вы не сказали нам, что он делает сейчас.

Нажмите кнопку "улучшить вопрос" и обновите свой вопрос с четким описанием проблемы.

RickZeeland

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

CHill60

Лично у меня была бы таблица под названием [Hardware] и еще одна под названием [HardwareType]. Таблица [Hardware] будет содержать информацию о запасах и столбец внешнего ключа для таблицы [HardwareType] (ID INT, [Type] nvarchar(125)), которая будет содержать 5 строк
1 рабочий стол
2 ноутбука
3 Оперативная память
4 Процессор
5 диск
Затем, когда кто-то приходит с другим типом оборудования, все, что мне нужно сделать, это добавить некоторые данные вместо создания новой схемы таблицы.
Вы можете (должны) найти эту статью полезной: Основы нормализации базы данных[^]

1 Ответов

Рейтинг:
4

CHill60

Сначала посмотрите на количество повторений в вашем коде. Сначала приведите это в порядок, чтобы мы могли сразу увидеть, с чем имеем дело...
Проход 1:

Dim ds As New DataSet
Dim dt As New DataTable
ds.Tables.Add(dt)

Dim sql As String

If tcStock.SelectedIndex = 0 Then
	sql = "SELECT * FROM CPU WHERE sold = 0"
ElseIf tcStock.SelectedIndex = 1 Then
	sql = "SELECT * FROM RAM WHERE sold = 0"
ElseIf tcStock.SelectedIndex = 2 Then
	sql = "SELECT * FROM DISK WHERE sold = 0"
ElseIf tcStock.SelectedIndex = 3 Then
	sql = "SELECT * FROM NOTEBOOK WHERE sold = 0"
ElseIf tcStock.SelectedIndex = 4 Then
	sql = "SELECT * FROM DESKTOP WHERE sold = 0"
End If

Dim da As New OleDbDataAdapter(sql, connection)
da.Fill(dt)
Dim coluna As DataRow
For Each coluna In dt.Rows
	lvProdutos.Items.Add(coluna.Item(0))
	lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
Next
Это немного опрятнее, но все же есть некоторое повторение ... это только имя таблицы, которое нам нужно изменить в SQL (предполагая, что вы остаетесь с этим плохим дизайном базы данных).
Сдать 2:
Dim tableNames() As String = New String() {"CPU", "RAM", "DISK", "NOTEBOOK", "DESKTOP"}
Dim sql As String = String.Format("SELECT * FROM {0} WHERE sold = 0", tableNames(tcStock.SelectedIndex))

Dim ds As New DataSet
Dim dt As New DataTable
ds.Tables.Add(dt)
Dim da As New OleDbDataAdapter(sql, connection)
da.Fill(dt)

For Each coluna As DataRow In dt.Rows
	lvProdutos.Items.Add(coluna.Item(0))
	lvProdutos.Items(lvProdutos.Items.Count - 1).SubItems.Add(coluna.Item(1))
Next

Теперь это довольно аккуратно, и я вижу потенциальные проблемы.
Во-первых, вы не очищаете какие-либо элементы уже в ListView, а во-вторых, неясно, настроили ли вы столбцы. Кроме того, хотя это и хорошо, что вы поняли, что 2-я колонка должна перейти в подпункты, есть более простой способ.
Попробуйте сделать это таким образом вместо этого
lvProdutos.Columns.Clear() 'Clear out the columns
lvProdutos.Items.Clear()  'Clear out any existing items
For Each col As DataColumn In dt.Columns
        lvProdutos.Columns.Add(col.ToString)  'Add columns depending on the data returned
Next
For Each coluna As DataRow In dt.Rows
    lvProdutos.Items.Add(coluna.Item(0), coluna.Item(1))
Next


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

Как я уже сказал в своем комментарии, лучше было бы иметь единую таблицу для всех типов оборудования, но каждая строка в этой таблице знает, что это за "тип" оборудования. Храните список типов оборудования в отдельной справочной таблице. Что-то вроде этого...
CREATE TABLE HardwareType
(
	TypeId int identity(1,1) NOT NULL,
	TypeName nvarchar(125),
	PRIMARY KEY (TypeId)
)
INSERT INTO HardwareType VALUES
('Desktop'),
('Notebook'),
('RAM'),
('CPU'),
('DISK')
SELECT * FROM HardwareType


CREATE TABLE Hardware
(
	HwId int identity(1,1)
	,HwType int
	,sold int 
	,manufacturer nvarchar(125)
	,[description] nvarchar(125)
	-- ,other columns as required
	,CONSTRAINT FK_HardwareType FOREIGN KEY (HwType)     
		REFERENCES HardwareType(TypeId)   
)

Чтобы получить данные обратно, вы можете сделать что-то вроде этого...
SELECT HW.manufacturer, HW.description, HWT.TypeName, sold
FROM Hardware HW
INNER JOIN HardwareType HWT ON HW.HwType=HWT.TypeId

Обратите внимание, что в моем SQL-операторе я явно перечисляю столбцы, которые мне нужно видеть, но не использую SELECT * ...Таким образом, если кто-то добавит новый столбец в таблицу(ы) позже, мои столбцы listview не будут внезапно меняться.