Форум программистов, компьютерный форум, киберфорум
Наши страницы
C++ Builder: Базы данных
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/7: Рейтинг темы: голосов - 7, средняя оценка - 5.00
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
1

Переход по записям в цикле. Вывод записей

26.04.2013, 22:47. Просмотров 1345. Ответов 12
Метки нет (Все метки)

Здравствуйте. Имеется база данных из 3-х таблиц: студент, группа, стипендия.
Необходимо в обычный СтрингГрид вывести название группы, ФИО студента и размер стипендии (и др.).
Для этого использую запрос:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int StudentCount = DataModule2->Student->RecordCount;
//....
for(int i=1; i<StudentCount; i++)
    {
        if(DataModule2->Query1->Active)
                        DataModule2->Query1->Close();
        DataModule2->Query1->SQL->Clear();
        DataModule2->Query1->SQL->Add("SELECT Name AS g_name, PIB AS pib, Seredniy_bal AS s_bal, Rozmir AS razmer FROM Grupa, Student, Stipendiya WHERE ((GRUPA_ID = ID_Grupa)AND(STIPENDIYA_ID=ID_Stipendiya)AND(ID_Student = "+IntToStr(i)+"))");
        DataModule2->Query1->Open();
        
        Form5->SG->RowCount++;
        Form5->SG->Cells[0][i] = DataModule2->Query1->FieldByName("g_name")->AsString;
        Form5->SG->Cells[1][i] = DataModule2->Query1->FieldByName("pib")->AsString;
        Form5->SG->Cells[2][i] = DataModule2->Query1->FieldByName("s_bal")->AsString;
        Form5->SG->Cells[3][i] = DataModule2->Query1->FieldByName("razmer")->AsString;
//...
}
Понимаю, что так переходить по записям - абсурд, но как по-другому сделать не знаю.
Проблема в том, что ID записей, при их удалении не "возвращается назад". Например, создали три записи. Потом удалили запись с номером 3 и создали еще одну. У новой будет ИД = 4. Из-за этого - ошибка при поиске и выводе.
Можно ли как-то "по-культурному" переходить по записям, без использования "индекса"? Наведите пример.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
26.04.2013, 22:47
Ответы с готовыми решениями:

Удаление записей в цикле
Не понимаю почему, но удаляется только одна запись, а должно две. Проверяю с...

Вывод в цикле
Здравствуйте. Делаю программу-калькулятор для комбинаторики. Подсчет количества...

Вывод CheckBox в цикле
Здравствуйте! Не могу никак разобраться. Пытаюсь сделать следующее: из базы...

Вывод в Memo (в цикле)
Подскажите как такое сделать : у меня есть цикл , который проходит 2000 раз....

Вывод записей и проверка
Имеется БД, которая подключается к проекту(тестировщик знаний учащихся). При...

12
The_Immortal
1560 / 496 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
26.04.2013, 23:13 2
Prostoplus,
Цитата Сообщение от Prostoplus Посмотреть сообщение
обычный СтрингГрид
А чем же, если не секрет, не устроил обычный DBGrid?


Цитата Сообщение от Prostoplus Посмотреть сообщение
Можно ли как-то "по-культурному" переходить по записям, без использования "индекса"?
Можно. У компонента ADOQuery (а точнее у базового класса TDataSet) для этого существуют определенные методы. В Вашем случае это:
First()
и
Next()

а также свойство RecordCount или Eof.
1
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
26.04.2013, 23:18  [ТС] 3
The_Immortal,
А чем же, если не секрет, не устроил обычный DBGrid?
Такой привычнее, так как работаю с базами данных от силы три дня.
Можно. У компонента ADOQuery для этого существуют определенные методы.
Я использую обычный Query, так как работаю с доисторическими базами данных и старым билдером.
Сейчас попробую...
0
Tim979
45 / 37 / 9
Регистрация: 26.04.2013
Сообщений: 89
26.04.2013, 23:23 4
Не совсем понятно что вы пытаетесь сделать и чем вас не устраивает DBGrid. Я так понял, что вы имеете какую то таблицу Student, почему бы вам не брать значение поля Student->FieldByName("ID_Student ") и при каждом проходе цикла делать что то вроде Student->Next(), а в своем запросе написать вместо +IntToStr(i)+ Student->FieldByName("ID_Student ")
0
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
26.04.2013, 23:25  [ТС] 5
Цитата Сообщение от Tim979 Посмотреть сообщение
Не совсем понятно что вы пытаетесь сделать и чем вас не устраивает DBGrid. Я так понял, что вы имеете какую то таблицу Student, почему бы вам не брать значение поля Student->FieldByName("ID_Student ") и при каждом проходе цикла делать что то вроде Student->Next(), а в своем запросе написать вместо +IntToStr(i)+ Student->FieldByName("ID_Student ")
В принципе да, только имеется 3 связанных таблицы со связями один ко многим. Вывожу в таблицу данные сразу из трех таблиц.
0
The_Immortal
1560 / 496 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
26.04.2013, 23:30 6
Prostoplus,
Цитата Сообщение от Prostoplus Посмотреть сообщение
использую обычный Query
Обычный это TQuery?

