|
Вопрос # 6 137/ вопрос закрыт / |
|
Приветствую, уважаемые эксперты!
Помогите разобраться... Требовалось написать программу справочник, всё работало, после, что то добавил и перестала запускаться, выдает ошибку "ADOTable1: Cannot perform this operation on a closed dataset" на строке "DMForm.ADOTable1.First".
P.S. DMForm это DataModule
Приложение: Переключить в обычный режим- procedure TMainForm.FormActivate(Sender: TObject);
- var
- nd, nr: TTreeNode;
- fds: string;
- begin
- MainForm.TreeView1.Items.BeginUpdate;
- MainForm.TreeView1.SortType := stNone;
- MainForm.TreeView1.Items.Clear;
- //DMForm.ADOTable1.Open;
- DMForm.ADOTable1.First;
- i := 0;
-
- if DMForm.ADOTable1.RecordCount > 0 then begin
- while not DMForm.ADOTable1.Eof do begin
- i := i + 1;
- RObject[i].ItemU1 := DMForm.ADOTable1.Fields[0].AsInteger;
- RObject[i].ItemU2 := 0;
- nd := MainForm.TreeView1.Items.AddObject(nil, DMForm.ADOTable1.Fields[1].AsString, nil);
- fds := DMForm.ADOTable1.Fields[0].AsString;
- DMForm.ADOQuery1.Active := False;
- DMForm.ADOQuery1.Parameters.ParamByName('razd').Value := fds;
- DMForm.ADOQuery1.Active := True;
-
- if DMForm.ADOQuery1.RecordCount > 0 then begin
- DMForm.ADOQuery1.First;
- while not DMForm.ADOQuery1.Eof do begin
- i := i + 1;
- RObject[i].ItemU1 := DMForm.ADOQuery1.Fields[2].AsInteger;
- RObject[i].ItemU2 := DMForm.ADOQuery1.Fields[0].AsInteger;
- nr := MainForm.TreeView1.Items.AddChildObject(nd, DMForm.ADOQuery1.Fields[1].AsString,
nil);
- DMForm.ADOQuery1.Next;
- end;
- end;
-
- DMForm.ADOTable1.Next;
- end;
- end;
- //DMForm.ADOTable1.Close;
- DMForm.ADOTable1.Filter := '';
- DMForm.ADOQuery1.Filter := '';
- MainForm.TreeView1.Items.EndUpdate;
- end;
 |
Вопрос задал: serox (статус: Посетитель)
Вопрос отправлен: 15 мая 2012, 21:09
Состояние вопроса: закрыт, ответов: 0.
|
Мини-форум вопроса
Всего сообщений: 11; последнее сообщение — 16 мая 2012, 21:52; участников в обсуждении: 3.
|
ANBsoft (статус: Студент), 15 мая 2012, 21:19 [#1]:
9 строка - отключена команда открытия таблицы.
|
|
serox (статус: Посетитель), 15 мая 2012, 22:12 [#2]:
Если с 9 и 38 снять комментарий, то дерево показывает, а выборка не происходит...
Хотя в другой аналогичной программе всё работает и без Открыть/Закрыть...
That will be, you and do not learn, if never will try! ^__^
|
|
Мережников Андрей (статус: Абитуриент), 15 мая 2012, 22:49 [#3]:
Цитата (serox):
а выборка не происходит.
ну так включи отладчик и посмотри пошагово где "затык". Может какое условие неправильно прописано. А делать выборку на закрытом наборе - это все равно, что пытаться пива выпить, не открыв бутылку
|
|
Мережников Андрей (статус: Абитуриент), 15 мая 2012, 22:51 [#4]:
и в догонку - нельзя было сделать всю выборку одним запросом?
|
|
serox (статус: Посетитель), 15 мая 2012, 23:01 [#5]:
Мережников Андрей:
Повторяю ещё раз, есть 2 программы. Первая - отлично всё работает и без Открыть/Закрыть (так как она написана в вопросе, только другие названия переменных). Вторая - я её изменяю, и после переименования некоторых переменных, начала выскакивать ошибка...
That will be, you and do not learn, if never will try! ^__^
|
|
Мережников Андрей (статус: Абитуриент), 15 мая 2012, 23:08 [#6]:
Цитата (serox):
Повторяю ещё раз,
Цитата (Мережников Андрей):
включи отладчик и посмотри пошагово где "затык"
а еще проверь значения свойств в компонентах
|
|
serox (статус: Посетитель), 16 мая 2012, 00:16 [#7]:
Свойства все одинаковые, отладчик с открыть/закрыть проходит так же как и в рабочей программе, но не делает выборку... Просто у меня такое уже не в первый раз происходит с ADO...
That will be, you and do not learn, if never will try! ^__^
|
|
ANBsoft (статус: Студент), 16 мая 2012, 00:31 [#8]:
Слишком все запутано, и куча лишних команд.
Я никогда не работал через ADO-компоненты, так что если ошибаюсь, то пусть знатоки поправят.
DMForm.ADOTable1.Open; //если таблица не открыта, то с ней нельзя работать, так что Open нужно выполнять
// DMForm.ADOTable1.First; //можно убрать, после Open курсор и так на первой строке
i := 0;
// if DMForm.ADOTable1.RecordCount > 0 then begin //лишняя проверка, если RecordCount=0, то ADOTable1.Eof будет сразу
True
while not DMForm.ADOTable1.Eof do begin
i := i + 1;
RObject[i].ItemU1 := DMForm.ADOTable1.Fields[0].AsInteger;
RObject[i].ItemU2 := 0;
nd := MainForm.TreeView1.Items.AddObject(nil, DMForm.ADOTable1.Fields[1].AsString, nil);
// fds := DMForm.ADOTable1.Fields[0].AsString; //зачем вообще эта переменная?
// DMForm.ADOQuery1.Active := False; //по логике здесь он и так должен быть закрыт
DMForm.ADOQuery1.Parameters.ParamByName('razd').Value := DMForm.ADOTable1.Fields[0].AsString; //Сразу без всяких
fds
DMForm.ADOQuery1.Active := True;
// if DMForm.ADOQuery1.RecordCount > 0 then begin //лишнее - выше описал
// DMForm.ADOQuery1.First; //лишнее - выше описал
while not DMForm.ADOQuery1.Eof do begin
i := i + 1;
RObject[i].ItemU1 := DMForm.ADOQuery1.Fields[2].AsInteger;
RObject[i].ItemU2 := DMForm.ADOQuery1.Fields[0].AsInteger;
nr := MainForm.TreeView1.Items.AddChildObject(nd, DMForm.ADOQuery1.Fields[1].AsString,
nil);
DMForm.ADOQuery1.Next;
end;
DMForm.ADOQuery1.Active := False; //закрывать после использования
// end;
DMForm.ADOTable1.Next;
end;
// end;
DMForm.ADOTable1.Close; //если больше не нужно, то закрыть
В логику работы не вникал, так как не все есть в листинге, но так с деревьями не работают.
Ваш код загрузит только один уровень вложения.
Приведу кусок кода из своего проекта. Не претендую на предельную оптимальность, но 1) компонент доступа используется только один, 2) запрос к базе выполняется всего один раз, 3) глубина вложения дерева не ограничена, 4) обратите внимание на свойство Data у TTreeNode, возможно RObject станет вообще не нужен.
//Работа с деревьями
Procedure ClearTree(T:TTreeView);
Var n : Integer;
Begin
T.Selected:=Nil;
for n:=0 to T.Items.Count-1 do begin
Dispose(T.Items[n].Data);
end;
T.Visible:=False;
T.Items.Clear;
T.Visible:=True;
End;
Procedure LoadSubTree(T:TTreeView;R:TTreeNode;Q:TIBQuery;FN:String;IDSelect:Integer);
Var I : PInteger;
Last:Integer;
TekNode:TTreeNode;
b:TBookmark;
Begin
Q.First;
while Not Q.Eof do begin
if Q.FieldByName('Parent').AsInteger=PInteger(R.Data)^ then begin
Last:=Q.FieldByName('ID').AsInteger;
b:=Q.GetBookmark;
New(I);
I^:=Last;
TekNode:=T.Items.AddChildObject(R,Q.FieldByName(FN).AsString,I);
if Last=IDSelect then T.Selected:=TekNode;
LoadSubTree(T,TekNode,Q,FN,IDSelect);
Q.GotoBookmark(b);
Q.FreeBookmark(b);
end;
Q.Next;
end;
End;
Procedure LoadTree(T:TTreeView;Q:TIBQuery;FN:String;IDSelect:Integer);
Var I : PInteger;
Last:Integer;
TekNode:TTreeNode;
b:TBookmark;
begin
ClearTree(T);
Q.FetchAll;
if Q.RecordCount=0 then Exit;
T.Visible:=False;
Q.First;
while Not Q.Eof do begin
if Q.FieldByName('Parent').AsInteger=0 then begin
Last:=Q.FieldByName('ID').AsInteger;
b:=Q.GetBookmark;
New(I);
I^:=Last;
TekNode:=T.Items.AddObject(Nil,Q.FieldByName(FN).AsString,I);
if Last=IDSelect then T.Selected:=TekNode;
LoadSubTree(T,TekNode,Q,FN,IDSelect);
Q.GotoBookmark(b);
Q.FreeBookmark(b);
end;
Q.Next;
end;
T.Visible:=True;
End;
Компоненты доступа из закладки InterBase - но идея должна быть понятна.
|
|
Мережников Андрей (статус: Абитуриент), 16 мая 2012, 18:07 [#9]:
Цитата (ANBsoft):
// if DMForm.ADOTable1.RecordCount > 0 then begin //лишняя проверка, если RecordCount=0, то ADOTable1.Eof будет сразу True
не совсем так - если верить документации, то одно только значение ADOTable1.Eof, установленное в true, еще не значит, что таблица пуста. При пустой таблице в true должны быть установлены сразу 2 свойства: ADOTable1.Eof и ADOTable1.Bof
|
|
ANBsoft (статус: Студент), 16 мая 2012, 21:42 [#10]:
Я же писал, что не работал с ADO компонентами, а у Interbase компонентов (у TTable и TQuery вроде тоже), если сразу после открытия датасета EoF=True, значит выборка пуста. Оно и логично, BoF=True значит что была выбрана последняя запись в выборке, если записи не вычитывались, значит их просто нет.
|
|
Мережников Андрей (статус: Абитуриент), 16 мая 2012, 21:52 [#11]:
да это не только для ADO написано. Такая вот странность дельфи. меня после foxpro это тоже сильно удивило.
|
27 мая 2013, 12:09: Вопрос закрыт (решение принял DNK): Автор потерял интерес к вопросу
Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.
|