Как создавать переменные динамически, по имени.

Программирование на Visual Basic for Applications
Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Как создавать переменные динамически, по имени.

Сообщение Avtopic » 10.12.2006 (Вс) 12:53

Здравствуйте!
Нашел в поиске чем-то похожую тему. Там автора сравняли с землей, все же рискну поднять похожий вопрос.

Имею свою функцию. Туда передаются пять аргументов. Один из них GoodsID.
Функция используется в запросе.
В самой функции для каждой GoodsID мне надо определить отдельные Static переменные, чтобы в них накоплялись результаты по группам для запроса. Т.е. мне нужно определять Static переменные динамически. Но как?

Сейчас я делаю так: (пожалуйста, не поленитесь разобраться в следующем маленьком коде)
Код: Выделить всё
Public Function sum_res3(..,,,,., GoodsID As Long) As Double
Static OLD_RES() As Double
Static FIRST_OBROSHCHENIE As Boolean

If FIRST_OBROSHCHENIE = False Then ReDim OLD_RES(2, 0): FIRST_OBROSHCHENIE = True
If GoodsID > UBound(OLD_RES(), 2) Then ReDim Preserve OLD_RES(2, GoodsID)
GoodsID увеличивает размер Static массива OLD_RES до GoodsID.
Но GoodsID это Long, и может быть произвольным. Т.е. несмотря на не надобность массив может получиться огромным.

Кто не будь, может посоветовать решенные?

2-й путь, вместо OLD_RES(2, 0) использовать OLD_RES(3, 0) и в 3-ем хранить GoodsID, не подходит. Перебор в цикле тормозит запрос до бесконечности.

3-й путь, вместо OLD_RES использовать Collection тоже не подходит, тормозит запрос примерно в четыре раза.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Как создавать переменные динамически, по имени.

Сообщение tyomitch » 10.12.2006 (Вс) 13:02

Avtopic писал(а):2-й путь, вместо OLD_RES(2, 0) использовать OLD_RES(3, 0) и в 3-ем хранить GoodsID, не подходит. Перебор в цикле тормозит запрос до бесконечности.

3-й путь, вместо OLD_RES использовать Collection тоже не подходит, тормозит запрос примерно в четыре раза.

Могу предложить использовать хеш-таблицу: вместо OLD_RES(2, 0) использовать OLD_RES(3, 0), и в 3-ем хранить GoodsID, а в качестве индекса использовать остаток от деления GoodsID на что-нибудь большое и простое. Тогда перебор будет минимальным.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Re: Как создавать переменные динамически, по имени.

Сообщение Avtopic » 10.12.2006 (Вс) 13:32

tyomitch писал(а):в качестве индекса использовать остаток от деления GoodsID на что-нибудь большое и простое
tyomitch убейте, но не понял. :(
остаток деления двух разных чисел на одно и тоже большое и простое, не может бить одинаковым?

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Re: Как создавать переменные динамически, по имени.

Сообщение tyomitch » 10.12.2006 (Вс) 13:35

Avtopic писал(а):
tyomitch писал(а):в качестве индекса использовать остаток от деления GoodsID на что-нибудь большое и простое
tyomitch убейте, но не понял. :(
остаток деления двух разных чисел на одно и тоже большое и простое, не может бить одинаковым?

Может, но редко.
Поэтому и будет: перебор, но маленький.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 10.12.2006 (Вс) 13:44


Nicky
Постоялец
Постоялец
 
Сообщения: 519
Зарегистрирован: 12.08.2004 (Чт) 12:14

Re: Как создавать переменные динамически, по имени.

Сообщение Nicky » 11.12.2006 (Пн) 0:00

[OFFTOP]
Нравятся мне такие названия ;)
Avtopic писал(а):FIRST_OBROSHCHENIE

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.12.2006 (Пн) 16:35

ТЗ:
имеется GoodsID, Long > 0, может быть произвольным.
должен сделать массив OLD_RES(2, GoodsID)

tyomitch поставил на правильный путь.

Прочитал, в основном понял, но... и все, застрял.

Кто не будь, может поделиться, какой принцип хеширования применил бы сам, в этом случае.

А если кто примерчик еще предложит, Вообще, буду благодарен.

Спасибо заранее!

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.12.2006 (Пн) 16:40

Да, еще одно примечание
происходит только увеличение массива, т.е. элементы не удаляются.

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 18.12.2006 (Пн) 16:52

Какие конкретно сложности?
Делить с остатком не удаётся?
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.12.2006 (Пн) 17:11

tyomitch
делить то канешно удается, но:
неужели эффективность не завысит от значения “что-нибудь большое и простое”,
Под эффективность подразумеваю, частоту коллизии, и при коллизии количество таких же “заколлизированных ” которые нужно перебирать.
Если честно, ведь вы сами же не использовали бы этот простой вариант хеширования :) .

tyomitch
Пользователь #1352
Пользователь #1352
Аватара пользователя
 
Сообщения: 12822
Зарегистрирован: 20.10.2002 (Вс) 17:02
Откуда: חיפה

Сообщение tyomitch » 18.12.2006 (Пн) 18:04

Использовал.
Изображение

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.12.2006 (Пн) 18:37

Ладно. Пойду по этому путы до конца, хотя
сомневаюсь, что результат будет лучше, чем при Collection.

Avtopic
Постоялец
Постоялец
 
Сообщения: 442
Зарегистрирован: 30.09.2005 (Пт) 17:15
Откуда: Tbilisi

Сообщение Avtopic » 18.12.2006 (Пн) 19:10

Блеск!
Первая же статья которая попалась мне по этому поводу, пустил по ложному путы (бинарных деревьев, АВЛ- деревьев, хотя тоже было полезно).
И потерял идею, которую вы предложили.
Построив маленький эксперимент, сразу понял свою ошибку.
Код: Выделить всё
Const Hash_Dim = 12
Dim arre(Hash_Dim)

Sub hashing()
Dim i As Long, St As String

For i = 17 To 105
    hash i
Next

Debug.Print Join(arre, ";;")
End Sub

Function hash(Vr As Long) As Long
hash = Vr Mod Hash_Dim
arre(hash) = arre(hash) + 1    'каким же стал размер этой ветки
End Function
7;;7;;7;;7;;7;;8;;8;;8;;8;;8;;7;;7

tyomitch Вы гений, спасибо большое!


Вернуться в VBA

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 103

    TopList