Как назначить массивы с несколькими типами данных в VBA, а затем использовать данные в функциях, требующих определенных типов данных?

Я работаю над программой, которая выполняет расчеты на нескольких физических элементах. Существует около 5 типов элементов, каждый из которых требует разных входных данных (с разными типами данных) для вычислений. Нет ограничений на количество элементов или порядок, в котором они могут быть вычислены.

Например: первый набор данных может иметь элемент типа A, элемент типа B и второй элемент типа A.

Второй набор данных может содержать элемент типа C, элемент типа B и пять элементов типа A.

Тип элемента A может иметь ввод типа (строка) и ввод давления (двойной). Тип элемента B может иметь ввод типа (строка), ввод длины (двойной), ввод количества ребер (целое число). Тип элемента C может иметь ввод длины (двойной), диаметра (двойной) и количество (целое) ввод

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

Проблема в том, что когда я затем пытаюсь использовать эти данные в других функциях (вызывая Array(1,2)) я получаю ошибку "несоответствие типа аргумента byref".

Из того, что я могу сказать, это означает, что моя программа не ЗНАЕТ, что значение, содержащееся в слоте моего массива, может/должно быть правильным типом данных. он просто видит «вариант», а не «двойной» или «строку», и выдает ошибку.

Я нашел пару способов обойти это. 1) Я могу поместить данные в круглые скобки при вызове функции. Очевидно, это заставляет данные соответствовать ожидаемому типу данных. функция(вход1, (Массив(1,2)), ввод3)

2) Я могу зайти во все свои функции и изменить ожидаемые типы данных на вариант.

Проблема в том, что я выполняю инженерный расчет и забочусь о поддержании определенного уровня точности в своих числах. Я также НЕ хочу, чтобы мои функции могли работать, если входные данные не имеют смысла. Мне кажется, что вариант 1 несет в себе высокий риск потери важных данных при принудительной конвертации. Я не уверен, что вариант 2 лучше, поскольку vba, похоже, не назначает/отслеживает эти типы данных, как я себе представлял.

Есть ли лучший способ для назначения и передачи данных различных типов?


person Whyengineersshouldntprogram    schedule 01.10.2019    source источник
comment
Всегда помогает показать небольшой образец того, что вы пробовали. Похоже, вам, вероятно, следует создать несколько пользовательских типов или классов (где каждый член имеет определенный тип данных) для ваших различных типов элементов, а затем вы можете добавить их в коллекцию/массив и передать для обработки.   -  person Tim Williams    schedule 02.10.2019


Ответы (1)


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

Например, используя классы:

Пара очень простых классов (только общедоступные переменные, без методов):

'class module clsA
Public MyType As String
Public Pressure As Double

'class module clsB
Public MyType As String
Public Length As Double
Public FinCount As Integer

В обычном модуле кода:

Sub tester()
    Dim colThings As New Collection, e

    colThings.Add MakeTypeAThing("TypeA", 67.92)
    colThings.Add MakeTypeBThing("TypeB", 19.56, 4)
    colThings.Add MakeTypeAThing("TypeA", 0.38)

    For Each e In colThings
        Debug.Print TypeName(e)
    Next e

End Sub


'Couple of "factory" functions to create instances of your classes
'  and set the member fields

Function MakeTypeAThing(typ As String, Pressure As Double) As clsA
    Dim rv As New clsA
    rv.MyType = typ
    rv.Pressure = Pressure
    Set MakeTypeAThing = rv
End Function

Function MakeTypeBThing(typ As String, l As Double, Fins As Integer) As clsB
    Dim rv As New clsB
    rv.MyType = typ
    rv.Length = l
    rv.FinCount = Fins
    Set MakeTypeBThing = rv
End Function
person Tim Williams    schedule 02.10.2019
comment
Это выглядит очень многообещающе, спасибо! Я не смогу попробовать это до следующей недели, но я дам вам знать, если это сработает для моего приложения! - person Whyengineersshouldntprogram; 02.10.2019