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


Автор: 123456789igor 19.9.2012, 19:56
Не могу понять как работает цикл в цикле
на пример 
repeat
begin
lalalala
if что-то1<>100 then
begin
lalalala2
что-то1:=что-то1+1;
end
end
until что-то2<чего-то

Выполняется это так?
Заходим в цикл repeat делаем lalalala затем входим в условие if делаем lalalala2 затем будет выполняться if пока что-то1 не станет равным 100 и только потом перейдет на until так?

Вот наглядный пример с которым мучаюсь, у меня есть таблица в ней в ячейке(8,1) есть текст далее в каком-то, неизвестном, кол-ве ячеек вниз пусто и потом опять в одной ячейке что-то есть надо объединить ячейку 8,1 со всеми пустыми ячейками,вниз, до след заполненной. И то же самое проделать с следующей.
Код

z:=Excel.WorkBooks[1].WorkSheets[1].UsedRange.Rows.Count-1;
     a_:=8;
     NRow:= a_;
     NCol:= 1;
     dir:= Excel.WorkBooks[1].WorkSheets[1].Cells[NRow,NCol];
     repeat
     begin
     NCol:= 1;
     If dir<>'' then
      begin
      Excel.WorkBooks[1].WorkSheets[1].Range[Excel.WorkBooks[1].WorkSheets[1].cells[NRow,NCol],Excel.WorkBooks[1].WorkSheets[1].cells[NRow+1,NCol]].merge;
      //NRow:=NRow+1;
      dir:= Excel.WorkBooks[1].WorkSheets[1].Cells[NRow+1,NCol];
      end
      //else
      //NRow:=NRow+2;
      end;
     until NRow<z;
 

Объединяется только ячейка 8,1 и 9,1

Автор: Rennigth 19.9.2012, 20:30
123456789igor, Как ты собираешься закончить цикл если z  не меняется?

Добавлено через 3 минуты и 40 секунд
ну или NRow )))

Автор: 123456789igor 19.9.2012, 20:38
А зачем его менять?
Вот как я представляю как работает этот код
z это кол-во всех строк-1
dir это переменная типа string в неё записывается значение ячейки
далее захожу в цикл repeat если ячейка не пустая то объединяем ячейки 8,1 и 9,1 
далее dir присваиваем значение ячейки 9,1
и значение nrow становиться 10 а так как 10<чем число строк то проходим по циклу ещё раз но только dir уже это ячейка 9,1 и она объединена с 8,1 соответственно она не пустая  и тогда так как nrow уже 10 должны объединиться 10,1 и 11,1 но этого не происходит

Добавлено через 50 секунд
NRow там просто закоменчено 
NRow:=NRow+2;

Автор: kami 19.9.2012, 20:41
Моим рекомендациям в прошлый раз вы не последовали.
Вы понимаете, что каждый раз при вызове такой конструкции
Цитата(123456789igor @  19.9.2012,  19:56 Найти цитируемый пост)
Excel.WorkBooks[1].WorkSheets[1].Range[Excel.WorkBooks[1].WorkSheets[1].cells[NRow,NCol],Excel.WorkBooks[1].WorkSheets[1].cells[NRow+1,NCol]]

компьютер выполняет как минимум 6 абсолютно лишних, достаточно длительных и не-безопасных для вашей программы операций по получению всяких WorkBooks|Sheets[1]?

По факту - код должен выглядеть как-то так: (пишу в браузере, могут быть незначительные ошибки)
Код

function FindNextNotEmptyCell(Sheet: OLEVariant; StartFrom:TPoint): TPoint;
begin
  if Sheet.Cells[StartFrom.y, StartFrom.x].FormulaR1C1 <> ''
    inc(StartFrom.y); // если стартовая ячейка непуста, переходим на следующую.

  while Sheet.Cells[StartFrom.y, StartFrom.x].FormulaR1C1 = '' do
    inc(StartFrom.y);
  // дошли до непустой ячейки

  dec(StartFrom.y); // возвращаемся на последнюю пустую.
  Result:=StartFrom;
end;

var
  CurrentPoint, NextPoint: TPoint;

MaxRow:=Sheet.UsedRange.Rows.Count;
CurrentPoint.x:=1;
CurrentPoint.y:=8;
while CurrentPoint.y<MaxRow do
  begin
    NextPoint:=FindNextNotEmptyCell(Sheet, CurrentPoint);
    Sheet.Range[Sheet.Cells[CurrentPoint.y, CurrentPoint.x], Sheet.Cells[NextPoint.y, NextPoint.x]].Merge;
    CurrentPoint:=NextPoint;
    inc(CurrentPoint.y, 1); // переходим на следующую непустую ячейку.
  end;


Добавлено через 2 минуты и 9 секунд
Вполне возможно, что в VBA для узнавания следующей непустой ячейки есть функции, но мне сейчас лень копаться.

Автор: 123456789igor 19.9.2012, 21:20
Если честно, то мне тяжело переделать под себя ваш код и в то же время не понимаю чем мой хуже(ну не считая что он не работает:) ) я прошу с моим кодом помочь вот к чему пришёл:
Код

z:=Excel.WorkBooks[1].WorkSheets[1].UsedRange.Rows.Count-1;
     NRow:= 8;
     NCol:= 1;
     repeat
     dir:= Excel.Cells[NRow,NCol];
     If dir<>'' then
      begin
 Excel.Range[Excel.cells[NRow,NCol],Excel.cells[NRow+1,NCol]].merge;
      NRow:=NRow+1;
      dir:= Excel.Cells[NRow+1,NCol];
      end
      else
      NRow:=NRow+2;
     until NRow>=z;

То, как я его понимаю:
z это кол-во всех строк-1
dir это переменная типа string в неё записывается значение ячейки
далее захожу в цикл repeat если ячейка не пустая то объединяем ячейки 8,1 и 9,1 
далее dir присваиваем значение ячейки 9,1
и значение nrow становиться 10 а так как 10>=чем число строк(так как это условие выхода) то проходим по циклу ещё раз но только dir уже это ячейка 9,1 и она объединена с 8,1 соответственно она не пустая и тогда так как nrow уже 9 должны объединиться 9,1 и 10,1
НО! прога компилется, но при запуске excel виснет и вместе с ним и прога

Автор: kami 19.9.2012, 21:39
Цитата(123456789igor @  19.9.2012,  21:20 Найти цитируемый пост)
мне тяжело переделать под себя ваш код

его не надо переделывать, а использовать в соответствии с назначением smile, учетом того, что
Код

Sheet:=Excel.Workbooks.Open(бла-бла-бла).Worksheets[1];

Цитата(123456789igor @  19.9.2012,  21:20 Найти цитируемый пост)
в то же время не понимаю чем мой хуже

я объяснял это в прошлой вашей теме, объяснил и сейчас.
Могу только добавить, что пользователь вас убьет (и будет иметь на это все основания), если до начала работы с программой у него будет идти работа в Excel с каким-либо файлом. Потому что в этом случае Worksheets[1] будет указывать не на ваш, на на его, пользователя, открытый файл. Соответственно - вы испортите ему всю работу, и кнопка Undo ничего не сможет с этим поделать. Кроме того, если работа идет длительная, то пользователь может отработав со своим файлом и закрыть его. Afair, нигде в справке по VBA не написано, что в коллекции Workbooks порядок следования книг сохраняется.

Кстати, не понимаю - в чем проблема "переделки под себя" приведенного кода - он писался под вашу конкретную задачу.

Автор: 123456789igor 21.9.2012, 19:05
Код

a_:=9;
      z:=Excel.WorkBooks[1].WorkSheets[1].UsedRange.Rows.Count-2;
      while a_ < z do
      begin
      repeat
      Excel.Range[Excel.cells[a_-1,1],Excel.cells[a_,1]].merge;
      inc(a_);
      until VarToStr(Excel.cells[a_,1]) <> '';
      break;
      end;

Сделал так, но объединяет только с 9 по 23 строку, 24 не пустая, а дальше опять идут пустые. Как изменить код, что бы объединяло дальше с 24?

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