2013-09-27 16 views
6

Mam problemy z obsługą niektórych tablic w języku VBA, a dokładniej mam problemy z próbą wydajnego wykorzystania niektórych istniejących podprogramów/metod do pracy na tablicach o różnych rozmiarach rozmiary/wymiary.Zmodyfikuj istniejącą funkcję do obsługi tablic o różnych wymiarach/strukturze

Tablice są pobierane z obiektu COM, a gdy są dostarczane w przewidywalnej, spójnej strukturze, na podstawie której procedura zwraca tablicę (y), we have had trouble getting all of the functions to return the data in the same structure.

Mam więc do czynienia z różnymi strukturami, czasami z tablicą 2D, ale czasami z tablicą 1D, gdzie każdy element tablicy jest wariantem/tablicą.

Na przykład, jeśli mają istniejącą funkcję, która oczekuje strukturę 2D jak arr(0,0), trzeba zmodyfikować, aby również przyjmować 1D tablicę, w której każdy element jest typu wariant (o strukturze jak arr(0)(0)).

Co mam aktualnie robi

wyłączyć błędy i przetestować Ubound drugiego wymiaru, wiedząc, że zgłosi błąd, jeśli jest to tablica 1D. Mogę wtedy wykonać nieco inną iterację opartą na strukturze macierzy.

  • Nienawidzę korzystania On Error Resume Next jeśli mogę tego uniknąć, ale wydaje takiego może być najbardziej efektywne w tym przypadku.

  • Ja również nie lubię polegać na Excel.Application.Transpose, ale nie znajdź żadnej metody, która może to zrobić natywnie w programie PowerPoint.

przykład:

Function GetSmallFromBar(counts As Variant, banner As Variant, categories As Variant) As Variant 
Dim small As Object 
Dim arrSizeErr As Variant 
Dim i As Long 
Set small = CreateObject("Scripting.Dictionary") 

On Error Resume Next 
arrSizeErr = UBound(counts, 2) 
arrSizeErr = (Err.Number <> 0) 
Err.Clear 
On Error GoTo 0 

'Array is structured like arr(0)(0) instead of arr(0,1) 
If arrSizeErr Then 
    counts = Excel.Application.Transpose(counts) 
    ReDim Preserve counts(0 To UBound(counts) - 1) 
    'Modify for unique array structure 
    For i = LBound(categories) To UBound(categories) 
     If counts(i) < 100 Then 
      small(i) = categories(i) 
     End If 
    Next 
    GoTo EarlyExit 
End If 

'This works for the expected array structure, arr(0,0) 
For i = LBound(categories) To UBound(categories) 
    If counts(i, 0) < 100 Then 
     small(i) = categories(i) 
    End If 
Next 
EarlyExit: 
GetSmallFromBar = small.Items() 

Set small = Nothing 
End Function 

uwaga: Redim tablicy, ponieważ trzeba pracować z tablic 0 bazowych.

Prawdopodobnie w moim kodzie jest pół tuzina miejsc, w których przechodzę do czegoś podobnego, a każdy opiera się na podobnej, ale prawdopodobnie nie identycznej metodzie.

Mam wygodne poprawianie kodu w innym miejscu, po prostu zastanawiam się, czy jest to dobre podejście, które mogę następnie standaryzować jako funkcję i wywołać z innych modułów, gdzie jest to potencjalny błąd, lub czy istnieje inny sposób rób to wydajniej.

Dodatkowe informacje i screeny

Pracuję wyłącznie z 1- i 2-D tablic. Ale czasami otrzymuję tablicę 1D, w której każdy element jest również typu Variant. To daje mi pasowanie, ponieważ mam nadzieję, że mogę zmodyfikować niektóre funkcje i metody, których używam w tablicy 2d, aby pracować na strukturze "array of array".

Oczekiwany 2D Array

enter image description here

Problematyczne Array wariantów

enter image description here

+0

Jednym ze sposobów może być owijanie wywołań COM w procedurze VBA, która standaryzuje wyjście do jednego określonego formatu (tablica 2d lub tablica tablic), tak aby cały twój drugi kod dokładnie wiedział, jakiego formatu oczekiwać. –

+1

Możesz również użyć 'application.choose (array (1), v)' do konwersji wariantu 'v' (range, array, array 1D-array) do tablicy 2D (opartej na 1). Może to służyć do standaryzacji formatów przed dodaniem do słownika. –

+0

@lori_m to działa w PPT? (Nie jestem w stanie testować teraz ...) Nie widziałem wcześniej metody '.choose'. Brzmi jak może, czego potrzebuję. –

Odpowiedz

1

Dopóki Twój kod działa obecnie myślę, że to w porządku. Jeśli chcesz, możesz łączyć niektóre funkcje podprogramu w swoje własne funkcje, aby można je było ponownie wykorzystać.

Chip Pearson ma dostępną funkcję na swojej stronie tablicy, który daje liczbę wymiarów tablicy, które można następnie wykorzystać do określenia, co trzeba zrobić:

Public Function NumberOfArrayDimensions(Arr As Variant) As Integer 
Dim Ndx As Integer 
Dim Res As Integer 
On Error Resume Next 
    Do 
     Ndx = Ndx + 1 
     Res = UBound(Arr, Ndx) 
    Loop Until Err.Number <> 0 
NumberOfArrayDimensions = Ndx - 1 
End Function 

Źródło: Chip Pearson, VBA Arrays

+0

To powinno pomóc. Używam już kilku jego funkcji tablicowych i chociaż wiedziałem o tym z jakiegokolwiek powodu, nie użyłem go, co z perspektywy czasu wydaje mi się głupie. –

Powiązane problemy