Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.90/40: Рейтинг темы: голосов - 40, средняя оценка - 4.90
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9

Заполнение ListBox значениями из БД Access

25.04.2018, 00:23. Показов 7489. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день!
Имеется такая задача: на форме размещен ComboBox и ListBox. Также имеется БД одной таблицей и с полями:
  1. Номер п/п (он же счетчик)
  2. Фамилия
  3. Имя
  4. Год рождения
Необходимо при загрузки формы (т.е. при запуске приложения) в ComboBox подтянуть данные из столбца "Год рождения". Затем, при выборе пользователем нужного года рождения отобразить в ListBox соответствующие данные из столбцов "Фамилия" и "Имя".
С первой частью я справился:

VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Public Class Form1
    Dim dBaseCommand As New System.Data.OleDb.OleDbCommand
    Dim dBaseConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=new_BD.mdb")
    Dim DT As New Data.DataTable
    Dim DA As OleDb.OleDbDataAdapter
 
    Private Function Quote(strVariable As String) As String
        Quote = " ' " & strVariable & " ' "
    End Function
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DT.Clear()
        dBaseCommand = New OleDb.OleDbCommand("SELECT DISTINCT [Год рождения] FROM [Общие данные] ORDER BY [Год рождения]", dBaseConnection)
        dBaseConnection.Open()
        dBaseCommand.ExecuteNonQuery()
        DA = New OleDb.OleDbDataAdapter(dBaseCommand)
        DA.Fill(DT)
        Me.ComboBox1.Items.Clear()
 
        For Each r As DataRow In DT.Rows
            Me.ComboBox1.Items.Add(r(0).ToString)
        Next
        dBaseConnection.Close()
        
    End Sub
А вот со второй возникла проблема - как составить запрос я вроде бы понял, а вот как вытащить из DataTable нужные данные и впихнуть их в ListBox - не сообразить...

VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        Dim FIO As New ArrayList()
        DT.Clear()
        dBaseCommand = New OleDb.OleDbCommand("SELECT [Фамилия] AND [Имя] FROM [Общие данные] WHERE [Год рождения] = " & Quote(ComboBox1.SelectedItem), dBaseConnection)
        dBaseConnection.Open()
        dBaseCommand.ExecuteNonQuery()
        DA = New OleDb.OleDbDataAdapter(dBaseCommand)
        DA.Fill(DT)
        ListBox1.MultiColumn = True
        Me.ListBox1.Items.Clear()
 
        For Each r As DataRow In DT.Rows
            FIO.Add(r(0, 1).ToString)
        Next
        Label1.Text = FIO.Count
        ListBox1.Items.Add(FIO)
        dBaseConnection.Close()
    End Sub
End Class
Добавлено через 38 минут
На всякий случай: во втором фрагменте кода все, что после
VB.NET Скопировано
1
Me.ListBox1.Items.Clear()
- мои попытки заполнить ListBox и понять, почему не получается =)
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.04.2018, 00:23
Ответы с готовыми решениями:

Заполнение ListBox из поля БД Access
Здравствуйте! Есть бд access, таблица1 которая содержит поле name как заполнить листбокс с этого поля? Спасибо.

Заполнение ListBox из поля БД Access
есть база данных фамилия и имя не понимаю как подключить , чтоб работало через кнопку отобразить список

ListBox ActiveX с уникальными значениями
Нужен контрол ListBox, который будет 1) при AddItem проверять, нет ли уже в ListBox такого значения и добавлять только в том случае,...

12
18 / 18 / 2
Регистрация: 23.02.2012
Сообщений: 132
25.04.2018, 08:59
А почему бы сразу не привязать в Me.ComboBox1 вашу выборку, а не в цикле перебирать строки? Тогда можно указать что будет выбираться, а что будет выводится на экран.
0
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
25.04.2018, 09:12  [ТС]
Цитата Сообщение от Wurgengel Посмотреть сообщение
А почему бы сразу не привязать в Me.ComboBox1 вашу выборку, а не в цикле перебирать строки? Тогда можно указать что будет выбираться, а что будет выводится на экран.
Хм, правильно ли я понял, что Вы предлагаете во фрагменте Private Sub Form1_Load заменить
VB.NET Скопировано
1
2
3
        For Each r As DataRow In DT.Rows
            Me.ComboBox1.Items.Add(r(0).ToString)
        Next
