Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Для новичков > Перемещение по строкам


Автор: Flaer 4.9.2008, 13:42
Такая проблемка: Чет совсем не сооброжу как передвигаться по строкам таблицы.
По столбцам строки получается, а вот по строкам таблицы нет(

Автор: Frees 4.9.2008, 13:52
Код

DBGrid.datasorce.dataset.first
DBGrid.datasorce.dataset.next
DBGrid.datasorce.dataset.prior
DBGrid.datasorce.dataset.last
DBGrid.datasorce.dataset.locate

Автор: Poseidon 4.9.2008, 14:02
Flaer, DBGrid - это всего-лишь компонент отображения информации. Если тебе нужно получить саму инфу непосредственно, то "смотреть" нужно не на DBGrid, а туда, откуда DBGrid берет эту инфу. Т.е. на TTable или TQuery (что ты там используешь?)

Даже на dataset, как предложил Frees, "смотреть" можно, но не правильно, т.к. dataset тоже берет эту инфу откуда-то. Так не проще ли сразу "туда" и глянуть?

Автор: Данкинг 4.9.2008, 14:11
Перемещаешься по таблице, которая у тебя отображается в гриде.

Автор: Flaer 4.9.2008, 14:16
хм...
спасибо за ответ
ну незнаю насколько проще ) 
мне просто нужно удалить посторяющиеся строки.Думал здесь проще будет.
Искал где же индекс на строку, а тут вот так ))  

Автор: Poseidon 4.9.2008, 14:22
Цитата(Flaer @  4.9.2008,  14:16 Найти цитируемый пост)
мне просто нужно удалить посторяющиеся строки.Думал здесь проще будет.
В DBGrid ты не удалишь строки, потому как эти, как ты выразился, "строки" - это записи в БД. Поэтому удалять нужно именно в БД. Можно с помощью TTable, можно в помощью запроса DELETE в TQuery. Ты, кстати, так и не указал каким образом ты получаешь данные в DBGrid.

Добавлено через 1 минуту и 48 секунд
Кстати, если ты используешь TQuery, то добавив всего одно слово DISTINCT в запрос, ты не будешь получать повторы.

Автор: Flaer 4.9.2008, 14:30
ADOTable и DBGrid лежат у меня на разных формах.
Связал я их  из через  DataSourse.
Я из таблицы выдергиваю некоторыестолбцы, в результате чего могу появляться дублирующие записи(строки      ) . От этого мне нужно освободиться. Если подскажите путь проще буду очень признателен 

Автор: Poseidon 4.9.2008, 15:18
Цитата(Flaer @  4.9.2008,  14:30 Найти цитируемый пост)
Если подскажите путь проще буду очень признателен 
Вместо ADOTable используй ADOQuery. Там, в SQL напиши что-то похожее на:

Код
SELECT DISTINCT stolbets1, stolbets2
FROM tablitsa

Все остальное у ADOQuery установи такое же как и у ADOTable. Сам ADOTable можно удалить.
Может быть придется немного подкорректировать запрос, т.к. не совсем понял из фразы "в результате чего могу появляться дублирующие записи" в результате чего это они так могут появится, если ты только отображаешь, а не записываешь данные? И "дублирующие" - это как? Один столбец похож на второй или одна строка (захватывающая оба столбца) похожа на другую строку? Во-втором случае зарос должен "прокатить".

Автор: Flaer 4.9.2008, 15:33
Я не знаю заранее какие поля остануться от таблицы ) 


поле1 поле2 поле3
   x         x        y
   x         x        z
   x         y        z 

Удаляю из таблицы БД поле3 , в результат чего 
полчаю в таблице, повторяющиеся запси.
такова суть дела ) 

наверно выгядит дико ) 
но это реальная задача 

Автор: Poseidon 4.9.2008, 15:40
Ну вот мой вышеуказанный запрос и сделает что надо.

Код

SELECT DISTINCT pole1, pole2
FROM tablitsa

