2010-02-15 2 views
1

Я использую условие цикла, чтобы проверить, есть ли нулевое значение в столбцах, а затем удалите его.Что не так в этом цикле

-Original author

[STart:] 
    For i As Integer = counter To dt1.Columns.Count - 1 
     For x As Integer = 0 To dt1.Rows.Count - 1 
     if some condition then 
      something = true 
     else 
       something = false 
      counter = counter + 1 
       Goto [Start] 
     end if 
     Next 

     If something = true 
     dt1.Columns.Remove(dt1.Columns(i)) 
     i -= 1 
     End If 
    Next 
    End If 

Иногда он работает правильно, а иногда даже, хотя, когда i становится больше (dt.columns.count - 1), он по-прежнему выполняет цикл и выдает ошибку, что нет никакого столбца с этим индексом. Я должен что-то упустить, но я не могу отладить проблему.

Вы нашли что-то не так с этим кодом?

+0

Не знаете, почему вы спустились - проголосовали здесь. Вот о чем этот сайт. Публикация вопросов в сеть других программистов. +1 от меня. –

+0

Я тоже не уверен :(Может быть, они отличные программисты, которым не нравятся такие программисты, как я, делающие ошибки и пытающиеся учиться. –

ответ

4

Оператор dt1.Columns.Count оценивается в самом начале для цикла. Он не получает повторной оценки каждый раз, когда цикл работает.

Итак, когда вы удаляете столбец в теле цикла, это приводит к неправильному завершению цикла.

+0

ok я пропустил что-то здесь, см. Обновленный код. –

+0

Я изменил свою петлю на цикл while правильно –

3

Я предполагаю, что i-loop только оценивает значение остановки один раз.

2

Плохая идея изменить объект, на котором вы зацикливаетесь. В некоторых случаях это может иметь эффект. Я бы скопировал ваш цикл данных на первой таблице и изменил вторую.

Также, вы видели Select method on datatable? Это может сделать этот поиск нулевых значений проще, то встроенные петли (петлю на колоннах и вызова выберите)

Dim DRs AS DataRow() = dt1.Select(dt1.Columns(i).ColumnName " IS NULL") 
If DRs.Count > 0 Then 
    '' // do something 
End If 
1

Поскольку вы удаляете в вашем внешнем контуре, не полагаться на reevalution из dt1.Columns.Count

Далее, попробуйте обратный отсчет вместо вверх (потому что если вы удалите столбец в вашем счете вниз, это не повлияет на то, что следующий действительный индекс)

что-то вроде этого для внешнего цикла:

предупреждения: Я AC# разработчика, мой синтаксис VB для цикла может быть выключен чтения: Я хочу зациклиться от наивысшего номера столбца до столбца 0

'' // leave no question as to how often count will be evaluated. 
'' // we will ensure it happens only once: 
Dim colmns as int = dt1.Columns.Count - 1 
for i as integer = columns to 0 step -1 
'' // your logic goes here 
'' // DON'T manualy modify the value of i -- it will always be right. 
Next 

Это работает лучше в обратном порядке. Подумайте об этом так: say У меня 4 столбца, и я нахожусь на # 3. Если # 3 не является нулевым, я оставлю его в покое, а мой следующий столбец будет # 2 Если # 3 является нулевым, я удалю его, но мои следующие столбцы все еще # 2, и я все еще закончил, когда Я добираюсь до нуля.

Смежные вопросы