Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Witam,
Mam tabele z 3 kolumnami A: ID, B: data i C: źródło. Id występuje kilkukrotnie dla różnych dat. Próbuję formułą znaleźć najniższą datę dla każdego ID i zwrócić wartość z kolumny C z tego samego wiersza. Formuła ma zwracać wartość bez względu jak będzie posortowana tabela. Próbuję z funkcją Index + podaj.pozycje tylko nie wiem jak wstawić dodatkowy warunek, który będzie uwzględniał najniższą datę (kolumna B) dla danego ID (kolumna A):
INDEKS($D$2:$D$29;PODAJ.POZYCJĘ(A2;$A$2:$A$29;0))
Bartłomiej Dąbrowski

Bartłomiej Dąbrowski
analiza/przetwarzani
e danych

Temat: zwrócenie wartości po 2 warunkach

Kolumny A, B, C zawierają odpowiednio: Indeks, Datę, Źródło
jeden ze sposobów:
=INDEKS(C:C;PODAJ.POZYCJĘ(F1&MIN(JEŻELI(A:A=F1;B:B;"olać"));A:A&B:B;0))

gdzie F1 to komórka zawierająca nr indeksu dla którego chcemy poznać "źródło"
Formuła tablicowa - zatwierdzana kombinacją Ctrl+Shift+Enter.
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Dzięki, o to chodziło. A da się to zrobić bez użycia formuły tablicowej?
Bartłomiej Dąbrowski

Bartłomiej Dąbrowski
analiza/przetwarzani
e danych

Temat: zwrócenie wartości po 2 warunkach

Nie wiem. Może ktoś będzie się chciał bawić się w takie ćwiczenia umysłowe. Ja staram się nie zawracać sobie głowy tworzeniem piętrowych formuł jak nie ma takiej potrzeby.

Można skorzystać z funkcji BD.MIN oraz BD.POLE - to funkcje z grupy funkcji baz danych
Ale w sumie one też działają na tablicach, tyle że nie są zatwierdzane tablicowo. No i trzeba gdzieś na boku wprowadzić kryteria.

PS. Oczywiście zawsze możesz dodać kolumny pomocnicze ale chyba nie o to chodzi?Ten post został edytowany przez Autora dnia 22.04.16 o godzinie 17:09
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Ok dzięki ta formuła załatwia to co chciałem uzyskać. Podpowiedzialbys mi moze jeszcze z 1 formuła: mamy w kolumnie A id (np 1, 2, 3 itd) i w kolumnie B kategorie (np A, B lub C). Id moga występować kilkukrotnie i w 1 wierszu maja przydzielona 1 kategorie. Jakiej formuły użyć, zeby do kazdego Id przydzielić wszystkie kategorie, jesli np. id 1 wystąpiło 2 razy i raz mialo kategorie A i raz B to w kolumnie C zwroci A+B, jesli wszystkie 3 to A+B+C?
Bartłomiej Dąbrowski

Bartłomiej Dąbrowski
analiza/przetwarzani
e danych

Temat: zwrócenie wartości po 2 warunkach

W takim przypadku można napisać sobie własną funkcję, która załatwi złączanie kategorii albo poszperać w sieci i znaleźć już taką napisaną.
Chip Perason popełnił taką rozszerzoną wersję funkcji ZŁĄCZ.TEKSTY -> link

Wtedy można zmajstrować np. coś takiego


Obrazek
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

tu masz bez CSE:(tak sobie wymyśliłem na cito)
=INDEX(C2:C100,MATCH(SUMPRODUCT(LARGE((A2:A100=D1)*(B2:B100),COUNTIF(A2:A100,D1))),B2:B100,0))
i tak na marginesie lepiej jest definiować zakresy. Niezdefiniowane zakresy są ok przy małej ilości danych (i to też nie zawsze).
Co do drugiego popieram Pearsona :)

Edit:
zapomiałem :)
D1 tutaj to to samo co u Bartka F1Ten post został edytowany przez Autora dnia 22.04.16 o godzinie 22:14
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Prawie idealnie :) Jedyny problem, że jeśli będzie kilka ID z tą samą kategorią np. 3 razy ID ABC z kategorią A to wynik dla ABC będzie A+A+A i w moim przypadku przy dużej bazie się to nie sprawdzi. Można rozbudować tą funkcję, żeby dla każdego ID pokazał kategorię tylko 1 raz?
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

Robisz listę wyników pod warunkiem e.g. D1
Z tej listy robisz listę Unique, której użyjesz w UDF podanej przez Bartka.
Można te formuły połączyć lub nie (lub ukryć).
Większym problemem jest to, że UDF nie zawsze się odświeża. Nie pomaga nawet Worksheet_Change i trzeba Ctrl+Shift+F9 używać.
Dlaczego? Nie wiem. - jeszcze :)

Generalnie działa wg. twoich reguł, czyli:
A:source1
A:source2
A:source1
pokaże: source1 | source2
a nie: source1 | source2 | source1

A:source1
A:source2
A:source3
pokaże: source1 | source2 | source3

tylko wtedy nie wiem po co ci ta pierwsza formuła, ale....
Bogdan Gilarski

Bogdan Gilarski www.excelperfect.pl
Perfect And
Practical

Temat: zwrócenie wartości po 2 warunkach

Zrób kopię tabeli i zastosuj na niej narzędzie "Usuń duplikaty" (karta Dane), dla dwóch kolumn (ID i kategoria), potem już z górki ...
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Dzięki Andy, co do formuł to potrzebuję obu do 1 bazy ale służą do czego innego. 1 po całej historii zamówień klienta w danym okresie ma zwrócić źródło z której była 1 transakcja a 2 ma sprawdzić czy klient kupował produkty z kategorii A, B, C czy mix. Wolałbym nie kopiować tego w inne miejsce tylko mieć wszystkie dane w bazie i obrabiać w tabeli przestawnej. Co do zakresów to jak najbardziej baza jest w formie tabeli i formuły się wypełniają w dół. Pokombinuje z tą 2 formuła i dam znać, najlepiej by było od razu w sql zrobić przypisywanie tych kategorii.
Bartłomiej Dąbrowski

Bartłomiej Dąbrowski
analiza/przetwarzani
e danych

Temat: zwrócenie wartości po 2 warunkach

Przerobiłem trochę funkcję Pearsona tak żeby ignorowała dla naszego przypadku powtórzenia kategorii.
Z tym, że zrobiłem to na szybko i po łebkach, więc może się wywalać albo nie działać jak należy (nie analizowałem kodu funkcji)
Function StringConcat(Sep As String, ParamArray Args()) As Variant
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
' StringConcat
' By Chip Pearson, chip@cpearson.com, www.cpearson.com
' www.cpearson.com/Excel/stringconcatenation.aspx
' This function concatenates all the elements in the Args array,
' delimited by the Sep character, into a single string. This function
' can be used in an array formula. There is a VBA imposed limit that
' a string in a passed in array (e.g., calling this function from
' an array formula in a worksheet cell) must be less than 256 characters.
' See the comments at STRING TOO LONG HANDLING for details.
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Dim S As String
Dim N As Long
Dim M As Long
Dim R As Range
Dim NumDims As Long
Dim LB As Long
Dim IsArrayAlloc As Boolean
Dim objCollection As Collection

'''''''''''''''''''''''''''''''''''''''''''
' If no parameters were passed in, return
' vbNullString.
'''''''''''''''''''''''''''''''''''''''''''
If UBound(Args) - LBound(Args) + 1 = 0 Then
StringConcat = vbNullString
Exit Function
End If

For N = LBound(Args) To UBound(Args)
''''''''''''''''''''''''''''''''''''''''''''''''
' Loop through the Args
''''''''''''''''''''''''''''''''''''''''''''''''
If IsObject(Args(N)) = True Then
'''''''''''''''''''''''''''''''''''''
' OBJECT
' If we have an object, ensure it
' it a Range. The Range object
' is the only type of object we'll
' work with. Anything else causes
' a #VALUE error.
''''''''''''''''''''''''''''''''''''
If TypeOf Args(N) Is Excel.Range Then
'''''''''''''''''''''''''''''''''''''''''
' If it is a Range, loop through the
' cells and create append the elements
' to the string S.
'''''''''''''''''''''''''''''''''''''''''
For Each R In Args(N).Cells
If Len(R.Text) > 0 Then
S = S & R.Text & Sep
End If
Next R
Else
'''''''''''''''''''''''''''''''''
' Unsupported object type. Return
' a #VALUE error.
'''''''''''''''''''''''''''''''''
StringConcat = CVErr(xlErrValue)
Exit Function
End If

ElseIf IsArray(Args(N)) = True Then
'''''''''''''''''''''''''''''''''''''
' ARRAY
' If Args(N) is an array, ensure it
' is an allocated array.
'''''''''''''''''''''''''''''''''''''
IsArrayAlloc = (Not IsError(LBound(Args(N))) And _
(LBound(Args(N)) <= UBound(Args(N))))
If IsArrayAlloc = True Then
''''''''''''''''''''''''''''''''''''
' The array is allocated. Determine
' the number of dimensions of the
' array.
'''''''''''''''''''''''''''''''''''''
NumDims = 1
On Error Resume Next
Err.Clear
NumDims = 1
Do Until Err.Number <> 0
LB = LBound(Args(N), NumDims)
If Err.Number = 0 Then
NumDims = NumDims + 1
Else
NumDims = NumDims - 1
End If
Loop
On Error GoTo 0
Err.Clear
''''''''''''''''''''''''''''''''''
' The array must have either
' one or two dimensions. Greater
' that two caues a #VALUE error.
''''''''''''''''''''''''''''''''''
If NumDims > 2 Then
StringConcat = CVErr(xlErrValue)
Exit Function
End If
Set objCollection = New Collection

If NumDims = 1 Then
For M = LBound(Args(N)) To UBound(Args(N))
If Args(N)(M) <> vbNullString Then
On Error Resume Next
objCollection.Add Args(N)(M), Args(N)(M)
On Error GoTo 0
Err.Clear
'S = S & Args(N)(M) & Sep
End If
Next M

Else
''''''''''''''''''''''''''''''''''''''''''''''''
' STRING TOO LONG HANDLING
' Here, the error handler must be set to either
' On Error GoTo ContinueLoop
' or
' On Error GoTo ErrH
' If you use ErrH, then any error, including
' a string too long error, will cause the function
' to return #VALUE and quit. If you use ContinueLoop,
' the problematic value is ignored and not included
' in the result, and the result is the concatenation
' of all non-error values in the input. This code is
' used in the case that an input string is longer than
' 255 characters.
''''''''''''''''''''''''''''''''''''''''''''''''
On Error GoTo ContinueLoop
'On Error GoTo ErrH
Err.Clear
For M = LBound(Args(N), 1) To UBound(Args(N), 1)
If Args(N)(M, 1) <> vbNullString Then
On Error Resume Next
objCollection.Add Args(N)(M, 1), Key:=Args(N)(M, 1)
On Error GoTo ContinueLoop
'On Error GoTo ErrH
Err.Clear
'S = S & Args(N)(M, 1) & Sep
End If
Next M

For i = 1 To objCollection.Count
S = S & objCollection(i) & Sep
Next i

Err.Clear
M = LBound(Args(N), 2)
If Err.Number = 0 Then
For M = LBound(Args(N), 2) To UBound(Args(N), 2)
If Args(N)(M, 2) <> vbNullString Then
On Error Resume Next
objCollection.Add Args(N)(M, 2), Args(N)(M, 2)
On Error GoTo ContinueLoop
'On Error GoTo ErrH
Err.Clear
'S = S & Args(N)(M, 2) & Sep
End If
Next M

For i = 1 To objCollection.Count
S = S & objCollection(i) & Sep
Next i
End If
On Error GoTo ErrH:
End If

Else
If Args(N) <> vbNullString Then
S = S & Args(N) & Sep
End If
End If
Else
On Error Resume Next
If Args(N) <> vbNullString Then
S = S & Args(N) & Sep
End If
On Error GoTo 0
End If
ContinueLoop:
Next N

'''''''''''''''''''''''''''''
' Remove the trailing Sep
'''''''''''''''''''''''''''''
If Len(Sep) > 0 Then
If Len(S) > 0 Then
S = Left(S, Len(S) - Len(Sep))
End If
End If

StringConcat = S
'''''''''''''''''''''''''''''
' Success. Get out.
'''''''''''''''''''''''''''''
Exit Function
ErrH:
'''''''''''''''''''''''''''''
' Error. Return #VALUE
'''''''''''''''''''''''''''''
StringConcat = CVErr(xlErrValue)
End Function
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

Ok, to czekam co wymyślisz :)
U mnie działa oprócz tego odświeżania UDF.

Edit:
a tak na marginesie to istnieje rozwiązanie tego całego problemu bez VBA :)Ten post został edytowany przez Autora dnia 23.04.16 o godzinie 15:51
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Bartek przerobiona funkcja działa tylko jest inny problem, bo zwraca różne kombinacje np. A+B+C, A+C+B, C+B+A i nie traktuje ich jako 1 kategoria. Funkcja też bardzo długo przelicza, więc chyba nie obejdzie się bez wyliczenia tegona poziomie SQL bo chyba każda formuła tablicowa przy dużej ilości wierszy będzie długo przeliczać.
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

Z ciekawości: ile masz kategorii i czy cały zakres się zmienia (ilość wierszy) czy tylko zmieniają się wartości przy stałej ilości wierszy?
Robert Kloc

Robert Kloc Starszy Analityk
E-commerce

Temat: zwrócenie wartości po 2 warunkach

Andy mam 4 kategorie i cały zakres się zmienia w zależności od okresu jaki wyrzucam z SQL. Większy zakres to kilkaset tys. wierszy. Na razie myślę, żeby to obrabiać w tabeli przestawnej gdzie w etykiecie wierszy będę miał ID a kolumnach kategorie i używając jeżeli + złącz teksty przypiszę te połączone kategorie i z tego kolejna przestawna z której będę wiedział kto kupował w jakich kategoriach. Chyba, że masz jeszcze inne rozwiązanie? :)
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

Jak wyżej napisałem: istnieje rozwiązanie bez VBA i (dopisuję) bez pivota.
w dodatkowym arkuszu który może być ukryty generujesz listę1 kategorii pod warunkiem $D$1 obok generujesz listę2 unikatową i sortowaną z listy1
następnie concatenate z 4 komórek listy2 w formule likwidującej nadmiarowe separatory w stylu +, | czy spacja albo jakieś inne.
w arkuszu podstawowym umieszczasz odniesienie do ostatniej formuły i gotowe.

Być może jest to nadmierna komplikacja ale ja wolę stosować formuły jeżeli jest to możliwe zanim zastosuję vba czy pivota.

Edit:
btw. jeżeli separatorem będzie spacja to bardzo upraszcza sprawę i sprowadza się do: Lista1 i Lista2 (o takich samych zakresach) i TRIM(CONCATENATE())

tu masz przyczynek do rozważań: Link nad pojedyńczą listą zamiast dwóch. :)))
A w zasadzie jeśli dobrze skorzystasz z tego co jest pod linkiem to nawet TRIM() nie jest potrzebny :0Ten post został edytowany przez Autora dnia 25.04.16 o godzinie 14:13
Bartłomiej Dąbrowski

Bartłomiej Dąbrowski
analiza/przetwarzani
e danych

Temat: zwrócenie wartości po 2 warunkach

Robert K.:
Bartek przerobiona funkcja działa tylko jest inny problem, bo zwraca różne kombinacje np. A+B+C, A+C+B, C+B+A i nie traktuje ich jako 1 kategoria. Funkcja też bardzo długo przelicza, więc chyba nie obejdzie się bez wyliczenia tegona poziomie SQL bo chyba każda formuła tablicowa przy dużej ilości wierszy będzie długo przeliczać.

Jak się ma po kilkaset tysięcy wierszy, to dowolne formuły excel'owe są raczej kiepskim pomysłem.
Co do funkcji - trzeba by jeszcze dodać sortowanie kolekcji i będzie zawsze A+B+C albo A+C albo B+C
Andy L.

Andy L. ITM, VUB

Temat: zwrócenie wartości po 2 warunkach

Używając dostosowanej formuły (zakres: A2:A100000) z linku, wprowadzając dane do 100 000 wierszy, przy ograniczeniu do 4 kategorii (czyli faktyczne wyświetlanie wyniku jest tylko w 4 wierszach) opóźnienie przeliczania jest ledwo zauważalne, ale jest.

Może użyłem tendencyjnych danych :)))))))))))))

Wojciech Gardziński

Wypowiedzi autora zostały ukryte. Pokaż autora

Następna dyskusja:

Zestawienie - Import Wartości




Wyślij zaproszenie do