Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удаление в цикле, с проверкой 
:(
    Опции темы
Akella
  Дата 23.8.2008, 00:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Замучался уже. Вроде код правильный. Но не все записи удаляются те, которые должны быть удалены.
Есть таблица, в которой хранятся объявления и список дат публикации. Нужно удалить те, которые не будут публиковаться.
Принцип такой: есть текстовое поле с датами вида: 
Цитата

04.03.2008,05.03.2008,

Цитата

11.03.2008,

Цитата

05.03.2008,06.03.2008,11.03.2008,

Т.е. в поле записан список дат. Ну и бывает, что поле пустое. С пустыми полями тоже удаляем.

Пользователь задаёт число, допустим 14.08.2008.
Что требуется?
Пробежаться по всем записям таблицы и удалить...внимание... те записи, которые просрочены.

Если в этом поле 04.03.2008,05.03.2008, то такую запись удаляем, ибо объявление уже публиковаться не будет после 14.08.2008.
Если в этом поле 04.03.2008,05.03.2008,15.08.2008, то такую запись НЕ удаляем, ибо объявление будет ещё публиковаться 15.08.2008.


даю полный код процедуры, за помощь буду весьма признателен.
Код

procedure TfmMain.actDelOldRecordsExecute(Sender: TObject);
Var
 i2, i3, iDeleted, iCommit: integer;
 slDatasDel: TStringList;//для преобразования строки в список.
 bRecordDel:boolean; //удалять запись или нет
 dDate:TDate;//то, что выбрал пользователь
 tStart, tEnd: TTime;//для определения времени работы процедуры
begin
   Screen.Cursor := crSQLWait;
   actResetFilterGroupSortExecute(nil);//сбрасываем всякую сортировку, фильтрацию и группировку
   tStart := Time;
   bStopDelOldOblv := False;//если нажимаем Esc, то прекращаем работу процедуры
   // удаляем записи, у которых в СПИСКЕ дат публикации нет будущих дат
   //т.е. удаляем те объявления, которые в будущем уже не будут публиковаться.

  if (not dbgReklama.DataController.DataSet.Active) then begin
    MessageBox(Application.ActiveFormHandle, 'Откройте/обновите таблицу с объявлениями.', 'Внимание', MB_ICONINFORMATION or MB_OK);
    exit;
  end;

  //даём пользователю выбрать дату
  fmSelDate := TfmSelDate.Create(self);
  fmSelDate.cxDateEdit1.Date := Date;
  fmSelDate.Label1.caption := 'Будут удалены все объявления из базы, в которых нет дат, больше текущей включительно';
  fmSelDate.Label1.Visible := true;
  try
    if fmSelDate.ShowModal = mrok then begin
//      Screen.Cursor := crSQLWait;
      dm.tReklama3.DisableControls;
      dm.tReklama3.last;
      dm.tReklama3.FetchAll;
      slDatasDel := TStringList.create;

      i3        := 0;// для ProgressBar1
      iDeleted  := 0;// для показа кол-ва удалённых
      iCommit   := 0;// для подтверждения транзакций через определённое кол-во удалённых записей
      ProgressBar1.Max := dm.tReklama3.RecordCount;
      ProgressBar1.Visible := true;
      dm.tReklama3.AutoCommit := false;

      with dm.tReklama3 do begin
      while not Bof do begin

            bRecordDel := True;//пока что можно удалять запись, а дальше определяем: можно или нельзя
            slDatasDel.Clear;
            Inc(i3);
            ProgressBar1.Position := i3;

             slDatasDel.text := G_ReplaceStr(FBN('datas').AsString, ',', #13);
//              slDatasDel.text := StringReplace(FieldByName('datas').AsString, ',', #13, [rfReplaceAll, rfIgnoreCase]);

             //идём по списку дат, если есть внутри дата, большая или равная той,
             //что выбрал пользователь, то пропускаем запись и не удаляем её.
             for i2 := 0 to slDatasDel.Count - 1 do begin
                 //показываем сколько удалено
                 StatusBar1.Panels[1].Text := 'Удалено: '+IntToStr(iDeleted);
                 Application.ProcessMessages;

                 if slDatasDel[i2] <> '' then begin//пустую строку в списке дат текущей записи пропускаем
                     try
                       dDate := StrToDate(slDatasDel[i2]);//преобразуем из строки в дату и попутно проверяем на корректность даты
                     except
                       bRecordDel := False;//некорректную дату не удаляем
                       continue;//в случае некорректной даты пропускаем её
                     end;//try-except

                     //если встретилась хоть одна будущая дата в списке, то эту запись не удаляем
                     if dDate >= fmSelDate.cxDateEdit1.Date then begin
                       bRecordDel := False;
                       break;//дальше не зачем проверять, т.к. уже найдена будущая дата
                     end;//if dDate >= fmSelDate.cxDateEdit1.EditValue then begin
                 end else begin
                     //если список дат пустой, то пропускаем такую запись
                     bRecordDel := False;
                     continue;
                 end;
              end;//for i2 := 0 to slDatasDel.Count - 1 do begin

              //если эта запись для удаления, то удаляем её
              if bRecordDel then begin
                dm.tReklama3.delete;
                Inc(iDeleted);
                Inc(iCommit);
                if iCommit > 1000 then begin
                  if dm.tReklama3.UpdateTransaction.InTransaction then dm.tReklama3.UpdateTransaction.Commit;
                  iCommit := 0;//сброс счётчика подтверждений
                end;
              end else
               dm.tReklama3.prior;//если запись не для удаления, то поднимаемся выше

              //нажали Esc - останавливаем удаление
              if bStopDelOldOblv then begin
                StatusBar1.Panels[1].Text := 'ОТМЕНА УДАЛЕНИЯ...';
                Application.ProcessMessages;
                exit;
              end;

      end;//while
      end;//with
      if dm.tReklama3.UpdateTransaction.InTransaction then dm.tReklama3.UpdateTransaction.Commit;

    end;//if fmSelDate.ShowModal = mrok then begin
  finally
    dm.tReklama3.AutoCommit := True;
    Freel(fmSelDate);
    Freel(slDatasDel);
    dm.tReklama3.EnableControls;
    Screen.Cursor := crDefault;
    ProgressBar1.Visible := false;

    Application.ProcessMessages;
    StatusBar1.Panels[1].Text := 'ЗАВЕРШЕНИЕ ОПЕРАЦИИ...';
    Application.ProcessMessages;
    tEnd := Time;

    actUpdateExecute(nil);
    StatusBar1.Panels[0].Text := '';
    StatusBar1.Panels[1].Text := '';
    ShowMessage('Готово. Время операции: ' + TimeToStr(tEnd - tStart) );
  end;
end;


Это сообщение отредактировал(а) Akella - 23.8.2008, 00:32
PM MAIL   Вверх
Akella
Дата 23.8.2008, 00:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 29
Всего: 329



Убрал код, который пропускал пустышки в поле со списком дат, вроде то, что нужно теперь.
Код

            //если пустое поле с датами, то пропускаем
            if FieldByName('datas').AsString  = '' then begin
              dm.tReklama3.prior;
              bRecordDel := false;
              continue;
            end;



Отдам пользователям, пусть тестируют smile .
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: Базы данных и репортинг"
Vit
Петрович

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


Обязательно указание:

1. Базы данных (Paradox, Oracle и т.п.)

2. Способа доступа (ADO, BDE и т.д.)


  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи
  • Вопросы по SQL и вопросы по базам данных не связанные с Дельфи задавать здесь

FAQ раздела лежит здесь!


Если Вам помогли и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Vit, Петрович.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Базы данных и репортинг | Следующая тема »


 




[ Время генерации скрипта: 0.0590 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.