Форум программистов, компьютерный форум, киберфорум
Visual Basic
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.72/92: Рейтинг темы: голосов - 92, средняя оценка - 4.72
 Аватар для Антихакер32
1201 / 473 / 46
Регистрация: 06.01.2014
Сообщений: 1,797
Записей в блоге: 19

Как получить название ключа в коллекции

14.02.2014, 19:59. Показов 18609. Ответов 65
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Делаю свой класс
который бы, имитировал класс Scripting.Dictionary
остановился на функции возврата списка имен ключей
где я тут чего не доглядел, где что упустил ?


Модуль класса
Visual Basic
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
Option Explicit
 
Private CL As Collection
Function Keys()
'Вот тут я остановился
'    Dim f&, v, v1
'    ReDim v(CL.Count - 1)
'    For Each v1 In CL
'        v(f) = CL(f + 1)
'        f = f + 1
'    Next
End Function
 
Public Sub Add(Key$, Item)
    CL.Add Item, Key
End Sub
 
Function Exists(Key) As Boolean
    On Error Resume Next
    Call CL.Item(Key)
    If Err.Number Then Else Exists = True
End Function
 
Function Items() As Variant()
    Dim f&, v, v1
    ReDim v(CL.Count - 1)
    For Each v1 In CL
        v(f) = v1
        f = f + 1
    Next
End Function
 
Private Sub Class_Initialize()
    Set CL = New Collection
End Sub
 
Private Sub Class_Terminate()
    Set CL = Nothing
End Sub
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
14.02.2014, 19:59
Ответы с готовыми решениями:

Как изменить имя ключа в коллекции?
Есть коллекция Dictionary<String, Process> PrcDic; (Process - самодельный класс). А как изменить значение одного из ключей...

Как узнать название лейбла элемента коллекции по номеру
Добрый день. Есть задача: После считывания меню создается коллекция вида: collection_menu.Add parameters, Name_Fuction ...

Использование коллекции с идентификатором ключа в виде пользовательского типа
Здравствуйте уважаемые форумчане. Очень неудобно обращаться к вам с такой просьбой, но на данный момент у меня нет другого выхода. Учу...

65
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
24.11.2023, 09:26
Студворк — интернет-сервис помощи студентам
testuser2, нужны тесты времени работы в сравнении со словарём (до 50 тыс ключей).
Если сделаете, с удовольствием посмотрю.
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 12:59
Jack Famous, тут больше не для скорости а для души ) Я конечно минимизировал вызовы CopyMemory (оставив один на процедуру), но, если ориентироваться на скорость, лучше вообще убрать CopyMemory из процедуры. Трик уже сказал, что на vba x64 при вызове любой Api-функции, происходит куча дополнитлеьных действий. Т.е., видимо, если что-то делается очень часто, лучше убрать там любые WinApi. Вот, кстати, кое что в этом направлении выяснилось. Можно ArrPtr выкинуть (если он конечно где-то что-то замедляет).. Для начала новый вариант функции CollKeys, где новый способ получения указателя массива.
Кликните здесь для просмотра всего текста
Visual Basic
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
42
43
44
45
46
47
Private Sub CollKeys2(Coll As Collection, Keys() As String, pKeys() As LongPtr)
    Dim collElem As tpCollElemPtr
    CollKeys2_ Coll, Keys, pKeys, collElem
End Sub
Private Sub CollKeys2_(Coll As Collection, Keys() As String, pKeys() As LongPtr, collElem As tpCollElemPtr, _
                      Optional Ptr As LongPtr, Optional pPtr As LongPtr, Optional ByVal Ptr0 As LongPtr)
    Dim i As Long, Cnt As Long, lpTmp As LongPtr, ptKeys As LongPtr
    
    If Coll Is Nothing Then Exit Sub
    Cnt = Coll.Count
    If Cnt Then
        ReDim Keys(1 To Cnt, 1 To 1)
        CopyMemory ByVal VarPtr(Ptr0) - ptrSz, VarPtr(Ptr0) - ptrSz * 2, ptrSz
        Ptr0 = VarPtr(Ptr0)
        pPtr = Ptr0 - ptrSz * 5: pPtr = Ptr: lpTmp = Ptr 'получение указателя Keys()
        pPtr = Ptr0 - ptrSz * 4: pPtr = Ptr: Ptr = lpTmp '2й вариант: pPtr = ArrPtr(pKeys): Ptr = lpTmp
        pPtr = ObjPtr(Coll) + collPtrOffset: lpTmp = Ptr
        pPtr = Ptr0 - ptrSz * 3: Ptr = lpTmp
        
        pKeys(1, 1) = collElem.pKey
        For i = 2 To Cnt
            Ptr = collElem.nxtPtr
            pKeys(i, 1) = collElem.pKey
        Next
    End If
End Sub
 
Private Sub Пример()    
    Dim Coll As New Collection
    Dim Ptr0 As LongPtr, pKeys() As LongPtr, Keys() As String
    Dim i&, Cnt&
    
    Coll.Add "item1", "key1"
    Coll.Add "item2", "key2"
    Coll.Add "item3", "key3"
    Cnt = Coll.Count
    
    CollKeys2 Coll, Keys, pKeys
    
    Range("A1").Resize(Cnt).Value = Keys 
    
    'освобождение указателей
    For i = 1 To Cnt
        pKeys(i, 1) = 0
    Next
    CopyMemory ByVal VarPtr(Ptr0) - ptrSz, Ptr0, ptrSz 'CopyMemory ByVal ArrPtr(pKeys), Ptr0, ptrSz
End Sub

В VB/VBA есть баг с получением указателя на строковый массив - api-функция ArrPtr возвращает 0 вместо указателя на массив. В предыдущей версии процедуры я использовал udt с массивом внутри, для получения указателя. Но на самом деле есть и другие варианты, как в данном случае - вычисления указателя в стеке аргументов (строки 15, 16). Но если массив задекларирован как обычная переменная, то получить указатель на массив, как оказалось, еще проще.
Visual Basic
1
2
3
Dim lp as longPtr, sArr() As String
lp = VarPtr(lp) - len(lp)
Debug.Ptring "Указатель массива: "; lp
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 13:03
Цитата Сообщение от testuser2 Посмотреть сообщение
lp = VarPtr(lp) - len(lp)
Не понимаю, почему работает этот код, я бы делал VarPtr(lp) + 4 ну или + 8, если longPtr это 8 байт, я просто не знаю ваших VBA'шных штучек этих

Добавлено через 29 секунд
А может я в этом и не разбираюсь просто...
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 13:08
HackerVlad, LongPtr это автоматический тип, который в 32 битах является Long (4 байт), в x64 LongLong(8 байт) очень удобная вещь, не надо писать дополнительных проверок и директив прекомпиляции (#IF Win64 Then), он автоматически подстраивается под ситуацию
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 13:25
testuser2, спасибо за объяснение, но всё равно я не понимаю почему там у тебя минус, а не плюс в коде

Добавлено через 28 секунд
Логичнее было бы lp = VarPtr(lp) + len(lp) тогда...
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 13:30
Цитата Сообщение от HackerVlad Посмотреть сообщение
я не понимаю почему там у тебя минус
а самому проверить в лом? )
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 13:30
testuser2, и кстати я никогда не пользуюсь ArrPtr или этими приблудами, я просто всегда пользуюсь кодом VarPtr(sArr(0)) вот и весь код получения указателя на массив, главное чтобы он был инициализирован
0
932 / 365 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
24.11.2023, 13:31
Цитата Сообщение от testuser2 Посмотреть сообщение
если что-то делается очень часто, лучше убрать там любые WinApi
не могу согласиться.
Возможно, некоторые апи и медленнее работают на x64, но все ли? К тому же, медленнее, чем на x32 всё равно может быть заметно быстрее, чем прочие НЕапи-аналоги. У меня немало на апи и это самые быстрые решения из найденных.
1
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 13:35
testuser2, как ты не понимаешь, я же не VBA'шник, у меня нет VBA чтобы проверить это

Добавлено через 2 минуты
Цитата Сообщение от testuser2 Посмотреть сообщение
а самому проверить в лом? )
А объяснить тебе влом? Например такое могло бы быть возможно в CDecl...

Добавлено через 44 секунды
Не, я не понимаю почему минус, а не плюс

Добавлено через 57 секунд
Цитата Сообщение от Jack Famous Посмотреть сообщение
но все ли
Вроде трик говорил что вызов любой АПи медленный
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 13:44
Цитата Сообщение от HackerVlad Посмотреть сообщение
у меня нет VBA чтобы проверить это
Забыл сделать пояснение для своего примера. Для VB нужно просто все longPtr заменить на Long, константу ptrSz на 4&

Добавлено через 1 минуту
Visual Basic
1
2
3
Dim lp as long, sArr() As String
lp = VarPtr(lp) - 4
Debug.Ptring "Указатель массива: "; lp
Добавлено через 4 минуты
Цитата Сообщение от HackerVlad Посмотреть сообщение
я просто всегда пользуюсь кодом VarPtr(sArr(0)) вот и весь код получения указателя на массив
Это указатель на данные массива, а ArrPtr дает указатель на заголовок массива, точнее указатель на указатель заголовочной структуры SafeArray
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 13:48
testuser2, всё равно мне непонятно почему минус а не плюс