pole1 и pole2 укажи свои названия "столбцов". tablitsa - название твоей таблицы. Это напиши в ADOQuery.SQL (можно прямо в инспекторе). Вся остальная работа с ADOQuery такая же как и с ADOTable.

В результате из приведенной тобой таблицы ты получишь только

поле1 поле2 
   x         y      

Автор: Flaer 4.9.2008, 15:58
Я удалил поле3
в результате чего получил:
поле1 поле2 
   x         x        
   x         x       
   x         y   


Дублирование нужно исключить и получить вот это:

поле1 поле2   
   x         x     
   x         y    

Автор: Poseidon 4.9.2008, 16:05
Ну так и будет. Это я постом выше ошибся... Прошу прощения.

Автор: Flaer 4.9.2008, 16:08
Сейчас проверю ))


Автор: Flaer 4.9.2008, 16:52
сделал так 

with ADOQuery do
    begin
     SQL.Clear;
     SQL.Add('SELECT DISTINCT '+ StrokaNameFields );
     SQL.Add('FROM '+ ADOTable.TableName  );
     ExecSQL;
    end;


StrokaNameFields - содержит имена полей
ADOTable.TableName - получает имя таблицы

и чет не работает ( 

Автор: Данкинг 4.9.2008, 17:46
Цитата(Flaer @  4.9.2008,  17:52 Найти цитируемый пост)
и чет не работает (  

Какая ошибка?

Автор: Rohoss 5.9.2008, 03:15
Может заменить ExecSQL на Open

Автор: Poseidon 5.9.2008, 08:25
Цитата(Flaer @  4.9.2008,  16:52 Найти цитируемый пост)
и чет не работает
 SELECT-запрос (т.е. запрос, который возвращает данные) выполняется командой Open. Командой ExecSQL выплняются запросы, которые изменяют данные (UPDATE, DELETE и т.п.). Я же писал, все остальное, в данном случае, как и у TTable.

Автор: Flaer 5.9.2008, 09:38
Цитата(Poseidon @ 5.9.2008,  08:25)
Цитата(Flaer @  4.9.2008,  16:52 Найти цитируемый пост)
и чет не работает
 SELECT-запрос (т.е. запрос, который возвращает данные) выполняется командой Open. Командой ExecSQL выплняются запросы, которые изменяют данные (UPDATE, DELETE и т.п.). Я же писал, все остальное, в данном случае, как и у TTable.

Так что я сделал не правильно ? )))

Автор: Poseidon 5.9.2008, 09:43
Цитата(Flaer @  5.9.2008,  09:38 Найти цитируемый пост)
Так что я сделал не правильно ? )))
Ты использовал ExecSQL для SELECT-запоса. Надо так:

Код
with ADOQuery do
    begin
     Close; // на всякий случай, вдруг где-то не закрыли
     SQL.Clear;
     SQL.Add('SELECT DISTINCT '+ StrokaNameFields );
     SQL.Add('FROM '+ ADOTable.TableName  );
     Open;
    end;


Добавлено через 2 минуты и 26 секунд
О! Еще заметил. В ADOTable.TableName заносится название базы с расширением. Тебе надо передавать в запрос без расширения.

Автор: Flaer 5.9.2008, 11:12
ADOTable.TableName заносит название базы без расширения.
Прверял. 
Но запрос почему то все равно не выполняется.
Таблица обрабатываемая из Access. Запрос непосредствено в нем работает.
А вот через компоненту не хочет.
Может я как то неправильно связываю компоненты между собой ?  

а код в котором я пытаюсь выполнить дедублирование выглядит так:

Код

procedure TFormEditTable.FormShow(Sender: TObject);
 const
  cs = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;Persist Security Info=False';
var
 index,MaxL :Integer;