на что-то вроде
VB.NET Скопировано
1
2
3
ComboBox1.DataSource = DT
ComboBox1.DisplayMember = "Год рождения"
ComboBox1.ValueMember = "Номер п/п"
Если речь про это, то как тогда отобразить в ListBox корректные Фамилию-Имя?
0
18 / 18 / 2
Регистрация: 23.02.2012
Сообщений: 132
25.04.2018, 09:19
Я давно не писал запросы, но можно так:
SQL Скопировано
1
SELECT [Фамилия] + ' ' + [Имя] AS FamImya FROM [Общие данные] WHERE [Год рождения] =
И будет у Вас столбец FamImya
0
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
25.04.2018, 16:47  [ТС]
Цитата Сообщение от Wurgengel Посмотреть сообщение
Я давно не писал запросы, но можно так:
SQLВыделить код
1
SELECT [Фамилия] + ' ' + [Имя] AS FamImya FROM [Общие данные] WHERE [Год рождения] =
И будет у Вас столбец FamImya
И потом этот столбец запихать в ListBox по аналогии с ComboBox? Попробую )

Добавлено через 7 часов 24 минуты
Вопрос: нужно ли заранее объявлять FamImya как переменную? Спрашиваю, т.к. Visual Studio ругается на использование FamImya в качестве источника данных - переменная не объявлена
0
1651 / 1091 / 158
Регистрация: 25.07.2015
Сообщений: 2,264
25.04.2018, 19:14
Цитата Сообщение от kelevara Посмотреть сообщение
нужно ли заранее объявлять FamImya как переменную
FamImya -это не переменная, это псевдоним (Alias) .
Запрос должен выглядеть как-то так
T-SQL Скопировано
1
SELECT ([Фамилия] + ' ' + [Имя]) AS FamImya FROM [Общие данные] WHERE [Год рождения] =
Студия ругалась , т.к. в предыдущей транскрипции запроса вы пытались объединить поля [Фамилия] и FamImya,
которого нет как источника.
0
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
25.04.2018, 21:48  [ТС]
Цитата Сообщение от Kulma Посмотреть сообщение
FamImya -это не переменная, это псевдоним (Alias) .
Запрос должен выглядеть как-то так
T-SQLВыделить код
1
SELECT ([Фамилия] + ' ' + [Имя]) AS FamImya FROM [Общие данные] WHERE [Год рождения] =
Студия ругалась , т.к. в предыдущей транскрипции запроса вы пытались объединить поля [Фамилия] и FamImya,
которого нет как источника.
Спасибо, теперь Студия не ругается )

Однако нужный результат получить не удалось - в ListBox так ничего и не передается =( Сам код с обновленным запросом выглядит теперь так:
VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
Public Class Form1
    Dim dBaseCommand As New System.Data.OleDb.OleDbCommand
    Dim dBaseConnection As New System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=new_BD.mdb")
    Dim DT As New Data.DataTable
    Dim DA As OleDb.OleDbDataAdapter
 
    Private Function Quote(strVariable As String) As String
        Quote = " ' " & strVariable & " ' "
    End Function
 
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        DT.Clear()
        dBaseCommand = New OleDb.OleDbCommand("SELECT DISTINCT [Год рождения] FROM [Общие данные] ORDER BY [Год рождения]", dBaseConnection)
        dBaseConnection.Open()
        dBaseCommand.ExecuteNonQuery()
        DA = New OleDb.OleDbDataAdapter(dBaseCommand)
        DA.Fill(DT)
        Me.ComboBox1.Items.Clear()
 
        For Each r As DataRow In DT.Rows
            Me.ComboBox1.Items.Add(r(0).ToString)
        Next
        dBaseConnection.Close()
        
    End Sub
 
    Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        DT.Clear()
        dBaseCommand = New OleDb.OleDbCommand("SELECT ([Фамилия] + ' ' + [Имя]) AS FI FROM [Общие данные] WHERE [Год рождения] = " & Quote(ComboBox1.SelectedItem), dBaseConnection)
        dBaseConnection.Open()
        dBaseCommand.ExecuteNonQuery()
        DA = New OleDb.OleDbDataAdapter(dBaseCommand)
        DA.Fill(DT)
        ListBox1.MultiColumn = True
        Me.ListBox1.Items.Clear()
 
        For Each r As DataRow In DT.Rows
            Me.ListBox1.Items.Add(r(0).ToString)
        Next
 
        dBaseConnection.Close()
    End Sub
End Class
Не могу понять, почему не работает теперь =(

Добавлено через 14 минут
Похоже, что часть проблемы крылась в запросе к БД - функцию Quote нужно исправить вот так:
VB.NET Скопировано
1
2
3
    Private Function Quote(strVariable As String) As String
        Quote = "'" & strVariable & "'"
    End Function
В таком виде у меня получилось вывести выборку людей за нужный год в консоль (сделал для проверки новое консольное приложение). Но вот с "GUI" программа не работает =(
0
1651 / 1091 / 158
Регистрация: 25.07.2015
Сообщений: 2,264
25.04.2018, 22:16
Цитата Сообщение от kelevara Посмотреть сообщение
Но вот с "GUI" программа не работает =(
У меня несколько вопросов :
1) Зачем вам функция Quote ?
Она , исходя из представленного кода , никакого дополнительного функционала не несёт , ничего
не возвращает , а только усложняет читабельность кода и подхомячивает ресурсы.
Вы просто из одной строковой переменной перегоняете данные в другую..зачем ?
2) Вы уверены , что запрос в Private Sub ComboBox1_SelectedIndexChanged что-то возвращает ?
По идее должно быть так в условии WHERE
VB.NET Скопировано
1
Quote(СomboBox1.SelectedItem.ToString())
3) И хотелось бы увидеть структуру таблицы [Общие данные], поле [Год рождения] какой тип имеет ?
0
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
25.04.2018, 22:26  [ТС]
1. Функция Quote - на мой взгляд с ней наоборот проще читать код было =)
2. Т.к. опыта у меня практически нет, то не могу сказать, что я сильно уверен =) Но мне казалось, что Private Sub ComboBox1_SelectedIndexChanged срабатывает в тот момент, когда пользователь выбирает какое-то значение в Combobox
На счет условия WHERE - да, я тоже заметил, что у меня скобок не хватает, но с ними тоже ничего не выводится )
3. БД приложил
Вложения
Тип файла: rar new_BD.rar (14.4 Кб, 21 просмотров)
0
1651 / 1091 / 158
Регистрация: 25.07.2015
Сообщений: 2,264
26.04.2018, 08:13
kelevara, как и предполагалось запрос в "Private Sub ComboBox1_SelectedIndexChanged "
ничего не возвращал , перемудрили вы с функцией.
И ещё : DT , созданный на основе запроса возвращает пустую строку по индексу 0
VB.NET Скопировано
1
r(0).ToString
Почему это происходит я сходу не понял , но разбираться уже лень , если честно.

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

Ниже рабочий код - пользуйтесь, разбирайтесь.
Удачи.

VB.NET Скопировано
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Private Sub ComboBox1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ComboBox1.SelectedIndexChanged
        DT.Clear()
        dBaseCommand = New OleDb.OleDbCommand("SELECT ([Фамилия] + ' ' + [Имя]) AS FI FROM [Общие данные] WHERE [Год рождения] ='" & ComboBox1.SelectedItem.ToString & "'", dBaseConnection)
        dBaseConnection.Open()
        dBaseCommand.ExecuteNonQuery()
        DA = New OleDb.OleDbDataAdapter(dBaseCommand)
        DA.Fill(DT)
        ListBox1.MultiColumn = True
        Me.ListBox1.Items.Clear()
 
        For Each r As DataRow In DT.Rows
            Me.ListBox1.Items.Add(r(1).ToString)
        Next
 
        dBaseConnection.Close()
    End Sub
