Excel (VBA)

Excel VBAに関するフォーラムです。
  • 解決済みのトピックにはコメントできません。
このトピックは解決済みです。
質問

 
(Windows 10 Pro : Excel 2016)
CollectionのForEachによる呼び出しはAdd順が事実上保証されますか
投稿日時: 17/10/07 18:03:11
投稿者: shamoyu

お世話になっております。
件名の通りなのですが、Excel VBAにおけるCollectionオブジェクトのItemにFor Eachステートメントを用いて個別にアクセスしようとした時、Addした順番にアクセスされる事が事実上保証されるかどうか、ご存知の事を教えていただけますでしょうか。
"事実上"という言い回しを用いた理由は後述します。また、状況は以下の通りです。
 
-------------------------------
・知っている事
他言語含め通常For Each構文ではアクセスする順番が保証されない事
For EachがNewEnumメソッド(IEnumVARIANT(IUnknown)型)を用いている事
色々なWeb投稿を含め、Excel VBAのFor Eachでは経験的にAddした順番で取り出される事
 
・なぜ質問したか
CollectionのItemメソッドを用いてIndex値によるアクセスを行うとパフォーマンスが悪いため
(テスト済 ここと同様の結果となりました: ttp://blog.starbug1.com/archives/568)
 
・具体的に何を知りたいか
Collectionの_NewEnumメソッドの内部挙動はAdd順に関係しているかどうか
(Microsoftが保証せずとも挙動がそのようになっていれば事実上保証されるという考えで、その程度の保証で構わない状況です)
-------------------------------
 
通常そのような事はMicrosoft以外は正確に知りえないということも承知の上です。
しかし例えばDictionaryオブジェクトについて以下Web投稿のように、間接的に内部挙動に触れる機会があると思います。
ttp://slowalpaca.hatenablog.com/entry/2014/07/17/223936
 
そのような可能性のレベルでも構いませんので、何かご存知の事がありましたら教えていただけますでしょうか。よろしくお願い致します。

回答
投稿日時: 17/10/09 16:38:05
投稿者: simple

保存されると言っているようです。
StackOverflowのpostなので、信頼できるんじゃないですかねえ。
 
"Does Collection preserve ordering?" (tagは VBAとなっています)
https://stackoverflow.com/questions/24938768/does-collection-preserve-ordering
 
その記事中のリンク先にも関連情報があるかもしれません。
 
また、Dictionary については
"Prove that Excel VBA Scripting.Dictionary does not preserve order of item insertion"
https://stackoverflow.com/questions/37705421/prove-that-excel-vba-scripting-dictionary-does-not-preserve-order-of-item-insert
が参考になるかもしれません。

投稿日時: 17/10/09 19:02:52
投稿者: shamoyu

simpleさん、ご回答ありがとうございます。
StackOverflowで同様に考えているような投稿が見つかると非常に心強いです。
また、Dictionaryについても情報提供ありがとうございます。Dictionaryもよく使用していますので後学のために参考にさせて頂きます。
 
こちらで質問してからも私自身色々と調査し、一定の裏付けを得られましたので解決済みとさせて頂きます。
私と同様の疑問を持たれる方がこれからいらっしゃるかわかりませんが、その方のために簡単に調査結果を記載してお礼とさせて頂きたいと思います。
---------------------------------
私の結論:CollectionをFor Eachで各Itemにアクセスした時はAdd順が事実上保証される
 
・COMのCollectionインターフェースについて
ttp://www.369o.com/data/books/atl/0321159624/ch08lev1sec1.html
(ATL Internals: Working with ATL 8, Second Edition という本の一部のようです)
 
・IEnumVARIANT::Next メソッドの挙動について
ttps://msdn.microsoft.com/en-us/library/ms221369(v=vs.85).aspx
 
・COMについて
ttp://garicchi.com/?p=19259
 
・MicrosoftによるC++を用いたBSTR Collection実装例 (これが決定打となりました)
ttps://github.com/Microsoft/VCSamples/tree/master/VC2008Samples/ComTypeLibfor7/inproc/server
 - IEnumVARIANTを実装している事からCOM Collectionと判断
 - enumvar.h, enumvar.cpp, strcoll.cpp が特に関係
 - GetNewEnumを呼び出した際にItem分の配列を用意し"順番に"格納している
 
・その他裏付け
ttp://thrysoee.dk/InsideCOM+/ch05c.htm
ttps://stackoverflow.com/questions/44332554/vba-determine-order-of-objects-in-for-each-loops