Домашняя страница Undo Do New Save Карта сайта Обратная связь Поиск по форуму
МИР MS EXCEL - Гость.xls

Вход

Регистрация

Напомнить пароль

 

= Мир MS Excel/Извлекаем дескриптор матрицы SAFEARRAY - Мир MS Excel

Старая форма входа
  • Страница 1 из 1
  • 1
Модератор форума: _Boroda_, китин  
Мир MS Excel » Вопросы и решения » Готовые решения » Извлекаем дескриптор матрицы SAFEARRAY (Макроведам на заметку)
Извлекаем дескриптор матрицы SAFEARRAY
Формуляр Дата: Среда, 20.06.2012, 23:13 | Сообщение № 1
Группа: Друзья
Ранг: Ветеран
Сообщений: 832
Репутация: 255 ±
Замечаний: 0% ±

Excel 2003, 2013
Всем привет!
Взялся давеча разбираться дискрипторами матриц, написал пару вспомогательных процедурок:

SafeArrayOf() - позволяет просматривать параметры дескриптора матрицы. Возвращаемый дескриптор является неполным в тех случаях, когда размерность матрицы > 1, из-за того что реальный дескриптор имеет переменной длины хвост описывающий границы каждого измерения. Эти границы и так легко определить с помощью Lbound(), Ubound().

SafeArrayPtr() - даёт возможность более решительных действий с помощью прямой ссылки на оригинал дескриптора.

[vba]
Code
Option Explicit
Option Base 1

Declare Function VarPtr Lib "msvbvm60" (variable As Any) As Long
Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long
Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
Declare Function GetMem2 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Declare Sub CopyMem Lib "kernel32" Alias _
                "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
            
Private Type SAFEARRAYBOUND
      cElements As Long    'Количество элементов в размерности
      lLBound As Long      'Нижняя граница размерности
End Type

Private Type SAFEARRAY
      cDims As Integer     'Число размерностей
      fFeatures As Integer 'Флаг, юзается функциями SafeArray
      cbElements As Long   'Размер одного элемента в байтах
      cLocks As Long       'Сколько раз массив был locked, но пока не unlocked.
      pvData As Long              'Указатель на данные.
      rgsabound As SAFEARRAYBOUND 'Повторяется для каждой размерности.
End Type

Private Function SafeArrayOf(ByRef arrVarRef As Variant) As SAFEARRAY
'Извлекает дескриптор матрицы
        Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
End Function

Public Function SafeArrayPtr(ByRef arrVarRef As Variant) As Long
'Возвращает адрес дескриптора матрицы
Const VT_BYREF = &H4000
Dim dWord(4) As Long
        If Not IsArray(arrVarRef) Then Exit Function

        Call CopyMem(dWord(1), arrVarRef, 16) 'разбираем Variant на 4-байтовые куски
        SafeArrayPtr = dWord(3)
        If dWord(1) And VT_BYREF Then _
            GetMem4 SafeArrayPtr, VarPtr(SafeArrayPtr) 'SafeArrayPtr = SafeArrayPtr(1)
End Function
[/vba]


Excel 2003 EN, 2013 EN

Сообщение отредактировал Формуляр - Четверг, 21.06.2012, 10:32
 
Ответить
СообщениеВсем привет!
Взялся давеча разбираться дискрипторами матриц, написал пару вспомогательных процедурок:

SafeArrayOf() - позволяет просматривать параметры дескриптора матрицы. Возвращаемый дескриптор является неполным в тех случаях, когда размерность матрицы > 1, из-за того что реальный дескриптор имеет переменной длины хвост описывающий границы каждого измерения. Эти границы и так легко определить с помощью Lbound(), Ubound().

SafeArrayPtr() - даёт возможность более решительных действий с помощью прямой ссылки на оригинал дескриптора.

[vba]
Code
Option Explicit
Option Base 1

Declare Function VarPtr Lib "msvbvm60" (variable As Any) As Long
Declare Function ArrPtr Lib "msvbvm60" Alias "VarPtr" (arr() As Any) As Long
Declare Function PutMem2 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
Declare Function PutMem4 Lib "msvbvm60" (ByVal pDst As Long, ByVal NewValue As Long) As Long
Declare Function GetMem2 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Declare Function GetMem4 Lib "msvbvm60" (ByVal pSrc As Long, ByVal pDst As Long) As Long
Declare Sub CopyMem Lib "kernel32" Alias _
                "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
            
Private Type SAFEARRAYBOUND
      cElements As Long    'Количество элементов в размерности
      lLBound As Long      'Нижняя граница размерности
End Type

Private Type SAFEARRAY
      cDims As Integer     'Число размерностей
      fFeatures As Integer 'Флаг, юзается функциями SafeArray
      cbElements As Long   'Размер одного элемента в байтах
      cLocks As Long       'Сколько раз массив был locked, но пока не unlocked.
      pvData As Long              'Указатель на данные.
      rgsabound As SAFEARRAYBOUND 'Повторяется для каждой размерности.
End Type

Private Function SafeArrayOf(ByRef arrVarRef As Variant) As SAFEARRAY
'Извлекает дескриптор матрицы
        Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
End Function

Public Function SafeArrayPtr(ByRef arrVarRef As Variant) As Long
'Возвращает адрес дескриптора матрицы
Const VT_BYREF = &H4000
Dim dWord(4) As Long
        If Not IsArray(arrVarRef) Then Exit Function

        Call CopyMem(dWord(1), arrVarRef, 16) 'разбираем Variant на 4-байтовые куски
        SafeArrayPtr = dWord(3)
        If dWord(1) And VT_BYREF Then _
            GetMem4 SafeArrayPtr, VarPtr(SafeArrayPtr) 'SafeArrayPtr = SafeArrayPtr(1)
End Function
[/vba]

Автор - Формуляр
Дата добавления - 20.06.2012 в 23:13
nerv Дата: Четверг, 21.06.2012, 22:37 | Сообщение № 2
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

прикольно мой парсер справился с подсветкой smile

смущает эта функция
[vba]
Code
Private Function SafeArrayOf(ByRef arrVarRef As Variant) As SAFEARRAY
       'Извлекает дескриптор матрицы
       Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
End Function
[/vba]
а именно
[vba]
Code
ByVal SafeArrayPtr(arrVarRef)
[/vba]
зачем ByVal? Причем в строке ниже
[vba]
Code
Public Function SafeArrayPtr(ByRef arrVarRef As Variant) As Long
[/vba]
передача параметра установлена совершенно противоположным образом.


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba


Сообщение отредактировал nerv - Четверг, 21.06.2012, 22:38
 
Ответить
Сообщениеприкольно мой парсер справился с подсветкой smile

смущает эта функция
[vba]
Code
Private Function SafeArrayOf(ByRef arrVarRef As Variant) As SAFEARRAY
       'Извлекает дескриптор матрицы
       Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
End Function
[/vba]
а именно
[vba]
Code
ByVal SafeArrayPtr(arrVarRef)
[/vba]
зачем ByVal? Причем в строке ниже
[vba]
Code
Public Function SafeArrayPtr(ByRef arrVarRef As Variant) As Long
[/vba]
передача параметра установлена совершенно противоположным образом.

Автор - nerv
Дата добавления - 21.06.2012 в 22:37
Формуляр Дата: Четверг, 21.06.2012, 23:29 | Сообщение № 3
Группа: Друзья
Ранг: Ветеран
Сообщений: 832
Репутация: 255 ±
Замечаний: 0% ±

Excel 2003, 2013
Quote (nerv)
ByVal SafeArrayPtr(arrVarRef)
зачем ByVal?
Сам пока в эти API-шки не очень въехал. Такое подозрение, что если ByVal не поставить, то использует вместо значения переменной её адрес, т.е. в случае
Quote (nerv)
 Call CopyMem(SafeArrayOf, SafeArrayPtr(arrVarRef), 24)
откопирует 24 случайных байта,начиная с адреса результата ф-ции. По крайней мере, с обычными переменными так, а с ф-цией - ХЗ.
Хочешь - проверь. smile


Excel 2003 EN, 2013 EN

Сообщение отредактировал Формуляр - Четверг, 21.06.2012, 23:30
 
Ответить
Сообщение
Quote (nerv)
ByVal SafeArrayPtr(arrVarRef)
зачем ByVal?
Сам пока в эти API-шки не очень въехал. Такое подозрение, что если ByVal не поставить, то использует вместо значения переменной её адрес, т.е. в случае
Quote (nerv)
 Call CopyMem(SafeArrayOf, SafeArrayPtr(arrVarRef), 24)
откопирует 24 случайных байта,начиная с адреса результата ф-ции. По крайней мере, с обычными переменными так, а с ф-цией - ХЗ.
Хочешь - проверь. smile

Автор - Формуляр
Дата добавления - 21.06.2012 в 23:29
nerv Дата: Четверг, 21.06.2012, 23:44 | Сообщение № 4
Группа: Редакторы
Ранг: Обитатель
Сообщений: 431
Репутация: 193 ±
Замечаний: 0% ±

могу ошибаться, но кажется здесь
[vba]
Code
Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
[/vba]
ByVal означает передачу копии функции


Чебурашка стал символом олимпийских игр. А чего достиг ты?
Тишина - самый громкий звук


YM 41001156540584 / WM WMR R21924176233

https://github.com/nervgh/vba
 
Ответить
Сообщениемогу ошибаться, но кажется здесь
[vba]
Code
Call CopyMem(SafeArrayOf, ByVal SafeArrayPtr(arrVarRef), 24)
[/vba]
ByVal означает передачу копии функции

Автор - nerv
Дата добавления - 21.06.2012 в 23:44
Мир MS Excel » Вопросы и решения » Готовые решения » Извлекаем дескриптор матрицы SAFEARRAY (Макроведам на заметку)
  • Страница 1 из 1
  • 1
Поиск:

Яндекс.Метрика Яндекс цитирования
© 2010-2024 · Дизайн: MichaelCH · Хостинг от uCoz · При использовании материалов сайта, ссылка на www.excelworld.ru обязательна!