title: DLL for VBA.Collection
body: <p>I need to use a VBA.Collection class and I need to register a COM component in order to do that. I found msvbvm60.dll file on my computer and successfully registered it in my system. I am creating an instance of a class VBA.Collection, but I get an exception in that line of code:</p>
  
  <pre><code>VBA.Collection collection = new VBA.Collection();
  </code></pre>
  
  <p>The exception has the following description:</p>
  
  <blockquote>
    <p>System.Runtime.InteropServices.COMException was unhandled<br>
    HResult=-2147221164   Message=Retrieving the COM class factory for
    component with CLSID {A4C4671C-499F-101B-BB78-00AA00383CBB} failed due
    to the following error: 80040154 Class not registered (Exception from
    HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).   Source=mscorlib<br>
    ErrorCode=-2147221164</p>
  </blockquote>
  
  <p>I used regedit.exe tool to search for a component with CLSID of {A4C4671C-499F-101B-BB78-00AA00383CBB}, but haven't been able to find one. I suspect that there should be another .dll file that I should register, even though I can see with Object Browser in Visual Studio that reference to msvbvm60.dll gives me access to VBA namespace and Collection class within it. </p>
  
  <p>It says on this web-page <a href="http://codeverge.com/asp.net.migrating-from-asp/using-vba.collection-object-in-net/577432" rel="nofollow noreferrer">http://codeverge.com/asp.net.migrating-from-asp/using-vba.collection-object-in-net/577432</a> that the problem will go away if I instantiate VBA.CollectionClass . However, if I do so, I receive the following error and my code doesn't compile: </p>
  
  <blockquote>
    <p>Interop type 'VBA.CollectionClass' cannot be embedded. Use the
    applicable interface instead</p>
  </blockquote>
  
  <p>Have I registered the wrong COM component? Or is there anything I need to change in my C# code?</p>
  
  <p>I also read on <a href="https://stackoverflow.com/questions/4446755/how-to-create-vba-collection-object-in-c-sharp">How to create VBA.Collection() object in c#</a> that I need to create my own class based on VBA._Collection interface and not instantiate VBA.Collection class. I created the following class:</p>
  
  <pre><code>class MyCollection : VBA._Collection
  {
      private Dictionary&lt;object, object&gt; _items = new Dictionary&lt;object, object&gt;();
  
      public void Add(ref object Item, [System.Runtime.InteropServices.OptionalAttribute]ref object Key, [System.Runtime.InteropServices.OptionalAttribute]ref object Before, [System.Runtime.InteropServices.OptionalAttribute]ref object After)
      {
          // Ignoring the Before and After params for simplicity
          _items.Add(Key, Item);
      }
  
      public int Count()
      {
          return _items.Count;
      }
  
      public System.Collections.IEnumerator GetEnumerator()
      {
          return _items.Values.GetEnumerator();
      }
  
      public dynamic Item(ref object Index)
      {
          return _items[Index];
      }
  
      public void Remove(ref object Index)
      {
          _items.Remove(Index);
      }
  }
  </code></pre>
  
  <p>I now instantiate MyCollection class with  <code>MyCollection collection = new MyCollection();</code>
  I do not get an exception there anymore. However, I need to call a method GetIncidentCodes() of another COM component that returns an object of type VBA.Collection. If I use <code>collection = class1.GetIncidentCodes();</code>, then my program won't compile because an explicit cast is required. If I use <code>collection = (MyCollection) class1.GetIncidentCodes();</code>, then I get the following exception: </p>
  
  <blockquote>
    <p>Unable to cast COM object of type 'System.__ComObject' to class type
    'PoliceDispatcherClient.MyCollection'. Instances of types that
    represent COM components cannot be cast to types that do not represent
    COM components; however they can be cast to interfaces as long as the
    underlying COM component supports QueryInterface calls for the IID of
    the interface.</p>
  </blockquote>
  
  <p>Should I cast the return value of <code>GetIncidentCodes()</code> into interface <code>VBA._Collection</code>? I am new to .NET, so I am not sure how to do it.</p>