2011-07-21 9 views
19

Wiem, że możesz z łatwością wziąć szereg komórek i umieścić je w Variant Array, ale chcę pracować z tablicą ciągów (ponieważ jest jednowymiarowa i zajmuje mniej pamięci niż tablica wariantów).Excel VBA: Range to String Array w 1 kroku

Czy istnieje sposób automatycznego przekonwertowania zakresu na tablicę ciągów znaków?

W tej chwili używam funkcji, która zajmie zakres i zapisze wartości w tablicy wariantów, a następnie zamieni tablicę wariantów na tablicę ciągów znaków. Działa dobrze, ale szukam sposobu, aby przejść bezpośrednio z zakresu do tablicy ciągów. Każda pomoc będzie bardzo ceniona.

Function RangeToArray(ByVal my_range As Range) As String() 

Dim vArray As Variant 
Dim sArray() As String 
Dim i As Long 

vArray = my_range.Value 
ReDim sArray(1 To UBound(vArray)) 

For i = 1 To UBound(vArray) 
    sArray(i) = vArray(i, 1) 
Next 

RangeToArray = sArray() 

End Function 

UPDATE: To wygląda jak nie ma sposobu, aby pominąć etap rzucania danych do zmiennej tablicy pierwszy przed przekształceniem go do jednego-wymiarowej tablicy ciągów. Wstyd, jeśli to prawda (nawet jeśli nie wymaga to dużego wysiłku, lubię ultra-optymalizację, więc miałem nadzieję, że istnieje sposób na pominięcie tego kroku). Za kilka dni zamknę to pytanie, jeśli nie pojawi się żadne rozwiązanie. Dzięki za pomocne komentarze, chłopaki!

UPDATE2: Odpowiedź należy do Simona, który włożył wielki wysiłek (podobnie jak wszyscy inni) i ostatecznie wskazał, że nie da się przejść z zasięgu do szyku ciągłego za jednym razem. Dziękuję wszystkim.

+0

Istnieje bezpośrednie procedury manipulacji pamięci można uzyskać dostęp w VBA stworzyć bardzo wydajną funkcję konwertowania tablicę. Nie mam czasu ani umiejętności, aby go ulepszyć, chociaż w mojej głównej aplikacji mam kod odwzorowania pamięci, więc jest tam i pomoże ci stworzyć niezwykle wydajny program do kopiowania tablic. –

+1

