Страницы: 1
RSS
Фильтрация в словаре
 
Доброго времени суток, уважаемые форумчане. Скажу сразу, вопрос больше теоретический, так как готовое решение уже есть, но хочется узнать можно ли решить это иначе. Итак, ситуация: имеется словарь dicData, в ключах которого находится информация типа:
"Яшин О.Р.|03.03.2021|"
"Шестаков Н.В.|05.03.2021|"
"Шестаков Н.В.|05.03.2021|ОК"
"Андреев А.Э.|29.03.2021|В"
Поясню, в конце ключа может быть признак (В или ОК) или не быть ничего и это тоже является признаком для последующего отбора. Для выборки из словаря необходимой информации, пытаюсь применить фильтр:
Код
For Each k In Filter(dicData.keys,  "|ОК", , 1)
...
Для вариантов с признаком понятно: "|ОК" или "|В", а вот можно ли указать для фильтра именно отсутствие признака? Если использовать "|", то фильтр фактически не работает, ведь такой символ есть в каждом ключе (можно конечно проверить ниже в коде If Split(k, "|")(2) = "" Then, но тогда это будет работать только для отсутствия признака, а я пытаюсь "сваять" универсальный вариант с минимумом строк (чисто для самообразования). Сейчас это решается тройным прогоном по массиву данных с советующим условием (нет признака или указан определенный).
P.S. Заранее спасибо всем откликнувшимся
Изменено: OlegO - 15.05.2021 20:20:31
 
Цитата
OlegO написал:
можно ли указать для фильтра именно отсутствие признака
Можно. Здесь главное желание поискать в сети матчасть по функции Filter. В вашем случае как-то так,:
Код
For Each k In Filter(Filter(dicData.keys,  "|B", 0, 1),  "|ОК", 0, 1)
«Бритва Оккама» или «Принцип Калашникова»?
 
по-идее, нужен 1 проход по словарю от начала до конца, где проверять каждое значение ключа либо через If, либо через Select Case. Но 3 прогона словаря точно не нужно.
P.S. Можно Left использовать и если это "|", то ....
Изменено: New - 16.05.2021 00:53:00
 
На мой взгляд использовать select case будет более универсально
Код
For Each k In dicData.keys
    Select Case Split(k, "|")(2)
        Case "B": MsgBox k
        Case "OK": MsgBox k
        Case "": MsgBox k
    End Select
Next
Спасибо
 
Спасибо за советы. А у меня самого вот какое решение придумалось. Ранее 3 отдельных массива для последующей выгрузки я планировал получить так:
Код
                    For f = 0 To UBound(Array("|", "|ОК", "|В"))
                        ReDim Arr_data(1 To dicData.Count, 1 To 4)
                            For Each k In Filter(dicData.keys, Array("|", "|ОК", "|В")(f), , 1)
                                If Split(k, "|")(2) = "" Then
                                    j = j + 1
                                    Arr_data(j, 1) = Array("касса", "оплата картой", "возврат")(f) 'признак
                                    Arr_data(j, 2) = Split(k, "|")(1) 'дата расхода
                                    Arr_data(j, 3) = Array("", "", "номер")(f)
                                    Arr_data(j, 4) = dicData.Item(k) 'сумма
                                    Count_dok = Count_dok + 1
                                End If
                            Next k
                                Range(адрес).Resize(UBound(Arr_data, 1), 4).Value = Arr_data
                                j = Empty
                     next f
А позже догадался что 4 строку кода можно тоже сделать многовариантной в зависимости от значения элемента массива:
Код
If Split(k, "|")(2) = Array("", "ОК", "В")(f) Then
По крайней мере эта проблема решается вроде правильно. Двигаюсь дальше :D
R Dmitry, Ваш вариант интересен, но получается, что для моей задачи мне придется формировать 3 отдельных массива ReDim Arr_data1, ReDim Arr_data2...с отдельными переменными для номеров строк этих массивов? Это наверное будет объёмнее моего предполагаемого варианта, но я проверю.
 
Мое решение смотрели? Работает?
«Бритва Оккама» или «Принцип Калашникова»?
 
bedvit, Ваш вариант правильно фильтрует именно для отсутствия признака, спасибо за алгоритм. НО в моей задаче в любом случае предполагается проверка и формирование массивов для всех 3 вариантов отбора данных и пришлось бы писать отдельный код для проверок по наличию признаков, а я пытаюсь минимизировать объем кода (повторюсь, чисто для самообразования, никто за "лишние" строки по рукам не бьет)
Страницы: 1
Наверх