begin

  ADOConnectionED.Close;
  try
    ADOConnectionED.ConnectionString:= Format(cs, [MainForm.edTargetFile.Text]);
    ADOConnectionED.Open;
  except
    ShowMessage('Connection Error !');
    exit;
  end;
  ADOConnectionED.Connected := true;


  ADOTableEd.TableName := FormSelectTable.ComboBox.Text;
  ADOTableEd.Active := true;

  with  ADOQueryED do
    begin
     Close; 
     SQL.Clear;
     SQL.Add('SELECT DISTINCT '+  StrokaNameFields );
     SQL.Add('FROM '+  ADOTableEd.TableName);
     Open;
    end;

end;


Автор: Poseidon 5.9.2008, 13:50
Цитата(Flaer @  5.9.2008,  11:12 Найти цитируемый пост)
Может я как то неправильно связываю компоненты между собой ? 
Скорее всего так. По твоему коду скажу:
ADOTableEd и все что с ним связано вообще удали. Тебе его заменил ADOQueryEd. А вот ADOQueryEd свяжи с DataSourse так же как бы связан ADOTableEd

Автор: Flaer 5.9.2008, 14:35
Убирал Adotable
Компоненту DBGride  соединил с ADOQueryED.
Наблюдаю результат без дублей.
Но в таблице смаой они физически есть.Как мне сохранить результат запроса в таблицу ? 

Автор: Poseidon 5.9.2008, 15:29
Стоп! Тебе нужно из самой базы данных удалить дубли? Так бы сразу и писал. Ты ведь вверху об этом ни строчки не написал...

http://www.sql.ru/faq/faq_topic.aspx?fid=711


Автор: Flaer 5.9.2008, 15:54
Кошмар какой ) 
Чуть разрыв мозга не случился  smile  когда открыл )))
не сооброжу как это мона "прикрепить" к моей "программе". smile 

У меня сам запрос ведь получился, результат верный.
Можно ли его применить к исходной таблице ? 
через компонету ADOConnection, её свойства транзакции ? (В моем случае DOConnectionED )
используя:  BeginTrans    Начинает транзакцию 
                   CommitTrans    Подтверждает сделанные изменения 
                   RollbackTrans    Откатывает транзакцию

 

Автор: Frees 8.9.2008, 08:50
Flaer, дак тебе надо 1 раз запрос выполнить на удаление строк дубликатов и все!!!
 делфи для этого совсем не нужно

Автор: Flaer 8.9.2008, 09:24
Так я его вроде как выполнил.Как мне его применить к исходной таблице? 
 smile 

Автор: Frees 8.9.2008, 09:35
вот такой запрос выполнил??
Код

delete TEST_DUPLICATE
where duplicate_id not in (
        select min(duplicate_id)
        from TEST_DUPLICATE
        group by value
      );



если да то нету у тебя больше дубликатов в базе!!

Автор: Flaer 8.9.2008, 09:44
TEST_DUPLICATE - Это имя таблицы ? 

Автор: Frees 8.9.2008, 09:48
Цитата(Flaer @  8.9.2008,  09:44 Найти цитируемый пост)
TEST_DUPLICATE - Это имя таблицы ? 

да
duplicate_id - поле первичного ключа

value - поле(поля) дубликаты которых надо удалить

Автор: Flaer 8.9.2008, 10:29
Ошибка синтаксиса (прорущен оператор)  в выражении запроса.
Код

  with  ADOQueryED do
    begin
    Close; 
     SQL.Clear;
     SQL.Add('delete '+  FormSelectTable.ComboBox.Text );
     SQL.Add(' where ' + Id + ' not in ( ');
     SQL.Add(' select min(' + Id +') ');
     SQL.Add(' from '+  FormSelectTable.ComboBox.Text);
     SQL.Add(' group by value ');
     SQL.Add(');');
     Open;
    end;



вроде все правильно...

Добавлено через 4 минуты и 27 секунд
Что то не так с запросм помойму.
В Accesse он тоже не работает


Автор: Frees 8.9.2008, 10:41
delete from

Автор: morpheyushka 8.9.2008, 12:51
и в конце вместо команды Open поставь ExecSQL!

Автор: Poseidon 8.9.2008, 13:12
Flaer, 
Цитата(Frees @  8.9.2008,  09:48 Найти цитируемый пост)
value - поле(поля) дубликаты которых надо удалить