Добавлено через 38 минут
Цитата Сообщение от Kulma Посмотреть сообщение
И ещё : DT , созданный на основе запроса возвращает пустую строку по индексу 0
Затупил , пустой столбец конечно по индексу 0 в строке r.
1
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
26.04.2018, 16:45  [ТС]
Kulma, Спасибо большое, все получилось =)

Сам код вроде бы понятен, за исключением нескольких моментов:
1. почему нужно ссылаться на индекс 1 для переменной r в цикле обхода DT? Ведь во фрагменте кода для combobox я ссылался на 0-ой индекс и он был не пуст?

2. если бы в базе данных столбец с годами имел бы тип не "Короткий текст", а например "Число", то что нужно изменить в запросе (попробовал запустить такой запрос, изменив тип данных в столбце - получил ошибку Студии "Несоответствие типов данных в выражении условия отбора" на выражении dBaseCommand.ExecuteNonQuery())? Правильно я понимаю, что проблема в том, что ComboBox1.SelectedItem.ToString имеет тип "Строка", а в БД я ее пытаюсь сравнивать с "числом"?
0
1651 / 1091 / 158
Регистрация: 25.07.2015
Сообщений: 2,264
26.04.2018, 19:30
Цитата Сообщение от kelevara Посмотреть сообщение
Правильно я понимаю, что проблема в том, что ComboBox1.SelectedItem.ToString имеет тип "Строка", а в БД я ее пытаюсь сравнивать с "числом"?
Всё правильно понимаете .
Вам нужно определиться , какие данные будете сравнивать (числа или строки) и от этого
будет зависеть транскрипция написания условия отбора.

Цитата Сообщение от kelevara Посмотреть сообщение
почему нужно ссылаться на индекс 1 для переменной r в цикле обхода DT? Ведь во фрагменте кода для combobox я ссылался на 0-ой индекс и он был не пуст?
Индекс 1 -это индекс столбца в строке r.
Вообще это тема целой лекции ))
Если коротко , то во фрагменте кода для combobox вы ЯВНО выбираете все значения из таблицы и ими заполняете
DataTable (DT) "SELECT DISTINCT [Год рождения] ....." Соответственно столбец с 0 индексом заполнен
значениями ( в вашем случае годом рождения ) и виден для отображения .
При запросах же с фильтром сначала выполняется фильтр WHERE , а потом уже выполняется выборка SELECT ,
согласно результатам фильтра. Если поле, участвующее в фильтре (как у вас), в SELECT ЯВНО не участвует , то это
не значит , что его нет в выборке , оно просто не видимо . Соответственно оно есть и в DT , просто не видимо (это легко
увидеть в отладчике). В вашем случае НЕЯВНОЕ поле [Год рождения], участвующее в фильтре WHERE занимает
в DT столбец с индексом 0 , т.е. r(0), но для внешней обработки /выборки/визуализации оно не доступно , оно
зарезервировано для внутреннего использования.
Поэтому обращаясь к нему вы всегда будете получать пустое результирующее значение.
Если же вы его выберите ЯВНО в SELECT , т.е. ваш запрос будет выглядеть
T-SQL Скопировано
1
SELECT [Год рождения],([Фамилия] + ' ' + [Имя]) AS FI FROM [Общие данные] WHERE [Год рождения] =...
то столбец с индексом 0 -(r(0)) в DT будет доступен и вы сможете к нему обращаться/выводить и т.д.

