Форум программистов, компьютерный форум, киберфорум
testuser2
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Изменение размерностей массива 1D, 2D в любых пределах

Запись от testuser2 размещена 14.06.2024 в 13:50
Показов 630 Комментарии 0
Метки vb, vba

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
Option Explicit
#If Win64 Then
    Private Const ptrSz As LongPtr = 8
#Else
    Private Const ptrSz As Long = 4
#End If
Private Type SAFEARRAYBOUND
    cCount              As Long
    lBound              As Long
End Type
Private Type SAFEARRAY
    cDims               As Integer
    fFeatures           As Integer
    cbElements          As Long
    cLocks              As Long
    #If Win64 Then
      unused            As Long
    #End If
    pvData              As LongPtr
End Type
Private Type SAFEARRAY2D
    Hdr                 As SAFEARRAY
    Bounds(1)           As SAFEARRAYBOUND
End Type
Private Declare PtrSafe Sub CopyPtr Lib "kernel32.dll" Alias "RtlMoveMemory" (Dst As Any, Src As Any, Optional ByVal Size As LongPtr = ptrSz)
Private Declare PtrSafe Sub SafeArrayAllocDescriptor Lib "oleaut32.dll" (ByVal cDims As Long, ppsaOut As LongPtr)
Private Declare PtrSafe Sub SafeArrayDestroyDescriptor Lib "oleaut32.dll" (ByVal pSA As LongPtr)
Private Declare PtrSafe Function GetProcessHeap Lib "kernel32.dll" () As LongPtr
Private Declare PtrSafe Function HeapReAlloc Lib "kernel32.dll" (ByVal hHeap As LongPtr, ByVal dwFlags As Long, ByVal lpMem As LongPtr, ByVal dwBytes As LongPtr) As LongPtr
Private Declare PtrSafe Function HeapSize Lib "kernel32.dll" (ByVal hHeap As LongPtr, ByVal dwFlags As Long, ByVal lpMem As LongPtr) As LongPtr
Private Const HEAP_ZERO_MEMORY = &H8
 
Private Sub TestChangeArrayDims()
    Dim Arr$()
    ReDim Arr(0 To 19)
    Arr(2) = 222
    Stop
    ChangeArrayDims Arr, 1, 20
    Stop
    ChangeArrayDims Arr, 1, 20, 1, 1
    Stop
    ChangeArrayDims Arr, 1, 1, 1, 20
    Stop
    ChangeArrayDims Arr, 0, 19, 0, 0
    Stop
    ChangeArrayDims Arr, 1, 20, 1, 2
    Stop
End Sub
 
Private Sub ChangeStrArrayDims(sArr() As String, ByVal Lb1 As Long, ByVal Ub1 As Long, _
            Optional ByVal Lb2 As Long = -1, Optional ByVal Ub2 As Long = -1, Optional ByVal Rllc As Boolean)
    Dim SA As SAFEARRAY2D, pArr As LongPtr
    
    CopyPtr pArr, ByVal VarPtr(Lb1) - ptrSz           'получаем указатель массива
    
    ChangeArrayDims_ pArr, Lb1, Ub1, Lb2, Ub2, SA, Rllc
End Sub
Private Sub ChangeArrayDims(vArr, ByVal Lb1 As Long, ByVal Ub1 As Long, _
            Optional ByVal Lb2 As Long = -1, Optional ByVal Ub2 As Long = -1, Optional ByVal Rllc As Boolean)
    Dim SA As SAFEARRAY2D, pArr As LongPtr, vt%
    CopyPtr vt, vArr, 2
    If vt < &H4000 Then 'isVariant = True             'получаем указатель массива
        pArr = VarPtr(vArr) + 8
    Else
        CopyPtr pArr, ByVal VarPtr(vArr) + 8
    End If
    ChangeArrayDims_ pArr, Lb1, Ub1, Lb2, Ub2, SA, Rllc
End Sub
Private Sub ChangeArrayDims_(ByVal pArr As LongPtr, ByVal Lb1 As Long, ByVal Ub1 As Long, _
                              ByVal Lb2 As Long, ByVal Ub2 As Long, SA As SAFEARRAY2D, ByVal Rllc As Boolean)
    Dim ptSA As LongPtr, ptSA2 As LongPtr, tmpSA As SAFEARRAY, hHeap As LongPtr
    Dim newSize As LongPtr, curSize As LongPtr, Cnt1D&, Cnt2D&
    
    CopyPtr ptSA, ByVal pArr                          'получение указателя дескриптора массива Safearray
    CopyPtr ByVal VarPtr(Ub2) + ptrSz, ptSA           'устанавливаем указатель SA на дескриптор массива
    If SA.Hdr.cDims > 2 Then Exit Sub                 'поддерживаются только 1D и 2D массивы
    
    hHeap = GetProcessHeap
    curSize = HeapSize(hHeap, 0, SA.Hdr.pvData)       'текущий размер блока данных
    Cnt1D = Ub1 - Lb1 + 1
    If Lb2 < 0 Then                                   'если не заданы параметры 2й размерности
        newSize = Cnt1D * SA.Hdr.cbElements           'вычисляем требуемый размер блока данных
        GoSub ReAlloc                                 '~ Redim Preserve
        SA.Hdr.cDims = 1
        SA.Bounds(0).lBound = Lb1
        SA.Bounds(0).cCount = Cnt1D
    Else                                              'если заданы параметры 2й размерности
        If SA.Hdr.cDims <> 2 Then                     'если массив не 2D (а 1D) переделываем его н 2D
            LSet tmpSA = SA                           'сохраняем параметры дескриптора 1D массива
            SafeArrayAllocDescriptor 2, ptSA2         'создаем новый дескриптор массива размерности 2D
            CopyPtr ByVal VarPtr(Ub2) + ptrSz, ptSA2  'устанавливаем указатель SA на новый дескриптор массива
            LSet SA = tmpSA                           'восстанавливаем сохраненные параметры массива
            CopyPtr ByVal pArr, ptSA2                 'назначаем массиву новый 2D дескриптор
            SafeArrayDestroyDescriptor ptSA           'уничтожаем старый 1D дескриптор
            SA.Hdr.cDims = 2
        End If
        Cnt2D = Ub2 - Lb2 + 1
        newSize = Cnt1D * Cnt2D * SA.Hdr.cbElements   'вычисляем требуемый размер блока данных
        GoSub ReAlloc
        SA.Bounds(0).lBound = Lb2                     'устанавлииваем заданные 1D и 2D размерности
        SA.Bounds(0).cCount = Cnt2D
        SA.Bounds(1).lBound = Lb1
        SA.Bounds(1).cCount = Cnt1D
    End If
Exit Sub
ReAlloc:                                              'перераспределяем блок данных согласно требуемого размера
    Select Case True
    Case newSize > curSize, Rllc                      'HEAP_ZERO_MEMORY - заполнение нулями добавленного объема
        SA.Hdr.pvData = HeapReAlloc(hHeap, HEAP_ZERO_MEMORY, SA.Hdr.pvData, newSize)
    End Select
Return
End Sub
Метки vb, vba
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 0
Комментарии
 
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru