Excel Forum - Porady, Pomoc,  Excel Help, Excel FAQ Strona Główna
 FAQ  RegulaminRegulamin  Szukaj   Użytkownicy   Grupy   Rejestracja   Profil   Twoje wiadomości   Zaloguj 


Poprzedni temat «» Następny temat
ID tematu: 56663 Skopiuj do schowka 61. Łączenie danych w tablicę jednowymiarową
Autor Wiadomość
Maciej Gonet 
Excel Expert


Wersja: Win Office 365
Posty: 10323
Wysłany: 20-03-2017, 15:18   61. Łączenie danych w tablicę jednowymiarową

Problem łączenia danych (zakresów, stałych zwykłych i tablicowych) nie jest zagadnieniem trywialnym, gdyż nie przewidziano w Excelu specjalnych funkcji do tego celu. Operacje tablicowe w Excelu są tak zaprogramowane, że wszystkie argumenty są synchronizowane według pierwszych elementów i trudno "przesunąć" fragment do połączenia w inne miejsce. Zwykle niezbędne jest liczenie elementów do połączenia i trzeba je dodawać pojedynczo, żeby uzyskać pożądany rezultat.
Stosunkowo najłatwiej można wykonać operację łączenia, przekształcając chwilowo tablice do połączenia w teksty, a po połączeniu rozdzielając je z powrotem na elementy. Można wykorzystać do tego funkcje VBA Join i Split. Pierwsza z funkcji przekształca 1-wymiarową tablicę w łańcuch tekstowy, dodając w miarę potrzeby znaki separujące elementy; druga funkcja wykonuje działanie odwrotne — rozdziela tekst w miejscach separatorów i zwraca wynik w postaci jednowymiarowej tablicy złożonej z elementów tekstowych. Dzięki wykorzystaniu formatu tekstowego rozwiązanie to jest dość uniwersalne, gdyż łączone dane mogą być zarówno liczbami, jak i tekstami. W wyniku otrzymuje się tablicę złożoną z elementów tekstowych, które można łatwo skonwertować na liczby, jeśli jest taka potrzeba.
Mankamentem tego rozwiązania jest wrażliwość na błędy w danych, które trzeba zamaskować, jeżeli występują. Pewną niedogodnością jest też konieczność przygotowania danych w postaci tablic jednowymiarowych. Jeśli wśród danych występują pojedyncze wartości, to mamy do wyboru dwie drogi — albo nadamy im w sposób jawny strukturę tablic, otaczając stałe nawiasami klamrowymi, a w przypadku odwołań dopisując stałą tablicową z pustym tekstem, np. A1&{""}, albo w kodzie funkcji będziemy sprawdzać każdy argument, czy jest tablicą i używać wtedy funkcji Join, a gdy nie jest, tylko dopisywać go do wyniku (pośredniego). Musimy pokonać jeszcze jedną trudność: spośród obiektów tablicowych Excela tylko tablice reprezentujące wiersz mają strukturę tablic jednowymiarowych, tablice reprezentujące kolumny oraz zakresy komórek mają zawsze strukturę dwuwymiarową, wymagają więc przekształcenia. I znowu mamy wybór – można dokonać tego przekształcenia w kodzie funkcji, ale to wymaga sprawdzenia struktury każdego argumentu i w zależności, czy jest to wiersz, czy kolumna – zastosowania odpowiedniego przekształcenia. Wydaje mi się, że prościej będzie przygotować przekształcone argumenty bezpośrednio przy wywołaniu funkcji. Zakres i tablicę kolumnową przekształcamy przez zastosowanie funkcji TRANSPONUJ, a w przypadku zakresu wierszowego wystarczy wykonanie dowolnego działania lub dereferencja, w najprostszym przypadku wstawienie znaku + przed adresem zakresu. Gdyby dane mogły zawierać błędy, należy je zamaskować za pomocą funkcji JEŻELI.BŁĄD. Użycie tej funkcji zastępuje również dereferencję. Jeśli zdecydowalibyśmy się na konwersję w kodzie funkcji, to w przypadku zakresu wierszowego można użyć funkcji WorksheetFunction.IfError (ewentualnie dwukrotnie WorksheetFunction.Transpose), a w przypadku zakresu kolumnowego funkcji WorksheetFunction.Transpose, uzupełnionej ewentualnie przez WorksheetFunction.IfError.
Moim zdaniem optymalnym wyborem jest selekcja danych pojedynczych i grupowych w kodzie funkcji, natomiast pozostawienie sprawy konwersji danych do postaci jednowymiarowej użytkownikowi wywołującemu funkcję. Gdyby do połączenia były też zakresy faktycznie dwuwymiarowe, należy je podzielić na wiersze lub kolumny za pomocą funkcji INDEKS, a następnie przekształcić w struktury jednowymiarowe. W tym wariancie kod funkcji mógłby mieć postać:
Kod:
Function Połącz1D(ParamArray T())
       Dim i As Long, Tt As String
       For i = 0 To UBound(T)
             If IsArray(T(i)) Then
                   Tt = Join(T(i))
             Else
                   Tt = T(i)
             End If
             If Połącz1D = "" Then
                   Połącz1D = Tt
             ElseIf Tt <> "" Then
                  Połącz1D = Połącz1D & " " & Tt
             End If
       Next i
       Połącz1D = Split(Połącz1D)
End Function
Separatorem domyślnym funkcji Join i Split jest spacja. Gdyby łączone były dane tekstowe zawierające spacje jako normalne znaki, należy wybrać inny separator – znak, który normalnie w danych nie występuje i odpowiednio zmodyfikować kod funkcji.
Przykładowo gdy chcemy połączyć w tablicę jednowymiarową zakres B1:B5 (kolumna), pojedynczą komórkę C8, liczbę 2 i zakres C3:E3 (wiersz), wywołujemy funkcję tak (zakładam, że dane nie zawierają błędów):
Kod:
= Połącz1D(TRANSPONUJ(B1:B5);C8;2;+C3:E3)


Łączenie_Join_Split.xlsm
Pobierz Plik ściągnięto 531 raz(y) 16.57 KB

ID posta: 318843 Skopiuj do schowka
 
 
Wyświetl posty z ostatnich:   
Odpowiedz do tematu
Nie możesz pisać nowych tematów
Nie możesz odpowiadać w tematach
Nie możesz zmieniać swoich postów
Nie możesz usuwać swoich postów
Nie możesz głosować w ankietach
Nie możesz załączać plików na tym forum
Możesz ściągać załączniki na tym forum
Dodaj temat do Ulubionych
Wersja do druku

Skocz do:  

Powered by phpBB modified by Przemo © 2003 phpBB Group
Theme xandgreen created by spleen& Programosy modified v0.3 by warna
Opieka techniczna www.wip.pl

Archiwum

Strona uĹźywa plikĂłw cookies.

Kliknij tutaj, żeby dowiedzieć się jaki jest cel używania cookies oraz jak zmienić ustawienia cookie w przegl�darce.
Korzystając ze strony użytkownik wyraża zgodę na używanie plików cookies, zgodnie z bieżącymi ustawieniami przeglądarki.
SprawdĹş, w jaki sposĂłb przetwarzamy dane osobowe