Добавлено через 1 минуту
Уверен, что в Vb6 нужно получать указатель на массив так:

Visual Basic
1
2
3
Dim lp as long, sArr() As String
lp = VarPtr(lp) + 4
Debug.Ptring "Указатель на массив: "; lp
0
24.11.2023, 13:55

Не по теме:

Цитата Сообщение от HackerVlad Посмотреть сообщение
Например такое могло бы быть возможно в CDecl...
На VB можно написать функцию CDecl? Впрочем все это флуд, тема про коллекции.

0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 14:01
testuser2, я не вижу от тебя ни одной объяснения: почему минус, а не плюс? сто раз уже спросил

Добавлено через 16 секунд
мне вот непонятно это совсем

Добавлено через 1 минуту
Цитата Сообщение от testuser2 Посмотреть сообщение
На VB можно написать функцию CDecl?
Конечно можно, перекладывай стек вручную или используй надстройку The Trick но то что можно это 100%

Добавлено через 46 секунд
testuser2, да и мы с тобой уже обсуждали CDecl функции в одной из моих тем, как ты мог забыть
0
Модератор
10048 / 3894 / 883
Регистрация: 22.02.2013
Сообщений: 5,847
Записей в блоге: 79
24.11.2023, 14:02
Цитата Сообщение от testuser2 Посмотреть сообщение
Для VB нужно просто все longPtr заменить на Long
Можно сделать так:
Visual Basic
1
2
3
Public Enum LongPtr
[_]
End Enum
1
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 15:06

Не по теме:

Цитата Сообщение от HackerVlad Посмотреть сообщение
Конечно можно, перекладывай стек вручную или используй надстройку The Trick но то что можно это 100%
Если такой умный, почему спрашиваешь глупые вещи?



Добавлено через 55 минут
Цитата Сообщение от HackerVlad Посмотреть сообщение
я не вижу от тебя ни одной объяснения: почему минус, а не плюс?
Потому что я проверил - так работает. Если у кого-то не работает он может опровергнуть "закон мерфи"
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 16:41
testuser2, а плюс не работает?
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
24.11.2023, 17:00
Deleted
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
24.11.2023, 17:15
Цитата Сообщение от testuser2 Посмотреть сообщение
Deleted
очень умно) ахаххаах
0
1385 / 840 / 91
Регистрация: 08.02.2017
Сообщений: 3,569
Записей в блоге: 1
26.11.2023, 07:26
Цитата Сообщение от HackerVlad Посмотреть сообщение
плюс не работает?
работает
0
Испарился
 Аватар для HackerVlad
1741 / 637 / 45
Регистрация: 10.09.2021
Сообщений: 2,769
26.11.2023, 08:32
testuser2, тогда почему минус а не плюс?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.11.2023, 08:32
Помогаю со студенческими работами здесь

Как получить список вместо коллекции
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using...

Как в Ajax получить значение определенного ключа?
сейчас мне Ajax возвращает результат вот в таком виде {"org":"IK1","con":null,"reg_date":"2016-06-10...

Как получить все значения по полю в коллекции?
Например есть коллекция Книги в ней если по индексу обращаться Books.Author то можно взять значения автора каждого, как еще можно через...

Как правильно получить последний элемент коллекции?
Доброго времени суток! Возникла пролема с использованием метода .ElementAt(). Необходимо получить последний элемент коллекции для...

Как получить тип элемента обобщенной коллекции?
Добрый день, господа! Столкнулся с нетривиальной задачей: как получить тип элемента коллекции List<T>, в которой нет значений. ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
60
Ответ Создать тему
Новые блоги и статьи
SDL3 для Web (WebAssembly): сборка C/C++ проекта из консоли
8Observer8 30.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
Установка Emscripten SDK (emsdk) и CMake на Windows для сборки C и C++ приложений в WebAssembly (Wasm)
8Observer8 30.01.2026
Чтобы скачать Emscripten SDK (emsdk) необходимо сначало скачать и уставить Git: Install for Windows. Следуйте стандартной процедуре установки Git через установщик. Система контроля версиями Git. . .
Подключение Box2D v3 к SDL3 для Android: физика и отрисовка коллайдеров
8Observer8 29.01.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами. Версия v3 была полностью переписана на Си, в. . .
Инструменты COM: Сохранение данный из VARIANT в файл и загрузка из файла в VARIANT
bedvit 28.01.2026
Сохранение базовых типов COM и массивов (одномерных или двухмерных) любой вложенности (деревья) в файл, с возможностью выбора алгоритмов сжатия и шифрования. Часть библиотеки BedvitCOM Использованы. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
Влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru