Скользящий массив

YUBA

Имеется два больших массива
dim X(<b>100000</b>)
dim Y(<b>100000</b>)
Эти массивы напрямую не используются, а используются через малые
dim x1(<b>2000</b>)
dim y1(<b>2000</b>)
Часть информации копируется в малые массивы,
i1=<b>121</b>
for i=<b>0</b> to <b>2000</b>
x1(i)=X(i+i1)
y1(i)=Y(i+i1)
Next
и они, в свою очередь передаются объекту
obj1.x=x1
obj1.y=y1
Т.е. малые массивы представляют собой как-бы скользящее окно которое передвигается вдоль большого и массива и предает данные в объект.Хотелось-бы обойтись без копирования и напрямую передавать данные в объект из большого массива (объект неизменяем). С указателями все это решалось бы просто. Здесь даже не знаю, возможно ли.
15 ответов

YUBA

Я бы попробовал-бы сделать класс, который эмулировал-бы твоё скользящее окно. Перед передачей устанавливаются границы окна и передавать объект окна, а обработку переделать с учетом того, что это объект окна, а не массив, потом границы сдвигаются и процесс повторяется. Может быть даже обошлось-бы без дополнительных массивов.


YUBA

Я бы попробовал-бы сделать класс, который эмулировал-бы твоё скользящее окно. Перед передачей устанавливаются границы окна и передавать объект окна, а обработку переделать с учетом того, что это объект окна, а не массив, потом границы сдвигаются и процесс повторяется. Может быть даже обошлось-бы без дополнительных массивов.
Спасибо. Такой эмулирующий класс сделать несложно. Будет что-то вида Class.x(i) и Class.y(i)Скользячка хорошая. Задаешь положение и ширину окна и все типа имеешь.Но вот этот объект, кот obj1, сам определяет размер переданного массива, т.е. способов указать размер не существует. Воспримет ли он такую конструкцию?
obj1.x=Class.x
К сожалению, попробовать это далеко не 5 мин. :(


YUBA

> Автор: YUBA> Но вот этот объект, кот obj1, сам определяет размер переданного массива, т.е. способов указать размер не > существует. Воспримет ли он такую конструкцию?>> obj1.x=Class.xК сожалению, попробовать это далеко не 5 мин. :(я имел в виду переделать именно обработку внутри obj1. Что-бы он не сам определял размер, а получал из класса окна. и я имел в виду что x в obj1 это должна быть переменная типа окна. И этот фрагмент будет выглядеть так:
Set obj1.x = clsWindow
а внутри obj1 нужно скорректировать работу с x как с объектом


YUBA

> Автор: YUBA> Но вот этот объект, кот obj1, сам определяет размер переданного массива, т.е. способов указать размер не > существует. Воспримет ли он такую конструкцию?>> obj1.x=Class.xК сожалению, попробовать это далеко не 5 мин. :(я имел в виду переделать именно обработку внутри obj1. Что-бы он не сам определял размер, а получал из класса окна. и я имел в виду что x в obj1 это должна быть переменная типа окна. И этот фрагмент будет выглядеть так:
Set obj1.x = clsWindow
а внутри obj1 нужно скорректировать работу с x как с объектом
Невозможно. obj1 - неизменяем, это DLL. Что внутри никому неизвестно, кроме авторов. Сразу, скажу, что используется нештатно, т.е. взят из другой программы. Но работает и устраивает.


YUBA

Игорь Горбонос, Естественно, все коды не настоящие, только иллюстрация к проблеме.


YUBA

YUBA,Используйте вместо массивов словари и сделайте свойство вашего класса типа словарь. Тогда через Let, Set сразу все и передадите вашему объекту.Успехов


YUBA

> Автор: VladConnНе Влад, это не получится, т.к. obj1 - это сторонний СОМ-объест, к внутренностям которого он не имеет доступа2 YUBAА вот воспользоватся советом Влада и попробовать копировать нужные участки массива можно попробовать


YUBA

> Автор: VladConnНе Влад, это не получится, т.к. obj1 - это сторонний СОМ-объест, к внутренностям которого он не имеет доступа2 YUBAА вот воспользоватся советом Влада и попробовать копировать нужные участки массива можно попробовать
Он и так копируется, в цикле, а хотелось бы ссылкой, типа (код неправильный)
dim X(<b>100000</b>)
dim Y(<b>100000</b>)
dim x1(<b>2000</b>)
dim y1(<b>2000</b>)
x1=Y(<b>123</b>)
y1=Y(<b>123</b>)
Примерно так это бы решилось с указателями.Дурь конечно, и так все дышит.


YUBA

YUBA,конечно, баловство всё это, но можно создать структуру SAFEARRAY и заполнить её так, чтобы она имела свои границы массива и указывала на данные (с произвольного места) существующего массива. В таком духе.


YUBA

YUBA,конечно, баловство всё это, ....
Безусловно. :) Но если проблемы с массивами решить, то с листов Екселя можно убрать большую часть информации. Иначе уже получается такой винегрет из массивов, скрытых листов, БД и пр. удовольствия и бесконечного копирования туда и обратно.Там, в Екселе, и так все медленно, но пользовательский интерфейс уж оч хорош, отказаться невозможно. :)


YUBA

Ты поставь задачу, возможно это можно решить не таким образом?


YUBA

Ты поставь задачу, возможно это можно решить не таким образом?


YUBA

Наверняка можно решить и другими способами, но чтобы довести способ с формированием SAFEARRAY до чего-то, что можно пощупать руками:
'Описания см. по ссылке выше
Private Sub CreateWindowArray( _
 SourceArray() As ******, WindowArray() As ******, saWindow As SAFEARRAY1VT, _
 ByVal WindowPos As Long, ByVal WindowLBound As Long, _
 ByVal WindowLength As Long)
 Dim ppsaWindow As Long
 
 saWindow.vtType = VarType(SourceArray(LBound(SourceArray)))
 With saWindow.sa
 .cDims = <b>1</b>
 .fFeatures = FADF_HAVEVARTYPE Or FADF_FIXEDSIZE
 .cbElements = LenB(SourceArray(LBound(SourceArray)))
 '.cLocks = 1
 .pvData = VarPtr(SourceArray(WindowPos))
 With .rgsabound(<b>0</b>)
 .lLbound = WindowLBound
 .cElements = WindowLength
 End With
 End With
 
 ppsaWindow = ArrPtr(WindowArray())
 CopyMemory ByVal ppsaWindow, VarPtr(saWindow.sa), LenB(ppsaWindow)
End Sub

Private Sub ClearWindowArray(WindowArray() As ******)
 Dim ppsaWindow As Long
 ppsaWindow = ArrPtr(WindowArray())
 CopyMemory ByVal ppsaWindow, <b>0</b>&, LenB(ppsaWindow)
End Sub

Private Sub MoveWindowArray( _
 SourceArray() As ******, saWindow As SAFEARRAY1VT, _
 ByVal WindowPos As Long)
 saWindow.sa.pvData = VarPtr(SourceArray(WindowPos))
End Sub

Private Sub Test2()
 Dim X(<b>100</b>) As ******
 Dim Y(<b>100</b>) As ******
 Dim x1() As ******
 Dim y1() As ******
 Dim i As Long
 Dim sax1 As SAFEARRAY1VT
 Dim say1 As SAFEARRAY1VT
 
 'Заполнение больших массивов
 For i = LBound(X) To UBound(X)
 X(i) = i
 Next i
 For i = LBound(Y) To UBound(Y)
 Y(i) = <b>1</b> + i / <b>1000</b>
 Next i
 
 'Наложение "окон"
 CreateWindowArray X(), x1(), sax1, <b>40</b>, <b>0</b>, <b>21</b>
 CreateWindowArray Y(), y1(), say1, <b>32</b>, <b>1</b>, <b>10</b>
 
 'Использование "окон"
 For i = LBound(x1) To UBound(x1)
 Debug.Print i, x1(i)
 Next i
 For i = LBound(y1) To UBound(y1)
 Debug.Print i, Format$(y1(i), "0.000")
 Next i
 
 'Перемещение имеющегося "окна"
 MoveWindowArray X(), sax1, <b>13</b>
 
 'Использование перемещённого "окна"
 For i = LBound(x1) To UBound(x1)
 Debug.Print i, x1(i)
 Next i
 
 'Уничтожение "окон"
 ClearWindowArray x1()
 ClearWindowArray y1()
End Sub

Private Sub Command2_Click()
 Test2
End Sub


YUBA

Бенедикт, Спасибо, в пон-к буду разбираться. Нет, наверно до среды, в воскресенье на дачу.


YUBA

почитай "сущность массивов в VB" Гергерт эту статью видел на сайтах VBNet.ru,vbstreets.ru удачи в статье он ковыряется с указателями и в примере решает похожую задачку и еще раз удачи