-
Доброго времени суток. Создаю в делфи7 программно Fields для ADOQuery, код ниже.
procedure TForm1.FormCreate(Sender: TObject);
var
tfil:TStringField;
begin
ADOQuery1.SQL.Clear;
ADOQuery1.SQL.Add('SELECT login, password, id_roles');
ADOQuery1.SQL.Add('FROM account');
tfil:=TStringField.Create(ADOQuery1);
tfil.FieldName :='login';
tfil.DataSet :=ADOQuery1;
tfil.SetFieldType(ftString);
tfil.DisplayLabel :='Логин';
tfil.DisplayWidth :=15;
tfil.FieldKind :=fkData;
ADOQuery1.Fields.Add(tfil);
DBGrid1.Columns.Add.FieldName:='login';
ADOQuery1.Open;
ADOQuery1.Active:=true;
end;
Созданное поле выводится отлично, но при закрытие формы появляется ошибка
Exception EAccessViolation in module Project1.exe at 000E4918. Access violation at address 004E4918 in module 'Project1.exe'. Read of address 01AF93E0.
Ошибка исчезает, если закоментировать строкуADOQuery1.Fields.Add(tfil);
У меня вопрос, почему такая хрень и что с ней делать.
И второй вопрос как вывести все поля?
Заранее спасибо. -
> но при закрытие формы появляется ошибка
Что показывает отладчик?ADOQuery1.Open;
ADOQuery1.Active:=true;
Зачем? -
Anatoly Podgoretsky © (23.03.12 08:37) [2]ADOQuery1.SQL.Add('SELECT login, password, id_roles');
{
tfil:=TStringField.Create(ADOQuery1);
tfil.FieldName :='login';
tfil.DataSet :=ADOQuery1;
tfil.SetFieldType(ftString);
tfil.DisplayLabel :='Логин';
tfil.DisplayWidth :=15;
tfil.FieldKind :=fkData;
ADOQuery1.Fields.Add(tfil);
DBGrid1.Columns.Add.FieldName:='login';
}
ADOQuery1.Open; -
Anatoly Podgoretsky
Я согласен, что для вывода всех полей проще всего сделать запрос SELECT. Но дело в том, что я планирую создать программно lookup поле, а для этого необходимо описать Fields. А т.к. подключение к БД происходит программно, я вынужден делать это в тексте программы. -
При компиляции ничего не показывает, но проблема явно в этой строкеADOQuery1.Fields.Add(tfil);
-
> планирую создать программно lookup поле, а для этого необходимо описать Fields
зачем "необходимо описать"? почему не подходит автосозданное Fields? -
> [4] sasha198407 © (23.03.12 09:23)
> При компиляции ничего не показывает
Отладчиком пользуются не при компиляции. -
Anatoly Podgoretsky © (23.03.12 09:35) [7]> sasha198407 (23.03.2012 09:21:03) [3]
Ну так создавай ВСЕ поля. -
Cobalt © (23.03.12 10:04) [8]Два поля с именем login?
мсье определенно знает толк в извращениях. -
Напишу по-подробнее.
Есть БД на MSSQL в ней 2 таблицы account и roles
account
id_account int
name1 vchar
login vchar
password vchar
id_roles int
roles
id_roles int
roles vchar
таблицы соединены по полю id_roles
В delphi вывожу таблицу account через DBGrid. Хочу что бы в DBGrid отображалось поле roles в виде выпадающего списка. Применяю для этого lookup. Но т.к. подключение к БД происходит в процессе выполнения программы, то пришлось описать lookup программно. Если код такой
procedure TFCreateUsers.FormCreate(Sender: TObject);
begin
DataModule1.ADOQuery2.SQL.Clear;
//вывод таблицы roles
DataModule1.ADOQuery2.SQL.Add('SELECT * FROM roles');
DataModule1.ADOQuery2.Open;
//закрытие запросов
DataModule1.ADOQuery1.SQL.Clear;
//вывод таблицы account
DataModule1.ADOQuery1.SQL.Add('SELECT name1,login,password,id_roles');
DataModule1.ADOQuery1.SQL.Add('FROM account');
DataModule1.ADOQuery1.Open;
//описываем lookup
FieldName := '3role';
FieldKind := fkLookup;
DataSet := DataModule1.ADOQuery1;
Name := 'ADOQuery1Field3role';
KeyFields := 'id_roles';
LookUpDataSet := DataModule1.ADOQuery2;
LookUpKeyFields := 'id_roles';
LookUpResultField:= 'roles';
DataModule1.ADOQuery2.FieldDefs.Add(Name, ftString, 20, false);
//активируем ADOQuery2
DataModule1.ADOQuery2.Active:=true;
//активируем ADOQuery1
DataModule1.ADOQuery1.Active:=true;
//привязываем колонки в DBGrid1 к полям таблицы account
DBGrid1.Columns[0].FieldName:='name1';
DBGrid1.Columns[1].FieldName:='login';
DBGrid1.Columns[2].FieldName:='password';
DBGrid1.Columns[3].FieldName:='3role';
end;
, то выпадает ошибка: 'ADOQuery4: Field 'id_roles' not found'
Отсюда делаю вывод, что Fields надо описывать программно.
Начинаю добавлять, пишу к примеру
tfil:=TStringField.Create(ADOQuery1);
tfil.FieldName :='login';
tfil.DataSet :=ADOQuery1;
tfil.SetFieldType(ftString);
tfil.DisplayLabel :='Ëîãèí';
tfil.DisplayWidth :=15;
tfil.FieldKind :=fkData;
ADOQuery1.Fields.Add(tfil);
DBGrid1.Columns.Add.FieldName:='login';
tfil.FieldName :='password';
tfil.DataSet :=ADOQuery1;
tfil.SetFieldType(ftString);
tfil.DisplayLabel :='Ïàðîëü';
tfil.DisplayWidth :=15;
tfil.FieldKind :=fkData;
ADOQuery1.Fields.Add(tfil);
DBGrid1.Columns.Add.FieldName:='password';
, т.е. добавляю поля login и password, то он выводит эти поля, но показывает записи только последнего поля, т.е. поля password, а при закрытие окна выводит ошибкаписи только последнего поляу
Exception EAccessViolation in module Project1.exe at 000E4918. Access violation at address 004E4918 in module 'Project1.exe'. Read of address 01AF93E0.
КомментируюADOQuery1.Fields.Add(tfil);
и меняюDBGrid1.Columns.Add.FieldName
наDBGrid1.Columns[i].FieldName
, где i порядковый индекс колонки. Ошибка при закрытие исчезает, но по прежнему выводит записи только последнего поля. -
> Два поля с именем login?
Имеете ввиду строки?
ADOQuery1.Fields.Add(tfil);
DBGrid1.Columns.Add.FieldName:='login'; -
> Отсюда делаю вывод, что Fields надо описывать программно.
Вот. Из-за неверного подхода и неверно сделанного вывода начинаем строить монстроподобное страхоуё..ще. -
> Вот. Из-за неверного подхода и неверно сделанного вывода
> начинаем строить монстроподобное страхоуё..ще.
Какой вариант -
найти ошибку, не делая выводов.
-
> найти ошибку
в смысле, не в том что уже наворочено из-за неверного, а в самом первом коде. -
Я так и не понял, почему нелязя всё сделать в дизайнере.
Несколько полей в лукап разделяются знаком ";". -
> Я так и не понял, почему нелязя всё сделать в дизайнере.
А как сделать в дизайне, если подключение к БД происходит в тексте программы, а значит и ADOQuery начинает выполняться в программе. -
> [16] sasha198407 © (23.03.12 11:33)
> если подключение к БД происходит в тексте программы
Подключить в дизайнере, настроить, оключить. -
И за пользование TADOQuery сейчас поругают.
-
> А как сделать в дизайне, если подключение к БД происходит
> в тексте программы, а значит и ADOQuery начинает выполняться
> в программе.
Написать нужные поля. То, что оно ошибку подключения выдаёт - ну и хрен с ней. Напиши эти поля в блокноте, скопируй, вставь. -
Сделал как Ega3 посоветовал, заработало. Конечно немного неудобно, да и хрен с ним, результат меня устраивает. Всем спасибо, тему можно закрывать.