Форум программистов, компьютерный форум, киберфорум
VBA
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.83/6: Рейтинг темы: голосов - 6, средняя оценка - 4.83
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
Excel

Как отличить вариативную переменную с массивом от вариативного массива?

29.05.2024, 14:53. Показов 2370. Ответов 24

Студворк — интернет-сервис помощи студентам
Приветствую!
Никак не могу понять…
Пример кода
Visual Basic
1
2
3
4
5
Private Sub t()
Dim v, aV()
    v = Array(1):   Debug.Print VarType(v), TypeName(v)     ' 8204 | Variant()
    aV = Array(1):  Debug.Print VarType(aV), TypeName(aV)   ' 8204 | Variant()
End Sub
VBE разницу ВИДИТ
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
29.05.2024, 14:53
Ответы с готовыми решениями:

Как записать в переменную Array элемент массива, который в свою очередь так же является массивом
Вот часть кода. Array sim = new Array; for (int i = 0; i <= slova.Length - 1; i++) { if...

Извлечь цену вариативного товара в корзине
Сайт на wordpress woocommerce, из корзины нужно сделать кнопку оформления рассрочки и передать post запросом содержимое корзины и цены. ...

Сравнить переменную с массивом
Нужно в условии сравнить переменную со всеми элементами массива. Лучше делать это без цикла. У меня ничего не получилось for(int...

24
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
29.05.2024, 16:27  [ТС]
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от bedvit Посмотреть сообщение
Лучше оформить сразу со всеми проверками
делать больше нечего. Оформишь, так испугаются и/или запутаются. Кто захочет — спросит. Да и тесты довольно однозначные, как и название темы.
Не нужно всё в кучу сваливать — проходили

P.S.: Наконец-то нормальные обсуждения на форуме
0
1412 / 878 / 93
Регистрация: 08.02.2017
Сообщений: 3,750
Записей в блоге: 2
29.05.2024, 16:51
Цитата Сообщение от bedvit Посмотреть сообщение
CopyMemory vt, var, 2
Лучше записать так
Цитата Сообщение от bedvit Посмотреть сообщение
CopyMemory vt, ByVal VarPtr(var), 2
Поскольку, если в переменной var бует строка или массив строк, он скорее всего будет дополнительно конвертироваться в ANSI при передаче Api-функции.
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
29.05.2024, 17:22  [ТС]
testuser2, спасибо! Учту
UPD: Разницы не замечено. Время проверки: 0.00 sec
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
Function PRDX_Arr_Check_IsVariant_NotArray(a) As Boolean
Dim i%
    API_Memory_Copy_Int_Any i, a, 2
    PRDX_Arr_Check_IsVariant_NotArray = (i < 16384) ' &H4000
End Function
'==================================================================================================
Private Sub Test()
Dim v, aV(), aSt$(), t!, n&
Const nEl& = 10000000  ' 10 mln
 
ReDim aV(nEl), aSt(nEl)
t = Timer
    For n = 1 To nEl
        aSt(n) = "MiddleStringWithIndex_" & n
        aV(n) = aSt(n)
    Next n
Debug.Print Round(Timer - t, 2), "Create"
 
t = Timer
    PRDX_Arr_Check_IsVariant_NotArray aV
Debug.Print Round(Timer - t, 2), "aV"
 
t = Timer
    PRDX_Arr_Check_IsVariant_NotArray aSt
Debug.Print Round(Timer - t, 2), "aSt"
 
v = aV: t = Timer
    PRDX_Arr_Check_IsVariant_NotArray v
Debug.Print Round(Timer - t, 2), "Var_aV"
 
v = aSt: t = Timer
    PRDX_Arr_Check_IsVariant_NotArray v
Debug.Print Round(Timer - t, 2), "Var_aSt"
End Sub
Мой вариант API
Visual Basic
1
Declare PtrSafe Sub API_Memory_Copy_Int_Any Lib "kernel32.dll" Alias "RtlMoveMemory" (Destination As Integer, Source As Any, ByVal Length As LongPtr)
1
1412 / 878 / 93
Регистрация: 08.02.2017
Сообщений: 3,750
Записей в блоге: 2
29.05.2024, 17:27
Цитата Сообщение от Jack Famous Посмотреть сообщение
Разницы не замечено. Время проверки: 0.00 sec
Да, я тоже проверил, строки дополнительно не конвертируются и не копируются внутри варианта при передаче их внешним функциям.
Кликните здесь для просмотра всего текста
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Sub testVariantStringWinApi()
  #If Win64 Then
    Const ptrSz^ = 8, varSz^ = 24
  #Else
    Const ptrSz& = 4, varSz& = 16
  #End If
    Dim v1, v2, lp0 As LongPtr
    'Проверяем копирование варианта со строкой внутри
    v1 = "fafaf"
    CopyMemory v2, v1, varSz
    Debug.Print StrPtr(v1) = StrPtr(v2) 'True
    
    'Проверяем копирование варианта со строковым массивом внутри
    ReDim sArr$(2): sArr(0) = "a": sArr(1) = "b": sArr(2) = "c"
    v1 = sArr
    CopyMemory v2, v1, varSz
    v1(0) = "n"                         'изменяем 1й элемент массива в первой переменной
    Debug.Print v1(0) = v2(0)           'True
    
    CopyMemory v2, Empty, varSz 'освобождаем указатель
End Sub
1
933 / 366 / 43
Регистрация: 10.05.2021
Сообщений: 1,564
Записей в блоге: 10
30.05.2024, 09:20  [ТС]
Более правильное/точное название темы: "Как идентифицировать вариативную переменную?".
Прошу модераторов перенести весь текст ниже этой строки в конец начального поста темы.

Привёл мысли в порядок и хочу зафиксировать основные моменты по теме.
Если где-то неточен или неправ — прошу поправить.
Смысл темы:
Речь идёт о процедуре (или функции) вида Sub WhatIsIt(v) — то есть, когда процедура имеет вариативный аргумент, то есть позволяет передать что угодно — хоть число, хоть массив, хоть словарь (и так далее).

Как в таком случае идентифицировать, ЧТО именно было передано?
Здесь и далее под вариативной оболочкой будет подразумеваться присвоение значения/массива/объекта вариативной переменной. V будет означать вариативную переменную (Dim V [As Variant] )

Для этого нужно всего 2 (редко — 3) инструмента:
1. Функция VarType(). Определяет тип переменной, но не видит вариативной оболочки.
Пример
Visual Basic
1
2
3
4
5
Private Sub Test()
Dim V, n&
    Debug.Print (VarType(n) = vbLong), (VarType(V) = vbEmpty)   ' True True
    V = n: Debug.Print (VarType(V) = vbLong)                    ' True
End Sub
  Это справедливо для любых типов данных.
2. [Опционально] Для Объектов VarType() вернёт vbObject — будь то словарь регулярка или что ещё. И тут помогает функция TypeName(). Она различает объекты, но только после их инициации
Пример
Visual Basic
1
2
3
4
5
6
7
8
9
10
11
Private Sub Test()
Dim RE As RegExp, dic As Dictionary
 
    Debug.Print (VarType(RE) = vbObject), (VarType(dic) = vbObject) ' True True
    Debug.Print TypeName(RE), TypeName(dic)                         ' Nothing Nothing
 
    Set RE = New RegExp: Set dic = New Dictionary
 
    Debug.Print (VarType(RE) = vbObject), (VarType(dic) = vbObject) ' True True
    Debug.Print TypeName(RE), TypeName(dic)                         ' IRegExp2 Dictionary
End Sub

3. Последний кусочек паззла. Решение от testuser2 из этой темы. Позволяет отличить "истинную" переменную от неё же, но в вариативной обёртке. Это "знание" критически важно для работы с замечательной библой от bedvit — большинство инструментов для работы с массивами ожидают вариативный массив в вариативной переменной/оболочке. То есть, Dim a() [As Variant]: V = a. Или Variant/Variant() — если смотреть в Locals. Собственно, именно необходимость контроля (и трансформации) переменных при передаче в библу, стала причиной этой темы.
Итак, тема отвечает на вопрос, КАК эту самую вариативную оболочку идентифицировать. То есть, как отличить "истинную переменную" от неё же, но присвоенной вариативной переменной.
Или, как сказал автор решения — testuser2: Моя функция определяет является ли переменная Вариантом, не важно массив, она или какого-то простого типа.
Или, если смотреть скрин Locals из шапки темы, то можно сказать, что решение от testuser2 позволяет отличать Variant/String() от String() и им подобных пар — то есть, "увидеть левую часть", если она есть.

Надеюсь, теперь стало понятнее
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
30.05.2024, 09:20

Обычную переменную заменить массивом или списком и реализовать события
Есть программа, в ней кроме самого тела Main имеется 2 класа: 1) нужно сделать так, чтобы из обычной перменной сделать перечислимый...

Как отличить С++ и С?
Добрый день, у нас семинарист не разрешает использовать плюсы на парах. Я после небольшого погружения в cpp запутался, что откуда, как...

Как отличить магнит?
Есть полосовый магнит и стальной брусок, не имеющий собственного магнитного поля, но окрашенный точно также и имеющий те же размеры, других...

Как отличить символы?
Хочу чтобы нельзя было вводить более одного символа &quot;)(/*-+&quot; подряд: ввод одинаковых получилось запретить, а вот разных не получается ...

Как отличить программу от человека?
Здравствуйте! Вопрос: Если на моём сайте сидит программа, которая использует WebBroser, то я могу узнать, что это не человек, получив...


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

Или воспользуйтесь поиском по форуму:
25
Ответ Создать тему
Новые блоги и статьи
Про "Windows must die!"
kumehtar 04.11.2026
Знаете, чет накатило. . . . Когда-то это было почти боевым кличем: мол, нормальный человек сидит на DOS, OS/ 2 или Linux, а вот это вот - Must Die. А теперь человек произносит «мастдай» с усмешкой - и. . .
Красочные поля с номером страницы svg+background-image
russiannick 04.11.2026
Красочные поля с номером страницы не менее важны чем в эпоху бумажных книг. Посему спешу представить почтеннейшей публике этот важный инструмент который эти поля и формирует. В процессе разработки. . .
Вступаем в новую фазу генерации favicons, векторную.
russiannick 02.11.2026
Теперь нет нужды скрывать что используется простой svg. Исходный код изображения помещаем в поле и жмем кнопку. Исходник преобразуется в вид корректный для помещения в favicon или в url(). Нажатие. . .
Генератор паролей (вариант №4)
Maks 01.11.2026
После публикации 3-го варианта генератора паролей, разослал его своим коллегам (с целью оценки), в итоге были получены следующие рекомендации: 1. Вернуть возможность использования знаков | 1 l I;. . .
Генератор паролей (вариант №3)
Maks 30.10.2026
Финальная версия генератора паролей 1С. Доработка решения в этот раз коснулась только визуальной части, а именно, добавлен реквизит ДопПараметры (тип Булево), который скрывает/ отображает реквизиты:. . .
Магическое мышление и магия, современная наука не отличима от магии (говорит ИИ Джемени)
zorxor 30.10.2026
Джемени, расскажи, пожалуйста, что такое магическое мышление, что такое магия, почему современная наука чем-то напоминает магию? Фраза «Любая достаточно развитая технология неотличима от магии». . .
За какое время ИИ может подобрать пароль по хешу (рассказывает Джемени ИИ)
zorxor 30.10.2026
Расскажи, Джемени, если известен хэш МД5, например, за сколько ИИ сможет подобрать соответствующий пароль? Искусственный интеллект (ИИ) может подобрать простой или средний по сложности пароль по. . .
Кто убил Suno? Почему наше солнышко погасло? (диалог с ИИ Джемени)
zorxor 30.10.2026
Как убивали Suno. Хронология. «Убийство» музыкальной нейросети Suno — это затяжной процесс, в котором технологический хайп стартапа разбился о жесткую реальность судебных исков от гигантов. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru