/ / Zbierka s poliami - vb.net, vba, vb6, excel-vba, excel

Populácia kolekcie s poliami - vb.net, vba, vb6, excel-vba, excel

Dim A As Collection
Set A = New Collection

Dim Arr2(15, 5)
Arr2(1,1) = 0
" ...

A.Add (Arr2)

Ako môžem získať prístup k Arr2 skrz A? Napríklad chcem urobiť nasledovné:

A.Item(1) (1,1) = 15

takže vyššie uvedené by zmenilo prvý prvok prvého dvojrozmerného poľa v kolekcii ...

odpovede:

7 pre odpoveď č. 1

Hmmm ...syntax vyzerá dostatočne legálne bez toho, aby ma pred sebou mala VBA. Mám pravdu, že váš problém je v tom, že sa váš kód „kompiluje“ a spustí bez toho, aby došlo k chybe, ale pole v kolekcii sa nikdy nezmení? Ak áno, myslím si, že je to preto, že váš A.Item (1) sa môže vracať a kópie poľa, ktoré ste uložili v kolekcii. Potom budete mať prístup k vybranému prvku a upravovať ho v poriadku, ale nemá požadovaný efekt, pretože je to nesprávna inštancia poľa.

Zvyčajne zbierky VBA pri skladovaní fungujú najlepšieobjektov. Potom budú pracovať tak, ako chcete, pretože ukladajú referencie. Sú v poriadku pri ukladaní hodnôt, ale myslím si, že ich vždy skopírujú, dokonca aj „veľké“, ako sú varianty polí, čo znamená, že nemôžete mutovať obsah uloženého array.

Považujte túto odpoveď iba za špekuláciu, kým sa niekto, kto pozná základné informácie o COM, lepšie váži. Um ... stránkujte Joela Spolského?

EDIT: Po vyskúšaní v programe Excel VBA si myslím, že mám pravdu. Uvedením variantu poľa do kolekcie sa vytvorí kópia, a tak sa dá získať aj jedna. Zdá sa, že neexistuje priamy spôsob, ako kódovať to, čo máte vlastne požiadal.

Vyzerá to, že to, čo skutočne chcete, je trojrozmerné zobrazenieale skutočnosť, že ste chceli použiť kolekciu pre prvú dimenziu, znamená, že chcete mať možnosť zmeniť jej veľkosť v tejto dimenzii. VBA vám umožní iba zmeniť veľkosť poslednej dimenzie poľa ( pozri pomoc pri opätovnom zachovaní) môcť vložte svoje 2D polia do poľa 1-D, ktoré však môžete zmeniť:

ReDim a(5)
Dim b(2, 2)
a(2) = b
a(2)(1, 1) = 42
ReDim Preserve a(6)

Všimnite si, že a je deklarované s ReDim, nie Dim v tomto prípade.

Nakoniec je celkom možné, že nejaký iný prístup k čomukoľvek, čo sa snažíte, by bolo lepšie. Rastúce, premenlivé 3-D polia sú prinajmenšom zložité a náchylné na chyby.


4 pre odpoveď č. 2

@jtolle je správny. Ak spustíte kód uvedený nižšie a skontrolujete hodnoty (Quick Watch je Shift-F9) Arr2 a x uvidíte, že sa líšia:

Dim A As Collection
Set A = New Collection
Dim Arr2(15, 5)

Arr2(1, 1) = 99

" ...

A.Add (Arr2) " adds a copy of Arr2 to teh collection

Arr2(1, 1) = 11  " this alters the value in Arr2, but not the copy in the collection

Dim x As Variant

x = A.Item(1)
x(1, 1) = 15  " this does not alter Arr2

1 pre odpoveď č. 3

Možno, že VBA vytvorí kópiu poľa, keď ju priradí do kolekcie? VB.net to nerobí. Po tomto kóde je a (3,3) 20 vo vba a 5 vo vb.net.

Dim c As New Collection
Dim a(10, 10) As Integer

a(3, 3) = 20
c.Add(a)
c(1)(3, 3) = 5

1 pre odpoveď č. 4

Nedávno som mal tento presný problém. Obklopil som ju naplnením poľa predmetným poľom položiek, vykonaním zmeny v tomto poli, odstránením poľa položiek z kolekcie a následným pridaním zmeneného poľa do kolekcie. Nie je to pekné, ale fungovalo to .... a nemôžem nájsť iný spôsob.


0 pre odpoveď č. 5

Ak chcete, aby kolekcia mala kópiu poľa a nie odkaz na pole, použite metódu array.clone: ​​-

Dim myCollection As New Collection
Dim myDates() as Date
Dim i As Integer

Do
i = 0
Array.Resize(myDates, 0)
Do
Array.Resize(myDates, i + 1)
myDates(i) = Now
...
i += 1
Loop
myCollection.Add(myDates.Clone)
Loop

Na konci bude myCollection obsahovať kumulatívnu zbierku myDates ().