Экспертная система Delphi.int.ru

Сообщество программистов
Общение, помощь, обмен опытом

Логин:
Пароль:
Регистрация | Забыли пароль?

Delphi.int.ru Expert

Другие разделы портала

Переход к вопросу:

#   

Статистика за сегодня:  


Лучшие эксперты

Подробнее »



Вопрос # 6 137

/ вопрос закрыт /

Приветствую, уважаемые эксперты!

Помогите разобраться... Требовалось написать программу справочник, всё работало, после, что то добавил и перестала запускаться, выдает ошибку "ADOTable1: Cannot perform this operation on a closed dataset" на строке "DMForm.ADOTable1.First".

P.S. DMForm это DataModule

Приложение:
  1. procedure TMainForm.FormActivate(Sender: TObject);
  2. var
  3. nd, nr: TTreeNode;
  4. fds: string;
  5. begin
  6. MainForm.TreeView1.Items.BeginUpdate;
  7. MainForm.TreeView1.SortType := stNone;
  8. MainForm.TreeView1.Items.Clear;
  9. //DMForm.ADOTable1.Open;
  10. DMForm.ADOTable1.First;
  11. i := 0;
  12.  
  13. if DMForm.ADOTable1.RecordCount > 0 then begin
  14. while not DMForm.ADOTable1.Eof do begin
  15. i := i + 1;
  16. RObject[i].ItemU1 := DMForm.ADOTable1.Fields[0].AsInteger;
  17. RObject[i].ItemU2 := 0;
  18. nd := MainForm.TreeView1.Items.AddObject(nil, DMForm.ADOTable1.Fields[1].AsString, nil);
  19. fds := DMForm.ADOTable1.Fields[0].AsString;
  20. DMForm.ADOQuery1.Active := False;
  21. DMForm.ADOQuery1.Parameters.ParamByName('razd').Value := fds;
  22. DMForm.ADOQuery1.Active := True;
  23.  
  24. if DMForm.ADOQuery1.RecordCount > 0 then begin
  25. DMForm.ADOQuery1.First;
  26. while not DMForm.ADOQuery1.Eof do begin
  27. i := i + 1;
  28. RObject[i].ItemU1 := DMForm.ADOQuery1.Fields[2].AsInteger;
  29. RObject[i].ItemU2 := DMForm.ADOQuery1.Fields[0].AsInteger;
  30. nr := MainForm.TreeView1.Items.AddChildObject(nd, DMForm.ADOQuery1.Fields[1].AsString, nil);
  31. DMForm.ADOQuery1.Next;
  32. end;
  33. end;
  34.  
  35. DMForm.ADOTable1.Next;
  36. end;
  37. end;
  38. //DMForm.ADOTable1.Close;
  39. DMForm.ADOTable1.Filter := '';
  40. DMForm.ADOQuery1.Filter := '';
  41. MainForm.TreeView1.Items.EndUpdate;
  42. end;


serox Вопрос закрыт (ответы не принимаются, мини-форум закрыт)

Вопрос задал: serox (статус: Посетитель)
Вопрос отправлен: 15 мая 2012, 21:09
Состояние вопроса: закрыт, ответов: 0.


Мини-форум вопроса

Всего сообщений: 11; последнее сообщение — 16 мая 2012, 21:52; участников в обсуждении: 3.
ANBsoft

ANBsoft (статус: Студент), 15 мая 2012, 21:19 [#1]:

9 строка - отключена команда открытия таблицы.
serox

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

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

serox (статус: Посетитель), 16 мая 2012, 00:16 [#7]:

Свойства все одинаковые, отладчик с открыть/закрыть проходит так же как и в рабочей программе, но не делает выборку... Просто у меня такое уже не в первый раз происходит с ADO...
That will be, you and do not learn, if never will try! ^__^
ANBsoft

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

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): Автор потерял интерес к вопросу

Чтобы оставлять сообщения в мини-форумах, Вы должны авторизироваться на сайте.

Версия движка: 2.6+ (26.01.2011)
Текущее время: 22 февраля 2025, 11:38
Выполнено за 0.03 сек.