Страницы: 1
RSS
Как узнать key текущего item при просмотре коллекции?
 
Доброе время суток!

Как можно вернуть значение key про просмотре коллекции в цикле
For Each Item in Collection...Next?

В теле цикла есть условие, которому должно удовлетворять значение Item. Если оно выполняется, хотелось бы знать, какой ключ
 
А почему Вы думаете что есть ключ? Не факт что есть ключ.
 
Ключ есть однозначно. Условие заполнения коллекции такое. Конкретно - это номер строки, на которой нашлось подходящее значение, помещенное в item
 
syt navy Мне кажется, что нельзя вернуть.
 
Обидно. Будем пробовать через двумерные массивы
 
Если сами заносите - ну кладите ещё и в словарь. Даже если для мака ((
 
syt navy, вы б боле приближенный к реальному пример приложили ибо у меня есть подозрение, что есть разночтение в термине KEY.
Изменено: БМВ - 20.11.2023 20:39:21
По вопросам из тем форума, личку не читаю.
 
А в чем разница? Неужели в словаре я могу узнать ключ по значению элемента?
 
БМВ, по определению в статье про метод Add объекта Collection: key - Необязательный параметр. Уникальное строковое выражение, задающее строку ключа, которая может использоваться вместо индекса позиции для доступа к элементу коллекции.
У меня это номер строки.
А пример,близкий к реальному
Две таблицы
1 таблица имеет группировку строк
Яблоко
    красное
    зелёное
    жёлтое
2 таблица без группировки, где в списке есть
Яблоко красное
Зелёное яблоко
Яблоко большое жёлтое
Ну и с ценой
Вот и хочу эту цену из второй таблицы притянуть в первую
Изменено: syt navy - 20.11.2023 20:55:57
 
syt navy
Цитата
А в чем разница? Неужели в словаре я могу узнать ключ по значению элемента?
Если значения в словаре уникальные, то при цикле по ключам словаря можно вернуть ключ.
 
Евгений Смирнов, можете подсказать как? Я не работал со словарями
 
Ну приблизительно так надеюсь разберетесь
Код
Sub Табл13DicvDic()
Dim Dic1, Arr1, Tp1, Tp2, i&, j&, k&, sTime!
Arr1 = Cells(1).CurrentRegion
    Set Dic1 = CreateObject("Scripting.Dictionary")
    For i = 1 To UBound(Arr1, 1)
Dic1(Arr1(i, 1)) = Arr1(i, 2)
    Next i
'Sim Искомое значение словаря
    For Each Tp1 In Dic1.keys
If Sim = Dic1(Tp1) Then MsgBox "Искомый Ключ " & Tp1
    Next
End Sub
 

syt navy А вам действительно нужен сам ключ. Может вас устроит дубликат ключа. Тогда все проще, причем в коллекции запись легче для понимания. Просто в значении сохраняйте не значение, а массив из 2 элементов. Один элемент массива значение, а второй элемент массива дубликат ключа.

 
Цитата
Евгений Смирнов написал:
Просто в значении сохраняйте не значение, а массив из 2 элементов.
А зачем тогда коллекция?  :)
Согласие есть продукт при полном непротивлении сторон
 
Sanja Ну человеку надо вернуть не только значение но и ключ. Сам ключ из коллекции никак не выдернешь. А если сделать дубликат его просто вернуть. И по всей видимости автору без разницы сам ключ или дубликат
Код
Sub ResizePrim()
Dim Col1 As New Collection, Tp
ReDim Tp(1)
Tp(0) = Item ' Записываем значение Item
Tp(1) = Key ' Записываем дубликат ключа
Col1.Add Tp, CStr(Key) 'Добавляем элемент коллекции в виде массива в коллекцию
XX = Col1(1)(0) ' Возвращаем значение Item
ZZ = col(1)(1) ' Возвращаем дубликат ключа
End Sub
Изменено: Евгений Смирнов - 21.11.2023 06:29:52
 
Sanja
Цитата
А зачем тогда коллекция
С коллекцией проще работать, чем с массивом, потому что не надо заботиться о размерности.
 
syt navy, ключ коллекции можно узнать по индексу такой функцией.
Код
Option Explicit

Private Declare PtrSafe Sub CopyMemory Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As LongPtr)
#If Win64 Then
    Private Const ptrSz = 8
    Private Const varSz = 24
    Private Const collPtrOffset = 40
#Else
    Private Const ptrSz = 4
    Private Const varSz = 16
    Private Const collPtrOffset = 24
#End If

Private Sub Пример()
    Dim Coll As New Collection, elem
    Dim i&
    Coll.Add "item1", "key1"
    Coll.Add "item2", "key2"
    Coll.Add "item3", "key3"
    For i = 1 To Coll.Count
        Debug.Print "Key: ", CollKey(i, Coll)
        Debug.Print "Item: ", Coll(i)
    Next

End Sub

Private Function CollKey(ByVal Index As Long, Col As Collection) As String
    Dim i As Long, Ptr0 As LongPtr, Ptr As LongPtr, Key As String
    If Col Is Nothing Then Exit Function
    Select Case Index
    Case Is < 1, Is > Col.Count: Exit Function
    Case Else
        Ptr = ObjPtr(Col)
        For i = 1 To Index
            CopyMemory Ptr, ByVal Ptr + collPtrOffset, ptrSz
        Next    
        CopyMemory ByVal VarPtr(Key), ByVal Ptr + varSz, ptrSz
        CollKey = Key
        CopyMemory ByVal VarPtr(Key), Ptr0, ptrSz
    End Select
End Function
Изменено: testuser - 22.11.2023 11:12:45
 
Я вообще не понимаю о чем идёт речь, если это не CreateObject("System.Collections.SortedList"), тут можно напрямую проверить наличие значения, не ключа, а именно значения, но там тоже свои заморчки. А если это CreateObject("Scripting.Dictionary"), то обращение идёт только через ключ т.е.
Цитата
syt navy написал:
For Each Item in Collection...Next
должна выглядеть
For Each key in Collection...Next.
Либо, у вас всё равно цикл, можно его организовать по массиву .items, а результат брать из  .keys, только не забыть добавить индекс, или цикл не через For each ... in ... Next, а просто For n = 0 to... Next
Изменено: Msi2102 - 21.11.2023 22:46:43
 
Евгений Смирнов, совершенно верно. Именно поэтому я смотрел сначала в сторону коллекции. Но для моей задачи двумерный массив подошел лучше.  
 
Я когда писал про словарь предполагал так - в коллекцию заносим что-то с ключами, и тут же это что-то кладём как ключ в словарь, а ключ коллекции как итем.
Тогда при запросе ключа для этого чего-то получаем его не из коллекции, а из словаря.
Только если эти значения будут дублироваться (а могут судя по логике процесса) - то и ключей/итемов будет несколько, это может обеспечить словарь создавая итем как массив, коллекцию или строку с разделителем.
 
testuser, красиво  :idea:
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
 
Jack Famous, это функция The trick-а с Кибера, кастомизированая под VBA
 
testuser, могёт, человек  8)
Во всех делах очень полезно периодически ставить знак вопроса к тому, что вы с давних пор считали не требующим доказательств (Бертран Рассел) ►Благодарности сюда◄
Страницы: 1
Наверх