Прошу прощения за столь корявые разъяснения )))
Настоятельно рекомендую , если планируете заниматься БД , почитать по языку T-SQL....
1
0 / 0 / 0
Регистрация: 23.04.2018
Сообщений: 9
26.04.2018, 21:24  [ТС]
Kulma, блин, все бы так "коряво" объясняли =) спасибо за помощь! )
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
26.04.2018, 21:24
Помогаю со студенческими работами здесь

Заполнить Listbox значениями с листа
Есть listbox на форме, как его заполнить какими-то значениями из таблицы excel, чтобы при изменении таблицы (удаление и добавление...

Заполнение массива значениями
Камрады, есть еще одна задача. в массив int month = new int надо с помощью цикла for внести значения, дней месяца. то-есть: ...

Заполнение массива значениями
Всем привет! В результате данная программа выдает массив. Но не могу понять, почему он заполняется именно этими цифрами - от 0 до 6?...

Заполнение матрицы значениями
Создать матрицу 36 35 34 33 32 31 30 29 28 27 26 25 19 20 21 22 23 24 13 14 15 16 17 18 12 11 10 9 8 7 6 5 4 3 2 1

Заполнение структуры значениями
Как правильно заполнить структуру рандомными значениями? Проблема с инициализацией :( #include <iostream> #include...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Результаты исследования от команды MCM (март 2025 г.)
Programma_Boinc 07.04.2025
Результаты исследования от команды MCM (март 2025 г. ) В рамках наших текущих исследований мы продолжаем изучать гены, которые имеют наибольшую вероятность развития рака легких, выявленные в рамках. . .
Рекурсивные типы в Python
py-thonny 07.04.2025
Рекурсивные типы - это типы данных, которые определяются через самих себя или в сочетании с другими типами, которые в свою очередь ссылаются на исходный тип. В мире программирования такие структуры. . .
C++26: Объединение и конкатенация последовательностей и диапазонов в std::ranges
NullReferenced 07.04.2025
Работа с последовательностями данных – одна из фундаментальных задач, с которой сталкивается каждый разработчик. C++ прошел длинный путь в эволюции средств для манипуляции коллекциями – от. . .
Обмен данными в микросервисной архитектуре
ArchitectMsa 06.04.2025
Когда разработчики начинают погружаться в мир микросервисов, они часто сталкиваются с парадоксальным правилом: "два сервиса не должны делить один источник данных". Эта мантра звучит повсюду в. . .
PostgreSQL в Kubernetes: Автоматизация обслуживания с CNPG
Mr. Docker 06.04.2025
Администраторы баз данных сталкиваются с целым рядом проблем при обслуживании PostgreSQL в Kubernetes: как обеспечить правильную репликацию данных, как настроить автоматическое переключение при. . .
Async/await в TypeScript
run.dev 06.04.2025
Асинхронное программирование — это подход к разработке программного обеспечения, при котором операции выполняются независимо друг от друга. В отличие от синхронного выполнения, где каждая последующая. . .
Многопоточность в C#: Синхронизация потоков
UnmanagedCoder 06.04.2025
Многопоточное программирование стало неотъемлемой частью разработки современных приложений на C#. С появлением многоядерных процессоров возможность выполнять несколько задач параллельно значительно. . .
TypeScript: Классы и конструкторы
run.dev 06.04.2025
TypeScript, как статически типизированный язык, построенный на основе JavaScript, привнес в веб-разработку новый уровень надежности и структурированности кода. Одним из важнейших элементов этой. . .
Многопоточное программирование: Rust против C++
golander 06.04.2025
C++ существует уже несколько десятилетий и его поддержка параллелизма постепенно наращивалась со временем. Начиная с C++11, язык получил стандартную библиотеку для работы с потоками, а в последующих. . .
std::vector в C++: от основ к оптимизации производительности
NullReferenced 05.04.2025
Для многих программистов знакомство с std::vector происходит на ранних этапах изучения языка, но между базовым пониманием и подлинным мастерством лежит огромная дистанция. Контейнер std::vector. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru
Выделить код Копировать код Сохранить код Нормальный размер Увеличенный размер