2016-11-04 59 views
1

這是我的第一個問題。我無法解決這個錯誤2周。 爲了解決註冊的問題。 這是我的vb代碼。InvalidArgument =''的值不適用於'索引'(''內部編號)

Try 
    For i As Integer = 0 To ListBox1.Items.Count - 1 Step 1 
     For j As Integer = 0 To ListBox2.Items.Count - 1 Step 1 
      If ListBox1.Items(i).ToString().Equals(ListBox2.Items(j).ToString()) = True Then 
       ListBox1.Items.RemoveAt(i) 
      End If 
     Next 
    Next 
Catch ex As Exception 
    MsgBox("LOAD ERROR: " + ex.Message, vbCritical, "ERROR") 
End Try 

錯誤:

InvalidArgument '20' 的=值是無效的 '索引'(」'是變體光盤。)

項目具有除了這個誤差沒有問題

回答

1

當我運行你的代碼時,我收到了一個不同的異常,參數超出了範圍......這是由於在遍歷它時刪除索引集合中的項目而引起的。例如,我們假設listbox1中有10個項目。如果您在listbox2中找到項目編號1並將其刪除,那麼現在您在列表框1中只剩下9個項目。問題是,當你進入你的循環時,你告訴它循環10個項目,它仍然會嘗試這樣做。在某個時候,如果有任何項目被刪除,這個循環會拋出一個異常......所以你需要遲早改變它。爲了緩解這一點,通過一步,你會從落後刪除項目這樣的收集:

For i As Integer = ListBox1.Items.Count - 1 to 0 Step -1 

當我運行上面所示變化的代碼,它按預期工作,並從ListBox1中的重複的項目。不幸的是,我無法重現你的無效論證異常。奇怪的是,因爲通常這種異常在使用列表視圖時彈出,而不是列表框。也許你可以編輯你的文章並在你的列表框中添加數據的截圖,這樣其他人可以更容易地排除故障。

+0

這段代碼簡單地解決了!另外,Example很容易理解它。謝謝你的建議! – baegopa

3

試試這個:

Dim items = ListBox1.Items.Where(Function(item) ListBox2.Items.Contains(item)).ToList() 
For Each item in items 
    ListBox1.Remove(item) 
Next 
+0

@baegopa這是一個更乾淨的方式來完成你想要做的事情,也將避免我提到 – soohoonigan

+0

@soohoonigan的ArgumentOutOfRange異常,但它並不教授初學者「編碼的內部」。看,我們已經在Linq之前的世界裏經歷過它。這是什麼讓我們「知道事情」 –

+0

嗯..我試過這個代碼。但發生編譯錯誤..謝謝指教 – baegopa

0

正如您從ListBox1項目總數量會下降(顯然)項目,但是For循環不尊重這一點。一個For循環將只有To的右側設置一次,這是在第一次迭代之前完成的。

你正在做什麼其實是等於這個:

Dim a As Integer = ListBox1.Items.Count - 1 
For i As Integer = 0 To a Step 1 

    Dim b As Integer = ListBox2.Items.Count - 1 
    For j As Integer = 0 To b Step 1 
     ... 
    Next 

Next 

這種情況的解決方法是簡單的;創建一個變量,用於保存已刪除的項目數量,然後在If -statement中檢查i是否大於或等於當前項目數量減去已刪除的項目數量。如果是這樣,退出循環。

Dim ItemsRemoved As Integer = 0 
For i As Integer = 0 To ListBox1.Items.Count - 1 Step 1 
    If i >= ListBox1.Items.Count - ItemsRemoved Then Exit For 

    For j As Integer = 0 To ListBox2.Items.Count - 1 Step 1 
     If ListBox1.Items(i).ToString().Equals(ListBox2.Items(j).ToString()) = True Then 
      ListBox1.Items.RemoveAt(i) 
     End If 
    Next 
Next 

以供將來參考,你也應該隨時刪除/註釋掉Try/Catch語句來,所以你可以看到其中錯誤發生,並獲得更多的細節。

0

我的答案是,當你迭代任何集合時,你不應該嘗試修改這個集合。在for-loops你遇到這樣的麻煩。但是你可以使用迭代與while-loop沒有問題

Try 
    Dim index As Integer = 0 
    While index < ListBox1.Items.Count '!! this code based on fact that ListBox1 item Count changes 
     For j As Integer = 0 To ListBox2.Items.Count - 1 ' <- this is ok because ListBox2 doesn't chage 
      If string.Equals(ListBox1.Items(index).ToString(), ListBox2.Items(j).ToString()) Then 
       ListBox1.Items.RemoveAt(index) 
       Continue While ' no index increase here because if you remove item N, next item become item N 
      End If 
     Next 
     index += 1 
    End While 
Catch ex As Exception 
    MsgBox("LOAD ERROR: " + ex.Message, vbCritical, "ERROR") 
End Try 

這是事情是如何工作的好例子。它顯示了很少的技術

相關問題