А у тебя что?

Цитата(morpheyushka @  8.9.2008,  12:51 Найти цитируемый пост)
и в конце вместо команды Open поставь ExecSQL!
и это тоже. Flaer, я же тебе писал выше, команда Open только для запросов возвращающих данные. Твой запрос возвращает какие-то данные? Нет. Значит ExecSQL.

Автор: Flaer 9.9.2008, 10:01
У меня получилось ) 
Запрос удаляет дубли записей.
В Id я записываю имя первого поля в таблице. Оно у меня не всегда индексное.

Код

  with  ADOQueryED do
    begin
     Close; 
     SQL.Clear;
     SQL.Add('delete from '+  FormSelectTable.ComboBox.Text );
     SQL.Add(' where ' + Id + ' not in ( ');
     SQL.Add(' select min(' + Id +') ');
     SQL.Add(' from '+  FormSelectTable.ComboBox.Text);
     SQL.Add(' group by value ');
     SQL.Add(');');
     Parameters.ParamByName('value').Value := 1 ;
     ExecSQL;     
    end;



Немного не понятен смысл задачи параметра Value.
Тонее его первоначального заполнения.
Я так понимаю, в него можно записать абстрактное значение ? 
Я присвоил ему единицу.И вроде как работает.

Автор: morpheyushka 9.9.2008, 10:24
а эта строчка зачем там? попробуй без нее smile 

Автор: Poseidon 9.9.2008, 10:25
Цитата(Flaer @  9.9.2008,  10:01 Найти цитируемый пост)
Немного не понятен смысл задачи параметра Value.Тонее его первоначального заполнения.Я так понимаю, в него можно записать абстрактное значение ? Я присвоил ему единицу.И вроде как работает.
Попытайся разобраться не с Value, а с group by. Если разберешься зачем это, поймешь почему у тебя удаляются только дубликаты.

Автор: Flaer 9.9.2008, 10:27
не получается ))
гвоврит, установи мол значение по умолчанию и всё тут.
Я так же в Accesse пробовал.Там тоже смое просит.
Что бы задали параметр Value.

Автор: morpheyushka 9.9.2008, 10:44
Poseidonб видимо автор не сильно вчитывается в посты  smile 

Автор: Frees 9.9.2008, 10:50
Цитата(Flaer @  9.9.2008,  10:01 Найти цитируемый пост)
Parameters.ParamByName('value').Value := 1 ;

а че разве на это строку не ругается, при выполнений??


Цитата(Flaer @  9.9.2008,  10:27 Найти цитируемый пост)
Я так же в Accesse пробовал.Там тоже смое просит.Что бы задали параметр Value.

это он как просит, прям так и пишет"Ух епт параметр value задай"?? в оригенале как сообщение звучит?



Цитата(Flaer @  9.9.2008,  10:01 Найти цитируемый пост)
SQL.Add(' where ' + Id + ' not in ( ');

переменнуйю Id ты где заполняеш покажи

Добавлено через 12 минут и 48 секунд
зы и еще сходи в церковь свечку поставь, чертавщина какая то у тебя

Автор: Flaer 9.9.2008, 11:12
-> а че разве на это строку не ругается, при выполнений??

Нет, не ругается. А вот без нее ругается.


->это он как просит, прям так и пишет"Ух епт параметр value задай"?? в оригенале как сообщение звучит?

Появляется маленькое окно ввода, с предложением заполнить это параметр.

->переменнуйю Id ты где заполняеш покажи
Смысл в том что я перебираю поля исходной таблицы.Запоминаю нужные.И создаю запросом таблицу с нужными полями.В этот момент в Id я записываю первое поле из результирующей таблицы.


->зы и еще сходи в церковь свечку поставь, чертавщина какая то у тебя 

У меня бубен есть)))))

Автор: Frees 9.9.2008, 12:50


Цитата(Flaer @  9.9.2008,  11:12 Найти цитируемый пост)
У меня бубен есть)))))