Łącze do odpowiedzi, którą dałem z niektórymi funkcjami pamięci w nim zawartymi, jest [tutaj] (http://superuser.com/questions/196565/how-to-merge-data-from-two-drugie-strukturalne-excel -files/196577 # 196577). –

+0

Chociaż nie byłem w stanie zastosować informacji w twoich linkach do tego konkretnego problemu, był to dobry odczyt i interesujący. Dzięki za link. – aevanko

Odpowiedz

10

Jak o ...

Public Function RangeToStringArray(theRange As Excel.Range) As String() 

    ' Get values into a variant array 
    Dim variantValues As Variant 
    variantValues = theRange.Value 

    ' Set up a string array for them 
    Dim stringValues() As String 
    ReDim stringValues(1 To UBound(variantValues, 1), 1 To UBound(variantValues, 2)) 

    ' Put them in there! 
    Dim columnCounter As Long, rowCounter As Long 
    For rowCounter = UBound(variantValues, 1) To 1 Step -1 
     For columnCounter = UBound(variantValues, 2) To 1 Step -1 
      stringValues(rowCounter, columnCounter) = CStr(variantValues(rowCounter, columnCounter)) 
     Next columnCounter 
    Next rowCounter 

    ' Return the string array 
    RangeToStringArray = stringValues 

End Function 
+1

Mam już funkcję, która pobiera tablicę wariantów i czyni ją tablicą ciągów (wysłaną w pytaniu). Szukasz sposobu na pominięcie tego kroku! – aevanko

+1

Ah ... moje złe. Naprawdę nie ma sposobu na pominięcie tego kroku, chociaż jaki jest problem z koniecznością wywołania funkcji konwersji? To tylko około 10 dodatkowych znaków kodu ... –

+0

@SimonCowen, ale są setki znaków w twojej funkcji, wciąż działa, ale niemniej – iliketocode

2
Function RangeToStringArray(myRange as range) as String() 

    ReDim strArray(myRange.Cells.Count - 1) As String 
    Dim idx As Long 
    Dim c As Range 
    For Each c In myRange 
     Set strArray(idx) = c.Text 
     idx = idx + 1 
    Next c 

    RangeToStringArray = strArray 
End sub 
1

Jeśli nie przeszkadza zmieniając zawartość schowka, a następnie:

  1. skopiować zakres do schowka z metodą kopiowania :

    MyTargetRange.Copy 
    
  2. Skopiuj zawartość ze schowka do zmiennej łańcuchowej (przeszukaj tę stronę lub w innym miejscu, aby funkcje przesyłały łańcuchy do/ze schowka).

  3. SPLIT ciąg do tablicy wariantowej:

    MyStringArray = Split(MyClipboardText, vbCrLf) 
    
  4. Opcjonalnie: tablica będzie mieć jeden dodatkowy pusty element, ponieważ nie zawsze jest dodatkowy zysk (vbCrLf) na końcu tekstu po prostu skopiowane do schowka. Aby usunąć po prostu zmienić rozmiar tablicy:

    Redim Preserve MyStringArray(Ubound(MyStringArray) - 1) 
    

Bardzo proste i szybkie !!!

Wady polegają na tym, że schowek może ulec zmianie, kiedy najmniej się tego spodziewamy (podczas przeliczania) i że tworzy tylko tablice łańcuchów (nie podwójne lub inne wartości liczbowe).

Byłoby to bardzo pomocne, jeśli pracujesz z wieloma powtarzającymi się funkcjami (tysiącami), które używają tych samych danych (tysiące punktów danych). Przy pierwszym wywołaniu funkcji wykonaj wszystkie pośrednie obliczenia na zakresach danych, które są potrzebne, ale zapisz wyniki w statycznych zmiennych. Zapisz także ciąg znaków z zakresami wejściowymi za pomocą schowka. Przy każdym kolejnym wywołaniu funkcji przelicz dane wejściowe na tekst, ponownie za pomocą schowka i porównaj z zapisaną kopią.Jeśli są takie same, możesz ominąć wiele wstępnych obliczeń.

+0

Może ktoś może dodać do tego, w jaki sposób skopiować do schowka i odzyskać go ponownie, nie zmieniając najwyższych danych schowka. Może przez API? –

3

Rzeczywiście można przejść bezpośrednio z zakresu do tablicy za pomocą funkcji Podziel, Dołącz i ogranicznika nie w tekście.

Zakładając już przypisany 1D zakres wartości jak SrcRange

Dim Array() As String: Array = Split(Join(Application.Transpose(SrcRange), "#"), "#") 
+1

Jest to jedyna odpowiedź na pełne pytanie "Zakres do tablicy szumów ** w 1 kroku **". Począwszy od wersji Office 2010, dostęp do metody transpozycji można uzyskać za pośrednictwem obiektu WorksheetFunction. 'WorksheetFunction.Transpose (SrcRange)' – lonestorm

+0

Kiedy próbuję to zrobić w programie Excel 2016, otrzymuję komunikat "Nieprawidłowe wywołanie procedury lub argument". – nhinkle

0

Nazwane zakresy stosowane w VBA już są tablice. Najpierw ustaw zakres w nazwanym zakresie, a następnie odwołaj się do niego i usuń nazwany zakres. Na przykład:

ThisWorkbook.Names.Add Name:="test_array", RefersTo:=Sheet1.Range("A4:B10") 
a = Sheet1.Range("test_array") 
ThisWorkbook.Names("test_array").Delete