ここから本文です

vbaのコレクションオブジェクトに関する質問です。

chielien_1a98155ef0a41b9fd58448232さん

2017/10/323:39:15

vbaのコレクションオブジェクトに関する質問です。

下に載せているのはコードの一部です。
具体的にはデータリストにnを追加していき、nの中から最小のものを選択し、その項目を削除するといった流れですが、うまく削除ができません。DtList.Remove(n)とするとn(階数)という項目が消えるのではなく、n番目の項目が消えちゃうのです。ここではnは階数を表す整数Integerとしています。

ループするたびに新規でデータリストが作成されると思っていたのですが、なかなか新規にならなくて困っています。どなたか教えてください。

SkipX:
'nが10未満ならリストに追加する
Dim DtList As Collection
Set DtList = New Collection
For n =1 To Ncnt
If deg(n) <10 Then
DtList. Add n
End If
Next n

'DtListの中から最小のnを選択する
Dim Dx As Integer
Dim Decide As Integer
Dx =1000
For Each n In DtList
If n >= 1 Then
If Dx > n Then
Dx = n
Decide = n
End If
End If

'選択したnを削除する
DtList. Remove(n)

GoTo skipX

閲覧数:
49
回答数:
2

違反報告

ベストアンサーに選ばれた回答

2017/10/406:11:43

良い方法かはわかりかねますが。

.NET Frameworkを使う(ArrayListクラス)
http://officetanaka.net/excel/vba/tips/tips98.htm

を用いれば

ArrayList メンバ
https://msdn.microsoft.com/ja-jp/library/system.collections.arrayli...

Sort ArrayList 内およびその一部の要素を並べ替えます。
Remove ArrayList 内で最初に見つかった特定のオブジェクトを削除します。


並べ替えて添え字で最小値はわかるでしょうし、最小値を消すのも値で指定できるのでは?


Sub Sample1_改良()
Dim DataList, i As Long, buf As String
Set DataList = CreateObject("System.Collections.ArrayList") ''.NET Frameworkへの参照
For i = 1 To 5
DataList.Add Int(Rnd() * 100) ''5個の乱数を配列にセットする
Next i
DataList.Sort ''配列をソートする

For i = 0 To DataList.Count - 1
buf = buf & DataList(i) & vbCrLf
Next i

MsgBox "値のリスト" & vbCrLf & buf & vbCrLf & "最小値 " & DataList(0)

DataList.Remove (DataList(0))

buf = ""

For i = 0 To DataList.Count - 1
buf = buf & DataList(i) & vbCrLf
Next i

MsgBox "値のリスト" & vbCrLf & buf & vbCrLf & "最小値 " & DataList(0)

Set DataList = Nothing
End Sub


>ループするたびに新規でデータリストが作成されると思っていたのですが

ループ中に変数を宣言していたら都度やり直しになりそうですし、何よりループを『抜け出せるの?』と
疑問もありそうな・・・・

GoTo を使ったループは余りお薦めはしませんけどね。

この質問は投票によってベストアンサーに選ばれました!

ベストアンサー以外の回答

1〜1件/1件中

2017/10/406:05:36

ソースを何度みても分かりません。
次のことを教えてください。

n(階数)とは何ですか。
deg(n)とは何をする関数?、配列?ですか。定義がありません。
Dxの意味はなんですか。
Decideの意味はなんですか。
質問に合った回答ができると思います。
-------------------
インデックスとキーとアイテムを区別することが重要です。
DtList.Add n
でアイテムnのみ指定して、キーは指定していません。
インデックスは数値の1から始まります。

For n =1 To Ncnt
DtList.Add n
としているので
偶然インデックスとアイテムが一致しています。
DtListの内容は下記のようになります。

インデックス__アイテム
1_____________1
2_____________2
3_____________3
以下続く。

DtList.Remove(n)
でインデックスnの項目が削除されます。
今回はインデックスとアイテムが同じなのでアイテムnが削除されます。
n(階数)は削除されないのです。

-------------------
次のようにするとうまくいくのではないでしょうか。

DtList.Add deg(n), Cstr(n)
DtList.Remove(Cstr(n))

deg(n)がアイテムです。
nがキーです。.Addメソッドのキーは必ず文字列にしなければならず、数値は使えません。
文字列にするためにCstrを使用しています。

-------------------
サンプルです。Collectionの理解が深まりますように。

'----ここから
Option Explicit
Sub Sample()
Dim i, c
Dim cc As New Collection

'インデックスは自動的に1から付けられます。
'アイテムはcat,キーはa,インデックスは1
cc.Add "cat", "a"

'アイテムはdog,キーは10(文字列),インデックスは2
cc.Add "dog", "10"

'キーの無い例
'アイテムはman,キーはない,インデックスは3
cc.Add "man"

'インデックスによるアクセス
Range("A1").Value = cc(1)
Range("A2").Value = cc(2)
Range("A3").Value = cc(3)

'キーによるアクセス
Range("B1").Value = cc("a")
Range("B2").Value = cc("10")
'manはキーがないのでキーによるアクセスはできません。

'For文によるアクセス
For i = 1 To cc.Count
Range("C" & i).Value = cc(i)
Next

'For Each文によるアクセス
i = 1
For Each c In cc
Range("D" & i).Value = c
i = i + 1
Next

'インデックスによる削除
cc.Remove (1)
'確認
For i = 1 To cc.Count
Range("E" & i).Value = cc(i)
Next
'セルはdog
'manとなります

'キーによる削除
cc.Remove ("10")
'確認
For i = 1 To cc.Count
Range("F" & i).Value = cc(i)
Next
'セルはmanとなります

End Sub
'----ここまで

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問や知恵ノートは選択されたID/ニックネームのMy知恵袋で確認できます。