Язычник




Цитата(Flaer @  9.9.2008,  11:12 Найти цитируемый пост)
Смысл в том что я перебираю поля исходной таблицы.Запоминаю нужные.И создаю запросом таблицу с нужными полями.В этот момент в Id я записываю первое поле из результирующей таблицы.


вот раз поля перебираеш перебири все поля кроме того которое ид 
и вот сюда их запиши вместо слова value
Код

SQL.Add(' group by value ');


вот как то так у тя должно быть

Код

SQL.Add(' group by ' + FieldList+' ');

если у тя в таблице 3 поля id, Field1, field2 то в FieldList должно быть следующие 'Field1, field2'!!!


Автор: Flaer 9.9.2008, 13:04
сейчас попробую.
А то при более подробном прогоне, выяснилось что удаляются далеко не повторяющиеся записи.

Автор: Flaer 9.9.2008, 16:19
Усе работает ) 
Болльшое спасибо за помощь.
Сам бы долго еще разбирался.

Кому интересно вот код:
Код

   with  ADOQueryED do
    begin
    Close;
     SQL.Clear;
     SQL.Add('delete from '+  TableNameEdite );
     SQL.Add(' where ' + Id + ' not in ( ');
     SQL.Add(' select min(' + Id +') ');
     SQL.Add(' from '+  TableNameEdite);
     SQL.Add(' group by ' + FList+ ' ');
     SQL.Add(');');
     ExecSQL;
    end;


TableNameEdite - имя таблицы;
Id - Индексное поле;
FList - список полей таблицы без индексного поля.

Что интересно, если допустим есть повторения в индесах, то запрос уже не работает.



Автор: morpheyushka 9.9.2008, 16:29
значит тему закрывай

Автор: Frees 10.9.2008, 06:40
Цитата(Flaer @  9.9.2008,  16:19 Найти цитируемый пост)
Что интересно, если допустим есть повторения в индесах, то запрос уже не работает.

если есть повторение в индексном поле то оно уже не первичный ключ и использовать его в данном запросе не коректно

Автор: Flaer 11.9.2008, 14:12
А как можно отоброзить ход выполнения запроса через Progressbar ? 

Автор: Frees 11.9.2008, 14:45
я могу но тока не ход выполнения запроса на сервере а прогресс полученния данных с сервера на клиент, и это я могу тока в FIBPlus
там событие onFetchRecord есть где я знаю сколько всего с сколько уже
а как это в ADO чесно говоря не знаю

Автор: Flaer 11.9.2008, 14:56
просто у меня таблица на на 100 метров.Боюсь что слабонервный пользователь решит, что все повисло ) 
Вот хотел бы его успокоить такой штукой ) 

Автор: Poseidon 11.9.2008, 15:18
Цитата(Flaer @  11.9.2008,  14:12 Найти цитируемый пост)
А как можно отоброзить ход выполнения запроса через Progressbar ? 
Запрос выполняет драйвер базы. Твоя программа его отсылает и получает данные. Что там творится в драйвере твоей программе не известно.

Цитата(Flaer @  11.9.2008,  14:56 Найти цитируемый пост)
Боюсь что слабонервный пользователь решит, что все повисло 
Обычно это обходится переводом курсора в crHourGlass. Может еще и показом спец.формы типо "Пожалуйста, ждите. Идет обработка".

Автор: morpheyushka 11.9.2008, 16:27
Цитата(Poseidon @  11.9.2008,  15:18 Найти цитируемый пост)
Обычно это обходится переводом курсора в crHourGlass.

я именно так и делаю - RxLib и делаю:
Код

StartWait;
try
//код
finally
StopWait;

Автор: Frees 12.9.2008, 06:59
Flaer, у тебя какие компоненты доступа, пргресс получения записей с сервера В АДО можено в событий OnFetchProgress реализовать

Автор: Flaer 12.9.2008, 10:31
У меня ADOConnection, DataSource,  ADOTable и ADOQuery

Ща посмотрю, что за событие.
 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)