Там также идет наследование от TDataSet, так что
Цитата Сообщение от The_Immortal Посмотреть сообщение
First()
и
Next()
а также свойство RecordCount или Eof.
это все справедливо.
1
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
26.04.2013, 23:31  [ТС] 7
The_Immortal, спасибо большое, буду пробовать.
0
Tim979
45 / 37 / 9
Регистрация: 26.04.2013
Сообщений: 89
26.04.2013, 23:41 8
попробуй что то вроде этого
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int StudentCount = DataModule2->Student->RecordCount;
Student->First()//установка курсора на первую запись в таблице студент
for(int i=1; i<StudentCount; i++)
    {
        if(DataModule2->Query1->Active)
                        DataModule2->Query1->Close();
        DataModule2->Query1->SQL->Clear();
        DataModule2->Query1->SQL->Add("SELECT Name AS g_name, PIB AS pib, Seredniy_bal AS s_bal, Rozmir AS razmer FROM Grupa, Student, Stipendiya WHERE ((GRUPA_ID = ID_Grupa)AND(STIPENDIYA_ID=ID_Stipendiya)AND(ID_Student = "+IntToStr(Student->FieldByName("ID_Student "))+"))");
        DataModule2->Query1->Open();
        
        Form5->SG->RowCount++;
        Form5->SG->Cells[0][i] = DataModule2->Query1->FieldByName("g_name")->AsString;
        Form5->SG->Cells[1][i] = DataModule2->Query1->FieldByName("pib")->AsString;
        Form5->SG->Cells[2][i] = DataModule2->Query1->FieldByName("s_bal")->AsString;
        Form5->SG->Cells[3][i] = DataModule2->Query1->FieldByName("razmer")->AsString;
Student->Next()//перевод на следующую запись
}
0
The_Immortal
1560 / 496 / 48
Регистрация: 04.04.2009
Сообщений: 1,891
26.04.2013, 23:51 9
Ну и небольшая поправочка:
C++
1
for(int i=1; i<=StudentCount; i++)
, а то одну запись не учтем.
0
Tim979
45 / 37 / 9
Регистрация: 26.04.2013
Сообщений: 89
26.04.2013, 23:55 10
внимания не обратил, согласен
0
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
27.04.2013, 00:12  [ТС] 11
Tim979, выводит только одну запись несколько раз... сейчас буду разбераться.

Добавлено через 12 минут
Сделал вот так:
C++
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
try
{
    //обрываем связи сто бы подсчитало общее количество студентов
    DataModule2->Student->MasterSource = NULL;
    DataModule2->Student->MasterFields = "";
    DataModule2->Student->IndexName = "";
 
    int StudentCount = DataModule2->Student->RecordCount;
 
    DataModule2->Student->First();
 
    for(int i=1; i<=StudentCount; i++)
    {
        if(DataModule2->Query1->Active)
                        DataModule2->Query1->Close();
        DataModule2->Query1->SQL->Clear();
 
        DataModule2->Query1->SQL->Add("SELECT Name AS g_name, PIB AS pib, Seredniy_bal AS s_bal, Rozmir AS razmer FROM Grupa, Student, Stipendiya WHERE ((GRUPA_ID = ID_Grupa)AND(STIPENDIYA_ID=ID_Stipendiya)AND(ID_Student = "+DataModule2->Student->FieldByName("ID_Student")->AsString+"))");
        DataModule2->Query1->Open();
 
        Form5->SG->RowCount++;
        Form5->SG->Cells[0][i] = DataModule2->Query1->FieldByName("g_name")->AsString;
        Form5->SG->Cells[1][i] = DataModule2->Query1->FieldByName("pib")->AsString;
        Form5->SG->Cells[2][i] = DataModule2->Query1->FieldByName("s_bal")->AsString;
        Form5->SG->Cells[3][i] = DataModule2->Query1->FieldByName("razmer")->AsString;
 
        DataModule2->Student->Next();
    }
 
     //возвращаем связи
    DataModule2->Student->MasterSource = DataModule2->GrupaDS;
    DataModule2->Student->MasterFields = "ID_Grupa";
    DataModule2->Student->IndexName = "GRUPA_ID1";
}
Вроде бы работает как нужно.
0
Tim979
45 / 37 / 9
Регистрация: 26.04.2013
Сообщений: 89
27.04.2013, 00:14 12
значит у вас не переводится курсор на следующую запись в таблице Student смотрите в эту сторону, а самый лучший вариант изучите компоненты ADOQuery и DBGrid прочтите книгу А.Я. Архангельский Компоненты C++ Builder
0
Prostoplus
11 / 1 / 1
Регистрация: 21.09.2012
Сообщений: 122
27.04.2013, 00:15  [ТС] 13
Tim979, после небольших изменений все работает и переходит на следующую строку.
0
27.04.2013, 00:15
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.04.2013, 00:15

Вывод уникальных записей из поля в DBComboBox
Здравствуйте, нужно вывести уникальные записи из поля в DBComboBox. Имеем:...

Выборка записей по Listbox и вывод результатов в DBGird
Разскажите пожалуйста как сделать Query запрос из БД таблицы выводил нужную...

Переход по записям (изменение вида формы кликом - переход на определенную запись)
есть форма ленточная, хочу сделать чтобы при нажатии на инфу открывалась запись...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru