Страницы: 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
Цитата
А в чем разница? Неужели в словаре я могу узнать ключ по значению элемента?
Если значения в словаре уникальные, то при цикле по ключам словаря можно вернуть ключ.
 
Евгений Смирнов, можете подсказать как? Я не работал со словарями
 
Ну приблизительно так надеюсь разберетесь
Код
1
2
3
4
5
6
7
8
9
10
11
12
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 Ну человеку надо вернуть не только значение но и ключ. Сам ключ из коллекции никак не выдернешь. А если сделать дубликат его просто вернуть. И по всей видимости автору без разницы сам ключ или дубликат
Код
1
2
3
4
5
6
7
8
9
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, ключ коллекции можно узнать по индексу такой функцией.
Код
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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
Читают тему
Loading...